jnr-invoke - MethodHandle access to native functions

116 views
Skip to first unread message

Wayne Meissner

unread,
Sep 30, 2013, 6:28:57 PM9/30/13
to jvm...@googlegroups.com
I've been experimenting with the low-level plumbing of JNR, trying to
replace the multitude of code generators (there's different ones in
JRuby's FFI, jnr-ffi and jython's ctypes), with a common API.

To use it, you do something like:

// Create a function signature for long getpid();
CallContext callContext =
CallContext.getCallContext(ResultType.primitive(NativeType.ULONG,
long.class),
new ParameterType[0], CallingConvention.DEFAULT, false);

Library libc =
Library.open(Platform.getPlatform().mapLibraryName("c"), Library.LAZY
| Library.LOCAL);

MethodHandle mh = Native.getMethodHandle(callContext,
libc.getFunction("getpid"));
System.out.println("pid = " + (long) mh.invokeExact());

That generates a class with a single static method that looks like:

public final class jnr/invoke/Native$x86asm$0 {
public final static native long invokeNative();
}

with an asm trampoline that implements the native method:

jnr.invoke.Native$x86asm$0.invokeNative ()J
0: sub rsp, 0x8
4: mov rax, 0x0
b: call 0x15
10: add rsp, 0x8
14: ret
15: <indirect call trampolines>


and returns a MethodHandle bound to the java class's native method.

The interface is somewhat low level - intentionally. Upper layers
should interpret the user-friendly API, convert that into low-level
types (e.g. based on meta-data from clang), and then feed that to
jnr-invoke.

There is also https://github.com/wmeissner/crazy-ivan which uses
jnr-invoke to wire up x86_86 asm into the jvm.
Reply all
Reply to author
Forward
0 new messages