On Mar 15, 2011, at 3:36 PM, Eliot Miranda wrote:
> I expect that if the standard FFI plugin answers an instance of OopType64
> then you've found a bug in the ReentrantFFIPlugin. If you're brave you'll
> have a look at both plugins and try and verify that that's the case. But I
> have to say that the FFI plugins are not simple.
Brave, yes. Smart, no. Here's what it looks like to my untrained eye:
1. When the ExternalFunction is compiled, the return argType is not flagged as
a structure. So the primitives, old and new, see this as a regular non-struct
callout, but with return class = OopType64. So far, so good.
2. The old plugin had this one-slot "wrapping" capability at the bottom of
#ffiCreateReturn: (which is called only for non-pointer, non-structure
functions):
ffiRetClass := interpreterProxy popRemappableOop.
ffiRetClass == interpreterProxy nilObject ifTrue:[
"Just return oop"
^interpreterProxy push: retOop].
"Otherwise create an instance of external structure and store the
return oop"
interpreterProxy pushRemappableOop: retOop.
retOop := interpreterProxy instantiateClass: ffiRetClass indexableSize:
0.
oop := interpreterProxy popRemappableOop.
interpreterProxy storePointer: 0 ofObject: retOop withValue: oop.
^interpreterProxy push: retOop.
3. There's some very similar code in FFIPlugin>>ffiCreateReturnStruct and
ReentrantIA32FFIPlugin>>ffiReturnStruct:ofType:in: -- the main difference is a
memcpy().
Am I on the right track? If so, how would you like to see the code structured
to get this feature restored? We could add a new wrap-if-necessary return
method, or we could try to reuse #ffiReturnStruct:ofType:in: if we guarded the
memcpy() with a flag check for FFIFlagStructure.
Or maybe there's a cleaner solution that's beyond my hazy view at the moment.
--
Ken Treis
Miriam Technologies, Inc.