@@ -673,7 +673,7 @@ public void execute(int index, AbstractInsnNode anode) {
673
673
a = stack [--sp ]; // pop this
674
674
// initialize
675
675
if (a .charAt (0 ) == 'U' ) {
676
- b = a .substring (a .indexOf (':' )+1 );
676
+ b = a .substring (a .indexOf (':' )+1 ). intern () ;
677
677
for (int i = 0 ; i < stack .length ; i ++)
678
678
if (a == stack [i ]) stack [i ] = b ;
679
679
}
@@ -804,6 +804,7 @@ public void merge(int index, Frame f) {
804
804
String c = lub (a ,b );
805
805
if (b != c ) {
806
806
//System.out.printf("%d.%d %s -> %s\n", index, i, b, c);
807
+ if (DEBUG_FRAGMENT && a != c && b != c ) System .out .printf ("%d.%d %s | %s => %s\n " , index , i , a , b , c );
807
808
slot .stack [i ] = c ;
808
809
changed = true ;
809
810
}
@@ -853,6 +854,9 @@ String lub(String a,String b) {
853
854
// at this point in a real verifier we would load the named classes and use their common superclass
854
855
// lub(P6OpaqueInstance, CodeRef) = SixModelObject
855
856
// punt.
857
+ if (a == "Lorg/perl6/nqp/runtime/CodeRef;" && b == "Lorg/perl6/nqp/sixmodel/SixModelObject;" ) return b ;
858
+ if (b == "Lorg/perl6/nqp/runtime/CodeRef;" && a == "Lorg/perl6/nqp/sixmodel/SixModelObject;" ) return a ;
859
+
856
860
return "Ljava/lang/Object;" ;
857
861
}
858
862
}
@@ -902,6 +906,18 @@ private void getTypes() {
902
906
if (DEBUG_FRAGMENT && (step % 10000 ) == 0 ) System .out .printf ("Inference step %d\n " , step );
903
907
}
904
908
types = state .frames ;
909
+
910
+ if (DEBUG_FRAGMENT ) {
911
+ Map <String ,Integer > histog = new HashMap < >();
912
+ for (Frame fr : types ) {
913
+ for (int i = 0 ; i < fr .sp ; i ++) {
914
+ Integer r = histog .get (fr .stack [i ]);
915
+ histog .put (fr .stack [i ], r == null ? 1 : 1 +r );
916
+ }
917
+ }
918
+ for (Map .Entry <String ,Integer > ent : histog .entrySet ())
919
+ System .out .printf ("%s : %d\n " , ent .getKey (), ent .getValue ());
920
+ }
905
921
}
906
922
907
923
private int insnSize (AbstractInsnNode ai ) {
@@ -1306,7 +1322,15 @@ private void emitFragment(int fno, int begin, int end) {
1306
1322
}
1307
1323
v .visitLabel (insnLabels [end - begin ]);
1308
1324
1309
- if (exitTrampolineLabels .containsKey (end ))
1325
+ boolean fallthru = false ;
1326
+ for (ControlEdge ce : successors [end -1 ]) {
1327
+ if (ce .to == end ) {
1328
+ fallthru = true ;
1329
+ break ;
1330
+ }
1331
+ }
1332
+
1333
+ if (fallthru )
1310
1334
v .visitJumpInsn (Opcodes .GOTO , exitTrampolineLabels .get (end ));
1311
1335
1312
1336
int lineno = -1 ;
@@ -1338,13 +1362,15 @@ private void emitFragment(int fno, int begin, int end) {
1338
1362
}
1339
1363
1340
1364
// common exit code
1341
- v .visitLabel (commonExitLabel );
1342
- v .visitInsn (Opcodes .SWAP );
1343
- for (int i = 0 ; i < commonExit .length ; i ++) {
1344
- localExitCode (v , i , commonExit [i ]);
1365
+ if (exitPts .length > 0 ) {
1366
+ v .visitLabel (commonExitLabel );
1367
+ v .visitInsn (Opcodes .SWAP );
1368
+ for (int i = 0 ; i < commonExit .length ; i ++) {
1369
+ localExitCode (v , i , commonExit [i ]);
1370
+ }
1371
+ v .visitInsn (Opcodes .POP );
1372
+ v .visitInsn (Opcodes .IRETURN );
1345
1373
}
1346
- v .visitInsn (Opcodes .POP );
1347
- v .visitInsn (Opcodes .IRETURN );
1348
1374
v .visitMaxs (0 ,0 );
1349
1375
v .visitEnd ();
1350
1376
}
@@ -1374,6 +1400,8 @@ private void emitFragmentInsn(MethodVisitor v, int iix, int begin, Label[] insnL
1374
1400
v .visitInsn (Opcodes .DUP );
1375
1401
v .visitVarInsn (Opcodes .ILOAD + t , nlocal +1 );
1376
1402
v .visitMethodInsn (Opcodes .INVOKESPECIAL , box_types [t ], "<init>" , box_descs [t ]);
1403
+ } else {
1404
+ v .visitVarInsn (Opcodes .ILOAD + t , nlocal +1 );
1377
1405
}
1378
1406
v .visitInsn (Opcodes .AASTORE );
1379
1407
v .visitInsn (Opcodes .ICONST_M1 );
@@ -1541,9 +1569,9 @@ private void localExitCode(MethodVisitor v, int loc, String desc) {
1541
1569
int load ;
1542
1570
switch (c0 ) {
1543
1571
case 'I' : ty = "java/lang/Integer" ; load = Opcodes .ILOAD ; break ;
1544
- case 'J' : ty = "java/lang/Long" ; load = Opcodes .ILOAD ; break ;
1545
- case 'F' : ty = "java/lang/Float" ; load = Opcodes .ILOAD ; break ;
1546
- case 'D' : ty = "java/lang/Double" ; load = Opcodes .ILOAD ; break ;
1572
+ case 'J' : ty = "java/lang/Long" ; load = Opcodes .LLOAD ; break ;
1573
+ case 'F' : ty = "java/lang/Float" ; load = Opcodes .FLOAD ; break ;
1574
+ case 'D' : ty = "java/lang/Double" ; load = Opcodes .DLOAD ; break ;
1547
1575
default : throw new IllegalArgumentException (desc );
1548
1576
}
1549
1577
@@ -1625,7 +1653,7 @@ private void becomeWrapper() {
1625
1653
1626
1654
// allocate the scratchpad
1627
1655
instructions .add (intNode (maxStack ));
1628
- instructions .add (new TypeInsnNode (Opcodes .ANEWARRAY , "Ljava /lang/Object; " ));
1656
+ instructions .add (new TypeInsnNode (Opcodes .ANEWARRAY , "java /lang/Object" ));
1629
1657
// move the arguments onto the scratchpad
1630
1658
int ltmp = 0 ;
1631
1659
if ((access & Opcodes .ACC_STATIC ) == 0 ) ltmp += saveArg (instructions , ltmp , Type .getType (Object .class ));
@@ -1676,6 +1704,8 @@ private void becomeWrapper() {
1676
1704
1677
1705
if (rty != null ) {
1678
1706
instructions .add (new VarInsnNode (Opcodes .ALOAD , 0 ));
1707
+ instructions .add (new InsnNode (Opcodes .ICONST_0 ));
1708
+ instructions .add (new InsnNode (Opcodes .AALOAD ));
1679
1709
instructions .add (new TypeInsnNode (Opcodes .CHECKCAST , rty ));
1680
1710
if (unboxName != null )
1681
1711
instructions .add (new MethodInsnNode (Opcodes .INVOKEVIRTUAL , rty , unboxName , unboxDesc ));
0 commit comments