# HG changeset patch # User Jaroslav Tulach # Date 1356954291 -3600 # Node ID 5452b9fbd253f9c52c5e19bc9f05c8df6d267679 # Parent 1679cdfe4172ce935950c3854e2adf98133a2ec3 Multiple exceptions in a single method supported diff -r 1679cdfe4172 -r 5452b9fbd253 emul/src/main/java/java/lang/Class.java --- a/emul/src/main/java/java/lang/Class.java Sat Dec 29 20:20:59 2012 +0100 +++ b/emul/src/main/java/java/lang/Class.java Mon Dec 31 12:44:51 2012 +0100 @@ -147,7 +147,7 @@ throws ClassNotFoundException { Class c = loadCls(className, className.replace('.', '_')); if (c == null) { - throw new ClassNotFoundException(); + throw new ClassNotFoundException(className); } return c; } diff -r 1679cdfe4172 -r 5452b9fbd253 javap/src/main/java/org/apidesign/javap/TrapDataIterator.java --- a/javap/src/main/java/org/apidesign/javap/TrapDataIterator.java Sat Dec 29 20:20:59 2012 +0100 +++ b/javap/src/main/java/org/apidesign/javap/TrapDataIterator.java Mon Dec 31 12:44:51 2012 +0100 @@ -30,33 +30,57 @@ 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); + put(exStart, td.start_pc, td); + put(exStop, td.end_pc, td); } } - - public boolean advanceTo(int i) { + + private static void put(Hashtable h, short key, TrapData td) { + Short s = Short.valueOf((short)key); + Vector v = (Vector) h.get(s); + if (v == null) { + v = new Vector(1); + h.put(s, v); + } + v.add(td); + } + + private boolean processAll(Hashtable h, Short key, boolean add) { boolean change = false; - Short s = Short.valueOf((short)i); - TrapData e = (TrapData) exStart.get(s); - if (e != null) { - add(e); - change = true; - } - e = (TrapData) exStop.get(s); - if (e != null) { - remove(e); - change = true; + Vector v = (Vector)h.get(key); + if (v != null) { + int s = v.size(); + for (int i = 0; i < s; i++) { + TrapData td = (TrapData)v.elementAt(i); + if (add) { + add(td); + change = true; + } else { + remove(td); + change = true; + } + } } return change; } + + public boolean advanceTo(int i) { + Short s = Short.valueOf((short)i); + boolean ch1 = processAll(exStart, s, true); + boolean ch2 = processAll(exStop, s, false); + return ch1 || ch2; + } public boolean useTry() { return currentCount > 0; } public TrapData[] current() { - return current; + TrapData[] copy = new TrapData[currentCount]; + for (int i = 0; i < currentCount; i++) { + copy[i] = current[i]; + } + return copy; } private void add(TrapData e) { @@ -71,6 +95,9 @@ } private void remove(TrapData e) { + if (currentCount == 0) { + return; + } int from = 0; while (from < currentCount) { if (e == current[from++]) { diff -r 1679cdfe4172 -r 5452b9fbd253 vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Dec 29 20:20:59 2012 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Dec 31 12:44:51 2012 +0100 @@ -1584,7 +1584,7 @@ } private void generateCatch(TrapData[] traps) throws IOException { - out.append("} catch (e) {"); + out.append("} catch (e) {\n"); for (TrapData e : traps) { if (e == null) { break; @@ -1594,12 +1594,12 @@ addReference(classInternalName); out.append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {"); out.append("gt=" + e.handler_pc + "; stA0 = e; continue;"); - out.append("} "); + out.append("}\n"); } else { //finally - todo } } out.append("throw e;"); - out.append("}"); + out.append("\n}"); } } diff -r 1679cdfe4172 -r 5452b9fbd253 vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java Sat Dec 29 20:20:59 2012 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java Mon Dec 31 12:44:51 2012 +0100 @@ -22,6 +22,8 @@ * @author tom */ public class Exceptions { + private Exceptions() { + } public static int methodWithTryCatchNoThrow() { int res = 0; @@ -46,4 +48,17 @@ return res; } + public static String newInstance(String n) { + try { + Class c; + try { + c = Class.forName(n); + } catch (ClassNotFoundException ex) { + return ("CNFE:" + ex.getMessage()).toString(); + } + return c.newInstance().getClass().getName(); + } catch (InstantiationException | IllegalAccessException ex) { + return ex.getMessage(); + } + } } diff -r 1679cdfe4172 -r 5452b9fbd253 vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java Sat Dec 29 20:20:59 2012 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java Mon Dec 31 12:44:51 2012 +0100 @@ -46,6 +46,30 @@ new Double(2.0)); } + @Test public void createObject() throws Exception { + assertExec("Object created", Exceptions.class, + "newInstance__Ljava_lang_String_2Ljava_lang_String_2", + "java.lang.Object", + "java.lang.Object" + ); + } + + @Test public void createFloatFails() throws Exception { + assertExec("Float not created", Exceptions.class, + "newInstance__Ljava_lang_String_2Ljava_lang_String_2", + "java.lang.Float", + "java.lang.Float" + ); + } + + @Test public void createUnknownFails() throws Exception { + assertExec("Object created", Exceptions.class, + "newInstance__Ljava_lang_String_2Ljava_lang_String_2", + "CNFE:org.apidesign.Unknown", + "org.apidesign.Unknown" + ); + } + private static CharSequence codeSeq; private static Invocable code;