vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
branchexceptions
changeset 285 c8be2d837788
parent 106 346633cd13d6
child 287 6f696a0ef12f
     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      }