diff -r 346633cd13d6 -r c8be2d837788 vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Oct 16 12:42:00 2012 +0200 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Dec 08 08:19:46 2012 +0100 @@ -36,9 +36,13 @@ import java.io.IOException; import java.io.InputStream; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; +import java.util.Deque; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apidesign.bck2brwsr.core.ExtraJavaScript; import org.apidesign.bck2brwsr.core.JavaScriptBody; import org.netbeans.modules.classfile.Annotation; @@ -54,6 +58,7 @@ import org.netbeans.modules.classfile.ClassName; import org.netbeans.modules.classfile.Code; import org.netbeans.modules.classfile.ElementValue; +import org.netbeans.modules.classfile.ExceptionTableEntry; import org.netbeans.modules.classfile.Method; import org.netbeans.modules.classfile.Parameter; import org.netbeans.modules.classfile.PrimitiveElementValue; @@ -198,7 +203,7 @@ out.append("arg").append(String.valueOf(i)).append(";\n"); } out.append(" var stack = new Array();\n"); - produceCode(code.getByteCodes()); + produceCode(code.getByteCodes(), code.getExceptionTable()); } else { out.append(" /* no code found for ").append(m.getTypeSignature()).append(" */\n"); } @@ -241,18 +246,38 @@ out.append("arg").append(String.valueOf(i + 1)).append(";\n"); } out.append(";\n var stack = new Array();\n"); - produceCode(code.getByteCodes()); + produceCode(code.getByteCodes(), code.getExceptionTable()); } else { out.append(" /* no code found for ").append(m.getTypeSignature()).append(" */\n"); } out.append("}"); } - private void produceCode(byte[] byteCodes) throws IOException { + private void produceCode(byte[] byteCodes, ExceptionTableEntry[] exceptionTable) throws IOException { + final Map exStart = new HashMap(); + final Map exStop = new HashMap(); + for (ExceptionTableEntry e : exceptionTable) { + exStart.put(e.getStartPC(), e); + exStop.put(e.getEndPC(), e); + } + final Deque current = new ArrayDeque(); out.append("\n var gt = 0;\n for(;;) switch(gt) {\n"); for (int i = 0; i < byteCodes.length; i++) { + { + ExceptionTableEntry e = exStart.get(i); + if (e != null) { + current.addFirst(e); + } + e = exStop.get(i); + if (e != null) { + current.remove(e); + } + } int prev = i; out.append(" case " + i).append(": "); + if (!current.isEmpty()) { + out.append("try {"); + } final int c = (byteCodes[i] + 256) % 256; switch (c) { case bc_aload_0: @@ -708,13 +733,29 @@ } } + if (!current.isEmpty()) { + out.append("} catch (e) {"); + for (ExceptionTableEntry e : current) { + if (e.getCatchType() != null) { + final String classInternalName = e.getCatchType().getClassName().getInternalName(); + addReference(classInternalName); + out.append("if (e.$instOf_"+classInternalName.replace('/', '_')+") {"); + out.append("gt="+e.getHandlerPC()+"; continue;"); + out.append("} "); + } else { + //finally - todo + } + } + out.append("throw e;"); + out.append("}"); + } out.append(" //"); for (int j = prev; j <= i; j++) { out.append(" "); final int cc = (byteCodes[j] + 256) % 256; out.append(Integer.toString(cc)); } - out.append("\n"); + out.append("\n"); } out.append(" }\n"); }