nalim icon indicating copy to clipboard operation
nalim copied to clipboard

Code annotations require supporting code to use correctly

Open zero318 opened this issue 2 years ago • 3 comments

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);

zero318 avatar Nov 26 '22 05:11 zero318

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();

apangin avatar Nov 26 '22 18:11 apangin

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();

zero318 avatar Nov 26 '22 23:11 zero318

Here's the PR for this issue. Please take a look! :pray: #8

trustin avatar Feb 13 '23 14:02 trustin