1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Dec 06 16:11:48 2012 +0100
1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Dec 08 10:32:04 2012 +0100
1.3 @@ -24,6 +24,8 @@
1.4 import org.apidesign.javap.FieldData;
1.5 import org.apidesign.javap.MethodData;
1.6 import static org.apidesign.javap.RuntimeConstants.*;
1.7 +import org.apidesign.javap.TrapData;
1.8 +import org.apidesign.javap.Vector;
1.9
1.10 /** Translator of the code inside class files to JavaScript.
1.11 *
1.12 @@ -215,7 +217,7 @@
1.13 out.append("arg").append(String.valueOf(i)).append(";\n");
1.14 }
1.15 out.append(" var s = new Array();\n");
1.16 - produceCode(code);
1.17 + produceCode(code, m.getexception_table());
1.18 } else {
1.19 out.append(" throw 'no code found for ").append(m.getInternalSig()).append("';\n");
1.20 }
1.21 @@ -251,7 +253,7 @@
1.22 out.append("arg").append(String.valueOf(i + 1)).append(";\n");
1.23 }
1.24 out.append(";\n var s = new Array();\n");
1.25 - produceCode(code);
1.26 + produceCode(code, m.getexception_table());
1.27 } else {
1.28 out.append(" throw 'no code found for ").append(m.getInternalSig()).append("';\n");
1.29 }
1.30 @@ -259,11 +261,35 @@
1.31 return mn;
1.32 }
1.33
1.34 - private void produceCode(byte[] byteCodes) throws IOException {
1.35 + private void produceCode(byte[] byteCodes, Vector exceptionTable) throws IOException {
1.36 +
1.37 + final java.util.Map<Short, TrapData> exStart = new java.util.HashMap<Short, TrapData>();
1.38 + final java.util.Map<Short, TrapData> exStop = new java.util.HashMap<Short, TrapData>();
1.39 + for (int i=0 ; i < exceptionTable.size(); i++) {
1.40 + final TrapData td = (TrapData)exceptionTable.elementAt(i);
1.41 + exStart.put(td.start_pc, td);
1.42 + exStop.put(td.end_pc, td);
1.43 + }
1.44 + final java.util.Deque<TrapData> current = new java.util.ArrayDeque<TrapData>();
1.45 out.append("\n var gt = 0;\n for(;;) switch(gt) {\n");
1.46 +
1.47 for (int i = 0; i < byteCodes.length; i++) {
1.48 +
1.49 + {
1.50 + TrapData e = exStart.get((short)i);
1.51 + if (e != null) {
1.52 + current.addFirst(e);
1.53 + }
1.54 + e = exStop.get((short)i);
1.55 + if (e != null) {
1.56 + current.remove(e);
1.57 + }
1.58 + }
1.59 int prev = i;
1.60 - out.append(" case " + i).append(": ");
1.61 + out.append(" case " + i).append(": ");
1.62 + if (!current.isEmpty()) {
1.63 + out.append("try {");
1.64 + }
1.65 final int c = readByte(byteCodes, i);
1.66 switch (c) {
1.67 case opc_aload_0:
1.68 @@ -784,13 +810,29 @@
1.69 }
1.70
1.71 }
1.72 + if (!current.isEmpty()) {
1.73 + out.append("} catch (e) {");
1.74 + for (TrapData e : current) {
1.75 + if (e.catch_cpx != 0) { //not finally
1.76 + final String classInternalName = jc.getClassName(e.catch_cpx);
1.77 + addReference(classInternalName);
1.78 + out.append("if (e.$instOf_"+classInternalName.replace('/', '_')+") {");
1.79 + out.append("gt="+e.handler_pc+"; continue;");
1.80 + out.append("} ");
1.81 + } else {
1.82 + //finally - todo
1.83 + }
1.84 + }
1.85 + out.append("throw e;");
1.86 + out.append("}");
1.87 + }
1.88 out.append(" //");
1.89 for (int j = prev; j <= i; j++) {
1.90 out.append(" ");
1.91 final int cc = readByte(byteCodes, j);
1.92 out.append(Integer.toString(cc));
1.93 }
1.94 - out.append("\n");
1.95 + out.append("\n");
1.96 }
1.97 out.append(" }\n");
1.98 }