1818import java .lang .reflect .Method ;
1919import java .util .Random ;
2020
21- import static org .objectweb .asm .Opcodes .*;
22-
2321/**
2422 * The function call-site class compiler.
2523 * This cannot use {@link mx.kenzie.foundation} because it is required for
@@ -48,7 +46,7 @@ public Class<?> createClass()
4846 final Class <?>[] parameters = target .getParameterTypes ();
4947 final Class <?> expected = source .returnType ();
5048 final Class <?> result = target .getReturnType ();
51- if (arguments .length != parameters .length )
49+ if (arguments .length != parameters .length ) // todo dynamic?
5250 throw new ScriptRuntimeError ("Function argument count did not match target parameter count." );
5351 final ClassWriter writer = new ClassWriter (0 );
5452 writer .visit (Skript .JAVA_VERSION , 0x0001 | 0x1000 , location , null , "java/lang/Object" , null );
@@ -62,13 +60,18 @@ public Class<?> createClass()
6260 final Class <?> parameter = parameters [i ];
6361 visitor .visitVarInsn (20 + this .instructionOffset (argument ), i );
6462 this .boxAtomic (visitor , parameter );
65- visitor .visitTypeInsn (CHECKCAST , Type .getInternalName (this .getUnboxingType (parameter )));
63+ visitor .visitTypeInsn (192 , Type .getInternalName (this .getUnboxingType (parameter )));
6664 this .unbox (visitor , parameter );
6765 }
6866 this .invoke (visitor );
69- this .box (visitor , result );
70- visitor .visitTypeInsn (CHECKCAST , Type .getInternalName (this .getWrapperType (expected )));
71- visitor .visitInsn (171 + this .instructionOffset (expected ));
67+ if (result == void .class ) {
68+ visitor .visitInsn (1 );
69+ visitor .visitInsn (176 );
70+ } else {
71+ this .box (visitor , result );
72+ visitor .visitTypeInsn (192 , Type .getInternalName (this .getWrapperType (expected )));
73+ visitor .visitInsn (171 + this .instructionOffset (expected ));
74+ }
7275 visitor .visitMaxs (Math .max (parameters .length + 1 + this .wideIndexOffset (parameters , result ), 1 ), arguments .length );
7376 visitor .visitEnd ();
7477 writer .visitEnd ();
@@ -85,38 +88,7 @@ public CallSite getCallSite()
8588 //region Utilities
8689 protected void invoke (MethodVisitor visitor ) {
8790 final boolean special = target .getDeclaringClass ().isInterface ();
88- visitor .visitMethodInsn (INVOKESTATIC , Type .getInternalName (target .getDeclaringClass ()), target .getName (), Type .getMethodDescriptor (target ), special );
89- }
90-
91- protected void doTypeConversion (MethodVisitor visitor , Class <?> from , Class <?> to ) {
92- if (from == to ) return ;
93- if (from == void .class || to == void .class ) return ;
94- if (from .isPrimitive () && to .isPrimitive ()) {
95- final int opcode ;
96- if (from == float .class ) {
97- if (to == double .class ) opcode = F2D ;
98- else if (to == long .class ) opcode = F2L ;
99- else opcode = F2I ;
100- } else if (from == double .class ) {
101- if (to == float .class ) opcode = D2F ;
102- else if (to == long .class ) opcode = D2L ;
103- else opcode = D2I ;
104- } else if (from == long .class ) {
105- if (to == float .class ) opcode = L2F ;
106- else if (to == double .class ) opcode = L2D ;
107- else opcode = L2I ;
108- } else {
109- if (to == float .class ) opcode = I2F ;
110- else if (to == double .class ) opcode = I2D ;
111- else if (to == byte .class ) opcode = I2B ;
112- else if (to == short .class ) opcode = I2S ;
113- else if (to == char .class ) opcode = I2C ;
114- else opcode = I2L ;
115- }
116- visitor .visitInsn (opcode );
117- } else if (from .isPrimitive () ^ to .isPrimitive ()) {
118- throw new IllegalArgumentException ("Type wrapping is currently unsupported due to side-effects: '" + from .getSimpleName () + "' -> '" + to .getSimpleName () + "'" );
119- } else visitor .visitTypeInsn (CHECKCAST , Type .getInternalName (to ));
91+ visitor .visitMethodInsn (184 , Type .getInternalName (target .getDeclaringClass ()), target .getName (), Type .getMethodDescriptor (target ), special );
12092 }
12193
12294 protected Class <?> getUnboxingType (Class <?> primitive ) {
@@ -143,48 +115,48 @@ protected Class<?> getWrapperType(Class<?> primitive) {
143115
144116 protected void boxAtomic (MethodVisitor visitor , Class <?> parameter ) {
145117 if (parameter == AtomicVariable .class )
146- visitor .visitMethodInsn (INVOKESTATIC , Type .getInternalName (AtomicVariable .class ), "wrap" , "(Ljava/lang/Object;)" + Type .getDescriptor (AtomicVariable .class ), false );
118+ visitor .visitMethodInsn (184 , Type .getInternalName (AtomicVariable .class ), "wrap" , "(Ljava/lang/Object;)" + Type .getDescriptor (AtomicVariable .class ), false );
147119 else
148- visitor .visitMethodInsn (INVOKESTATIC , Type .getInternalName (AtomicVariable .class ), "unwrap" , "(Ljava/lang/Object;)Ljava/lang/Object;" , false );
120+ visitor .visitMethodInsn (184 , Type .getInternalName (AtomicVariable .class ), "unwrap" , "(Ljava/lang/Object;)Ljava/lang/Object;" , false );
149121 }
150122
151123 protected void unbox (MethodVisitor visitor , Class <?> parameter ) {
152124 final String source = Type .getInternalName (OperatorHandler .class );
153125 if (parameter == byte .class )
154- visitor .visitMethodInsn (INVOKESTATIC , source , "unboxB" , "(Ljava/lang/Number;)B" , false );
126+ visitor .visitMethodInsn (184 , source , "unboxB" , "(Ljava/lang/Number;)B" , false );
155127 if (parameter == short .class )
156- visitor .visitMethodInsn (INVOKESTATIC , source , "unboxS" , "(Ljava/lang/Number;)S" , false );
128+ visitor .visitMethodInsn (184 , source , "unboxS" , "(Ljava/lang/Number;)S" , false );
157129 if (parameter == int .class )
158- visitor .visitMethodInsn (INVOKESTATIC , source , "unboxI" , "(Ljava/lang/Number;)I" , false );
130+ visitor .visitMethodInsn (184 , source , "unboxI" , "(Ljava/lang/Number;)I" , false );
159131 if (parameter == long .class )
160- visitor .visitMethodInsn (INVOKESTATIC , source , "unboxJ" , "(Ljava/lang/Number;)J" , false );
132+ visitor .visitMethodInsn (184 , source , "unboxJ" , "(Ljava/lang/Number;)J" , false );
161133 if (parameter == float .class )
162- visitor .visitMethodInsn (INVOKESTATIC , source , "unboxF" , "(Ljava/lang/Number;)F" , false );
134+ visitor .visitMethodInsn (184 , source , "unboxF" , "(Ljava/lang/Number;)F" , false );
163135 if (parameter == double .class )
164- visitor .visitMethodInsn (INVOKESTATIC , source , "unboxD" , "(Ljava/lang/Number;)D" , false );
136+ visitor .visitMethodInsn (184 , source , "unboxD" , "(Ljava/lang/Number;)D" , false );
165137 if (parameter == boolean .class )
166- visitor .visitMethodInsn (INVOKESTATIC , source , "unbox" , "(Ljava/lang/Boolean;)Z" , false );
138+ visitor .visitMethodInsn (184 , source , "unbox" , "(Ljava/lang/Boolean;)Z" , false );
167139 if (parameter == char .class )
168- visitor .visitMethodInsn (INVOKESTATIC , source , "unbox" , "(Ljava/lang/Character;)C" , false );
140+ visitor .visitMethodInsn (184 , source , "unbox" , "(Ljava/lang/Character;)C" , false );
169141 }
170142
171143 protected void box (MethodVisitor visitor , Class <?> value ) {
172144 if (value == byte .class )
173- visitor .visitMethodInsn (INVOKESTATIC , Type .getInternalName (Byte .class ), "valueOf" , "(B)Ljava/lang/Byte;" , false );
145+ visitor .visitMethodInsn (184 , Type .getInternalName (Byte .class ), "valueOf" , "(B)Ljava/lang/Byte;" , false );
174146 if (value == short .class )
175- visitor .visitMethodInsn (INVOKESTATIC , Type .getInternalName (Short .class ), "valueOf" , "(S)Ljava/lang/Short;" , false );
147+ visitor .visitMethodInsn (184 , Type .getInternalName (Short .class ), "valueOf" , "(S)Ljava/lang/Short;" , false );
176148 if (value == int .class )
177- visitor .visitMethodInsn (INVOKESTATIC , Type .getInternalName (Integer .class ), "valueOf" , "(I)Ljava/lang/Integer;" , false );
149+ visitor .visitMethodInsn (184 , Type .getInternalName (Integer .class ), "valueOf" , "(I)Ljava/lang/Integer;" , false );
178150 if (value == long .class )
179- visitor .visitMethodInsn (INVOKESTATIC , Type .getInternalName (Long .class ), "valueOf" , "(J)Ljava/lang/Long;" , false );
151+ visitor .visitMethodInsn (184 , Type .getInternalName (Long .class ), "valueOf" , "(J)Ljava/lang/Long;" , false );
180152 if (value == float .class )
181- visitor .visitMethodInsn (INVOKESTATIC , Type .getInternalName (Float .class ), "valueOf" , "(F)Ljava/lang/Float;" , false );
153+ visitor .visitMethodInsn (184 , Type .getInternalName (Float .class ), "valueOf" , "(F)Ljava/lang/Float;" , false );
182154 if (value == double .class )
183- visitor .visitMethodInsn (INVOKESTATIC , Type .getInternalName (Double .class ), "valueOf" , "(D)Ljava/lang/Double;" , false );
155+ visitor .visitMethodInsn (184 , Type .getInternalName (Double .class ), "valueOf" , "(D)Ljava/lang/Double;" , false );
184156 if (value == boolean .class )
185- visitor .visitMethodInsn (INVOKESTATIC , Type .getInternalName (Boolean .class ), "valueOf" , "(Z)Ljava/lang/Boolean;" , false );
157+ visitor .visitMethodInsn (184 , Type .getInternalName (Boolean .class ), "valueOf" , "(Z)Ljava/lang/Boolean;" , false );
186158 if (value == void .class )
187- visitor .visitInsn (ACONST_NULL );
159+ visitor .visitInsn (1 );
188160 }
189161
190162 protected int wideIndexOffset (Class <?>[] params , Class <?> ret ) {
0 commit comments