Ich versuche, Java 8 Nashorn mit vollständiger Quelle (nicht instrumentiert) zu haben. Wie Sie vielleicht wissen, verwendet es Nasgen die .classes zu ändern und die Ausgabe in JRE/lib/ext/nashorn.jar
ausgeliefert wird.Java-Code, der in MethodHandle im konstanten Pool kompiliert wird
auf den Ausgang der Demontage mit javap
:
0: aload_0
1: ldc #24 // String Function
3: ldc #31 // MethodHandle invokestatic jdk/nashorn/internal/objects/NativeFunction.function:(ZLjava/lang/Object;[Ljava/lang/Object;)Ljdk/nashorn/internal/runtime/ScriptFunction;
5: getstatic #22 // Field $nasgenmap$:Ljdk/nashorn/internal/runtime/PropertyMap;
8: aconst_null
9: invokespecial #34 // Method jdk/nashorn/internal/objects/ScriptFunctionImpl."<init>":(Ljava/lang/String;Ljava/lang/invoke/MethodHandle;Ljdk/nashorn/internal/runtime/PropertyMap;[Ljdk/nashorn/internal/runtime/Specialization;)V
, die sein könnte fälschlicherweise als
geschriebensuper("Function", NativeFunction.function, $nasgenmap$, (Specialization[]) null);
, die den Super-Konstruktor mit Unterschrift nennen sollte:
ScriptFunctionImpl(String, MethodHandle, PropertyMap, Specialization[]) { }
Mein Problem ist der zweite Parameter NativeFunction.function
, die ich nicht übersetzbar Quelle haben könnte, die gleichen MethodHandle
im Konstanten-Pool zu erzeugen,
#31 = MethodHandle #6:#30 // invokestatic jdk/nashorn/internal/objects/NativeFunction.function:(ZLjava/lang/Object;[Ljava/lang/Object;)Ljdk/nashorn/internal/runtime/ScriptFunction;
Dieser Teil der Instrumentierung von ASM getan wurde, durch den Anruf .
So ist es eine Möglichkeit, ein solches Verfahren Griff aus der Java-Quellcode zu erstellen, oder das ist ein Merkmal, das nur auf Bytecode-Ebene getan werden kann?
Der vollständige javap Ausgang:
$javap -c -v NativeFunction$Constructor.class
Last modified Apr 10, 2015; size 1161 bytes
MD5 checksum dcae2f54643befc519a45e9ac9bc4781
final class jdk.nashorn.internal.objects.NativeFunction$Constructor extends jdk.nashorn.internal.objects.ScriptFunctionImpl
minor version: 0
major version: 51
flags: ACC_FINAL
Constant pool:
#1 = Utf8 jdk/nashorn/internal/objects/NativeFunction$Constructor
#2 = Class #1 // jdk/nashorn/internal/objects/NativeFunction$Constructor
#3 = Utf8 jdk/nashorn/internal/objects/ScriptFunctionImpl
#4 = Class #3 // jdk/nashorn/internal/objects/ScriptFunctionImpl
#5 = Utf8 $nasgenmap$
#6 = Utf8 Ljdk/nashorn/internal/runtime/PropertyMap;
#7 = Utf8 <clinit>
#8 = Utf8 ()V
#9 = Utf8 java/util/ArrayList
#10 = Class #9 // java/util/ArrayList
#11 = Utf8 <init>
#12 = Utf8 (I)V
#13 = NameAndType #11:#12 // "<init>":(I)V
#14 = Methodref #10.#13 // java/util/ArrayList."<init>":(I)V
#15 = Utf8 jdk/nashorn/internal/runtime/PropertyMap
#16 = Class #15 // jdk/nashorn/internal/runtime/PropertyMap
#17 = Utf8 newMap
#18 = Utf8 (Ljava/util/Collection;)Ljdk/nashorn/internal/runtime/PropertyMap;
#19 = NameAndType #17:#18 // newMap:(Ljava/util/Collection;)Ljdk/nashorn/internal/runtime/PropertyMap;
#20 = Methodref #16.#19 // jdk/nashorn/internal/runtime/PropertyMap.newMap:(Ljava/util/Collection;)Ljdk/nashorn/internal/runtime/PropertyMap;
#21 = NameAndType #5:#6 // $nasgenmap$:Ljdk/nashorn/internal/runtime/PropertyMap;
#22 = Fieldref #2.#21 // jdk/nashorn/internal/objects/NativeFunction$Constructor.$nasgenmap$:Ljdk/nashorn/internal/runtime/PropertyMap;
#23 = Utf8 Function
#24 = String #23 // Function
#25 = Utf8 jdk/nashorn/internal/objects/NativeFunction
#26 = Class #25 // jdk/nashorn/internal/objects/NativeFunction
#27 = Utf8 function
#28 = Utf8 (ZLjava/lang/Object;[Ljava/lang/Object;)Ljdk/nashorn/internal/runtime/ScriptFunction;
#29 = NameAndType #27:#28 // function:(ZLjava/lang/Object;[Ljava/lang/Object;)Ljdk/nashorn/internal/runtime/ScriptFunction;
#30 = Methodref #26.#29 // jdk/nashorn/internal/objects/NativeFunction.function:(ZLjava/lang/Object;[Ljava/lang/Object;)Ljdk/nashorn/internal/runtime/ScriptFunction;
#31 = MethodHandle #6:#30 // invokestatic jdk/nashorn/internal/objects/NativeFunction.function:(ZLjava/lang/Object;[Ljava/lang/Object;)Ljdk/nashorn/internal/runtime/ScriptFunction;
#32 = Utf8 (Ljava/lang/String;Ljava/lang/invoke/MethodHandle;Ljdk/nashorn/internal/runtime/PropertyMap;[Ljdk/nashorn/internal/runtime/Specialization;)V
#33 = NameAndType #11:#32 // "<init>":(Ljava/lang/String;Ljava/lang/invoke/MethodHandle;Ljdk/nashorn/internal/runtime/PropertyMap;[Ljdk/nashorn/internal/runtime/Specialization;)V
#34 = Methodref #4.#33 // jdk/nashorn/internal/objects/ScriptFunctionImpl."<init>":(Ljava/lang/String;Ljava/lang/invoke/MethodHandle;Ljdk/nashorn/internal/runtime/PropertyMap;[Ljdk/nashorn/internal/runtime/Specialization;)V
#35 = Utf8 jdk/nashorn/internal/objects/NativeFunction$Prototype
#36 = Class #35 // jdk/nashorn/internal/objects/NativeFunction$Prototype
#37 = NameAndType #11:#8 // "<init>":()V
#38 = Methodref #36.#37 // jdk/nashorn/internal/objects/NativeFunction$Prototype."<init>":()V
#39 = Utf8 jdk/nashorn/internal/objects/PrototypeObject
#40 = Class #39 // jdk/nashorn/internal/objects/PrototypeObject
#41 = Utf8 setConstructor
#42 = Utf8 (Ljava/lang/Object;Ljava/lang/Object;)V
#43 = NameAndType #41:#42 // setConstructor:(Ljava/lang/Object;Ljava/lang/Object;)V
#44 = Methodref #40.#43 // jdk/nashorn/internal/objects/PrototypeObject.setConstructor:(Ljava/lang/Object;Ljava/lang/Object;)V
#45 = Utf8 jdk/nashorn/internal/runtime/ScriptFunction
#46 = Class #45 // jdk/nashorn/internal/runtime/ScriptFunction
#47 = Utf8 setPrototype
#48 = Utf8 (Ljava/lang/Object;)V
#49 = NameAndType #47:#48 // setPrototype:(Ljava/lang/Object;)V
#50 = Methodref #46.#49 // jdk/nashorn/internal/runtime/ScriptFunction.setPrototype:(Ljava/lang/Object;)V
#51 = Utf8 setArity
#52 = NameAndType #51:#12 // setArity:(I)V
#53 = Methodref #46.#52 // jdk/nashorn/internal/runtime/ScriptFunction.setArity:(I)V
#54 = Utf8 Code
{
public static {};
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=0, args_size=0
0: new #10 // class java/util/ArrayList
3: dup
4: iconst_1
5: invokespecial #14 // Method java/util/ArrayList."<init>":(I)V
8: invokestatic #20 // Method jdk/nashorn/internal/runtime/PropertyMap.newMap:(Ljava/util/Collection;)Ljdk/nashorn
/internal/runtime/PropertyMap;
11: putstatic #22 // Field $nasgenmap$:Ljdk/nashorn/internal/runtime/PropertyMap;
14: return
jdk.nashorn.internal.objects.NativeFunction$Constructor();
flags:
Code:
stack=5, locals=1, args_size=1
0: aload_0
1: ldc #24 // String Function
3: ldc #31 // MethodHandle invokestatic jdk/nashorn/internal/objects/NativeFunction.function:(ZLjava/lang/Object;[Ljava/lang/Object;)Ljdk/nashorn/internal/runtime/ScriptFunction;
5: getstatic #22 // Field $nasgenmap$:Ljdk/nashorn/internal/runtime/PropertyMap;
8: aconst_null
9: invokespecial #34 // Method jdk/nashorn/internal/objects/ScriptFunctionImpl."<init>":(Ljava/lang/String;Ljava/lang/invoke/MethodHandle;Ljdk/nashorn/internal/runtime/PropertyMap;[Ljdk/nashorn/internal/runtime/Specialization;)V
12: aload_0
13: new #36 // class jdk/nashorn/internal/objects/NativeFunction$Prototype
16: dup
17: invokespecial #38 // Method jdk/nashorn/internal/objects/NativeFunction$Prototype."<init>":()V
20: dup
21: aload_0
22: invokestatic #44 // Method jdk/nashorn/internal/objects/PrototypeObject.setConstructor:(Ljava/lang/Object;Ljava/lang/Object;)V
25: invokevirtual #50 // Method jdk/nashorn/internal/runtime/ScriptFunction.setPrototype:(Ljava/lang/Object;)V
28: aload_0
29: iconst_1
30: invokevirtual #53 // Method jdk/nashorn/internal/runtime/ScriptFunction.setArity:(I)V
33: return
}
Es ist wahrscheinlich, Byte-Code. Es gibt mehrere Dinge, die anderen JVM Sprachen zu tun, dass Java nicht kann, und es ist eine Frage der Sprachspezifikation, nicht das, was die Byte-Codes sind in der Lage. von. – markspace
Die einzige Java-Sprache-Funktion ich darüber wissen verwendet das 'invokespecial' Opcode lambda ist. Ansonsten wird es hauptsächlich für dynamische Sprachen (wie Javascript) verwendet, die auf der JVM laufen. Ich weiß nicht, ob das hilft. – biziclop
Das sollte natürlich "aufgerufen" werden. – biziclop