53
53
54
54
import static java .util .Collections .emptyList ;
55
55
import static java .util .Collections .unmodifiableSet ;
56
- import static org .elasticsearch .painless .WriterConstants .BASE_CLASS_TYPE ;
56
+ import static org .elasticsearch .painless .WriterConstants .BASE_INTERFACE_TYPE ;
57
+ import static org .elasticsearch .painless .WriterConstants .BITSET_TYPE ;
57
58
import static org .elasticsearch .painless .WriterConstants .BOOTSTRAP_METHOD_ERROR_TYPE ;
58
59
import static org .elasticsearch .painless .WriterConstants .CLASS_TYPE ;
59
60
import static org .elasticsearch .painless .WriterConstants .COLLECTIONS_TYPE ;
65
66
import static org .elasticsearch .painless .WriterConstants .DEF_BOOTSTRAP_METHOD ;
66
67
import static org .elasticsearch .painless .WriterConstants .EMPTY_MAP_METHOD ;
67
68
import static org .elasticsearch .painless .WriterConstants .EXCEPTION_TYPE ;
69
+ import static org .elasticsearch .painless .WriterConstants .GET_NAME_METHOD ;
70
+ import static org .elasticsearch .painless .WriterConstants .GET_SOURCE_METHOD ;
71
+ import static org .elasticsearch .painless .WriterConstants .GET_STATEMENTS_METHOD ;
72
+ import static org .elasticsearch .painless .WriterConstants .OBJECT_TYPE ;
68
73
import static org .elasticsearch .painless .WriterConstants .OUT_OF_MEMORY_ERROR_TYPE ;
69
74
import static org .elasticsearch .painless .WriterConstants .PAINLESS_ERROR_TYPE ;
70
75
import static org .elasticsearch .painless .WriterConstants .PAINLESS_EXPLAIN_ERROR_GET_HEADERS_METHOD ;
71
76
import static org .elasticsearch .painless .WriterConstants .PAINLESS_EXPLAIN_ERROR_TYPE ;
72
77
import static org .elasticsearch .painless .WriterConstants .STACK_OVERFLOW_ERROR_TYPE ;
78
+ import static org .elasticsearch .painless .WriterConstants .STRING_TYPE ;
73
79
74
80
/**
75
81
* The root of all Painless trees. Contains a series of statements.
@@ -203,9 +209,9 @@ public void write() {
203
209
204
210
int classFrames = ClassWriter .COMPUTE_FRAMES | ClassWriter .COMPUTE_MAXS ;
205
211
int classAccess = Opcodes .ACC_PUBLIC | Opcodes .ACC_SUPER | Opcodes .ACC_FINAL ;
206
- String classBase = BASE_CLASS_TYPE .getInternalName ();
212
+ String interfaceBase = BASE_INTERFACE_TYPE .getInternalName ();
207
213
String className = CLASS_TYPE .getInternalName ();
208
- String classInterfaces [] = new String [] { Type .getType (scriptInterface .getInterface ()).getInternalName () };
214
+ String classInterfaces [] = new String [] { interfaceBase , Type .getType (scriptInterface .getInterface ()).getInternalName () };
209
215
210
216
ClassWriter writer = new ClassWriter (classFrames );
211
217
ClassVisitor visitor = writer ;
@@ -218,7 +224,7 @@ public void write() {
218
224
if (debugStream != null ) {
219
225
visitor = new TraceClassVisitor (visitor , debugStream , null );
220
226
}
221
- visitor .visit (WriterConstants .CLASS_VERSION , classAccess , className , null , classBase , classInterfaces );
227
+ visitor .visit (WriterConstants .CLASS_VERSION , classAccess , className , null , OBJECT_TYPE . getInternalName () , classInterfaces );
222
228
visitor .visitSource (Location .computeSourceName (name , source ), null );
223
229
224
230
// Write the a method to bootstrap def calls
@@ -231,6 +237,11 @@ public void write() {
231
237
bootstrapDef .returnValue ();
232
238
bootstrapDef .endMethod ();
233
239
240
+ // Write static variables for name, source and statements used for writing exception messages
241
+ visitor .visitField (Opcodes .ACC_PUBLIC | Opcodes .ACC_STATIC , "$NAME" , STRING_TYPE .getDescriptor (), null , null ).visitEnd ();
242
+ visitor .visitField (Opcodes .ACC_PUBLIC | Opcodes .ACC_STATIC , "$SOURCE" , STRING_TYPE .getDescriptor (), null , null ).visitEnd ();
243
+ visitor .visitField (Opcodes .ACC_PUBLIC | Opcodes .ACC_STATIC , "$STATEMENTS" , BITSET_TYPE .getDescriptor (), null , null ).visitEnd ();
244
+
234
245
// Write the static variable used by the method to bootstrap def calls
235
246
visitor .visitField (Opcodes .ACC_PUBLIC | Opcodes .ACC_STATIC , "$DEFINITION" , DEFINITION_TYPE .getDescriptor (), null , null ).visitEnd ();
236
247
@@ -239,10 +250,32 @@ public void write() {
239
250
constructor .visitCode ();
240
251
constructor .loadThis ();
241
252
constructor .loadArgs ();
242
- constructor .invokeConstructor (BASE_CLASS_TYPE , CONSTRUCTOR );
253
+ constructor .invokeConstructor (OBJECT_TYPE , CONSTRUCTOR );
243
254
constructor .returnValue ();
244
255
constructor .endMethod ();
245
256
257
+ // Write a method to get static variable source
258
+ MethodWriter nameMethod = new MethodWriter (Opcodes .ACC_PUBLIC , GET_NAME_METHOD , visitor , globals .getStatements (), settings );
259
+ nameMethod .visitCode ();
260
+ nameMethod .getStatic (CLASS_TYPE , "$NAME" , STRING_TYPE );
261
+ nameMethod .returnValue ();
262
+ nameMethod .endMethod ();
263
+
264
+ // Write a method to get static variable source
265
+ MethodWriter sourceMethod = new MethodWriter (Opcodes .ACC_PUBLIC , GET_SOURCE_METHOD , visitor , globals .getStatements (), settings );
266
+ sourceMethod .visitCode ();
267
+ sourceMethod .getStatic (CLASS_TYPE , "$SOURCE" , STRING_TYPE );
268
+ sourceMethod .returnValue ();
269
+ sourceMethod .endMethod ();
270
+
271
+ // Write a method to get static variable statements
272
+ MethodWriter statementsMethod =
273
+ new MethodWriter (Opcodes .ACC_PUBLIC , GET_STATEMENTS_METHOD , visitor , globals .getStatements (), settings );
274
+ statementsMethod .visitCode ();
275
+ statementsMethod .getStatic (CLASS_TYPE , "$STATEMENTS" , BITSET_TYPE );
276
+ statementsMethod .returnValue ();
277
+ statementsMethod .endMethod ();
278
+
246
279
// Write the method defined in the interface:
247
280
MethodWriter executeMethod = new MethodWriter (Opcodes .ACC_PUBLIC , scriptInterface .getExecuteMethod (), visitor ,
248
281
globals .getStatements (), settings );
@@ -357,7 +390,7 @@ void write(MethodWriter writer, Globals globals) {
357
390
writer .dup ();
358
391
writer .getStatic (CLASS_TYPE , "$DEFINITION" , DEFINITION_TYPE );
359
392
writer .invokeVirtual (PAINLESS_EXPLAIN_ERROR_TYPE , PAINLESS_EXPLAIN_ERROR_GET_HEADERS_METHOD );
360
- writer .invokeVirtual ( BASE_CLASS_TYPE , CONVERT_TO_SCRIPT_EXCEPTION_METHOD );
393
+ writer .invokeInterface ( BASE_INTERFACE_TYPE , CONVERT_TO_SCRIPT_EXCEPTION_METHOD );
361
394
writer .throwException ();
362
395
// This looks like:
363
396
// } catch (PainlessError | BootstrapMethodError | OutOfMemoryError | StackOverflowError | Exception e) {
@@ -373,7 +406,7 @@ void write(MethodWriter writer, Globals globals) {
373
406
writer .loadThis ();
374
407
writer .swap ();
375
408
writer .invokeStatic (COLLECTIONS_TYPE , EMPTY_MAP_METHOD );
376
- writer .invokeVirtual ( BASE_CLASS_TYPE , CONVERT_TO_SCRIPT_EXCEPTION_METHOD );
409
+ writer .invokeInterface ( BASE_INTERFACE_TYPE , CONVERT_TO_SCRIPT_EXCEPTION_METHOD );
377
410
writer .throwException ();
378
411
writer .mark (endCatch );
379
412
}
0 commit comments