Skip to content

Instantly share code, notes, and snippets.

@harpocrates
Created December 9, 2020 23:28
Show Gist options
  • Save harpocrates/e8a1f12abdfa1db0ce8d5a9ffefcb90c to your computer and use it in GitHub Desktop.
Save harpocrates/e8a1f12abdfa1db0ce8d5a9ffefcb90c to your computer and use it in GitHub Desktop.
import java.lang.invoke.*;
/* Problem: given an array of method handle, produce a method handle that will
*
* - use its first `int` argument to index into an array of method handles
* - call the extracted method handle with the second `int` argument
*
* Why is this interesting? Because we can use this sort of thing for a
* bootstrap `invokedynamic` method, for optimized indirect calls with an offset.
*/
class MethodHandleArrayIndex {
public static MethodHandle[] table;
// Methods to put into the `table`
public static int func1(int i) { return i + 1; }
public static int func2(int i) { return i * 2 - 5; }
public static int func3(int i) { return i * 3 - 8; }
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup();
// Initialize `MethodHandleArrayIndex`
ClassLoader classLoader = MethodHandleArrayIndex.class.getClassLoader();
MethodType typ = MethodType.fromMethodDescriptorString("(I)I", classLoader);
MethodHandleArrayIndex.table = new MethodHandle[] {
lookup.findStatic(MethodHandleArrayIndex.class, "func1", typ),
lookup.findStatic(MethodHandleArrayIndex.class, "func2", typ),
lookup.findStatic(MethodHandleArrayIndex.class, "func3", typ),
};
// Type of the method handle: `(II)I`
MethodHandle callIndirect = MethodHandles.collectArguments(
MethodHandles.collectArguments(
MethodHandles.exactInvoker(typ),
0,
MethodHandles.arrayElementGetter(MethodHandle[].class)
),
0,
lookup.findStaticGetter(MethodHandleArrayIndex.class, "table", MethodHandle[].class)
);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 100; j++) {
int output = (int)callIndirect.invokeExact(i, j);
System.out.println("Called table[" + i + "] with argument " + j + " = " + output);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment