Multiple exceptions in a single method supported
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 31 Dec 2012 12:44:51 +0100
changeset 4005452b9fbd253
parent 399 1679cdfe4172
child 401 a9be982d9b9c
Multiple exceptions in a single method supported
emul/src/main/java/java/lang/Class.java
javap/src/main/java/org/apidesign/javap/TrapDataIterator.java
vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java
vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java
     1.1 --- a/emul/src/main/java/java/lang/Class.java	Sat Dec 29 20:20:59 2012 +0100
     1.2 +++ b/emul/src/main/java/java/lang/Class.java	Mon Dec 31 12:44:51 2012 +0100
     1.3 @@ -147,7 +147,7 @@
     1.4                  throws ClassNotFoundException {
     1.5          Class<?> c = loadCls(className, className.replace('.', '_'));
     1.6          if (c == null) {
     1.7 -            throw new ClassNotFoundException();
     1.8 +            throw new ClassNotFoundException(className);
     1.9          }
    1.10          return c;
    1.11      }
     2.1 --- a/javap/src/main/java/org/apidesign/javap/TrapDataIterator.java	Sat Dec 29 20:20:59 2012 +0100
     2.2 +++ b/javap/src/main/java/org/apidesign/javap/TrapDataIterator.java	Mon Dec 31 12:44:51 2012 +0100
     2.3 @@ -30,33 +30,57 @@
     2.4      TrapDataIterator(Vector exceptionTable) {
     2.5          for (int i=0 ; i < exceptionTable.size(); i++) {
     2.6              final TrapData td = (TrapData)exceptionTable.elementAt(i);
     2.7 -            exStart.put(td.start_pc, td);
     2.8 -            exStop.put(td.end_pc, td);
     2.9 +            put(exStart, td.start_pc, td);
    2.10 +            put(exStop, td.end_pc, td);
    2.11          }
    2.12      }
    2.13 -
    2.14 -    public boolean advanceTo(int i) {
    2.15 +    
    2.16 +    private static void put(Hashtable h, short key, TrapData td) {
    2.17 +        Short s = Short.valueOf((short)key);
    2.18 +        Vector v = (Vector) h.get(s);
    2.19 +        if (v == null) {
    2.20 +            v = new Vector(1);
    2.21 +            h.put(s, v);
    2.22 +        }
    2.23 +        v.add(td);
    2.24 +    }
    2.25 +    
    2.26 +    private boolean processAll(Hashtable h, Short key, boolean add) {
    2.27          boolean change = false;
    2.28 -        Short s = Short.valueOf((short)i);
    2.29 -        TrapData e = (TrapData) exStart.get(s);
    2.30 -        if (e != null) {
    2.31 -            add(e);
    2.32 -            change = true;
    2.33 -        }
    2.34 -        e = (TrapData) exStop.get(s);
    2.35 -        if (e != null) {
    2.36 -            remove(e);
    2.37 -            change = true;
    2.38 +        Vector v = (Vector)h.get(key);
    2.39 +        if (v != null) {
    2.40 +            int s = v.size();
    2.41 +            for (int i = 0; i < s; i++) {
    2.42 +                TrapData td = (TrapData)v.elementAt(i);
    2.43 +                if (add) {
    2.44 +                    add(td);
    2.45 +                    change = true;
    2.46 +                } else {
    2.47 +                    remove(td);
    2.48 +                    change = true;
    2.49 +                }
    2.50 +            }
    2.51          }
    2.52          return change;
    2.53      }
    2.54 +    
    2.55 +    public boolean advanceTo(int i) {
    2.56 +        Short s = Short.valueOf((short)i);
    2.57 +        boolean ch1 = processAll(exStart, s, true);
    2.58 +        boolean ch2 = processAll(exStop, s, false);
    2.59 +        return ch1 || ch2;
    2.60 +    }
    2.61  
    2.62      public boolean useTry() {
    2.63          return currentCount > 0;
    2.64      }
    2.65  
    2.66      public TrapData[] current() {
    2.67 -        return current;
    2.68 +        TrapData[] copy = new TrapData[currentCount];
    2.69 +        for (int i = 0; i < currentCount; i++) {
    2.70 +            copy[i] = current[i];
    2.71 +        }
    2.72 +        return copy;
    2.73      }
    2.74  
    2.75      private void add(TrapData e) {
    2.76 @@ -71,6 +95,9 @@
    2.77      }
    2.78  
    2.79      private void remove(TrapData e) {
    2.80 +        if (currentCount == 0) {
    2.81 +            return;
    2.82 +        }
    2.83          int from = 0;
    2.84          while (from < currentCount) {
    2.85              if (e == current[from++]) {
     3.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Sat Dec 29 20:20:59 2012 +0100
     3.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Mon Dec 31 12:44:51 2012 +0100
     3.3 @@ -1584,7 +1584,7 @@
     3.4      }
     3.5  
     3.6      private void generateCatch(TrapData[] traps) throws IOException {
     3.7 -        out.append("} catch (e) {");
     3.8 +        out.append("} catch (e) {\n");
     3.9          for (TrapData e : traps) {
    3.10              if (e == null) {
    3.11                  break;
    3.12 @@ -1594,12 +1594,12 @@
    3.13                  addReference(classInternalName);
    3.14                  out.append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {");
    3.15                  out.append("gt=" + e.handler_pc + "; stA0 = e; continue;");
    3.16 -                out.append("} ");
    3.17 +                out.append("}\n");
    3.18              } else {
    3.19                  //finally - todo
    3.20              }
    3.21          }
    3.22          out.append("throw e;");
    3.23 -        out.append("}");
    3.24 +        out.append("\n}");
    3.25      }
    3.26  }
     4.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java	Sat Dec 29 20:20:59 2012 +0100
     4.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java	Mon Dec 31 12:44:51 2012 +0100
     4.3 @@ -22,6 +22,8 @@
     4.4   * @author tom
     4.5   */
     4.6  public class Exceptions {
     4.7 +    private Exceptions() {
     4.8 +    }
     4.9  
    4.10      public static int methodWithTryCatchNoThrow() {
    4.11          int res = 0;
    4.12 @@ -46,4 +48,17 @@
    4.13          return res;
    4.14      }
    4.15  
    4.16 +    public static String newInstance(String n) {
    4.17 +        try {
    4.18 +            Class c;
    4.19 +            try {
    4.20 +                c = Class.forName(n);
    4.21 +            } catch (ClassNotFoundException ex) {
    4.22 +                return ("CNFE:" + ex.getMessage()).toString();
    4.23 +            }
    4.24 +            return c.newInstance().getClass().getName();
    4.25 +        } catch (InstantiationException | IllegalAccessException ex) {
    4.26 +            return ex.getMessage();
    4.27 +        }
    4.28 +    }
    4.29  }
     5.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java	Sat Dec 29 20:20:59 2012 +0100
     5.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java	Mon Dec 31 12:44:51 2012 +0100
     5.3 @@ -46,6 +46,30 @@
     5.4                      new Double(2.0));
     5.5      }
     5.6      
     5.7 +    @Test public void createObject() throws Exception {
     5.8 +        assertExec("Object created", Exceptions.class, 
     5.9 +            "newInstance__Ljava_lang_String_2Ljava_lang_String_2",
    5.10 +            "java.lang.Object",
    5.11 +            "java.lang.Object"
    5.12 +        );
    5.13 +    }
    5.14 +
    5.15 +    @Test public void createFloatFails() throws Exception {
    5.16 +        assertExec("Float not created", Exceptions.class, 
    5.17 +            "newInstance__Ljava_lang_String_2Ljava_lang_String_2",
    5.18 +            "java.lang.Float",
    5.19 +            "java.lang.Float"
    5.20 +        );
    5.21 +    }
    5.22 +
    5.23 +    @Test public void createUnknownFails() throws Exception {
    5.24 +        assertExec("Object created", Exceptions.class, 
    5.25 +            "newInstance__Ljava_lang_String_2Ljava_lang_String_2",
    5.26 +            "CNFE:org.apidesign.Unknown",
    5.27 +            "org.apidesign.Unknown"
    5.28 +        );
    5.29 +    }
    5.30 +    
    5.31      private static CharSequence codeSeq;
    5.32      private static Invocable code;
    5.33