20
20
package org .elasticsearch .painless ;
21
21
22
22
import org .elasticsearch .painless .Definition .Cast ;
23
- import org .elasticsearch .painless .Definition .Type ;
23
+ import org .elasticsearch .painless .Definition .def ;
24
24
import org .objectweb .asm .ClassVisitor ;
25
25
import org .objectweb .asm .Label ;
26
26
import org .objectweb .asm .Opcodes ;
27
+ import org .objectweb .asm .Type ;
27
28
import org .objectweb .asm .commons .GeneratorAdapter ;
28
29
import org .objectweb .asm .commons .Method ;
29
30
30
31
import java .util .ArrayDeque ;
31
32
import java .util .ArrayList ;
33
+ import java .util .Arrays ;
32
34
import java .util .BitSet ;
33
35
import java .util .Deque ;
34
36
import java .util .List ;
@@ -128,68 +130,68 @@ public void writeLoopCounter(int slot, int count, Location location) {
128
130
mark (end );
129
131
}
130
132
131
- public void writeCast (final Cast cast ) {
133
+ public void writeCast (Cast cast ) {
132
134
if (cast != null ) {
133
- if (cast .from . clazz == char .class && cast .to . clazz == String .class ) {
135
+ if (cast .from == char .class && cast .to == String .class ) {
134
136
invokeStatic (UTILITY_TYPE , CHAR_TO_STRING );
135
- } else if (cast .from . clazz == String .class && cast .to . clazz == char .class ) {
137
+ } else if (cast .from == String .class && cast .to == char .class ) {
136
138
invokeStatic (UTILITY_TYPE , STRING_TO_CHAR );
137
139
} else if (cast .unboxFrom != null ) {
138
- unbox (cast .unboxFrom . type );
140
+ unbox (getType ( cast .unboxFrom ) );
139
141
writeCast (cast .from , cast .to );
140
142
} else if (cast .unboxTo != null ) {
141
- if (cast .from . dynamic ) {
143
+ if (cast .from == def . class ) {
142
144
if (cast .explicit ) {
143
- if (cast .to . clazz == Boolean .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_BOOLEAN );
144
- else if (cast .to . clazz == Byte .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_BYTE_EXPLICIT );
145
- else if (cast .to . clazz == Short .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_SHORT_EXPLICIT );
146
- else if (cast .to . clazz == Character .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_CHAR_EXPLICIT );
147
- else if (cast .to . clazz == Integer .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_INT_EXPLICIT );
148
- else if (cast .to . clazz == Long .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_LONG_EXPLICIT );
149
- else if (cast .to . clazz == Float .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_FLOAT_EXPLICIT );
150
- else if (cast .to . clazz == Double .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_DOUBLE_EXPLICIT );
145
+ if (cast .to == Boolean .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_BOOLEAN );
146
+ else if (cast .to == Byte .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_BYTE_EXPLICIT );
147
+ else if (cast .to == Short .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_SHORT_EXPLICIT );
148
+ else if (cast .to == Character .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_CHAR_EXPLICIT );
149
+ else if (cast .to == Integer .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_INT_EXPLICIT );
150
+ else if (cast .to == Long .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_LONG_EXPLICIT );
151
+ else if (cast .to == Float .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_FLOAT_EXPLICIT );
152
+ else if (cast .to == Double .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_DOUBLE_EXPLICIT );
151
153
else {
152
154
throw new IllegalStateException ("Illegal tree structure." );
153
155
}
154
156
} else {
155
- if (cast .to . clazz == Boolean .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_BOOLEAN );
156
- else if (cast .to . clazz == Byte .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_BYTE_IMPLICIT );
157
- else if (cast .to . clazz == Short .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_SHORT_IMPLICIT );
158
- else if (cast .to . clazz == Character .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_CHAR_IMPLICIT );
159
- else if (cast .to . clazz == Integer .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_INT_IMPLICIT );
160
- else if (cast .to . clazz == Long .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_LONG_IMPLICIT );
161
- else if (cast .to . clazz == Float .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_FLOAT_IMPLICIT );
162
- else if (cast .to . clazz == Double .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_DOUBLE_IMPLICIT );
157
+ if (cast .to == Boolean .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_BOOLEAN );
158
+ else if (cast .to == Byte .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_BYTE_IMPLICIT );
159
+ else if (cast .to == Short .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_SHORT_IMPLICIT );
160
+ else if (cast .to == Character .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_CHAR_IMPLICIT );
161
+ else if (cast .to == Integer .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_INT_IMPLICIT );
162
+ else if (cast .to == Long .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_LONG_IMPLICIT );
163
+ else if (cast .to == Float .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_FLOAT_IMPLICIT );
164
+ else if (cast .to == Double .class ) invokeStatic (DEF_UTIL_TYPE , DEF_TO_DOUBLE_IMPLICIT );
163
165
else {
164
166
throw new IllegalStateException ("Illegal tree structure." );
165
167
}
166
168
}
167
169
} else {
168
170
writeCast (cast .from , cast .to );
169
- unbox (cast .unboxTo . type );
171
+ unbox (getType ( cast .unboxTo ) );
170
172
}
171
173
} else if (cast .boxFrom != null ) {
172
- box (cast .boxFrom . type );
174
+ box (getType ( cast .boxFrom ) );
173
175
writeCast (cast .from , cast .to );
174
176
} else if (cast .boxTo != null ) {
175
177
writeCast (cast .from , cast .to );
176
- box (cast .boxTo . type );
178
+ box (getType ( cast .boxTo ) );
177
179
} else {
178
180
writeCast (cast .from , cast .to );
179
181
}
180
182
}
181
183
}
182
184
183
- private void writeCast (final Type from , final Type to ) {
185
+ private void writeCast (Class <?> from , Class <?> to ) {
184
186
if (from .equals (to )) {
185
187
return ;
186
188
}
187
189
188
- if (from . clazz != boolean .class && from .clazz . isPrimitive () && to . clazz != boolean .class && to . clazz .isPrimitive ()) {
189
- cast (from . type , to . type );
190
+ if (from != boolean .class && from .isPrimitive () && to != boolean .class && to .isPrimitive ()) {
191
+ cast (getType ( from ), getType ( to ) );
190
192
} else {
191
- if (!to .clazz . isAssignableFrom (from . clazz )) {
192
- checkCast (to . type );
193
+ if (!to .isAssignableFrom (from )) {
194
+ checkCast (getType ( to ) );
193
195
}
194
196
}
195
197
}
@@ -202,6 +204,29 @@ public void box(org.objectweb.asm.Type type) {
202
204
valueOf (type );
203
205
}
204
206
207
+ public static Type getType (Class <?> clazz ) {
208
+ if (clazz .isArray ()) {
209
+ Class <?> component = clazz .getComponentType ();
210
+ int dimensions = 1 ;
211
+
212
+ while (component .isArray ()) {
213
+ component = component .getComponentType ();
214
+ ++dimensions ;
215
+ }
216
+
217
+ if (component == def .class ) {
218
+ char [] braces = new char [dimensions ];
219
+ Arrays .fill (braces , '[' );
220
+
221
+ return Type .getType (new String (braces ) + Type .getType (Object .class ).getDescriptor ());
222
+ }
223
+ } else if (clazz == def .class ) {
224
+ return Type .getType (Object .class );
225
+ }
226
+
227
+ return Type .getType (clazz );
228
+ }
229
+
205
230
public void writeBranch (final Label tru , final Label fals ) {
206
231
if (tru != null ) {
207
232
visitJumpInsn (Opcodes .IFNE , tru );
@@ -227,7 +252,7 @@ public int writeNewStrings() {
227
252
}
228
253
}
229
254
230
- public void writeAppendStrings (final Type type ) {
255
+ public void writeAppendStrings (final Definition . Type type ) {
231
256
if (INDY_STRING_CONCAT_BOOTSTRAP_HANDLE != null ) {
232
257
// Java 9+: record type information
233
258
stringConcatArgs .peek ().add (type .type );
@@ -267,7 +292,7 @@ public void writeToStrings() {
267
292
}
268
293
269
294
/** Writes a dynamic binary instruction: returnType, lhs, and rhs can be different */
270
- public void writeDynamicBinaryInstruction (Location location , Type returnType , Type lhs , Type rhs ,
295
+ public void writeDynamicBinaryInstruction (Location location , Definition . Type returnType , Definition . Type lhs , Definition . Type rhs ,
271
296
Operation operation , int flags ) {
272
297
org .objectweb .asm .Type methodType = org .objectweb .asm .Type .getMethodType (returnType .type , lhs .type , rhs .type );
273
298
@@ -318,7 +343,7 @@ public void writeDynamicBinaryInstruction(Location location, Type returnType, Ty
318
343
}
319
344
320
345
/** Writes a static binary instruction */
321
- public void writeBinaryInstruction (Location location , Type type , Operation operation ) {
346
+ public void writeBinaryInstruction (Location location , Definition . Type type , Operation operation ) {
322
347
if ((type .clazz == float .class || type .clazz == double .class ) &&
323
348
(operation == Operation .LSH || operation == Operation .USH ||
324
349
operation == Operation .RSH || operation == Operation .BWAND ||
0 commit comments