[Vm-dev] external addresses and callbacks (FFI+Alien merge)
Ryan Macnak
rmacnak at gmail.com
Fri Sep 18 03:55:13 UTC 2015
On Tue, Sep 15, 2015 at 8:29 AM, Esteban Lorenzano <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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20150917/d6262da4/attachment.htm
More information about the Vm-dev
mailing list