package org.xwt.js;
import org.xwt.util.*;
+import org.xwt.*;
import java.io.*;
import java.util.*;
// 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);
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();
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 */
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); }
}
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);
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();
}
}