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