nalim
nalim copied to clipboard
Code annotations require supporting code to use correctly
Currently @Code
annotations do not implement any argument processing or any means of handling multiple architectures, unlike linked functions. This effectively forces all functions to go through a Java wrapper function at runtime to process arguments and select the appropriate implementation.
For example, even something as simple as querying CPUID output requires something like this:
@Code("4D01C8 4989D9 89D0 0FA2 418900 41895804 41894808 4189500C 4C89CB C3")
private static native void cpuid_amd64_win(int func, int[] out, long out_base_offset);
@Code("488D3C11 89F0 4889DE 0FA2 8907 895F04 894F08 89570C 4889F3 C3")
private static native void cpuid_amd64_linux(int func, int[] out, long out_base_offset);
private static final boolean is_windows = System.getProperty("os.name").toLowerCase().contains("windows");
public static void cpuid(int func, int[] out) {
if (is_windows) {
cpuid_amd64_win(func, out, UNSAFE.ARRAY_INT_BASE_OFFSET);
} else {
cpuid_amd64_linux(func, out, UNSAFE.ARRAY_INT_BASE_OFFSET);
}
}
Instead, it seems reasonable to allow specifying multiple possible bytecode sequences that the linker can select at runtime when parsing a class. This would make the feature much simpler to use.
@Code(
amd64_win = "4989D9 89D0 0FA2 418900 41895804 41894808 4189500C 4C89CB C3",
amd64_linux = "4889D7 89F0 4889DE 0FA2 8907 895F04 894F08 89570C 4889F3 C3"
)
public static native void cpuid(int func, int[] out);
The request definitely makes sense.
I was thinking of allowing multiple @Code
annotations with different attributes, e.g.
@Code(os = OS.Windows, arch = Arch.AMD64, value = "12345678")
@Code(os = OS.Linux, arch = Arch.AMD64, value = "1234567890")
@Code(arch = Arch.AArch64, value = "aabbccdd")
public static native void func();
That would definitely be nicer syntax than what I came up with, though it raises the question of how attributes would be parsed when there are multiple valid combinations present.
For example, it's unclear whether this first annotation would act as a fall through for any x64 that doesn't match the more specific annotation or if it would be an error since both annotations would be valid simultaneously.
@Code(arch = Arch.AMD64, value = "1234")
@Code(os = OS.Windows, arch = Arch.AMD64, value = "5678")
public static native void func();
Here's the PR for this issue. Please take a look! :pray: #8