1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Oct 16 12:42:00 2012 +0200
1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Dec 08 08:19:46 2012 +0100
1.3 @@ -36,9 +36,13 @@
1.4
1.5 import java.io.IOException;
1.6 import java.io.InputStream;
1.7 +import java.util.ArrayDeque;
1.8 import java.util.ArrayList;
1.9 import java.util.Collection;
1.10 +import java.util.Deque;
1.11 +import java.util.HashMap;
1.12 import java.util.List;
1.13 +import java.util.Map;
1.14 import org.apidesign.bck2brwsr.core.ExtraJavaScript;
1.15 import org.apidesign.bck2brwsr.core.JavaScriptBody;
1.16 import org.netbeans.modules.classfile.Annotation;
1.17 @@ -54,6 +58,7 @@
1.18 import org.netbeans.modules.classfile.ClassName;
1.19 import org.netbeans.modules.classfile.Code;
1.20 import org.netbeans.modules.classfile.ElementValue;
1.21 +import org.netbeans.modules.classfile.ExceptionTableEntry;
1.22 import org.netbeans.modules.classfile.Method;
1.23 import org.netbeans.modules.classfile.Parameter;
1.24 import org.netbeans.modules.classfile.PrimitiveElementValue;
1.25 @@ -198,7 +203,7 @@
1.26 out.append("arg").append(String.valueOf(i)).append(";\n");
1.27 }
1.28 out.append(" var stack = new Array();\n");
1.29 - produceCode(code.getByteCodes());
1.30 + produceCode(code.getByteCodes(), code.getExceptionTable());
1.31 } else {
1.32 out.append(" /* no code found for ").append(m.getTypeSignature()).append(" */\n");
1.33 }
1.34 @@ -241,18 +246,38 @@
1.35 out.append("arg").append(String.valueOf(i + 1)).append(";\n");
1.36 }
1.37 out.append(";\n var stack = new Array();\n");
1.38 - produceCode(code.getByteCodes());
1.39 + produceCode(code.getByteCodes(), code.getExceptionTable());
1.40 } else {
1.41 out.append(" /* no code found for ").append(m.getTypeSignature()).append(" */\n");
1.42 }
1.43 out.append("}");
1.44 }
1.45
1.46 - private void produceCode(byte[] byteCodes) throws IOException {
1.47 + private void produceCode(byte[] byteCodes, ExceptionTableEntry[] exceptionTable) throws IOException {
1.48 + final Map<Integer, ExceptionTableEntry> exStart = new HashMap<Integer, ExceptionTableEntry>();
1.49 + final Map<Integer, ExceptionTableEntry> exStop = new HashMap<Integer, ExceptionTableEntry>();
1.50 + for (ExceptionTableEntry e : exceptionTable) {
1.51 + exStart.put(e.getStartPC(), e);
1.52 + exStop.put(e.getEndPC(), e);
1.53 + }
1.54 + final Deque<ExceptionTableEntry> current = new ArrayDeque<ExceptionTableEntry>();
1.55 out.append("\n var gt = 0;\n for(;;) switch(gt) {\n");
1.56 for (int i = 0; i < byteCodes.length; i++) {
1.57 + {
1.58 + ExceptionTableEntry e = exStart.get(i);
1.59 + if (e != null) {
1.60 + current.addFirst(e);
1.61 + }
1.62 + e = exStop.get(i);
1.63 + if (e != null) {
1.64 + current.remove(e);
1.65 + }
1.66 + }
1.67 int prev = i;
1.68 out.append(" case " + i).append(": ");
1.69 + if (!current.isEmpty()) {
1.70 + out.append("try {");
1.71 + }
1.72 final int c = (byteCodes[i] + 256) % 256;
1.73 switch (c) {
1.74 case bc_aload_0:
1.75 @@ -708,13 +733,29 @@
1.76 }
1.77
1.78 }
1.79 + if (!current.isEmpty()) {
1.80 + out.append("} catch (e) {");
1.81 + for (ExceptionTableEntry e : current) {
1.82 + if (e.getCatchType() != null) {
1.83 + final String classInternalName = e.getCatchType().getClassName().getInternalName();
1.84 + addReference(classInternalName);
1.85 + out.append("if (e.$instOf_"+classInternalName.replace('/', '_')+") {");
1.86 + out.append("gt="+e.getHandlerPC()+"; continue;");
1.87 + out.append("} ");
1.88 + } else {
1.89 + //finally - todo
1.90 + }
1.91 + }
1.92 + out.append("throw e;");
1.93 + out.append("}");
1.94 + }
1.95 out.append(" //");
1.96 for (int j = prev; j <= i; j++) {
1.97 out.append(" ");
1.98 final int cc = (byteCodes[j] + 256) % 256;
1.99 out.append(Integer.toString(cc));
1.100 }
1.101 - out.append("\n");
1.102 + out.append("\n");
1.103 }
1.104 out.append(" }\n");
1.105 }