propose-patch
[org.ibex.core.git] / src / org / xwt / js / Interpreter.java
index c6c61b7..b5becd0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
 package org.xwt.js;
 
 import org.xwt.util.*;
@@ -44,7 +44,17 @@ class Interpreter implements ByteCodes, Tokens {
         }
     }
 
-    private static JSExn je(String s) { return new JSExn(JS.getSourceName() + ":" + JS.getLine() + " " + s); }
+    static int getLine() {
+        Interpreter c = Interpreter.current();
+        return c == null || c.f == null || c.pc < 0 || c.pc >= c.f.size ? -1 : c.f.line[c.pc];
+    }
+
+    static String getSourceName() {
+        Interpreter c = Interpreter.current();
+        return c == null || c.f == null ? null : c.f.sourceName;
+    } 
+
+    private static JSExn je(String s) { return new JSExn(getSourceName() + ":" + getLine() + " " + s); }
 
     // FIXME: double check the trap logic
     private Object run() throws JSExn {
@@ -87,17 +97,17 @@ class Interpreter implements ByteCodes, Tokens {
             case ASSERT: if (!JS.toBoolean(stack.pop())) throw je("xwt.assertion.failed" /*FEATURE: line number*/); break;
             case BITNOT: stack.push(JS.N(~JS.toLong(stack.pop()))); break;
             case BANG: stack.push(JS.B(!JS.toBoolean(stack.pop()))); break;
-            case NEWFUNCTION: stack.push(((JSFunction)arg).cloneWithNewParentScope(scope)); break;
+            case NEWFUNCTION: stack.push(((JSFunction)arg)._cloneWithNewParentScope(scope)); break;
             case LABEL: break;
 
             case TYPEOF: {
                 Object o = stack.pop();
                 if (o == null) stack.push(null);
-                else if (o instanceof JS) stack.push(((JS)o).typeName());
+                else if (o instanceof JS) stack.push("object");
                 else if (o instanceof String) stack.push("string");
                 else if (o instanceof Number) stack.push("number");
                 else if (o instanceof Boolean) stack.push("boolean");
-                else stack.push("unknown");
+                else throw new Error("this should not happen");
                 break;
             }
 
@@ -139,7 +149,7 @@ class Interpreter implements ByteCodes, Tokens {
                     }
                 }
                 throw new Error("CONTINUE/BREAK invoked but couldn't find LoopMarker at " +
-                                JS.getSourceName() + ":" + JS.getLine());
+                                getSourceName() + ":" + getLine());
 
             case TRY: {
                 int[] jmps = (int[]) arg;
@@ -379,24 +389,27 @@ class Interpreter implements ByteCodes, Tokens {
                 break;
             }
 
+            case ADD_TRAP: case DEL_TRAP: {
+                Object val = stack.pop();
+                Object key = stack.pop();
+                Object obj = stack.peek();
+                // A trap addition/removal
+                JS js = obj instanceof JSScope ? ((JSScope)obj).top() : (JS) obj;
+                if(op == ADD_TRAP) js.addTrap(key, (JSFunction)val);
+                else js.delTrap(key, (JSFunction)val);
+                break;
+            }
+
             case ASSIGN_SUB: case ASSIGN_ADD: {
                 Object val = stack.pop();
                 Object key = stack.pop();
                 Object obj = stack.peek();
-                if (val instanceof JSFunction && obj instanceof JS) {
-                    // A trap addition/removal
-                    JS js = obj instanceof JSScope ? ((JSScope)obj).top() : (JS) obj;
-                    if(op == ASSIGN_ADD) js.addTrap(key, (JSFunction)val);
-                    else js.delTrap(key, (JSFunction)val);
-                    pc += ((Integer)arg).intValue() - 1;
-                } else {
-                    // The following setup is VERY important. The generated bytecode depends on the stack
-                    // being setup like this (top to bottom) KEY, OBJ, VAL, KEY, OBJ
-                    stack.push(key);
-                    stack.push(val);
-                    stack.push(obj);
-                    stack.push(key);
-                }
+                // The following setup is VERY important. The generated bytecode depends on the stack
+                // being setup like this (top to bottom) KEY, OBJ, VAL, KEY, OBJ
+                stack.push(key);
+                stack.push(val);
+                stack.push(obj);
+                stack.push(key);
                 break;
             }