fixed heinous breakage, added backtrace support
[org.ibex.core.git] / src / org / ibex / js / JSExn.java
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 */