<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Sep 15, 2015 at 8:29 AM, Esteban Lorenzano <span dir="ltr"><<a href="mailto:estebanlm@gmail.com" target="_blank">estebanlm@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
Hi,<br>
<br>
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).<br>
That means review certain stuff, a couple of them I already submitted in my last commit.<br>
Now I have this problem. This is my example method:<br>
<br>
exampleCqsort<br>
| cb rand values orig sort |<br>
<br>
rand := Random new.<br>
values := FFIExternalArray newType: 'double' size: 100.<br>
1 to: 100 do: [ :i| values at: i put: rand next ].<br>
orig := (1 to: 100) collect: [:i| values at: i].<br>
cb := Callback<br>
signature: #(int (*)(const void *, const void *))<br>
block: [ :arg1 :arg2 | ((arg1 doubleAt: 1) - (arg2 doubleAt: 1)) sign ].<br>
[<br>
self primQsort: values getHandle with: 100 with: values type typeSize with: cb thunk.<br>
sort := values asArray ]<br>
ensure: [ values free ].<br>
^orig -> sort<br>
<br>
primQsort: array with: count with: size with: compare<br>
<cdecl: void 'qsort' (void* ulong ulong void*) module: 'libc’><br>
^ self primitiveFailed<br>
<br>
… that basically works. But this depends on this method in Callback:<br>
<br>
voidstarvoidstarRetint: callbackContext sp: spAlien<br>
<signature: #(int (*)(const void *, const void *)) abi: 'IA32'><br>
| value |<br>
<br>
value := block<br>
value: (Alien forPointer: (spAlien unsignedLongAt: 1))<br>
value: (Alien forPointer: (spAlien unsignedLongAt: 5)).<br>
^ callbackContext wordResult: value<br>
<br>
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).<br>
So this function would be something like this instead:<br>
<br>
voidstarvoidstarRetint: callbackContext sp: spAlien<br>
<signature: #(int (*)(const void *, const void *)) abi: 'IA32'><br>
| value |<br>
<br>
value := block<br>
value: (spAlien pointerAt: 1) “It will answer an ExternalAddress”<br>
value: ((spAlien pointerAt: 5). “It will answer an ExternalAddress”<br>
^ callbackContext wordResult: value<br>
<br>
So… this *should* work but it doesn’t because in primitiveFFIDoubleAt: I have a call to<br>
<br>
ffiAddressOf: rcvr startingAt: byteOffset size: byteSize<br>
<br>
who mades this check:<br>
<br>
"don't you dare to read from object memory!"<br>
(addr == 0 or:[interpreterProxy isInMemory: addr])<br>
ifTrue:[^interpreterProxy primitiveFail].<br>
<br>
and well… since I’m calling things from a callback the #isInMemory: method fails.<br>
<br>
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.<br>
<br>
But! Since there was that comment ("don't you dare to read from object memory!”)… I’m afraid I can be making a mistake.<br>
<br>
What do you think?</blockquote><div><br></div><div>The elements of your FFIExternalArray should be in malloc's heap, not in the Smalltalk heap, so the check should pass. </div></div></div></div>