[Vm-dev] Pharo FFI on aarch64/arm64

Eliot Miranda eliot.miranda at gmail.com
Fri Mar 15 03:19:11 UTC 2019

Hi Ken,

On Thu, Mar 14, 2019 at 2:09 PM <ken.dickey at whidbey.com> wrote:

>  Greetings,
> I have been making small progress in getting Pharo's FFI unit tests to
> pass on arm64.
> Built from recent
>    OpenSmalltalk opensmalltalk-vm build.linux64ARMv8/pharo.stack.spur
> I get a pharo vm whose UI is pretty slow (no JIT so far), so current
> progress is slow.
> I am looking at #FFICallbackThunk>initializeARM32 but I don't yet
> understand quite what this code is trying to do, so have not made proper
> changes for arm64.
> Anybody care to join in or advise me on this?
> Note that I am neither a Pharo nor a UnifiedFFI user, so I may be making
> really dumb mistakes at this point (i.e. _you_ could help me out here!
> 8^).

Can we start from the last section of the comment for which I wrote on
February 6th?  I wrote the following.  What is missing from this
information that you need to understand how to proceed?

Callbacks are not handled by this plugin.  Instead they are handled by
image-level code to create Alien "thunks", small sequences of machine code,
that invoke a function thunkEntry, implemented as required by each platform
in one of the files in platforms/Cross/plugins/IA32ABI (a regrettable name;
it should be something like platforms/Cross/plugins/AlienCallbacks).  Each
platform's thunkEntry has a signature that takes all integer register
parameters (if any), all floating-point register parameters (if any), a
pointer to the thunk, and the stack pointer at the point the thunk was
invoiked.  To pass a callback to foreign code, the marshaller in this
plugin passes the address of the thunk.  When external code calls that
address the think is invoked, and it invokes thunkEntry as required.
 thunkEntry then saves its parameters locally in an instance of
VMCallbackContext, which includes a jmpbuf.  thunkEntry then does a setjmp
and enters the VM via sendInvokeCallbackContext[:], which creates an
activation of invokeCallbackContext: to execute the callback.  This method
then extracts the address of the thunk from the VMCallbackContext and
invokes machinery in Callback to match the address with a Smalltalk block.
The block is then evaluated with the parameters extracted from the
VMCallbackContext, marshalled by methods in Callback subclasses signatures
protocol, which know whether a parameter would be passed in a register or
on the stack.  The result of the block is then passed back to thunkEntry by
storing it in a field in the VMCallbackContext and invoking
primSignal:andReturnAs:fromContext:, which uses longjmp to jump back to
thunkEntry which then extracts the result from its VMCallbackContext and

For  example, the signature of thunkEntry on x86/IA32
(platforms/Cross/plugins/IA32ABI/ia32abicc.c) is
thunkEntry(void *thunkp, sqIntptr_t *stackp)
whereas on ARMv4/5/6 (platforms/Cross/plugins/IA32ABI/arm32abicc.c) it is
long long
thunkEntry(long r0, long r1, long r2, long r3,
           double d0, double d1, double d2, double d3,
           double d4, double d5, double d6, double d7,
           void *thunkpPlus16, sqIntptr_t *stackp)

> Thanks much in advance,
> -KenD

best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20190314/0c5d959f/attachment-0001.html>

More information about the Vm-dev mailing list