<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">&lt;<a href="mailto:estebanlm@gmail.com" target="_blank">estebanlm@gmail.com</a>&gt;</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: &#39;double&#39; 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 -&gt; sort<br>
<br>
primQsort: array with: count with: size with: compare<br>
        &lt;cdecl: void &#39;qsort&#39; (void* ulong ulong void*) module: &#39;libc’&gt;<br>
        ^ self primitiveFailed<br>
<br>
… that basically works. But this depends on this method in Callback:<br>
<br>
voidstarvoidstarRetint: callbackContext sp: spAlien<br>
        &lt;signature: #(int (*)(const void *, const void *)) abi: &#39;IA32&#39;&gt;<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>
        &lt;signature: #(int (*)(const void *, const void *)) abi: &#39;IA32&#39;&gt;<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>
                &quot;don&#39;t you dare to read from object memory!&quot;<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 (&quot;don&#39;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&#39;s heap, not in the Smalltalk heap, so the check should pass. </div></div></div></div>