On 30 March 2011 10:01, Andreas Raab andreas.raab@gmx.de wrote:
On 3/30/2011 4:12, Eliot Miranda wrote:
Classes *don't* inherit from nil. nil is at the end of their superclass chain. That's different from inheriting. At least in current images UndefinedObject includesBehavior: nil is false, which seems right to me. nil is not a behavior; its use as the sentinel at the end of the superclass chain doesn't imply it is a behavior. So I propose that we change includesBehavior:ThatOf: to something like StackInterpreter methods for plugin primitive support includesBehavior: aClass ThatOf: aSuperclass "Return the equivalent of aClass includesBehavior: aSuperclass. Note: written for efficiency and better inlining (only 1 temp)" | theClass | <inline: true> aSuperclass = objectMemory nilObject ifTrue: [^false]. theClass := aClass. [theClass = aSuperclass ifTrue: [^true]. theClass ~= objectMemory nilObject] whileTrue: [theClass := self superclassOf: theClass]. ^false I don't think this will affect anything other than FFI and Alien since those are the only uses I can find, and in my reading of that code the proposed change seems fine; safer in fact. Agreed?
Sounds reasonable to me. The one thing to check is if there are any places that currently assume that includesBehavior:ThatOf: returns true for a nil argument. If so, we can still add an explicit check that tests for interpreterProxy classAlien to be nil but I agree that the above would be the better solution.
Hmm.. i'd prefer to not see this in marshalling code. But its easier to say than to do.
I did the following trick in NativeBoost:
- added own GC root - an array which serves as a registry for all classes & other tricky stuff, like callbacks.
To test if argument belongs to specific class, i putting the class to that array and then code generator emits the code to load class oop from that array at specific index (which i have obtained during registration), and compares that class oop with class of argument which needs to be marshalled. (For curious, the marshalling implementation is in NBExternalObjectType class).
In Alien, one could do a similar trick. For signature like:
void * foo (MyAlienClass arg1 , MyAlienClass2 arg2)
one could: - put the MyAlienClass and MyAlienClass2 into signature descriptor (or somewhere else), which will tell that during marshalling, a passed argument's class must be exactly same. Then you can avoid slow and cumbersome membership testing, but just test oop's class.
As to me, using inheritance to check argument type is slow and not guarantees correct coercion. For example, all external structures is subclasses of NBExternalStructure, but obviously if you pass an instance of one struct type, say StructA to function which expects StructB. In this case, a membership testing gives nothing.
Cheers, - Andreas