@@ -43,6 +43,78 @@ public BridgeCompiler(MethodHandles.Lookup lookup, String owner, MethodType sour
43
43
}
44
44
45
45
public Class <?> createClass ()
46
+ throws IllegalAccessException {
47
+ final Class <?>[] arguments = source .parameterArray ();
48
+ final Class <?>[] parameters = target .getParameterTypes ();
49
+ final Class <?> expected = source .returnType ();
50
+ final Class <?> result = target .getReturnType ();
51
+ if (arguments .length != parameters .length && !target .isVarArgs ())
52
+ throw new ScriptRuntimeError ("Function argument count did not match target parameter count." );
53
+ final ClassWriter writer = new ClassWriter (0 );
54
+ writer .visit (Skript .JAVA_VERSION , 0x0001 | 0x1000 , location , null , "java/lang/Object" , null );
55
+ final MethodVisitor visitor ;
56
+ final Type [] types = new Type [arguments .length ];
57
+ for (int i = 0 ; i < arguments .length ; i ++) types [i ] = Type .getType (arguments [i ]);
58
+ visitor = writer .visitMethod (0x0001 | 0x0008 | 0x0040 | 0x1000 , "bridge" , Type .getMethodDescriptor (Type .getType (expected ), types ), null , null );
59
+ visitor .visitCode ();
60
+ final int length ;
61
+ if (target .isVarArgs ()) length = parameters .length - 1 ;
62
+ else length = arguments .length ;
63
+ this .extractSimpleArguments (length , arguments , parameters , visitor );
64
+ this .extractVarArguments (arguments , parameters , visitor , length );
65
+ this .invoke (visitor );
66
+ if (result == void .class ) {
67
+ visitor .visitInsn (1 );
68
+ visitor .visitInsn (176 );
69
+ } else {
70
+ this .box (visitor , result );
71
+ visitor .visitTypeInsn (192 , Type .getInternalName (this .getWrapperType (expected )));
72
+ visitor .visitInsn (171 + this .instructionOffset (expected ));
73
+ }
74
+ final int stack ;
75
+ if (target .isVarArgs ())
76
+ stack = Math .max (parameters .length + 1 + this .wideIndexOffset (parameters , result ), 1 ) + 4 ;
77
+ else stack = Math .max (parameters .length + 1 + this .wideIndexOffset (parameters , result ), 1 );
78
+ visitor .visitMaxs (stack , arguments .length );
79
+ visitor .visitEnd ();
80
+ writer .visitEnd ();
81
+ this .generated = lookup .defineClass (writer .toByteArray ());
82
+ return generated ;
83
+ }
84
+
85
+ private void extractVarArguments (Class <?>[] arguments , Class <?>[] parameters , MethodVisitor visitor , int length ) {
86
+ if (!target .isVarArgs ()) return ;
87
+ final int remaining = arguments .length - length ;
88
+ final Class <?> array = parameters [parameters .length - 1 ];
89
+ final Class <?> parameter = array .getComponentType ();
90
+ visitor .visitIntInsn (16 , remaining );
91
+ visitor .visitTypeInsn (189 , Type .getInternalName (parameter ));
92
+ for (int i = 0 ; i < remaining ; i ++) {
93
+ visitor .visitInsn (89 );
94
+ visitor .visitIntInsn (16 , i );
95
+ final Class <?> argument = arguments [i ];
96
+ visitor .visitVarInsn (20 + this .instructionOffset (argument ), i );
97
+ this .boxAtomic (visitor , parameter );
98
+ this .conform (visitor , parameter );
99
+ visitor .visitTypeInsn (192 , Type .getInternalName (this .getUnboxingType (parameter )));
100
+ this .unbox (visitor , parameter );
101
+ visitor .visitInsn (83 );
102
+ }
103
+ }
104
+
105
+ private void extractSimpleArguments (int length , Class <?>[] arguments , Class <?>[] parameters , MethodVisitor visitor ) {
106
+ for (int i = 0 ; i < length ; i ++) { // assume no fat arguments ?
107
+ final Class <?> argument = arguments [i ];
108
+ final Class <?> parameter = parameters [i ];
109
+ visitor .visitVarInsn (20 + this .instructionOffset (argument ), i );
110
+ this .boxAtomic (visitor , parameter );
111
+ this .conform (visitor , parameter );
112
+ visitor .visitTypeInsn (192 , Type .getInternalName (this .getUnboxingType (parameter )));
113
+ this .unbox (visitor , parameter );
114
+ }
115
+ }
116
+
117
+ public Class <?> createClass0 ()
46
118
throws IllegalAccessException {
47
119
final Class <?>[] arguments = source .parameterArray ();
48
120
final Class <?>[] parameters = target .getParameterTypes ();
0 commit comments