# HG changeset patch # User tzezula # Date 1354959124 -3600 # Node ID 6f696a0ef12f53c908832794ac230a9af4fee416 # Parent 21c0cf272b0590649a5ad6f5e79d2bb59505d6ec# Parent 15053b74bdd92ab66dc3c5f0ea1f9484eebebaf3 'synched w/ trunk' diff -r 21c0cf272b05 -r 6f696a0ef12f javap/src/main/java/org/apidesign/javap/TrapData.java --- a/javap/src/main/java/org/apidesign/javap/TrapData.java Fri Dec 07 10:35:31 2012 +0100 +++ b/javap/src/main/java/org/apidesign/javap/TrapData.java Sat Dec 08 10:32:04 2012 +0100 @@ -34,9 +34,12 @@ * * @author Sucheta Dambalkar (Adopted code from jdis) */ -class TrapData { - short start_pc, end_pc, handler_pc, catch_cpx; - int num; +public class TrapData { + public final short start_pc; + public final short end_pc; + public final short handler_pc; + public final short catch_cpx; + final int num; /** diff -r 21c0cf272b05 -r 6f696a0ef12f javap/src/main/java/org/apidesign/javap/Vector.java --- a/javap/src/main/java/org/apidesign/javap/Vector.java Fri Dec 07 10:35:31 2012 +0100 +++ b/javap/src/main/java/org/apidesign/javap/Vector.java Sat Dec 08 10:32:04 2012 +0100 @@ -8,7 +8,7 @@ * * @author Jaroslav Tulach */ -final class Vector { +public final class Vector { private Object[] arr; Vector() { @@ -27,7 +27,7 @@ setElementAt(obj, s); } - int size() { + public int size() { return arr == null ? 0 : arr.length; } @@ -41,7 +41,7 @@ } } - Object elementAt(int index) { + public Object elementAt(int index) { return arr[index]; } diff -r 21c0cf272b05 -r 6f696a0ef12f vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Dec 07 10:35:31 2012 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Dec 08 10:32:04 2012 +0100 @@ -24,6 +24,8 @@ import org.apidesign.javap.FieldData; import org.apidesign.javap.MethodData; import static org.apidesign.javap.RuntimeConstants.*; +import org.apidesign.javap.TrapData; +import org.apidesign.javap.Vector; /** Translator of the code inside class files to JavaScript. * @@ -215,7 +217,7 @@ out.append("arg").append(String.valueOf(i)).append(";\n"); } out.append(" var s = new Array();\n"); - produceCode(code); + produceCode(code, m.getexception_table()); } else { out.append(" throw 'no code found for ").append(m.getInternalSig()).append("';\n"); } @@ -251,7 +253,7 @@ out.append("arg").append(String.valueOf(i + 1)).append(";\n"); } out.append(";\n var s = new Array();\n"); - produceCode(code); + produceCode(code, m.getexception_table()); } else { out.append(" throw 'no code found for ").append(m.getInternalSig()).append("';\n"); } @@ -259,11 +261,35 @@ return mn; } - private void produceCode(byte[] byteCodes) throws IOException { + private void produceCode(byte[] byteCodes, Vector exceptionTable) throws IOException { + + final java.util.Map exStart = new java.util.HashMap(); + final java.util.Map exStop = new java.util.HashMap(); + for (int i=0 ; i < exceptionTable.size(); i++) { + final TrapData td = (TrapData)exceptionTable.elementAt(i); + exStart.put(td.start_pc, td); + exStop.put(td.end_pc, td); + } + final java.util.Deque current = new java.util.ArrayDeque(); out.append("\n var gt = 0;\n for(;;) switch(gt) {\n"); + for (int i = 0; i < byteCodes.length; i++) { + + { + TrapData e = exStart.get((short)i); + if (e != null) { + current.addFirst(e); + } + e = exStop.get((short)i); + if (e != null) { + current.remove(e); + } + } int prev = i; - out.append(" case " + i).append(": "); + out.append(" case " + i).append(": "); + if (!current.isEmpty()) { + out.append("try {"); + } final int c = readByte(byteCodes, i); switch (c) { case opc_aload_0: @@ -784,13 +810,29 @@ } } + if (!current.isEmpty()) { + out.append("} catch (e) {"); + for (TrapData e : current) { + if (e.catch_cpx != 0) { //not finally + final String classInternalName = jc.getClassName(e.catch_cpx); + addReference(classInternalName); + out.append("if (e.$instOf_"+classInternalName.replace('/', '_')+") {"); + out.append("gt="+e.handler_pc+"; continue;"); + out.append("} "); + } else { + //finally - todo + } + } + out.append("throw e;"); + out.append("}"); + } out.append(" //"); for (int j = prev; j <= i; j++) { out.append(" "); final int cc = readByte(byteCodes, j); out.append(Integer.toString(cc)); } - out.append("\n"); + out.append("\n"); } out.append(" }\n"); } diff -r 21c0cf272b05 -r 6f696a0ef12f vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java Sat Dec 08 10:32:04 2012 +0100 @@ -0,0 +1,49 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.vm4brwsr; + +/** + * + * @author tom + */ +public class Exceptions { + + public static int methodWithTryCatchNoThrow() { + int res = 0; + try { + res = 1; + } catch (IllegalArgumentException e) { + res = 2; + } + //join point + return res; + } + + public static int methodWithTryCatchThrow() { + int res = 0; + try { + res = 1; + throw new IllegalArgumentException(); + } catch (IllegalArgumentException e) { + res = 2; + } + //join point + return res; + } + +} diff -r 21c0cf272b05 -r 6f696a0ef12f vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java Sat Dec 08 10:32:04 2012 +0100 @@ -0,0 +1,63 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.vm4brwsr; + +import javax.script.Invocable; +import javax.script.ScriptException; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * + * @author Tomas Zezula + */ +public class ExceptionsTest { + @Test + public void verifyMethodWithTryCatchNoThrow() throws Exception { + assertExec( + "No throw", + Exceptions.class, + "methodWithTryCatchNoThrow__I", + new Double(1.0)); + } + + @Test + public void verifyMethodWithTryCatchThrow() throws Exception { + assertExec( + "Throw", + Exceptions.class, + "methodWithTryCatchThrow__I", + new Double(2.0)); + } + + private static CharSequence codeSeq; + private static Invocable code; + + @BeforeClass + public void compileTheCode() throws Exception { + StringBuilder sb = new StringBuilder(); + code = StaticMethodTest.compileClass(sb, + "org/apidesign/vm4brwsr/Exceptions" + ); + codeSeq = sb; + } + private static void assertExec(String msg, Class clazz, String method, Object expRes, Object... args) throws Exception { + StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args); + } +}