Replies: 4 comments 5 replies
-
Apparently, acquiring the pointers was quite easy, but injecting them into the final var allocator = MemoryUtil.getAllocator();
final var alloc = allocator.getMalloc();
final var free = allocator.getFree();
final var realloc = allocator.getRealloc();
final var memory = FT_Memory.malloc().user(0);
final var address = memory.address();
memPutAddress(address + FT_Memory.ALLOC, alloc);
memPutAddress(address + FT_Memory.FREE, free);
memPutAddress(address + FT_Memory.REALLOC, realloc); This seems to work, so far. The problem is that LWJGL's FT_Memory class expects the function pointers to be functions generated by LibFFI, sourced from So doing public FT_Alloc_Func alloc() { return nalloc(address()); }
...
public static FT_Alloc_Func nalloc(long struct) {
return FT_Alloc_Func.createSafe(memGetAddress(struct + FT_Memory.ALLOC));
}
...
public static FT_Alloc_Func createSafe(long functionPointer) {
return functionPointer == NULL ? null : create(functionPointer);
}
...
public static FT_Alloc_Func create(long functionPointer) {
FT_Alloc_FuncI instance = Callback.get(functionPointer); // Does this create any problems?
return instance instanceof FT_Alloc_Func
? (FT_Alloc_Func)instance
: new Container(functionPointer, instance);
} This crashes the JVM: Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.lwjgl.system.libffi.FFIClosure.user_data()" because the return value of "org.lwjgl.system.Callback$ClosureRegistry.get(long)" is null
at org.lwjgl@3.3.2-snapshot+8/org.lwjgl.system.Callback.get(Callback.java:190)
at org.lwjgl.freetype@3.3.2-snapshot+8/org.lwjgl.util.freetype.FT_Alloc_Func.create(FT_Alloc_Func.java:31)
at org.lwjgl.freetype@3.3.2-snapshot+8/org.lwjgl.util.freetype.FT_Alloc_Func.createSafe(FT_Alloc_Func.java:40)
at org.lwjgl.freetype@3.3.2-snapshot+8/org.lwjgl.util.freetype.FT_Memory.nalloc(FT_Memory.java:242)
at org.lwjgl.freetype@3.3.2-snapshot+8/org.lwjgl.util.freetype.FT_Memory.alloc(FT_Memory.java:82) |
Beta Was this translation helpful? Give feedback.
-
I was looking into writing a custom subclass of I tried this, but came short as the super class's constructor is package-private. class NativeAllocFunc extends FT_Alloc_Func {
public NativeAllocFunc(final long address) {
super(address); // error
}
@Override
public long invoke(final long memory, final long size) {
return invokePPP(memory, size, super.address());
}
} |
Beta Was this translation helpful? Give feedback.
-
Hey @ws909,
The possible ways to address this:
Finally, the solution I've been considering for a while is having bindings to a native JIT compiler. It would solve this problem and create opportunities for many more improvements, both within LWJGL and in user programs. However, it's hard to find a solution that satisfies the following:
In the past, I've experimented with TinyCC and was fairly happy with it, but not entirely convinced. I've been looking for a better solution for a while, but there seems to be nothing out there that satisfies the above constraints as well as TinyCC. It's also been very actively maintained lately. Unless someone has a better suggestion that I've missed, I'll give it another chance soon. |
Beta Was this translation helpful? Give feedback.
-
JVMCI would be useful if we wanted to implement a compiler. That would be a very difficult undertaking, outside the scope of LWJGL. What we need is another library to do the hard work for us (calling-convention/ABI details, register allocator, optimizations, etc). C code isn't necessary, but that's what TinyCC uses as input. We could use LLVM bitcode, or WebAssembly, or whatever, as long as the constraints described above are satisfied. |
Beta Was this translation helpful? Give feedback.
-
FT_New_Library
requires an instance ofFT_Memory
.FT_Init_FreeType
is not an option due to its threading limitations.FT_Init_FreeType
does not support reference counting of the library, and so is not an option if that's a requirement. Pardon my initial misunderstanding, believing there was a multithreading difference between the two functions.FT_Memory
is a structure whose members are function pointers foralloc
,free
, andrealloc
, as well as avoid*
pointer to user data. There is no default instance of this structure, in either Java or FreeType.org.lwjgl.system.libc.LibCStdlib
provides Java and Java native methods for these functions, however, their addresses are not available.It is possible to supply lambdas that allocate native memory from Java, however, going via Java for native-to-native memory management, is likely a big performance obstacle.
Another very cumbersome way to access these functions, is through the FFI API currently in preview, though, downcall handles are not yet supported on AArch64, which creates a compatibility concern. I did not yet test if the function pointers are retrievable.
How can a high-performance, initialized
FT_Memory
instance be acquired?Beta Was this translation helpful? Give feedback.
All reactions