@@ -155,7 +155,9 @@ private void addDelegation(MethodVisitor mv, String methodName,
155
155
mv .visitMethodInsn (Opcodes .INVOKEVIRTUAL , "org/perl6/nqp/sixmodel/SixModelObject" , methodName ,
156
156
Type .getMethodDescriptor (retType , argTypes ));
157
157
158
- mv .visitInsn (retType == Type .VOID_TYPE ? Opcodes .RETURN : Opcodes .ARETURN );
158
+ mv .visitInsn (retType == Type .VOID_TYPE ? Opcodes .RETURN :
159
+ retType == Type .LONG_TYPE ? Opcodes .LRETURN :
160
+ Opcodes .ARETURN );
159
161
mv .visitLabel (label );
160
162
mv .visitInsn (Opcodes .POP );
161
163
}
@@ -279,6 +281,34 @@ private void generateJVMType(ThreadContext tc, STable st, List<AttrInfo> attrInf
279
281
}
280
282
}
281
283
284
+ /* is_attribute_initialized */
285
+ MethodVisitor isInitVisitor ;
286
+ Label isInitSwitch = null ;
287
+ Label [] isInitLabels = null ;
288
+ Label isInitDefault = new Label ();
289
+ Label isInitNull = new Label ();
290
+ {
291
+ String descriptor = Type .getMethodDescriptor (Type .LONG_TYPE ,
292
+ new Type [] { tcType , smoType , Type .getType (String .class ), Type .LONG_TYPE });
293
+ isInitVisitor = cw .visitMethod (Opcodes .ACC_PUBLIC , "is_attribute_initialized" , descriptor , null , null );
294
+ isInitVisitor .visitCode ();
295
+ addDelegation (isInitVisitor , "is_attribute_initialized" , Type .LONG_TYPE ,
296
+ new Type [] { tcType , smoType , Type .getType (String .class ), Type .LONG_TYPE }, false );
297
+
298
+ isInitVisitor .visitVarInsn (Opcodes .LLOAD , 4 );
299
+ isInitVisitor .visitInsn (Opcodes .L2I );
300
+
301
+ if (attrInfoList .size () > 0 ) {
302
+ isInitLabels = new Label [attrInfoList .size ()];
303
+ for (int i = 0 ; i < attrInfoList .size (); i ++) {
304
+ isInitLabels [i ] = new Label ();
305
+ }
306
+ isInitSwitch = new Label ();
307
+ isInitVisitor .visitLabel (isInitSwitch );
308
+ isInitVisitor .visitTableSwitchInsn (0 , attrInfoList .size () - 1 , isInitDefault , isInitLabels );
309
+ }
310
+ }
311
+
282
312
/* Now add all of the required fields and fill out the methods. */
283
313
for (int i = 0 ; i < attrInfoList .size (); i ++) {
284
314
AttrInfo attr = attrInfoList .get (i );
@@ -324,6 +354,15 @@ private void generateJVMType(ThreadContext tc, STable st, List<AttrInfo> attrInf
324
354
getBoxedVisitor .visitInsn (Opcodes .ARETURN );
325
355
}
326
356
357
+ /* Add is init code. */
358
+ isInitVisitor .visitLabel (isInitLabels [i ]);
359
+ isInitVisitor .visitVarInsn (Opcodes .ALOAD , 0 );
360
+ isInitVisitor .visitFieldInsn (Opcodes .GETFIELD , className , field , desc );
361
+ isInitVisitor .visitJumpInsn (Opcodes .IFNULL , isInitNull );
362
+ isInitVisitor .visitInsn (Opcodes .ICONST_1 );
363
+ isInitVisitor .visitInsn (Opcodes .I2L );
364
+ isInitVisitor .visitInsn (Opcodes .LRETURN );
365
+
327
366
/* Native variants should just throw. */
328
367
bindNativeVisitor .visitLabel (bindNativeLabels [i ]);
329
368
bindNativeVisitor .visitVarInsn (Opcodes .ALOAD , 0 );
@@ -344,6 +383,12 @@ private void generateJVMType(ThreadContext tc, STable st, List<AttrInfo> attrInf
344
383
getNativeVisitor .visitLabel (getNativeLabels [i ]);
345
384
attr .st .REPR .inlineGet (tc , attr .st , getNativeVisitor , className , prefix );
346
385
386
+ /* Add is init code. */
387
+ isInitVisitor .visitLabel (isInitLabels [i ]);
388
+ isInitVisitor .visitInsn (Opcodes .ICONST_1 );
389
+ isInitVisitor .visitInsn (Opcodes .I2L );
390
+ isInitVisitor .visitInsn (Opcodes .LRETURN );
391
+
347
392
/* Reference variants should just throw. */
348
393
bindBoxedVisitor .visitLabel (bindBoxedLabels [i ]);
349
394
bindBoxedVisitor .visitVarInsn (Opcodes .ALOAD , 0 );
@@ -426,9 +471,24 @@ private void generateJVMType(ThreadContext tc, STable st, List<AttrInfo> attrInf
426
471
getNativeVisitor .visitJumpInsn (Opcodes .GOTO , getNativeSwitch );
427
472
else
428
473
getNativeVisitor .visitInsn (Opcodes .RETURN );
429
-
430
474
getNativeVisitor .visitMaxs (6 , 6 );
431
475
getNativeVisitor .visitEnd ();
476
+
477
+ /* Finish is_attribute_initialized. */
478
+ isInitVisitor .visitLabel (isInitDefault );
479
+ isInitVisitor .visitVarInsn (Opcodes .ALOAD , 0 );
480
+ isInitVisitor .visitVarInsn (Opcodes .ALOAD , 2 );
481
+ isInitVisitor .visitVarInsn (Opcodes .ALOAD , 3 );
482
+ isInitVisitor .visitMethodInsn (Opcodes .INVOKEVIRTUAL , className , "resolveAttribute" ,
483
+ "(Lorg/perl6/nqp/sixmodel/SixModelObject;Ljava/lang/String;)I" );
484
+ if (attrInfoList .size () > 0 )
485
+ isInitVisitor .visitJumpInsn (Opcodes .GOTO , isInitSwitch );
486
+ isInitVisitor .visitLabel (isInitNull );
487
+ isInitVisitor .visitInsn (Opcodes .ICONST_1 );
488
+ isInitVisitor .visitInsn (Opcodes .I2L );
489
+ isInitVisitor .visitInsn (Opcodes .LRETURN );
490
+ isInitVisitor .visitMaxs (0 , 0 );
491
+ isInitVisitor .visitEnd ();
432
492
433
493
/* Finally, add empty constructor and generate the JVM storage class. */
434
494
MethodVisitor constructor = cw .visitMethod (Opcodes .ACC_PUBLIC , "<init>" , "()V" , null , null );
0 commit comments