1.1 --- a/javap/src/main/java/org/apidesign/javap/TrapData.java Fri Dec 07 10:35:31 2012 +0100
1.2 +++ b/javap/src/main/java/org/apidesign/javap/TrapData.java Sat Dec 08 10:32:04 2012 +0100
1.3 @@ -34,9 +34,12 @@
1.4 *
1.5 * @author Sucheta Dambalkar (Adopted code from jdis)
1.6 */
1.7 -class TrapData {
1.8 - short start_pc, end_pc, handler_pc, catch_cpx;
1.9 - int num;
1.10 +public class TrapData {
1.11 + public final short start_pc;
1.12 + public final short end_pc;
1.13 + public final short handler_pc;
1.14 + public final short catch_cpx;
1.15 + final int num;
1.16
1.17
1.18 /**
2.1 --- a/javap/src/main/java/org/apidesign/javap/Vector.java Fri Dec 07 10:35:31 2012 +0100
2.2 +++ b/javap/src/main/java/org/apidesign/javap/Vector.java Sat Dec 08 10:32:04 2012 +0100
2.3 @@ -8,7 +8,7 @@
2.4 *
2.5 * @author Jaroslav Tulach <jtulach@netbeans.org>
2.6 */
2.7 -final class Vector {
2.8 +public final class Vector {
2.9 private Object[] arr;
2.10
2.11 Vector() {
2.12 @@ -27,7 +27,7 @@
2.13 setElementAt(obj, s);
2.14 }
2.15
2.16 - int size() {
2.17 + public int size() {
2.18 return arr == null ? 0 : arr.length;
2.19 }
2.20
2.21 @@ -41,7 +41,7 @@
2.22 }
2.23 }
2.24
2.25 - Object elementAt(int index) {
2.26 + public Object elementAt(int index) {
2.27 return arr[index];
2.28 }
2.29
3.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Dec 07 10:35:31 2012 +0100
3.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Dec 08 10:32:04 2012 +0100
3.3 @@ -24,6 +24,8 @@
3.4 import org.apidesign.javap.FieldData;
3.5 import org.apidesign.javap.MethodData;
3.6 import static org.apidesign.javap.RuntimeConstants.*;
3.7 +import org.apidesign.javap.TrapData;
3.8 +import org.apidesign.javap.Vector;
3.9
3.10 /** Translator of the code inside class files to JavaScript.
3.11 *
3.12 @@ -215,7 +217,7 @@
3.13 out.append("arg").append(String.valueOf(i)).append(";\n");
3.14 }
3.15 out.append(" var s = new Array();\n");
3.16 - produceCode(code);
3.17 + produceCode(code, m.getexception_table());
3.18 } else {
3.19 out.append(" throw 'no code found for ").append(m.getInternalSig()).append("';\n");
3.20 }
3.21 @@ -251,7 +253,7 @@
3.22 out.append("arg").append(String.valueOf(i + 1)).append(";\n");
3.23 }
3.24 out.append(";\n var s = new Array();\n");
3.25 - produceCode(code);
3.26 + produceCode(code, m.getexception_table());
3.27 } else {
3.28 out.append(" throw 'no code found for ").append(m.getInternalSig()).append("';\n");
3.29 }
3.30 @@ -259,11 +261,35 @@
3.31 return mn;
3.32 }
3.33
3.34 - private void produceCode(byte[] byteCodes) throws IOException {
3.35 + private void produceCode(byte[] byteCodes, Vector exceptionTable) throws IOException {
3.36 +
3.37 + final java.util.Map<Short, TrapData> exStart = new java.util.HashMap<Short, TrapData>();
3.38 + final java.util.Map<Short, TrapData> exStop = new java.util.HashMap<Short, TrapData>();
3.39 + for (int i=0 ; i < exceptionTable.size(); i++) {
3.40 + final TrapData td = (TrapData)exceptionTable.elementAt(i);
3.41 + exStart.put(td.start_pc, td);
3.42 + exStop.put(td.end_pc, td);
3.43 + }
3.44 + final java.util.Deque<TrapData> current = new java.util.ArrayDeque<TrapData>();
3.45 out.append("\n var gt = 0;\n for(;;) switch(gt) {\n");
3.46 +
3.47 for (int i = 0; i < byteCodes.length; i++) {
3.48 +
3.49 + {
3.50 + TrapData e = exStart.get((short)i);
3.51 + if (e != null) {
3.52 + current.addFirst(e);
3.53 + }
3.54 + e = exStop.get((short)i);
3.55 + if (e != null) {
3.56 + current.remove(e);
3.57 + }
3.58 + }
3.59 int prev = i;
3.60 - out.append(" case " + i).append(": ");
3.61 + out.append(" case " + i).append(": ");
3.62 + if (!current.isEmpty()) {
3.63 + out.append("try {");
3.64 + }
3.65 final int c = readByte(byteCodes, i);
3.66 switch (c) {
3.67 case opc_aload_0:
3.68 @@ -784,13 +810,29 @@
3.69 }
3.70
3.71 }
3.72 + if (!current.isEmpty()) {
3.73 + out.append("} catch (e) {");
3.74 + for (TrapData e : current) {
3.75 + if (e.catch_cpx != 0) { //not finally
3.76 + final String classInternalName = jc.getClassName(e.catch_cpx);
3.77 + addReference(classInternalName);
3.78 + out.append("if (e.$instOf_"+classInternalName.replace('/', '_')+") {");
3.79 + out.append("gt="+e.handler_pc+"; continue;");
3.80 + out.append("} ");
3.81 + } else {
3.82 + //finally - todo
3.83 + }
3.84 + }
3.85 + out.append("throw e;");
3.86 + out.append("}");
3.87 + }
3.88 out.append(" //");
3.89 for (int j = prev; j <= i; j++) {
3.90 out.append(" ");
3.91 final int cc = readByte(byteCodes, j);
3.92 out.append(Integer.toString(cc));
3.93 }
3.94 - out.append("\n");
3.95 + out.append("\n");
3.96 }
3.97 out.append(" }\n");
3.98 }
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java Sat Dec 08 10:32:04 2012 +0100
4.3 @@ -0,0 +1,49 @@
4.4 +/**
4.5 + * Back 2 Browser Bytecode Translator
4.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
4.7 + *
4.8 + * This program is free software: you can redistribute it and/or modify
4.9 + * it under the terms of the GNU General Public License as published by
4.10 + * the Free Software Foundation, version 2 of the License.
4.11 + *
4.12 + * This program is distributed in the hope that it will be useful,
4.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.15 + * GNU General Public License for more details.
4.16 + *
4.17 + * You should have received a copy of the GNU General Public License
4.18 + * along with this program. Look for COPYING file in the top folder.
4.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
4.20 + */
4.21 +package org.apidesign.vm4brwsr;
4.22 +
4.23 +/**
4.24 + *
4.25 + * @author tom
4.26 + */
4.27 +public class Exceptions {
4.28 +
4.29 + public static int methodWithTryCatchNoThrow() {
4.30 + int res = 0;
4.31 + try {
4.32 + res = 1;
4.33 + } catch (IllegalArgumentException e) {
4.34 + res = 2;
4.35 + }
4.36 + //join point
4.37 + return res;
4.38 + }
4.39 +
4.40 + public static int methodWithTryCatchThrow() {
4.41 + int res = 0;
4.42 + try {
4.43 + res = 1;
4.44 + throw new IllegalArgumentException();
4.45 + } catch (IllegalArgumentException e) {
4.46 + res = 2;
4.47 + }
4.48 + //join point
4.49 + return res;
4.50 + }
4.51 +
4.52 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java Sat Dec 08 10:32:04 2012 +0100
5.3 @@ -0,0 +1,63 @@
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 +import javax.script.Invocable;
5.24 +import javax.script.ScriptException;
5.25 +import static org.testng.Assert.*;
5.26 +import org.testng.annotations.BeforeClass;
5.27 +import org.testng.annotations.Test;
5.28 +
5.29 +/**
5.30 + *
5.31 + * @author Tomas Zezula <tzezula@netbeans.org>
5.32 + */
5.33 +public class ExceptionsTest {
5.34 + @Test
5.35 + public void verifyMethodWithTryCatchNoThrow() throws Exception {
5.36 + assertExec(
5.37 + "No throw",
5.38 + Exceptions.class,
5.39 + "methodWithTryCatchNoThrow__I",
5.40 + new Double(1.0));
5.41 + }
5.42 +
5.43 + @Test
5.44 + public void verifyMethodWithTryCatchThrow() throws Exception {
5.45 + assertExec(
5.46 + "Throw",
5.47 + Exceptions.class,
5.48 + "methodWithTryCatchThrow__I",
5.49 + new Double(2.0));
5.50 + }
5.51 +
5.52 + private static CharSequence codeSeq;
5.53 + private static Invocable code;
5.54 +
5.55 + @BeforeClass
5.56 + public void compileTheCode() throws Exception {
5.57 + StringBuilder sb = new StringBuilder();
5.58 + code = StaticMethodTest.compileClass(sb,
5.59 + "org/apidesign/vm4brwsr/Exceptions"
5.60 + );
5.61 + codeSeq = sb;
5.62 + }
5.63 + private static void assertExec(String msg, Class clazz, String method, Object expRes, Object... args) throws Exception {
5.64 + StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args);
5.65 + }
5.66 +}