2020package org .elasticsearch .painless ;
2121
2222import org .elasticsearch .painless .Definition .Cast ;
23- import org .elasticsearch .painless .Definition .Type ;
23+ import org .elasticsearch .painless .Definition .def ;
2424import org .objectweb .asm .ClassVisitor ;
2525import org .objectweb .asm .Label ;
2626import org .objectweb .asm .Opcodes ;
27+ import org .objectweb .asm .Type ;
2728import org .objectweb .asm .commons .GeneratorAdapter ;
2829import org .objectweb .asm .commons .Method ;
2930
3031import java .util .ArrayDeque ;
3132import java .util .ArrayList ;
33+ import java .util .Arrays ;
3234import java .util .BitSet ;
3335import java .util .Deque ;
3436import java .util .List ;
@@ -128,68 +130,68 @@ public void writeLoopCounter(int slot, int count, Location location) {
128130 mark (end );
129131 }
130132
131- public void writeCast (final Cast cast ) {
133+ public void writeCast (Cast cast ) {
132134 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 ) {
134136 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 ) {
136138 invokeStatic (UTILITY_TYPE , STRING_TO_CHAR );
137139 } else if (cast .unboxFrom != null ) {
138- unbox (cast .unboxFrom . type );
140+ unbox (getType ( cast .unboxFrom ) );
139141 writeCast (cast .from , cast .to );
140142 } else if (cast .unboxTo != null ) {
141- if (cast .from . dynamic ) {
143+ if (cast .from == def . class ) {
142144 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 );
151153 else {
152154 throw new IllegalStateException ("Illegal tree structure." );
153155 }
154156 } 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 );
163165 else {
164166 throw new IllegalStateException ("Illegal tree structure." );
165167 }
166168 }
167169 } else {
168170 writeCast (cast .from , cast .to );
169- unbox (cast .unboxTo . type );
171+ unbox (getType ( cast .unboxTo ) );
170172 }
171173 } else if (cast .boxFrom != null ) {
172- box (cast .boxFrom . type );
174+ box (getType ( cast .boxFrom ) );
173175 writeCast (cast .from , cast .to );
174176 } else if (cast .boxTo != null ) {
175177 writeCast (cast .from , cast .to );
176- box (cast .boxTo . type );
178+ box (getType ( cast .boxTo ) );
177179 } else {
178180 writeCast (cast .from , cast .to );
179181 }
180182 }
181183 }
182184
183- private void writeCast (final Type from , final Type to ) {
185+ private void writeCast (Class <?> from , Class <?> to ) {
184186 if (from .equals (to )) {
185187 return ;
186188 }
187189
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 ) );
190192 } else {
191- if (!to .clazz . isAssignableFrom (from . clazz )) {
192- checkCast (to . type );
193+ if (!to .isAssignableFrom (from )) {
194+ checkCast (getType ( to ) );
193195 }
194196 }
195197 }
@@ -202,6 +204,29 @@ public void box(org.objectweb.asm.Type type) {
202204 valueOf (type );
203205 }
204206
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+
205230 public void writeBranch (final Label tru , final Label fals ) {
206231 if (tru != null ) {
207232 visitJumpInsn (Opcodes .IFNE , tru );
@@ -227,7 +252,7 @@ public int writeNewStrings() {
227252 }
228253 }
229254
230- public void writeAppendStrings (final Type type ) {
255+ public void writeAppendStrings (final Definition . Type type ) {
231256 if (INDY_STRING_CONCAT_BOOTSTRAP_HANDLE != null ) {
232257 // Java 9+: record type information
233258 stringConcatArgs .peek ().add (type .type );
@@ -267,7 +292,7 @@ public void writeToStrings() {
267292 }
268293
269294 /** 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 ,
271296 Operation operation , int flags ) {
272297 org .objectweb .asm .Type methodType = org .objectweb .asm .Type .getMethodType (returnType .type , lhs .type , rhs .type );
273298
@@ -318,7 +343,7 @@ public void writeDynamicBinaryInstruction(Location location, Type returnType, Ty
318343 }
319344
320345 /** 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 ) {
322347 if ((type .clazz == float .class || type .clazz == double .class ) &&
323348 (operation == Operation .LSH || operation == Operation .USH ||
324349 operation == Operation .RSH || operation == Operation .BWAND ||
0 commit comments