[Vm-dev] external addresses and callbacks (FFI+Alien merge)

Esteban Lorenzano estebanlm at gmail.com
Fri Sep 18 10:11:49 UTC 2015


> On 18 Sep 2015, at 05:55, Ryan Macnak <rmacnak at gmail.com> wrote:
> 
> On Tue, Sep 15, 2015 at 8:29 AM, Esteban Lorenzano <estebanlm at gmail.com <mailto:estebanlm at gmail.com>> wrote:
> 
> Hi,
> 
> I’m working on merge FFI with Alien as a way to provide a single callback mechanism (I already talked with Eliot and he agrees this is the way to go in the future).
> That means review certain stuff, a couple of them I already submitted in my last commit.
> Now I have this problem. This is my example method:
> 
> exampleCqsort
>         | cb rand values orig sort |
> 
>         rand := Random new.
>         values := FFIExternalArray newType: 'double' size: 100.
>         1 to: 100 do: [ :i| values at: i put: rand next ].
>         orig := (1 to: 100) collect: [:i| values at: i].
>         cb := Callback
>                 signature:  #(int (*)(const void *, const void *))
>                 block: [ :arg1 :arg2 | ((arg1 doubleAt: 1) - (arg2 doubleAt: 1)) sign ].
>         [
>                 self primQsort: values getHandle with: 100 with: values type typeSize with: cb thunk.
>                 sort := values asArray ]
>         ensure: [ values free ].
>         ^orig -> sort
> 
> primQsort: array with: count with: size with: compare
>         <cdecl: void 'qsort' (void* ulong ulong void*) module: 'libc’>
>         ^ self primitiveFailed
> 
> … that basically works. But this depends on this method in Callback:
> 
> voidstarvoidstarRetint: callbackContext sp: spAlien
>         <signature: #(int (*)(const void *, const void *)) abi: 'IA32'>
>         | value |
> 
>         value := block
>                         value: (Alien forPointer: (spAlien unsignedLongAt: 1))
>                         value: (Alien forPointer: (spAlien unsignedLongAt: 5)).
>         ^ callbackContext wordResult: value
> 
> And I want to remove Alien from the equation (there will still be some… and there will be the primitives of course, but I want to reduce their use at the minimum for obvious reasons: hide the extra complexity to users).
> So this function would be something like this instead:
> 
> voidstarvoidstarRetint: callbackContext sp: spAlien
>         <signature: #(int (*)(const void *, const void *)) abi: 'IA32'>
>         | value |
> 
>         value := block
>                         value: (spAlien pointerAt: 1) “It will answer an ExternalAddress”
>                         value: ((spAlien pointerAt: 5). “It will answer an ExternalAddress”
>         ^ callbackContext wordResult: value
> 
>  So… this *should* work but it doesn’t because in primitiveFFIDoubleAt: I have a call to
> 
> ffiAddressOf: rcvr startingAt: byteOffset size: byteSize
> 
> who mades this check:
> 
>                 "don't you dare to read from object memory!"
>                 (addr == 0 or:[interpreterProxy isInMemory: addr])
>                         ifTrue:[^interpreterProxy primitiveFail].
> 
> and well… since I’m calling things from a callback the #isInMemory: method fails.
> 
> If I took out that method everything works ok and since the equivalent IA32ABIPlugin does not have that check I can suppose it is ok to remove the validation.
> 
> But! Since there was that comment ("don't you dare to read from object memory!”)… I’m afraid I can be making a mistake.
> 
> What do you think?
> 
> The elements of your FFIExternalArray should be in malloc's heap, not in the Smalltalk heap, so the check should pass. 

it doesn’t, that’s the point. 
also IMO that’s incorrect: if I want to read some structure in smalltalk memory who will be passed as a ByteArray (bah, a byte*) to FFI, that check will fail too… and that’s incorrect.
and since that check was removed in IA32ABIPlugin, I think this has been taken into account.

Esteban


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20150918/d4d7c15a/attachment.htm


More information about the Vm-dev mailing list