# HG changeset patch # User Jaroslav Tulach # Date 1356333595 -3600 # Node ID 059cb07ac9b3393bb8b3b43df1c27795a1c7726d # Parent 5751fe604e6b3e726cc594fb11bcf0e055f1bdff# Parent fc3f6ea5e246d939c8f68511ed0cfbf58f9bc8e7 Initial attempt to merge current default branch with exceptions diff -r 5751fe604e6b -r 059cb07ac9b3 javap/src/main/java/org/apidesign/javap/MethodData.java --- a/javap/src/main/java/org/apidesign/javap/MethodData.java Mon Dec 24 08:04:45 2012 +0100 +++ b/javap/src/main/java/org/apidesign/javap/MethodData.java Mon Dec 24 08:19:55 2012 +0100 @@ -357,10 +357,10 @@ /** * Return exception table in code attributre. */ - public Vector getexception_table(){ - return exception_table; + public TrapDataIterator getTrapDataIterator(){ + return new TrapDataIterator(exception_table); } - + /** * Return method attributes. diff -r 5751fe604e6b -r 059cb07ac9b3 javap/src/main/java/org/apidesign/javap/TrapData.java --- a/javap/src/main/java/org/apidesign/javap/TrapData.java Mon Dec 24 08:04:45 2012 +0100 +++ b/javap/src/main/java/org/apidesign/javap/TrapData.java Mon Dec 24 08:19:55 2012 +0100 @@ -26,7 +26,6 @@ package org.apidesign.javap; -import java.util.*; import java.io.*; /** @@ -34,15 +33,18 @@ * * @author Sucheta Dambalkar (Adopted code from jdis) */ -class TrapData { - short start_pc, end_pc, handler_pc, catch_cpx; - int num; +public final 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; /** * Read and store exception table data in code attribute. */ - public TrapData(DataInputStream in, int num) throws IOException { + TrapData(DataInputStream in, int num) throws IOException { this.num=num; start_pc = in.readShort(); end_pc=in.readShort(); diff -r 5751fe604e6b -r 059cb07ac9b3 javap/src/main/java/org/apidesign/javap/TrapDataIterator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javap/src/main/java/org/apidesign/javap/TrapDataIterator.java Mon Dec 24 08:19:55 2012 +0100 @@ -0,0 +1,70 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.apidesign.javap; + +/** + * + * @author Jaroslav Tulach + */ +public final class TrapDataIterator { + private final Hashtable exStart = new Hashtable(); + private final Hashtable exStop = new Hashtable(); + private TrapData[] current = new TrapData[10]; + private int currentCount; + + TrapDataIterator(Vector exceptionTable) { + 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); + } + } + + public void advanceTo(int i) { + Short s = Short.valueOf((short)i); + TrapData e = (TrapData) exStart.get(s); + if (e != null) { + add(e); + } + e = (TrapData) exStop.get(s); + if (e != null) { + remove(e); + } + } + + public boolean useTry() { + return currentCount > 0; + } + + public TrapData[] current() { + return current; + } + + private void add(TrapData e) { + if (currentCount == current.length) { + TrapData[] data = new TrapData[currentCount * 2]; + for (int i = 0; i < currentCount; i++) { + data[i] = current[i]; + } + current = data; + } + current[currentCount++] = e; + } + + private void remove(TrapData e) { + int from = 0; + while (from < currentCount) { + if (e == current[from++]) { + break; + } + } + while (from < currentCount) { + current[from - 1] = current[from]; + current[from] = null; + from++; + } + currentCount--; + } +} diff -r 5751fe604e6b -r 059cb07ac9b3 vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Dec 24 08:04:45 2012 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Dec 24 08:19:55 2012 +0100 @@ -25,6 +25,8 @@ import org.apidesign.javap.MethodData; import org.apidesign.javap.StackMapIterator; import static org.apidesign.javap.RuntimeConstants.*; +import org.apidesign.javap.TrapData; +import org.apidesign.javap.TrapDataIterator; /** Translator of the code inside class files to JavaScript. * @@ -222,6 +224,7 @@ private void generateMethod(String prefix, String name, MethodData m) throws IOException { final StackMapIterator stackMapIterator = m.createStackMapIterator(); + TrapDataIterator trap = m.getTrapDataIterator(); final LocalsMapper lmapper = new LocalsMapper(stackMapIterator.getArguments()); @@ -273,14 +276,18 @@ for (int i = 0; i < byteCodes.length; i++) { int prev = i; stackMapIterator.advanceTo(i); + trap.advanceTo(i); if (lastStackFrame != stackMapIterator.getFrameIndex()) { lastStackFrame = stackMapIterator.getFrameIndex(); lmapper.syncWithFrameLocals(stackMapIterator.getFrameLocals()); smapper.syncWithFrameStack(stackMapIterator.getFrameStack()); - out.append(" case " + i).append(": "); + out.append(" case " + i).append(": "); } else { out.append(" /* " + i).append(" */ "); } + if (trap.useTry()) { + out.append("try {"); + } final int c = readByte(byteCodes, i); switch (c) { case opc_aload_0: @@ -1104,13 +1111,32 @@ Integer.toString(c)); } } + if (trap.useTry()) { + out.append("} catch (e) {"); + for (TrapData e : trap.current()) { + if (e == null) { + break; + } + 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"); out.append("};"); diff -r 5751fe604e6b -r 059cb07ac9b3 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 Mon Dec 24 08:19:55 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 5751fe604e6b -r 059cb07ac9b3 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 Mon Dec 24 08:19:55 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); + } +}