Initial attempt to merge current default branch with exceptions exceptions
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 24 Dec 2012 08:19:55 +0100
branchexceptions
changeset 376059cb07ac9b3
parent 375 5751fe604e6b
parent 292 fc3f6ea5e246
child 377 1295e596fd35
Initial attempt to merge current default branch with exceptions
javap/src/main/java/org/apidesign/javap/MethodData.java
javap/src/main/java/org/apidesign/javap/Vector.java
vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
     1.1 --- a/javap/src/main/java/org/apidesign/javap/MethodData.java	Mon Dec 24 08:04:45 2012 +0100
     1.2 +++ b/javap/src/main/java/org/apidesign/javap/MethodData.java	Mon Dec 24 08:19:55 2012 +0100
     1.3 @@ -357,10 +357,10 @@
     1.4      /**
     1.5       * Return exception table in code attributre.
     1.6       */
     1.7 -    public Vector getexception_table(){
     1.8 -        return exception_table;
     1.9 +    public TrapDataIterator getTrapDataIterator(){
    1.10 +        return new TrapDataIterator(exception_table);
    1.11      }
    1.12 -
    1.13 +    
    1.14  
    1.15      /**
    1.16       * Return method attributes.
     2.1 --- a/javap/src/main/java/org/apidesign/javap/TrapData.java	Mon Dec 24 08:04:45 2012 +0100
     2.2 +++ b/javap/src/main/java/org/apidesign/javap/TrapData.java	Mon Dec 24 08:19:55 2012 +0100
     2.3 @@ -26,7 +26,6 @@
     2.4  
     2.5  package org.apidesign.javap;
     2.6  
     2.7 -import java.util.*;
     2.8  import java.io.*;
     2.9  
    2.10  /**
    2.11 @@ -34,15 +33,18 @@
    2.12   *
    2.13   * @author  Sucheta Dambalkar (Adopted code from jdis)
    2.14   */
    2.15 -class TrapData {
    2.16 -    short start_pc, end_pc, handler_pc, catch_cpx;
    2.17 -  int num;
    2.18 +public final class TrapData {
    2.19 +  public final short start_pc;
    2.20 +  public final short end_pc;
    2.21 +  public final short handler_pc;
    2.22 +  public final short catch_cpx;
    2.23 +  final int num;
    2.24  
    2.25  
    2.26      /**
    2.27       * Read and store exception table data in code attribute.
    2.28       */
    2.29 -    public TrapData(DataInputStream in, int num) throws IOException {
    2.30 +    TrapData(DataInputStream in, int num) throws IOException {
    2.31          this.num=num;
    2.32          start_pc = in.readShort();
    2.33          end_pc=in.readShort();
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/javap/src/main/java/org/apidesign/javap/TrapDataIterator.java	Mon Dec 24 08:19:55 2012 +0100
     3.3 @@ -0,0 +1,70 @@
     3.4 +/*
     3.5 + * To change this template, choose Tools | Templates
     3.6 + * and open the template in the editor.
     3.7 + */
     3.8 +package org.apidesign.javap;
     3.9 +
    3.10 +/**
    3.11 + *
    3.12 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    3.13 + */
    3.14 +public final class TrapDataIterator {
    3.15 +    private final Hashtable exStart = new Hashtable();
    3.16 +    private final Hashtable exStop = new Hashtable();
    3.17 +    private TrapData[] current = new TrapData[10];
    3.18 +    private int currentCount;
    3.19 +    
    3.20 +    TrapDataIterator(Vector exceptionTable) {
    3.21 +        for (int i=0 ; i < exceptionTable.size(); i++) {
    3.22 +            final TrapData td = (TrapData)exceptionTable.elementAt(i);
    3.23 +            exStart.put(td.start_pc, td);
    3.24 +            exStop.put(td.end_pc, td);
    3.25 +        }
    3.26 +    }
    3.27 +
    3.28 +    public void advanceTo(int i) {
    3.29 +        Short s = Short.valueOf((short)i);
    3.30 +        TrapData e = (TrapData) exStart.get(s);
    3.31 +        if (e != null) {
    3.32 +            add(e);
    3.33 +        }
    3.34 +        e = (TrapData) exStop.get(s);
    3.35 +        if (e != null) {
    3.36 +            remove(e);
    3.37 +        }
    3.38 +    }
    3.39 +
    3.40 +    public boolean useTry() {
    3.41 +        return currentCount > 0;
    3.42 +    }
    3.43 +
    3.44 +    public TrapData[] current() {
    3.45 +        return current;
    3.46 +    }
    3.47 +
    3.48 +    private void add(TrapData e) {
    3.49 +        if (currentCount == current.length) {
    3.50 +            TrapData[] data = new TrapData[currentCount * 2];
    3.51 +            for (int i = 0; i < currentCount; i++) {
    3.52 +                data[i] = current[i];
    3.53 +            }
    3.54 +            current = data;
    3.55 +        }
    3.56 +        current[currentCount++] = e;
    3.57 +    }
    3.58 +
    3.59 +    private void remove(TrapData e) {
    3.60 +        int from = 0;
    3.61 +        while (from < currentCount) {
    3.62 +            if (e == current[from++]) {
    3.63 +                break;
    3.64 +            }
    3.65 +        }
    3.66 +        while (from < currentCount) {
    3.67 +            current[from - 1] = current[from];
    3.68 +            current[from] = null;
    3.69 +            from++;
    3.70 +        }
    3.71 +        currentCount--;
    3.72 +    }
    3.73 +}
     4.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Mon Dec 24 08:04:45 2012 +0100
     4.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Mon Dec 24 08:19:55 2012 +0100
     4.3 @@ -25,6 +25,8 @@
     4.4  import org.apidesign.javap.MethodData;
     4.5  import org.apidesign.javap.StackMapIterator;
     4.6  import static org.apidesign.javap.RuntimeConstants.*;
     4.7 +import org.apidesign.javap.TrapData;
     4.8 +import org.apidesign.javap.TrapDataIterator;
     4.9  
    4.10  /** Translator of the code inside class files to JavaScript.
    4.11   *
    4.12 @@ -222,6 +224,7 @@
    4.13      private void generateMethod(String prefix, String name, MethodData m)
    4.14              throws IOException {
    4.15          final StackMapIterator stackMapIterator = m.createStackMapIterator();
    4.16 +        TrapDataIterator trap = m.getTrapDataIterator();
    4.17          final LocalsMapper lmapper =
    4.18                  new LocalsMapper(stackMapIterator.getArguments());
    4.19  
    4.20 @@ -273,14 +276,18 @@
    4.21          for (int i = 0; i < byteCodes.length; i++) {
    4.22              int prev = i;
    4.23              stackMapIterator.advanceTo(i);
    4.24 +            trap.advanceTo(i);
    4.25              if (lastStackFrame != stackMapIterator.getFrameIndex()) {
    4.26                  lastStackFrame = stackMapIterator.getFrameIndex();
    4.27                  lmapper.syncWithFrameLocals(stackMapIterator.getFrameLocals());
    4.28                  smapper.syncWithFrameStack(stackMapIterator.getFrameStack());
    4.29 -                out.append("    case " + i).append(": ");
    4.30 +                out.append("    case " + i).append(": ");            
    4.31              } else {
    4.32                  out.append("    /* " + i).append(" */ ");
    4.33              }
    4.34 +            if (trap.useTry()) {
    4.35 +                out.append("try {");
    4.36 +            }
    4.37              final int c = readByte(byteCodes, i);
    4.38              switch (c) {
    4.39                  case opc_aload_0:
    4.40 @@ -1104,13 +1111,32 @@
    4.41                           Integer.toString(c));
    4.42                  }
    4.43              }
    4.44 +            if (trap.useTry()) {
    4.45 +                out.append("} catch (e) {");
    4.46 +                for (TrapData e : trap.current()) {
    4.47 +                    if (e == null) {
    4.48 +                        break;
    4.49 +                    }
    4.50 +                    if (e.catch_cpx != 0) { //not finally
    4.51 +                        final String classInternalName = jc.getClassName(e.catch_cpx);
    4.52 +                        addReference(classInternalName);
    4.53 +                        out.append("if (e.$instOf_"+classInternalName.replace('/', '_')+") {");
    4.54 +                        out.append("gt="+e.handler_pc+"; continue;");
    4.55 +                        out.append("} ");
    4.56 +                    } else {
    4.57 +                        //finally - todo
    4.58 +                    }
    4.59 +                }
    4.60 +                out.append("throw e;");
    4.61 +                out.append("}");
    4.62 +            }
    4.63              out.append(" //");
    4.64              for (int j = prev; j <= i; j++) {
    4.65                  out.append(" ");
    4.66                  final int cc = readByte(byteCodes, j);
    4.67                  out.append(Integer.toString(cc));
    4.68              }
    4.69 -            out.append("\n");
    4.70 +            out.append("\n");            
    4.71          }
    4.72          out.append("  }\n");
    4.73          out.append("};");
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java	Mon Dec 24 08:19:55 2012 +0100
     5.3 @@ -0,0 +1,49 @@
     5.4 +/**
     5.5 + * Back 2 Browser Bytecode Translator
     5.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     5.7 + *
     5.8 + * This program is free software: you can redistribute it and/or modify
     5.9 + * it under the terms of the GNU General Public License as published by
    5.10 + * the Free Software Foundation, version 2 of the License.
    5.11 + *
    5.12 + * This program is distributed in the hope that it will be useful,
    5.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.15 + * GNU General Public License for more details.
    5.16 + *
    5.17 + * You should have received a copy of the GNU General Public License
    5.18 + * along with this program. Look for COPYING file in the top folder.
    5.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    5.20 + */
    5.21 +package org.apidesign.vm4brwsr;
    5.22 +
    5.23 +/**
    5.24 + *
    5.25 + * @author tom
    5.26 + */
    5.27 +public class Exceptions {
    5.28 +
    5.29 +    public static int methodWithTryCatchNoThrow() {
    5.30 +        int res = 0;
    5.31 +        try {
    5.32 +            res = 1;
    5.33 +        } catch (IllegalArgumentException e) {
    5.34 +            res = 2;
    5.35 +        }
    5.36 +        //join point
    5.37 +        return res;
    5.38 +    }
    5.39 +
    5.40 +    public static int methodWithTryCatchThrow() {
    5.41 +        int res = 0;
    5.42 +        try {
    5.43 +            res = 1;
    5.44 +            throw new IllegalArgumentException();
    5.45 +        } catch (IllegalArgumentException e) {
    5.46 +            res = 2;
    5.47 +        }
    5.48 +        //join point
    5.49 +        return res;
    5.50 +    }
    5.51 +
    5.52 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java	Mon Dec 24 08:19:55 2012 +0100
     6.3 @@ -0,0 +1,63 @@
     6.4 +/**
     6.5 + * Back 2 Browser Bytecode Translator
     6.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     6.7 + *
     6.8 + * This program is free software: you can redistribute it and/or modify
     6.9 + * it under the terms of the GNU General Public License as published by
    6.10 + * the Free Software Foundation, version 2 of the License.
    6.11 + *
    6.12 + * This program is distributed in the hope that it will be useful,
    6.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.15 + * GNU General Public License for more details.
    6.16 + *
    6.17 + * You should have received a copy of the GNU General Public License
    6.18 + * along with this program. Look for COPYING file in the top folder.
    6.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    6.20 + */
    6.21 +package org.apidesign.vm4brwsr;
    6.22 +
    6.23 +import javax.script.Invocable;
    6.24 +import javax.script.ScriptException;
    6.25 +import static org.testng.Assert.*;
    6.26 +import org.testng.annotations.BeforeClass;
    6.27 +import org.testng.annotations.Test;
    6.28 +
    6.29 +/**
    6.30 + *
    6.31 + * @author Tomas Zezula <tzezula@netbeans.org>
    6.32 + */
    6.33 +public class ExceptionsTest {
    6.34 +    @Test
    6.35 +    public void verifyMethodWithTryCatchNoThrow() throws Exception {
    6.36 +            assertExec(
    6.37 +                    "No throw",
    6.38 +                    Exceptions.class,
    6.39 +                    "methodWithTryCatchNoThrow__I",
    6.40 +                    new Double(1.0));
    6.41 +    }
    6.42 +
    6.43 +    @Test
    6.44 +    public void verifyMethodWithTryCatchThrow() throws Exception {
    6.45 +            assertExec(
    6.46 +                    "Throw",
    6.47 +                    Exceptions.class,
    6.48 +                    "methodWithTryCatchThrow__I",
    6.49 +                    new Double(2.0));
    6.50 +    }
    6.51 +    
    6.52 +    private static CharSequence codeSeq;
    6.53 +    private static Invocable code;
    6.54 +    
    6.55 +    @BeforeClass 
    6.56 +    public void compileTheCode() throws Exception {
    6.57 +        StringBuilder sb = new StringBuilder();
    6.58 +        code = StaticMethodTest.compileClass(sb, 
    6.59 +            "org/apidesign/vm4brwsr/Exceptions"
    6.60 +        );
    6.61 +        codeSeq = sb;
    6.62 +    }
    6.63 +    private static void assertExec(String msg, Class clazz, String method, Object expRes, Object... args) throws Exception {
    6.64 +        StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args);
    6.65 +    }
    6.66 +}