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 +}