Created
December 9, 2020 23:28
-
-
Save harpocrates/e8a1f12abdfa1db0ce8d5a9ffefcb90c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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