Binding a single function symbol with [foreign]
Jorn Vernee
jbvernee at xs4all.nl
Mon Sep 10 12:24:24 UTC 2018
>> Firstly, I had to implement asCallback, which basically just creates a
>> new CallbackImpl with the pointer itself as the entry point.
> That's very clever - but what's the difference, may I ask, between this
> and:
>
> @NativeHeader("puts=(u64:i8)i32")
> public interface PutsLib {
> int puts(Pointer<Byte> message);
> }
>
> And then bind the interface with Libraries.bind ? Actually, I believe
> this latter version should be more performant, as the spinned
> implementation generated by the binder will just have a direct exact
> method handle call to the native code; whereas in the callback case
> there are some few extra checks (e.g. to check that the scope is still
> alive and also to check whether the entry point is a real native
> function or a synthetic stub generated by the binder, in which case we
> shortcircuit and do a Java 2 Java call directly).
Yeah, I suppose there is not much difference if I'm using a pointer to a
library symbol. My views on this have changed, I assumed wrapping a
single function in a MethodHandle would be easier. But, you still need
the same information, using an interface is just a different way of
providing it. Though my idea might still be a good solution for when you
have an arbitrary void Pointer that you want to make invokable, or when
you want to 'cast' a Callback to a different type (i.e.
Callback.entryPoint() -> void Pointer ->
Pointer.asCallback(SomeOtherCallbackType.class)) ?
I also had another version which used the result of
`NativeInvoker::getBoundMethodHandle` prefixed with a call to
`Pointer::addr`, also adding a constructor to NativeInvoker that took a
MethodType. That was working just as well, but this idea seemed more
interesting for the average use cases, since it's a more high-level API.
The only difference in capability I see between the two, is that the
MethodType + Function combination can be derived dynamically, where as
with an interface you would need the information to be statically know
(or spin the interface, which is 'meh' for usability imho).
>> Secondly, the CallbackImpl::asFunction method uses the Scope of it's
>> entry point, but in the case of a library symbol that scope is null,
>> so it fails with an NPE. As a workaround I'm creating (and leaking) a
>> new native scope in case the scope is null. Maybe a longer term
>> solution could be something like library symbol pointers returning a
>> Scope that is tied to the lifetime of the library itself?
> The idea (not implemented yet) is that each Library will have a
> meaningful Scope that will stay alive as long as that library is
> loaded. That Scope will also be used internally by the binder to, e.g.
> allocate constants, or global variable values, etc. So your code will
> be able to piggy back on that.
Sounds great!
>> The code half works; It prints the message, and then it crashes [1]
>> but that might just be because I'm on windows which is not supported?
>> At least I think this API is pretty nice. I haven't been able to build
>> jextract yet, so thorough testing is difficult.
> Yeah - windows is not supported - I'm actually surprised it works at
> all, given that the registers used by the Windows ABI and system V ABI
> are quite different; for instance, System V (the implemented one)
> passes its first integer argument via the RDI register, whereas the
> Windows ABI uses RCX; so the failure you are seeing is related to the
> fact that the current code doesn't arrange the arguments/return values
> in a way that is compatible with the underlying system ABI on your
> machine.
Using -Xlog:panama I did see the first argument being put into RCX.
Maybe that's just a coincidence? tbh I didn't know different ABIs were
being used. For the standard library I always thought 32bit used cdecl,
and 64bit used fastcall, which I thought would use the same registers on
all systems. That's interesting to hear (I don't dabble in ABIs too
often).
> But it seems like you are taking the code for some serious spin, and
> that's some invaluable feedback to us - thanks!
Glad to be doing it! The OpenJDK code is very interesting to look at
(though daunting at times). It's also a very cool feeling that I can
actually change the machinery I'm running my programs on, even if it's
just to do experiments with :)
Jorn
> Maurizio
More information about the panama-dev
mailing list