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;