JDK 7的预发布版本包含一个java.dyn.InvokeDynamic类,允许从源代码创建invokedynamic指令.
见这里:http: //fwierzbicki.blogspot.com/2009/08/invokedynamic-and-jython-part-i.html
在官方的JDK 7发布中,这个类似乎已经消失了.有谁知道这个源代码选项是否仍然受支持?
这里说:
Since 2.1 :
[..]
added the invokedynamic instruction
Run Code Online (Sandbox Code Playgroud)
因此,我认为可以用jasmin编写包含invokedynamics的指令代码.但是我找不到关于jasmin语法的任何文档,我只是想出了如何使用invokedynamic来获取Jasmin的VerifyErrors,而不是如何创建一个工作示例.
如何在Jasmin中正确使用该指令?
请提供一段用某种众所周知的动态语言(例如JavaScript)编写的代码,以及使用invokedynamic在Java字节码中的代码看起来如何,并在这里解释为什么使用invokedynamic是向前迈进的一步。
我已经在Google上搜索并阅读了很多有关“不再是新的” invokedynamic指令的信息,互联网上的每个人都同意这将有助于加快JVM上的动态语言的速度。多亏了stackoverflow,我设法使自己的字节码指令与Sable / Jasmin一起运行。
我已经知道invokedynamic对于惰性常量很有用,并且我还认为OpenJDK是如何利用lambda的invokedynamic的。
Oracle有一个很小的示例,但是据我所知,在这种情况下,invokedynamic的使用无法达到目的,因为“ adder”的示例可以更简单,更快,并且具有与以下字节码大致相同的效果:
aload whereeverAIs
checkcast java/lang/Integer
aload whereeverBIs
checkcast java/lang/Integer
invokestatic IntegerOps/adder(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;
Run Code Online (Sandbox Code Playgroud)
因为某种原因,Oracle的bootstrap方法知道两个参数都是整数。他们甚至“承认”:
[..]假设参数[..]将是Integer对象。如果引导程序方法的参数(在此示例中,callerClass,dynMethodName和dynMethodType)不同,则引导程序方法需要附加代码才能正确链接invokedynamic [..]。
好吧,是的,没有有趣的“附加代码”,在这里使用invokedynamic是没有意义的,是吗?
因此,在那之后,再加上另外两个Javadoc和Blog条目,我认为我对如何使用invokedynamic进行很好的掌握,当invokestatic / invokevirtual / invokevirtual或getfield也可以正常使用时,如何使用invokedynamic作为不良替代品。
现在,我很好奇如何实际将invokedynamic指令应用于现实世界的用例,以使它实际上比“传统”调用(除了惰性常量,我得到的...)要多一些改进。
我想从 Java 动态调用本机方法。因为方法签名在编译时是未知的,所以我为大多数具有相同签名的原始返回类型创建了通用本机方法:
class NativeHook {
public static native int callInt(String funcName, Object... funcArgs);
public static native void callVoid(String funcName, Object... funcArgs);
public static native Object callObject(String funcName, Object... funcArgs);
private static MethodHandle getNativeMethod(String callName, Class<?> returnType) {
return MethodHandles.lookup().findStatic(NativeHook.class, callName,
MethodType.methodType(returnType, String.class, Object[].class));
}
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找创建一个 MethodHandle ,然后调用匹配的callXXX方法并传入装箱的方法,funcArgs就好像它们是单独提供的一样。这些callXXX方法可以这样访问:
MethodHandle callInt = getNativeMethod("callInt", int.class);
MethodHandle boundCallInt = callInt.bindTo("my_c_function_name").asVarargsCollector(Object[].class);
// returns NativeHook.callInt("my_c_function_name", 1, 2, 3)
boundCallInt.invokeWithArguments(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
我正在使用这个 bootstrap 方法callXXX在 invokeDynamic 中间接引用这个方法,它的工作方式与上面相同: …