1616import com .codename1 .tools .translator .bytecodes .TypeInstruction ;
1717import com .codename1 .tools .translator .bytecodes .VarOp ;
1818import java .util .HashMap ;
19+ import java .util .HashSet ;
1920import java .util .List ;
2021import java .util .Map ;
22+ import java .util .Set ;
2123import org .objectweb .asm .Label ;
2224import org .objectweb .asm .Opcodes ;
2325import org .objectweb .asm .Type ;
@@ -277,6 +279,9 @@ private static boolean appendStraightLineMethodBody(StringBuilder out, ByteCodeC
277279 StringBuilder instructionBody = new StringBuilder ();
278280 StringBuilder body = new StringBuilder ();
279281 StraightLineContext ctx = new StraightLineContext (method .getMaxLocals (), method .getMaxStack ());
282+ if (method .isStatic () && !"__CLINIT__" .equals (method .getMethodName ())) {
283+ ctx .initializedClasses .add (cls .getClsName ());
284+ }
280285 if (!method .isStatic ()) {
281286 setup .append (" let l0 = __cn1ThisObject;\n " );
282287 ctx .localsInitialized [0 ] = true ;
@@ -628,7 +633,14 @@ private static boolean appendStraightLineBasicInstruction(StringBuilder out, Byt
628633 String value = ctx .pop ();
629634 String idx = ctx .pop ();
630635 String arr = ctx .pop ();
631- out .append (" { const __arr = " ).append (arr ).append ("; const __idx = " ).append (idx ).append ("; if (!__arr.__array) throw new Error(\" Array expected\" ); if (__idx < 0 || __idx >= __arr.length) throw new Error(\" ArrayIndexOutOfBoundsException\" ); __arr[__idx] = " ).append (value ).append ("; }\n " );
636+ String arrayTemp = ctx .nextTemp ("__arr" );
637+ String indexTemp = ctx .nextTemp ("__idx" );
638+ out .append (" { const " ).append (arrayTemp ).append (" = " ).append (arr )
639+ .append ("; const " ).append (indexTemp ).append (" = " ).append (idx )
640+ .append ("; if (!" ).append (arrayTemp ).append (".__array) throw new Error(\" Array expected\" ); if (" )
641+ .append (indexTemp ).append (" < 0 || " ).append (indexTemp ).append (" >= " ).append (arrayTemp )
642+ .append (".length) throw new Error(\" ArrayIndexOutOfBoundsException\" ); " )
643+ .append (arrayTemp ).append ("[" ).append (indexTemp ).append ("] = " ).append (value ).append ("; }\n " );
632644 return true ;
633645 }
634646 default :
@@ -744,11 +756,11 @@ private static boolean appendStraightLineFieldInstruction(StringBuilder out, Fie
744756 String propertyName = JavascriptNameUtil .fieldProperty (field .getOwner (), fieldName );
745757 switch (field .getOpcode ()) {
746758 case Opcodes .GETSTATIC :
747- out . append ( " jvm.ensureClassInitialized( \" " ). append ( owner ). append ( " \" ); \n " );
759+ appendStraightLineEnsureClassInitialized ( out , ctx , owner );
748760 out .append (" " ).append (ctx .push ("jvm.classes[\" " + owner + "\" ].staticFields[\" " + fieldName + "\" ]" )).append (";\n " );
749761 return true ;
750762 case Opcodes .PUTSTATIC :
751- out . append ( " jvm.ensureClassInitialized( \" " ). append ( owner ). append ( " \" ); \n " );
763+ appendStraightLineEnsureClassInitialized ( out , ctx , owner );
752764 out .append (" jvm.classes[\" " ).append (owner ).append ("\" ].staticFields[\" " ).append (fieldName ).append ("\" ] = " )
753765 .append (ctx .pop ()).append (";\n " );
754766 return true ;
@@ -768,6 +780,12 @@ private static boolean appendStraightLineFieldInstruction(StringBuilder out, Fie
768780 }
769781 }
770782
783+ private static void appendStraightLineEnsureClassInitialized (StringBuilder out , StraightLineContext ctx , String owner ) {
784+ if (ctx .initializedClasses .add (owner )) {
785+ out .append (" jvm.ensureClassInitialized(\" " ).append (owner ).append ("\" );\n " );
786+ }
787+ }
788+
771789 private static boolean appendStraightLineInvokeInstruction (StringBuilder out , Invoke invoke , StraightLineContext ctx ) {
772790 String methodId = JavascriptNameUtil .methodIdentifier (invoke .getOwner (), invoke .getName (), invoke .getDesc ());
773791 List <String > args = JavascriptNameUtil .argumentTypes (invoke .getDesc ());
@@ -791,9 +809,8 @@ private static boolean appendStraightLineInvokeInstruction(StringBuilder out, In
791809 if (invoke .getOpcode () == Opcodes .INVOKEVIRTUAL || invoke .getOpcode () == Opcodes .INVOKEINTERFACE ) {
792810 out .append (" {\n " );
793811 out .append (" const __target = " ).append (target ).append (";\n " );
794- out .append (" const __class = jvm.classes[__target.__class];\n " );
795- out .append (" const __method = (__class && __class.methods && __class.methods[\" " ).append (methodId )
796- .append ("\" ]) || jvm.resolveVirtual(__target.__class, \" " ).append (methodId ).append ("\" );\n " );
812+ out .append (" const __method = ((jvm.classes[__target.__class] && jvm.classes[__target.__class].methods) ? jvm.classes[__target.__class].methods[\" " ).append (methodId )
813+ .append ("\" ] : null) || jvm.resolveVirtual(__target.__class, \" " ).append (methodId ).append ("\" );\n " );
797814 if (hasReturn ) {
798815 out .append (" const __result = yield* __method(" );
799816 appendInvocationArgumentExpressions (out , "__target" , argValues );
@@ -839,13 +856,15 @@ private static void appendInvocationArgumentExpressions(StringBuilder out, Strin
839856 private static final class StraightLineContext {
840857 private final boolean [] localsInitialized ;
841858 private final boolean [] localsUsed ;
859+ private final Set <String > initializedClasses ;
842860 private int sp ;
843861 private int maxObservedStack ;
844862 private int nextTempId ;
845863
846864 private StraightLineContext (int maxLocals , int maxStack ) {
847865 this .localsInitialized = new boolean [Math .max (1 , maxLocals )];
848866 this .localsUsed = new boolean [Math .max (1 , maxLocals )];
867+ this .initializedClasses = new HashSet <String >();
849868 this .sp = 0 ;
850869 this .maxObservedStack = 0 ;
851870 this .nextTempId = 0 ;
@@ -1575,9 +1594,8 @@ private static void appendInvokeInstruction(StringBuilder out, Invoke invoke, in
15751594 out .append (" {\n " );
15761595 appendInvocationArgumentBindings (out , argCount , " " , "stack.pop()" );
15771596 out .append (" const __target = stack.pop();\n " );
1578- out .append (" const __class = jvm.classes[__target.__class];\n " );
1579- out .append (" const __method = (__class && __class.methods && __class.methods[\" " ).append (methodId )
1580- .append ("\" ]) || jvm.resolveVirtual(__target.__class, \" " ).append (methodId ).append ("\" );\n " );
1597+ out .append (" const __method = ((jvm.classes[__target.__class] && jvm.classes[__target.__class].methods) ? jvm.classes[__target.__class].methods[\" " ).append (methodId )
1598+ .append ("\" ] : null) || jvm.resolveVirtual(__target.__class, \" " ).append (methodId ).append ("\" );\n " );
15811599 if (hasReturn ) {
15821600 out .append (" const __result = yield* __method(" );
15831601 appendInvocationArguments (out , true , argCount );
0 commit comments