Files
asmhatreandClaude Sonnet 5.5 ecceaa8b32 Add jextract module: SQLite bindings generated with jextract, FFM arenas, C strings, out-parameters, errors, upcalls, and a JMH comparison with JNI
jextract-25 early-access build (25-jextract+2-4) on JDK 25.0.5+8 against SQLite 3.45.1: 25 functions and 13 constants
generated into 4 committed files (the whole header would be 83 files), a small Db wrapper, the four arena kinds
used wrongly on purpose, ADDRESS vs C_POINTER zero-length vs unbounded segments and the SIGSEGV from getString
on a NULL pointer, sqlite3_open out-parameter, return codes to exceptions, a sqlite3_exec upcall and the VM exit
when it throws, the JDK 25 native-access warning and --illegal-native-access=deny, library loading failures,
and a JMH benchmark of FFM vs hand-written JNI vs plain Java (indicative only: shared 2-CPU machine).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017ic4b6Kg9RWSTJzyz6KP9X
2026-10-30 16:36:09 +00:00

74 lines
2.1 KiB
Java

// Generated by jextract
package demo.sqlite;
import java.lang.invoke.*;
import java.lang.foreign.*;
import java.nio.ByteOrder;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import static java.lang.foreign.ValueLayout.*;
import static java.lang.foreign.MemoryLayout.PathElement.*;
/**
* {@snippet lang=c :
* int (*callback)(void *, int, char **, char **)
* }
*/
public final class sqlite3_exec$callback {
private sqlite3_exec$callback() {
// Should not be called directly
}
/**
* The function pointer signature, expressed as a functional interface
*/
public interface Function {
int apply(MemorySegment _x0, int _x1, MemorySegment _x2, MemorySegment _x3);
}
private static final FunctionDescriptor $DESC = FunctionDescriptor.of(
sqlite3_h.C_INT,
sqlite3_h.C_POINTER,
sqlite3_h.C_INT,
sqlite3_h.C_POINTER,
sqlite3_h.C_POINTER
);
/**
* The descriptor of this function pointer
*/
public static FunctionDescriptor descriptor() {
return $DESC;
}
private static final MethodHandle UP$MH = sqlite3_h.upcallHandle(sqlite3_exec$callback.Function.class, "apply", $DESC);
/**
* Allocates a new upcall stub, whose implementation is defined by {@code fi}.
* The lifetime of the returned segment is managed by {@code arena}
*/
public static MemorySegment allocate(sqlite3_exec$callback.Function fi, Arena arena) {
return Linker.nativeLinker().upcallStub(UP$MH.bindTo(fi), $DESC, arena);
}
private static final MethodHandle DOWN$MH = Linker.nativeLinker().downcallHandle($DESC);
/**
* Invoke the upcall stub {@code funcPtr}, with given parameters
*/
public static int invoke(MemorySegment funcPtr, MemorySegment _x0, int _x1, MemorySegment _x2, MemorySegment _x3) {
try {
return (int) DOWN$MH.invokeExact(funcPtr, _x0, _x1, _x2, _x3);
} catch (Error | RuntimeException ex) {
throw ex;
} catch (Throwable ex$) {
throw new AssertionError("should not reach here", ex$);
}
}
}