vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
changeset 398 945c799a6812
parent 397 2adac52f955e
child 399 1679cdfe4172
     1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sat Dec 29 19:46:09 2012 +0100
     1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sat Dec 29 20:10:10 2012 +0100
     1.3 @@ -280,22 +280,31 @@
     1.4          }
     1.5  
     1.6          int lastStackFrame = -1;
     1.7 -
     1.8 +        TrapData[] previousTrap = null;
     1.9 +        
    1.10          out.append("\n  var gt = 0;\n  for(;;) switch(gt) {\n");
    1.11          for (int i = 0; i < byteCodes.length; i++) {
    1.12              int prev = i;
    1.13              stackMapIterator.advanceTo(i);
    1.14 -            trap.advanceTo(i);
    1.15 +            boolean changeInCatch = trap.advanceTo(i);
    1.16 +            if (changeInCatch || lastStackFrame != stackMapIterator.getFrameIndex()) {
    1.17 +                if (previousTrap != null) {
    1.18 +                    generateCatch(previousTrap);
    1.19 +                    previousTrap = null;
    1.20 +                }
    1.21 +            }
    1.22              if (lastStackFrame != stackMapIterator.getFrameIndex()) {
    1.23                  lastStackFrame = stackMapIterator.getFrameIndex();
    1.24                  lmapper.syncWithFrameLocals(stackMapIterator.getFrameLocals());
    1.25                  smapper.syncWithFrameStack(stackMapIterator.getFrameStack());
    1.26                  out.append("    case " + i).append(": ");            
    1.27 +                changeInCatch = true;
    1.28              } else {
    1.29                  out.append("    /* " + i).append(" */ ");
    1.30              }
    1.31 -            if (trap.useTry()) {
    1.32 +            if (changeInCatch && trap.useTry()) {
    1.33                  out.append("try {");
    1.34 +                previousTrap = trap.current();
    1.35              }
    1.36              final int c = readByte(byteCodes, i);
    1.37              switch (c) {
    1.38 @@ -1120,25 +1129,6 @@
    1.39                           Integer.toString(c));
    1.40                  }
    1.41              }
    1.42 -            if (trap.useTry()) {
    1.43 -                out.append("} catch (e) {");
    1.44 -                for (TrapData e : trap.current()) {
    1.45 -                    if (e == null) {
    1.46 -                        break;
    1.47 -                    }
    1.48 -                    if (e.catch_cpx != 0) { //not finally
    1.49 -                        final String classInternalName = jc.getClassName(e.catch_cpx);
    1.50 -                        addReference(classInternalName);
    1.51 -                        out.append("if (e.$instOf_"+classInternalName.replace('/', '_')+") {");
    1.52 -                        out.append("gt="+e.handler_pc+"; stA0 = e; continue;");
    1.53 -                        out.append("} ");
    1.54 -                    } else {
    1.55 -                        //finally - todo
    1.56 -                    }
    1.57 -                }
    1.58 -                out.append("throw e;");
    1.59 -                out.append("}");
    1.60 -            }
    1.61              out.append(" //");
    1.62              for (int j = prev; j <= i; j++) {
    1.63                  out.append(" ");
    1.64 @@ -1147,6 +1137,9 @@
    1.65              }
    1.66              out.append("\n");            
    1.67          }
    1.68 +        if (previousTrap != null) {
    1.69 +            generateCatch(previousTrap);
    1.70 +        }
    1.71          out.append("  }\n");
    1.72          out.append("};");
    1.73      }
    1.74 @@ -1577,4 +1570,24 @@
    1.75  
    1.76          out.append(format, processed, length);
    1.77      }
    1.78 +
    1.79 +    private void generateCatch(TrapData[] traps) throws IOException {
    1.80 +        out.append("} catch (e) {");
    1.81 +        for (TrapData e : traps) {
    1.82 +            if (e == null) {
    1.83 +                break;
    1.84 +            }
    1.85 +            if (e.catch_cpx != 0) { //not finally
    1.86 +                final String classInternalName = jc.getClassName(e.catch_cpx);
    1.87 +                addReference(classInternalName);
    1.88 +                out.append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {");
    1.89 +                out.append("gt=" + e.handler_pc + "; stA0 = e; continue;");
    1.90 +                out.append("} ");
    1.91 +            } else {
    1.92 +                //finally - todo
    1.93 +            }
    1.94 +        }
    1.95 +        out.append("throw e;");
    1.96 +        out.append("}");
    1.97 +    }
    1.98  }