Limit the number of nested for cycles by some constant
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 12 Mar 2013 21:22:33 +0100
changeset 843140c739c607f
parent 842 5c4202b95e3c
child 844 023cda5b8b0b
child 846 7dc6128edb0d
Limit the number of nested for cycles by some constant
rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
     1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Tue Mar 12 15:14:20 2013 +0100
     1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Tue Mar 12 21:22:33 2013 +0100
     1.3 @@ -283,13 +283,14 @@
     1.4          
     1.5          out.append("\n  var gt = 0;\n");
     1.6          int openBraces = 0;
     1.7 +        int topMostLabel = 0;
     1.8          for (int i = 0; i < byteCodes.length; i++) {
     1.9              int prev = i;
    1.10              stackMapIterator.advanceTo(i);
    1.11              boolean changeInCatch = trap.advanceTo(i);
    1.12              if (changeInCatch || lastStackFrame != stackMapIterator.getFrameIndex()) {
    1.13                  if (previousTrap != null) {
    1.14 -                    generateCatch(previousTrap, i);
    1.15 +                    generateCatch(previousTrap, i, topMostLabel);
    1.16                      previousTrap = null;
    1.17                  }
    1.18              }
    1.19 @@ -297,6 +298,13 @@
    1.20                  if (i != 0) {
    1.21                      out.append("    }\n");
    1.22                  }
    1.23 +                if (openBraces > 64) {
    1.24 +                    for (int c = 0; c < 64; c++) {
    1.25 +                        out.append("break;}\n");
    1.26 +                    }
    1.27 +                    openBraces = 1;
    1.28 +                    topMostLabel = i;
    1.29 +                }
    1.30                  
    1.31                  lastStackFrame = stackMapIterator.getFrameIndex();
    1.32                  lmapper.syncWithFrameLocals(stackMapIterator.getFrameLocals());
    1.33 @@ -805,104 +813,104 @@
    1.34                      break;
    1.35                  case opc_if_acmpeq:
    1.36                      i = generateIf(byteCodes, i, smapper.popA(), smapper.popA(),
    1.37 -                                   "===");
    1.38 +                                   "===", topMostLabel);
    1.39                      break;
    1.40                  case opc_if_acmpne:
    1.41                      i = generateIf(byteCodes, i, smapper.popA(), smapper.popA(),
    1.42 -                                   "!==");
    1.43 +                                   "!==", topMostLabel);
    1.44                      break;
    1.45                  case opc_if_icmpeq:
    1.46                      i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
    1.47 -                                   "==");
    1.48 +                                   "==", topMostLabel);
    1.49                      break;
    1.50                  case opc_ifeq: {
    1.51                      int indx = i + readIntArg(byteCodes, i);
    1.52                      emitIf(out, "if (@1 == 0) ",
    1.53 -                         smapper.popI(), i, indx);
    1.54 +                         smapper.popI(), i, indx, topMostLabel);
    1.55                      i += 2;
    1.56                      break;
    1.57                  }
    1.58                  case opc_ifne: {
    1.59                      int indx = i + readIntArg(byteCodes, i);
    1.60                      emitIf(out, "if (@1 != 0) ",
    1.61 -                         smapper.popI(), i, indx);
    1.62 +                         smapper.popI(), i, indx, topMostLabel);
    1.63                      i += 2;
    1.64                      break;
    1.65                  }
    1.66                  case opc_iflt: {
    1.67                      int indx = i + readIntArg(byteCodes, i);
    1.68                      emitIf(out, "if (@1 < 0) ",
    1.69 -                         smapper.popI(), i, indx);
    1.70 +                         smapper.popI(), i, indx, topMostLabel);
    1.71                      i += 2;
    1.72                      break;
    1.73                  }
    1.74                  case opc_ifle: {
    1.75                      int indx = i + readIntArg(byteCodes, i);
    1.76                      emitIf(out, "if (@1 <= 0) ",
    1.77 -                         smapper.popI(), i, indx);
    1.78 +                         smapper.popI(), i, indx, topMostLabel);
    1.79                      i += 2;
    1.80                      break;
    1.81                  }
    1.82                  case opc_ifgt: {
    1.83                      int indx = i + readIntArg(byteCodes, i);
    1.84                      emitIf(out, "if (@1 > 0) ",
    1.85 -                         smapper.popI(), i, indx);
    1.86 +                         smapper.popI(), i, indx, topMostLabel);
    1.87                      i += 2;
    1.88                      break;
    1.89                  }
    1.90                  case opc_ifge: {
    1.91                      int indx = i + readIntArg(byteCodes, i);
    1.92                      emitIf(out, "if (@1 >= 0) ",
    1.93 -                         smapper.popI(), i, indx);
    1.94 +                         smapper.popI(), i, indx, topMostLabel);
    1.95                      i += 2;
    1.96                      break;
    1.97                  }
    1.98                  case opc_ifnonnull: {
    1.99                      int indx = i + readIntArg(byteCodes, i);
   1.100                      emitIf(out, "if (@1 !== null) ",
   1.101 -                         smapper.popA(), i, indx);
   1.102 +                         smapper.popA(), i, indx, topMostLabel);
   1.103                      i += 2;
   1.104                      break;
   1.105                  }
   1.106                  case opc_ifnull: {
   1.107                      int indx = i + readIntArg(byteCodes, i);
   1.108                      emitIf(out, "if (@1 === null) ",
   1.109 -                         smapper.popA(), i, indx);
   1.110 +                         smapper.popA(), i, indx, topMostLabel);
   1.111                      i += 2;
   1.112                      break;
   1.113                  }
   1.114                  case opc_if_icmpne:
   1.115                      i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
   1.116 -                                   "!=");
   1.117 +                                   "!=", topMostLabel);
   1.118                      break;
   1.119                  case opc_if_icmplt:
   1.120                      i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
   1.121 -                                   "<");
   1.122 +                                   "<", topMostLabel);
   1.123                      break;
   1.124                  case opc_if_icmple:
   1.125                      i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
   1.126 -                                   "<=");
   1.127 +                                   "<=", topMostLabel);
   1.128                      break;
   1.129                  case opc_if_icmpgt:
   1.130                      i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
   1.131 -                                   ">");
   1.132 +                                   ">", topMostLabel);
   1.133                      break;
   1.134                  case opc_if_icmpge:
   1.135                      i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
   1.136 -                                   ">=");
   1.137 +                                   ">=", topMostLabel);
   1.138                      break;
   1.139                  case opc_goto: {
   1.140                      int indx = i + readIntArg(byteCodes, i);
   1.141 -                    goTo(out, i, indx);
   1.142 +                    goTo(out, i, indx, topMostLabel);
   1.143                      i += 2;
   1.144                      break;
   1.145                  }
   1.146                  case opc_lookupswitch: {
   1.147 -                    i = generateLookupSwitch(i, byteCodes, smapper);
   1.148 +                    i = generateLookupSwitch(i, byteCodes, smapper, topMostLabel);
   1.149                      break;
   1.150                  }
   1.151                  case opc_tableswitch: {
   1.152 -                    i = generateTableSwitch(i, byteCodes, smapper);
   1.153 +                    i = generateTableSwitch(i, byteCodes, smapper, topMostLabel);
   1.154                      break;
   1.155                  }
   1.156                  case opc_invokeinterface: {
   1.157 @@ -1255,7 +1263,7 @@
   1.158              out.append("\n");            
   1.159          }
   1.160          if (previousTrap != null) {
   1.161 -            generateCatch(previousTrap, byteCodes.length);
   1.162 +            generateCatch(previousTrap, byteCodes.length, topMostLabel);
   1.163          }
   1.164          out.append("\n    }\n");
   1.165          while (openBraces-- > 0) {
   1.166 @@ -1264,14 +1272,12 @@
   1.167          out.append("\n};");
   1.168      }
   1.169  
   1.170 -    private int generateIf(byte[] byteCodes, int i,
   1.171 -                           final Variable v2, final Variable v1,
   1.172 -                           final String test) throws IOException {
   1.173 +    private int generateIf(byte[] byteCodes, int i, final Variable v2, final Variable v1, final String test, int topMostLabel) throws IOException {
   1.174          int indx = i + readIntArg(byteCodes, i);
   1.175          out.append("if (").append(v1)
   1.176             .append(' ').append(test).append(' ')
   1.177             .append(v2).append(") ");
   1.178 -        goTo(out, i, indx);
   1.179 +        goTo(out, i, indx, topMostLabel);
   1.180          return i + 2;
   1.181      }
   1.182      
   1.183 @@ -1746,7 +1752,7 @@
   1.184          out.append(format, processed, length);
   1.185      }
   1.186  
   1.187 -    private void generateCatch(TrapData[] traps, int current) throws IOException {
   1.188 +    private void generateCatch(TrapData[] traps, int current, int topMostLabel) throws IOException {
   1.189          out.append("} catch (e) {\n");
   1.190          int finallyPC = -1;
   1.191          for (TrapData e : traps) {
   1.192 @@ -1763,11 +1769,11 @@
   1.193                      out.append("  var stA0 = vm.java_lang_Throwable(true);");
   1.194                      out.append("  vm.java_lang_Throwable.cons__VLjava_lang_String_2.call(stA0, e.toString());");
   1.195                      out.append("}");
   1.196 -                    goTo(out, current, e.handler_pc);
   1.197 +                    goTo(out, current, e.handler_pc, topMostLabel);
   1.198                  } else {
   1.199                      out.append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {");
   1.200                      out.append("var stA0 = e;");
   1.201 -                    goTo(out, current, e.handler_pc);
   1.202 +                    goTo(out, current, e.handler_pc, topMostLabel);
   1.203                      out.append("}\n");
   1.204                  }
   1.205              } else {
   1.206 @@ -1778,22 +1784,29 @@
   1.207              out.append("throw e;");
   1.208          } else {
   1.209              out.append("var stA0 = e;");
   1.210 -            goTo(out, current, finallyPC);
   1.211 +            goTo(out, current, finallyPC, topMostLabel);
   1.212          }
   1.213          out.append("\n}");
   1.214      }
   1.215  
   1.216 -    private static void goTo(Appendable out, int current, int to) throws IOException {
   1.217 +    private static void goTo(Appendable out, int current, int to, int canBack) throws IOException {
   1.218          if (to < current) {
   1.219 -            out.append("{ gt = 0; continue X_" + to + "; }");
   1.220 +            if (canBack < to) {
   1.221 +                out.append("{ gt = 0; continue X_" + to + "; }");
   1.222 +            } else {
   1.223 +                out.append("{ gt = " + to + "; continue X_0; }");
   1.224 +            }
   1.225          } else {
   1.226              out.append("{ gt = " + to + "; break IF; }");
   1.227          }
   1.228      }
   1.229  
   1.230 -    private static void emitIf(Appendable out, String pattern, Variable param, int current, int to) throws IOException {
   1.231 +    private static void emitIf(
   1.232 +        Appendable out, String pattern, Variable param, 
   1.233 +        int current, int to, int canBack
   1.234 +    ) throws IOException {
   1.235          emit(out, pattern, param);
   1.236 -        goTo(out, current, to);
   1.237 +        goTo(out, current, to, canBack);
   1.238      }
   1.239  
   1.240      private void generateNewArray(int atype, final StackMapper smapper) throws IOException, IllegalStateException {
   1.241 @@ -1841,7 +1854,7 @@
   1.242          return i;
   1.243      }
   1.244  
   1.245 -    private int generateTableSwitch(int i, final byte[] byteCodes, final StackMapper smapper) throws IOException {
   1.246 +    private int generateTableSwitch(int i, final byte[] byteCodes, final StackMapper smapper, int topMostLabel) throws IOException {
   1.247          int table = i / 4 * 4 + 4;
   1.248          int dflt = i + readInt4(byteCodes, table);
   1.249          table += 4;
   1.250 @@ -1853,17 +1866,17 @@
   1.251          while (low <= high) {
   1.252              int offset = i + readInt4(byteCodes, table);
   1.253              table += 4;
   1.254 -            out.append("  case " + low).append(":"); goTo(out, i, offset); out.append('\n');
   1.255 +            out.append("  case " + low).append(":"); goTo(out, i, offset, topMostLabel); out.append('\n');
   1.256              low++;
   1.257          }
   1.258          out.append("  default: ");
   1.259 -        goTo(out, i, dflt);
   1.260 +        goTo(out, i, dflt, topMostLabel);
   1.261          out.append("\n}");
   1.262          i = table - 1;
   1.263          return i;
   1.264      }
   1.265  
   1.266 -    private int generateLookupSwitch(int i, final byte[] byteCodes, final StackMapper smapper) throws IOException {
   1.267 +    private int generateLookupSwitch(int i, final byte[] byteCodes, final StackMapper smapper, int topMostLabel) throws IOException {
   1.268          int table = i / 4 * 4 + 4;
   1.269          int dflt = i + readInt4(byteCodes, table);
   1.270          table += 4;
   1.271 @@ -1875,10 +1888,10 @@
   1.272              table += 4;
   1.273              int offset = i + readInt4(byteCodes, table);
   1.274              table += 4;
   1.275 -            out.append("  case " + cnstnt).append(": "); goTo(out, i, offset); out.append('\n');
   1.276 +            out.append("  case " + cnstnt).append(": "); goTo(out, i, offset, topMostLabel); out.append('\n');
   1.277          }
   1.278          out.append("  default: ");
   1.279 -        goTo(out, i, dflt);
   1.280 +        goTo(out, i, dflt, topMostLabel);
   1.281          out.append("\n}");
   1.282          i = table - 1;
   1.283          return i;