Hi All, Andreas, vm-devs this is a question of y'all. Recently I integrated some of the merge of Alien callback support into ReentrantFFIPlugin. This broke OpenGL example in images not containing Alien. Here's the breakage:
As part of Alien marshalling the FFI plugin needs to know if an argument is an Alien and hence dereference it correctly to pass its address. Here's the code in ReentrantFFIPlugin >>ffiAtomicArgByReference:Class:in:
isAlien := (isString := interpreterProxy includesBehavior: oopClass
ThatOf: interpreterProxy classString) ifTrue: [false] ifFalse:
[interpreterProxy includesBehavior: oopClass ThatOf: interpreterProxy classAlien].
This is erroneously setting isAlien to true when oopClass is Bitmap (i.e. when uploadFont: tries to glBitmap:with:with:with:with:with:with: a Bitmap). That causes the marshaller to treat the Bitmap as if it were an Alien and pass a field in the Bitmap instead of the Bitmap's base address. Boom.
The problem is that a) if Alien isn't installed in the image then interpreterProxy classAlien == interpreterProxy nilObject,
and b) includesBehavior:ThatOf: always answers true if its second argument is nilObject. I suggest that includesBehavior:ThatOf: is incorrect:
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> (((theClass := aClass) = aSuperclass) "aClass == aSuperclass"
or:[aSuperclass = objectMemory nilObject]) "every class inherits from nil" ifTrue:[^true].
[(theClass := self superclassOf: theClass) = aSuperclass ifTrue:[^true]. theClass ~= objectMemory nilObject] whileTrue.
^false 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?
On Thu, Mar 17, 2011 at 12:30 PM, Matthew Fulmer <[hidden email]> 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. 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. Cheers, - Andreas |
Free forum by Nabble | Edit this page |