fixed heinous breakage, added backtrace support
authoradam <adam@megacz.com>
Wed, 17 Mar 2004 10:38:54 +0000 (10:38 +0000)
committeradam <adam@megacz.com>
Wed, 17 Mar 2004 10:38:54 +0000 (10:38 +0000)
darcs-hash:20040317103854-5007d-5378cce7c743091e8387bab6329f78c88a0f761c.gz

src/org/ibex/Box.java
src/org/ibex/Scheduler.java
src/org/ibex/Template.java
src/org/ibex/js/Interpreter.java
src/org/ibex/js/JSExn.java
src/org/ibex/js/Trap.java
src/org/ibex/util/Log.java

index 6f618c1..f51723f 100644 (file)
@@ -570,8 +570,22 @@ public final class Box extends JSScope implements Scheduler.Task {
             MARK_RESIZE;
             dirty();
         case "fontsize": font = Font.getFont(font == null ? null : font.stream, toInt(value)); MARK_RESIZE; dirty();
-        case "x": if (parent==null && Surface.fromBox(this)!=null) { CHECKSET_INT(x); } else { if (test(PACKED) && parent != null) return; dirty(); CHECKSET_INT(ax); dirty(); MARK_RESIZE; dirty(); }
-        case "y": if (parent==null && Surface.fromBox(this)!=null) { CHECKSET_INT(y); } else { if (test(PACKED) && parent != null) return; dirty(); CHECKSET_INT(ay); dirty(); MARK_RESIZE; dirty(); }
+        case "x": if (parent==null && Surface.fromBox(this)!=null) {
+            CHECKSET_INT(x);
+        } else {
+            if (test(PACKED) && parent != null) return;
+            dirty(); CHECKSET_INT(ax);
+            dirty(); MARK_RESIZE;
+            dirty();
+        }
+        case "y": if (parent==null && Surface.fromBox(this)!=null) {
+            CHECKSET_INT(y);
+        } else {
+            if (test(PACKED) && parent != null) return;
+            dirty(); CHECKSET_INT(ay);
+            dirty(); MARK_RESIZE;
+            dirty();
+        }
         case "titlebar":
             if (getSurface() != null && value != null) getSurface().setTitleBarText(JS.toString(value));
             super.put(name,value);
index 358a0f7..9b39509 100644 (file)
@@ -79,7 +79,6 @@ public class Scheduler {
                 renderAll();
             } catch (JSExn e) {
                 Log.info(Scheduler.class, "a JavaScript thread spawned with ibex.thread() threw an exception:");
-                Log.info(Scheduler.class, "JS Exception: " + e.getObject() + "\n" + e.backtrace());
                 Log.info(Scheduler.class,e);
             } catch (Exception e) {
                 Log.info(Scheduler.class, "a Task threw an exception which was caught by the scheduler:");
index fb9f4cc..49748ac 100644 (file)
@@ -118,7 +118,6 @@ public class Template {
                     // FIXME: should we be resolving all of these in the XML-parsing code?
                 }
             }
-
             b.putAndTriggerTraps(key, val);
         }
     }
index 92b29a4..ce83f69 100644 (file)
@@ -235,21 +235,13 @@ class Interpreter implements ByteCodes, Tokens {
                     } else {
                         t = ((JS)target).getTrap(key);
                     }
-
                     while (t != null && t.f.numFormalArgs == 0) t = t.next; // find the first write trap
-                    if (t != null) {
-                        stack.push(new CallMarker(this));
-                        JSArray args = new JSArray();
-                        args.addElement(val);
-                        stack.push(args);
-                    }
                 }
                 if (t != null) {
-                    stack.pop();
                     stack.push(new CallMarker(this));
-                    stack.push(target);
                     JSArray args = new JSArray();
                     args.addElement(val);
+                    stack.push(args);
                     f = t.f;
                     scope = new Trap.TrapScope(f.parentScope, t, val);
                     pc = -1;
@@ -368,7 +360,8 @@ class Interpreter implements ByteCodes, Tokens {
             }
 
             case THROW:
-                throw new JSExn(stack.pop());
+                throw new JSExn(stack.pop(), stack, f, pc, scope);
+
                 /* FIXME
             case MAKE_GRAMMAR: {
                 final Grammar r = (Grammar)arg;
@@ -510,7 +503,6 @@ class Interpreter implements ByteCodes, Tokens {
             }
 
         } catch(JSExn e) {
-            if(f.op[pc] != FINALLY_DONE) e.addBacktrace(f.sourceName,f.line[pc]);
             while(stack.size() > 0) {
                 Object o = stack.pop();
                 if (o instanceof CatchMarker || o instanceof TryMarker) {
@@ -535,12 +527,6 @@ class Interpreter implements ByteCodes, Tokens {
                         pc = ((TryMarker)o).finallyLoc - 1;
                         continue OUTER;
                     }
-                } else if(o instanceof CallMarker) {
-                    CallMarker cm = (CallMarker) o;
-                    if(cm.f == null)
-                        e.addBacktrace("<java>",0); // This might not even be worth mentioning
-                    else
-                        e.addBacktrace(cm.f.sourceName,cm.f.line[cm.pc-1]);
                 }
             }
             throw e;
@@ -691,7 +677,7 @@ class Interpreter implements ByteCodes, Tokens {
     static Object getFromPrimitive(Object o, Object key) throws JSExn {
         boolean returnJS = false;
         if (o instanceof Boolean) {
-            throw new JSExn("cannot call methods on Booleans");
+            throw new JSExn("Booleans do not have properties");
         } else if (o instanceof Number) {
             if (key.equals("toPrecision") || key.equals("toExponential") || key.equals("toFixed"))
                 returnJS = true;
index 8d1a758..8c1362d 100644 (file)
@@ -2,22 +2,46 @@
 package org.ibex.js; 
 
 import org.ibex.util.*; 
+import java.io.*;
 
 /** An exception which can be thrown and caught by JavaScript code */
 public class JSExn extends Exception { 
     private Vec backtrace = new Vec();
     private Object js = null; 
-    public JSExn(Object js) { this.js = js; } 
+    public JSExn(Object js) {
+        this.js = js;
+        if (Interpreter.current() != null)
+            fill(Interpreter.current().stack, Interpreter.current().f, Interpreter.current().pc, Interpreter.current().scope);
+    }
+    public JSExn(Object js, Vec stack, JSFunction f, int pc, JSScope scope) { this.js = js; fill(stack, f, pc, scope); }
+    private void fill(Vec stack, JSFunction f, int pc, JSScope scope) {
+        addBacktrace(f.sourceName + ":" + f.line[pc]);
+        if (scope != null && scope instanceof Trap.TrapScope)
+            addBacktrace("trap on property \"" + ((Trap.TrapScope)scope).t.name + "\"");
+        for(int i=stack.size()-1; i>=0; i--) {
+            Object element = stack.elementAt(i);
+            if (element instanceof Interpreter.CallMarker) {
+                Interpreter.CallMarker cm = (Interpreter.CallMarker)element;
+                if (cm.f != null)
+                    addBacktrace(cm.f.sourceName + ":" + cm.f.line[cm.pc]);
+                if (cm.scope != null && cm.scope instanceof Trap.TrapScope)
+                    addBacktrace("trap on property \"" + ((Trap.TrapScope)cm.scope).t.name + "\"");
+            }
+        }
+    }
+    public void printStackTrace() { printStackTrace(System.err); }
+    public void printStackTrace(PrintWriter pw) {
+        for(int i=0; i<backtrace.size(); i++) pw.println("    at " + (String) backtrace.elementAt(i));
+        super.printStackTrace(pw);
+    }
+    public void printStackTrace(PrintStream ps) {
+        for(int i=0; i<backtrace.size(); i++) ps.println("    at " + (String) backtrace.elementAt(i));
+        super.printStackTrace(ps);
+    }
     public String toString() { return "JSExn: " + js; }
     public String getMessage() { return toString(); }
     public Object getObject() { return js; } 
-    public void addBacktrace(String sourceName, int lineNo) { backtrace.addElement(sourceName + ":" + lineNo); }
-    public String backtrace() {
-        StringBuffer sb = new StringBuffer(1024);
-        for(int i=0;i<backtrace.size();i++)
-            sb.append("    at " + (String) backtrace.elementAt(i) + "\n");
-        return sb.toString();
-    }
+    public void addBacktrace(String line) { backtrace.addElement(line); }
 } 
 
 /** should only be used for failed coercions */
index 4b2f92a..77476f6 100644 (file)
@@ -19,8 +19,8 @@ class Trap {
         trapee = b; name = n; this.f = f; this.next = nx;
     }
 
-    private static final JSFunction putInvoker = new JSFunction("putInvoker", 0, null);
-    private static final JSFunction getInvoker = new JSFunction("getInvoker", 0, null);
+    static final JSFunction putInvoker = new JSFunction("putInvoker", 0, null);
+    static final JSFunction getInvoker = new JSFunction("getInvoker", 0, null);
 
     static {
         putInvoker.add(1, ByteCodes.PUT, null);
index 9d03e6e..5d09216 100644 (file)
@@ -130,7 +130,7 @@ public class Log {
             try {
                 String m = "";
                 while((s = br.readLine()) != null) m += s + "\n";
-                log(o, m.substring(0, m.length() - 1), level);
+                if (m.length() > 0) log(o, m.substring(0, m.length() - 1), level);
             } catch (IOException e) {
                 logstream.println(colorize(RED, true, "Logger: exception thrown by ByteArrayInputStream -- this should not happen"));
             }