2003/11/03 05:28:32
[org.ibex.core.git] / src / org / xwt / js / JS.java
index ce48cb5..94809b5 100644 (file)
@@ -2,6 +2,7 @@
 
 package org.xwt.js; 
 import org.xwt.util.*; 
+import org.xwt.*; 
 import java.io.*;
 import java.util.*;
 
@@ -76,11 +77,10 @@ public abstract class JS {
     // Instance Methods ////////////////////////////////////////////////////////////////////
  
     public abstract Object get(Object key) throws JS.Exn; 
-    public abstract void put(Object key, Object val) throws JS.Exn; 
-    public void put(Object key, Object val, TailCall tail) throws JS.Exn { put(key, val); }
+    public abstract Object put(Object key, Object val) throws JS.Exn; 
     public abstract Object[] keys(); 
     public Object callMethod(Object method, Array args, boolean checkOnly) throws JS.Exn {
-       if(checkOnly) return Boolean.FALSE;
+       if (checkOnly) return Boolean.FALSE;
        Object o = get(method);
        if(o instanceof JS.Callable) {
            return ((JS.Callable)o).call(args);
@@ -107,7 +107,7 @@ public abstract class JS {
         public Obj() { this(false); }
         public Obj(boolean sealed) { this.sealed = sealed; }
         public void setSeal(boolean sealed) { this.sealed = sealed; }      ///< a sealed object cannot have its properties modified
-        public void put(Object key, Object val) { put2(key, null, val); }
+        public Object put(Object key, Object val) { put2(key, null, val); return null; }
         protected void put2(Object key, Object key2, Object val) {
             if (sealed) return;
             if (entries == null) entries = new Hash();
@@ -141,7 +141,7 @@ public abstract class JS {
         public void addElement(Object o) { super.addElement(o); }
         public void setElementAt(Object o, int i) { super.setElementAt(o, i); }
         public Object get(Object key) { return super._get(key); }
-        public void put(Object key, Object val) { super._put(key, val); }
+        public Object put(Object key, Object val) { super._put(key, val); return null; }
     }
 
     /** Any object which becomes part of the scope chain must support this interface */ 
@@ -152,7 +152,7 @@ public abstract class JS {
         public boolean isTransparent() { return super.isTransparent(); }
         public boolean has(Object key) { return super.has(key); }
         public Object get(Object key) { return super._get(key); }
-        public void put(Object key, Object val) { super._put(key, val); }
+        public Object put(Object key, Object val) { super._put(key, val); return null; }
         public void declare(String s) { super.declare(s); }
     } 
 
@@ -172,7 +172,7 @@ public abstract class JS {
         public boolean equals(Object o) { return (this == o || graftee.equals(o)); }
         public int hashCode() { return graftee.hashCode(); }
         public Object get(Object key) { return replaced_key.equals(key) ? replaced_val : graftee.get(key); }
-        public void put(Object key, Object val) { graftee.put(key, val); }
+        public Object put(Object key, Object val) { graftee.put(key, val); return null; }
         public Object callMethod(Object method, Array args, boolean checkOnly) throws JS.Exn {
             if (!replaced_key.equals(method)) return graftee.callMethod(method, args, checkOnly);
             if (replaced_val instanceof Callable) return checkOnly ? Boolean.TRUE : ((Callable)replaced_val).call(args);
@@ -222,36 +222,41 @@ public abstract class JS {
         public TailCall set(CompiledFunction func, JS.Array args) { this.func = func; this.args = args; return this; }
     }
  
-    /** encapsulates a single JavaScript thread; the JS.Thread->java.lang.Thread mapping is 1:1 */
-    public static class Thread {
+    /** encapsulates a single JavaScript thread; the JS.Context->java.lang.Thread mapping is 1:1 */
+    public static class Context {
 
-        CompiledFunction currentCompiledFunction = null;
+        CompiledFunction f = null;
         Vec stack = new Vec();
         public Scope scope = null;
         int pc = 0;
-        boolean paused = false;
 
-        public Thread(CompiledFunction function) { this(function, null); }
-        public Thread(CompiledFunction function, Scope scope) { this(function, scope, new JS.Array()); }
-        public Thread(CompiledFunction function, Scope scope, JS.Array args) {
+        /** return this to signal a pause */
+        public static Object pause = new Object();
+
+        public static int getLine() { return current().f == null ? -1 : current().f.getLine(current()); }
+        public static String getSourceName() { return current().f == null ? null : current().f.getSourceName();  }
+
+        public Context(CompiledFunction function, Scope scope, JS.Array args) {
             if (scope == null) scope = new CompiledFunctionImpl.FunctionScope("unknown", function.parentScope);
+            if (args == null) args = new JS.Array();
             stack.push(new CompiledFunctionImpl.CallMarker(this));
             stack.push(args);
-            this.currentCompiledFunction = function;
+            this.f = function;
             this.scope = scope;
         }
 
-        public static JS.Thread current() { return (JS.Thread)javaThreadToJSThread.get(java.lang.Thread.currentThread()); }
-        public Object resume() { bind(); paused = false; Object ret = CompiledFunctionImpl.eval(this); unbind(); return ret; }
-        public void pause() { paused = true; unbind(); }
-        public void bind() { javaThreadToJSThread.put(java.lang.Thread.currentThread(), this); }
-        public void unbind() { if (current() == this) javaThreadToJSThread.remove(java.lang.Thread.currentThread()); }
-        public int getLine() { return currentCompiledFunction == null ? -1 : currentCompiledFunction.getLine(this); }
-        public String getSourceName() { return currentCompiledFunction == null ? null : currentCompiledFunction.getSourceName();  }
+        public Object resume(Object o) {
+            try {
+                javaContextToJSContext.put(Thread.currentThread(), this);
+                return CompiledFunctionImpl.eval(this, o);
+            } finally {
+                javaContextToJSContext.remove(Thread.currentThread());
+            }
+        }
 
         /** fetches the currently-executing javascript function */
-        public JS.CompiledFunction getCurrentCompiledFunction() { return currentCompiledFunction; }
-        private static Hashtable javaThreadToJSThread = new Hashtable();
+        public static JS.Context current() { return (JS.Context)javaContextToJSContext.get(Thread.currentThread()); }
+        private static Hashtable javaContextToJSContext = new Hashtable();
     }
 }