<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
This community needs a repository for plugins. A directory at
<a class="moz-txt-link-freetext" href="http://ftp.squeak.org">http://ftp.squeak.org</a> ought to do it. <br>
<br>
If I want to try Alien I need the plugin. Where am I going to get
that? I could get VMMaker, read NewSqueakIA32ABIPlugin three times
to see it is not saying Newspeak and realize it compiles a plugin
called IA32ABI, which - coincidentally - is the name of the plugin
the error Alien exampleCqsort will gives me. (NewSqueakIA32ABIPlugin
class>> moduleName returns IA32ABI). <br>
<br>
Does anybody know what the Genie plugin does? Does Paul DeBrucker
need to store a BerkeleyDB plugin dll he got by emailing somebody on
GitHub? <br>
<br>
If I understand this correctly, if such a directory existed, then
all a person would need to do to try the above Alien code would be
to download a pre-compiled plugin from - say -
<a class="moz-txt-link-freetext" href="http://ftp.squeak/plugins/Alien/fooVersion">http://ftp.squeak/plugins/Alien/fooVersion</a>, put it in their VM
directory and start the image. Then check with SmalltalkImage
current listLoadedModules to see if you're ready to go. <br>
<br>
I nominate Fabio Niephaus to be the person the community can send
pre-compiled plugins for inclusion in such a directory. Eliot's been
banging away about Alien for some time [1]. If a person could go,
get the plugin and give the code shot, he could have more productive
conversations about Alien. <br>
<br>
So, if, Eliot, you have a pre-compiled plugin for Alien, perhaps in
an idle moment, you could email it to Fabio? And when, Fabio, you've
created the directory in <a class="moz-txt-link-freetext" href="http://ftp.squeak.org">http://ftp.squeak.org</a> you could announce it
here on Squeak-dev? <br>
<br>
FWIW,<br>
<br>
Chris <br>
<br>
[1] <a class="moz-txt-link-freetext" href="http://wiki.squeak.org/squeak/uploads/6100/">http://wiki.squeak.org/squeak/uploads/6100/</a><br>
<br>
<div class="moz-cite-prefix">On 2015-09-03 7:07 PM, Eliot Miranda
wrote:<br>
</div>
<blockquote
cite="mid:CAC20JE0JwYecL5onq-=-vL_Vs7nY13sjDX9Xn_s+2mk+pp+J-w@mail.gmail.com"
type="cite">
<div dir="ltr">Hi Craig,
<div><br>
</div>
<div> you need Alien-eem.24</div>
<div><br>
</div>
<div>Here's Alien class>>exampleCqsort</div>
<div><span class="" style="white-space:pre">        </span>"Call the
libc qsort function (which requires a callback)."</div>
<div><span class="" style="white-space:pre">        </span>"Alien
exampleCqsort"</div>
<div><span class="" style="white-space:pre">        </span>"(Time
millisecondsToRun: [100 timesRepeat: [Alien exampleCqsort]]) /
100.0"</div>
<div><span class="" style="white-space:pre">        </span>| cb rand
nElements sizeofDouble values orig sort |</div>
<div><span class="" style="white-space:pre">        </span>rand :=
Random new.</div>
<div><span class="" style="white-space:pre">        </span>values :=
Alien newC: (nElements := 100) * (sizeofDouble := 8).</div>
<div><span class="" style="white-space:pre">        </span>1 to: values
dataSize by: sizeofDouble do:</div>
<div><span class="" style="white-space:pre">                </span>[:i| values
doubleAt: i put: rand next].</div>
<div><span class="" style="white-space:pre">        </span>orig := (1
to: values dataSize by: sizeofDouble) collect: [:i| values
doubleAt: i].</div>
<div><span class="" style="white-space:pre">        </span>cb :=
Callback</div>
<div><span class="" style="white-space:pre">                        </span>signature:
#(int (*)(const void *, const void *))</div>
<div><span class="" style="white-space:pre">                        </span>block: [
:arg1 :arg2 | ((arg1 doubleAt: 1) - (arg2 doubleAt: 1)) sign].</div>
<div><span class="" style="white-space:pre">        </span>(Alien
lookup: 'qsort' inLibrary: Alien libcName)</div>
<div><span class="" style="white-space:pre">                </span>primFFICallResult:
nil</div>
<div><span class="" style="white-space:pre">                </span>with:
values pointer</div>
<div><span class="" style="white-space:pre">                </span>with:
nElements</div>
<div><span class="" style="white-space:pre">                </span>with:
sizeofDouble</div>
<div><span class="" style="white-space:pre">                </span>with: cb
thunk.</div>
<div><span class="" style="white-space:pre">        </span>sort := (1
to: values dataSize by: sizeofDouble) collect: [:i| values
doubleAt: i].</div>
<div><span class="" style="white-space:pre">        </span>values free.</div>
<div><span class="" style="white-space:pre">        </span>^orig ->
sort</div>
<div><br>
</div>
<div>The above example uses Alien to make the callout. To use
it with the FFI simply pass cb pointer as the argument as is
done above.</div>
<div><br>
</div>
<div><br>
</div>
<div>Implementation:</div>
<div><br>
</div>
<div>The way that it works is in two parts</div>
<div>- the VM passes up a pointer to a structure from which all
arguments, stacked and in registers (because the VM has copied
the register args into the struct) can be accessed, and
through which the result can be returned.</div>
<div>- the image level provides marshalling methods that match
the signature in the callback</div>
<div><br>
</div>
<div>So e.g. with a callback of<br>
</div>
<div>
<div><span class="" style="white-space:pre">                </span>Callback</div>
<div><span class="" style="white-space:pre">                        </span>signature:
#(int (*)(const void *, const void *))</div>
<div><span class="" style="white-space:pre">                        </span>block: [
:arg1 :arg2 | ((arg1 doubleAt: 1) - (arg2 doubleAt: 1))
sign]</div>
</div>
<div>the marshalling methods are in Callback's signature
protocol:</div>
<div><br>
</div>
<div>Callback>>voidstarvoidstarRetint: callbackContext sp:
spAlien</div>
<div><span class="" style="white-space:pre">        </span><signature:
#(int (*)(const void *, const void *)) abi: 'IA32'></div>
<div><span class="" style="white-space:pre">        </span>^callbackContext
wordResult:</div>
<div><span class="" style="white-space:pre">                </span>(block</div>
<div><span class="" style="white-space:pre">                        </span>value:
(Alien forPointer: (spAlien unsignedLongAt: 1))</div>
<div><span class="" style="white-space:pre">                        </span>value:
(Alien forPointer: (spAlien unsignedLongAt: 5)))</div>
<div><br>
</div>
<div>where spAlien is an Alien pointing to a
VMCallbackContext32.</div>
<div><br>
</div>
<div>For ARM support we would add</div>
<div><br>
</div>
<div>Callback>>voidstarvoidstarRetint: callbackContext sp:
spAlien intRegArgs: regsAlien</div>
<div><span class="" style="white-space:pre">        </span><signature:
#(int (*)(const void *, const void *)) abi: 'ARMV5'></div>
<div><span class="" style="white-space:pre">        </span>^callbackContext
wordResult:</div>
<div><span class="" style="white-space:pre">                </span>(block</div>
<div><span class=""><span class="" style="white-space:pre">                        </span>value:
(Alien forPointer: (</span>regsAlien<span class=""> unsignedLongAt:
1))</span></div>
<div><span class=""><span class="" style="white-space:pre">                        </span>value:
(Alien forPointer: (</span>regsAlien<span class=""> unsignedLongAt:
5)))</span></div>
<div><span class=""><br>
</span></div>
<div><span class="">Basically the idea is that the selector of
the method doesn't matter except for the number of
arguments. What's important is the pragma which defines the
signature and the ABI for which this is a valid marshalling
method.</span></div>
<div><span class=""><br>
</span></div>
<div><span class="">When the callback is instantiated, Callback
introspects to find the marshalling </span><span class="">method that
matches the signature. If one doesn't already exist you can
write one. Hopefully we'll write an ABI compiler that will
automatically generate these marshalling </span>methods
according to the platform's ABI, but for now its a manual
process. But at least it's open and flexible. When the
callback is invoked the evaluator is performed with the
current callbackContext and pointer(s) to the arguments.
There is a 32-bit and a 64-bit callback context, and it can
have a stack pointer, integer register args and floating point
register args. So it's general enough for any callback.</div>
<div><br>
</div>
<div>To pass back the result, a value is assigned into the
struct via the accessor in the marshalling method and control
returns to teh point where teh callback comes in, and this
uses a primitive to return. Inside the callbackCOntext is a
jmpbuf from a setjmp. The primitive longjmp's back to the
entry point in the VM which extracts the result and the code
for the kind of result and returns:</div>
<div><br>
</div>
<div>Callback class>>invokeCallbackContext:
vmCallbackContextAddress "<Integer>"
"^<FFICallbackReturnValue>"</div>
<div><span class="" style="white-space:pre">        </span>"The
low-level entry-point for callbacks sent from the VM/IA32ABI
plugin.</div>
<div><span class="" style="white-space:pre">        </span> Return via
primReturnFromContext:through:. thisContext's sender is the</div>
<div><span class="" style="white-space:pre">        </span> call-out
context."</div>
<div><span class="" style="white-space:pre">        </span>|
callbackAlien type |</div>
<div><span class="" style="white-space:pre">        </span>callbackAlien
:= (Smalltalk wordSize = 4</div>
<div><span class="" style="white-space:pre">                                                </span>ifTrue:
[VMCallbackContext32]</div>
<div><span class="" style="white-space:pre">                                                </span>ifFalse:
[VMCallbackContext64])</div>
<div><span class="" style="white-space:pre">                                                        </span>atAddress:
vmCallbackContextAddress.</div>
<div><span class="" style="white-space:pre">        </span>[type :=
Callback evaluateCallbackForContext: callbackAlien]</div>
<div><span class="" style="white-space:pre">                </span>ifCurtailed:
[self error: 'attempt to non-local return across a callback'].</div>
<div><span class="" style="white-space:pre">        </span>type ifNil:</div>
<div><span class="" style="white-space:pre">                </span>[type := 1.
callbackAlien wordResult: -1].</div>
<div><span class="" style="white-space:pre">        </span>callbackAlien
primReturnAs: type fromContext: thisContext</div>
</div>
<div class="gmail_extra"><br>
<div class="gmail_quote">On Thu, Sep 3, 2015 at 5:22 AM, Craig
Latta <span dir="ltr"><<a moz-do-not-send="true"
href="mailto:craig@netjam.org" target="_blank">craig@netjam.org</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Hi all--<br>
<br>
I'd like to use a C shared library via FFI from Squeak
or Pharo.<br>
Specifically, I want to call a C function which takes as one
of its<br>
parameters a pointer to an array of callback function
addresses. Does<br>
one of the FFI approaches floating around handle that, and
provide a<br>
relatively pleasant mapping between Smalltalk block closures
and C<br>
callback function addresses?<br>
<br>
I was doing this so far in GemStone, but apparently its
FFI only<br>
supports passing callback function addresses one at a time
as direct<br>
parameters of C callouts. I suppose I could write a wrapper
C library<br>
around the one I really want to use, that provides the
callback setup<br>
interface that GemStone expects, but whenever I have to
write actual C<br>
code I start to think "Hm, why don't I just use a Smalltalk
VM for which<br>
I have the source?" :) All the fancy distributed
object-database stuff<br>
that my project also wants can wait for a bit.<br>
<br>
<br>
thanks!<br>
<br>
-C<br>
<br>
--<br>
Craig Latta<br>
<a moz-do-not-send="true" href="http://netjam.org"
rel="noreferrer" target="_blank">netjam.org</a><br>
<a moz-do-not-send="true"
href="tel:%2B31%20%20%206%202757%207177"
value="+31627577177">+31 6 2757 7177</a> (SMS ok)<br>
<a moz-do-not-send="true"
href="tel:%2B%201%20415%20%20287%203547"
value="+14152873547">+ 1 415 287 3547</a> (no SMS)<br>
<br>
<br>
</blockquote>
</div>
<br>
<br clear="all">
<div><br>
</div>
-- <br>
<div class="gmail_signature">
<div dir="ltr">
<div><span style="font-size:small;border-collapse:separate">
<div>_,,,^..^,,,_<br>
</div>
<div>best, Eliot</div>
</span></div>
</div>
</div>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">
</pre>
</blockquote>
<br>
</body>
</html>