import java.io.*;
/** a JavaScript function, compiled into bytecode */
-public class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Tokens {
+class CompiledFunctionImpl extends JS.Callable implements ByteCodes, Tokens {
// Fields and Accessors ///////////////////////////////////////////////
public Object call(JS.Array args) throws JS.Exn { return call(args, new FunctionScope(sourceName, parentScope)); }
public Object call(JS.Array args, JS.Scope scope) throws JS.Exn {
- CompiledFunctionImpl saved = (CompiledFunctionImpl)Context.currentFunction.get(Thread.currentThread());
+ JS.Thread cx = JS.Thread.fromJavaThread(java.lang.Thread.currentThread());
+ CompiledFunction saved = cx.currentCompiledFunction;
try {
- Context.currentFunction.put(Thread.currentThread(), this);
- Context cx = Context.getContextForThread(Thread.currentThread());
+ cx.currentCompiledFunction = (CompiledFunction)this;
int size = cx.stack.size();
- cx.stack.push(new Context.CallMarker());
+ cx.stack.push(new CallMarker());
cx.stack.push(args);
eval(scope);
Object ret = cx.stack.pop();
- if (cx.stack.size() > size)
- Log.log(this, "warning, stack grew by " + (cx.stack.size() - size) +
- " elements during call to " + Context.getCurrentSourceNameAndLine());
+ if (cx.stack.size() > size) Log.logJS(this, "warning, stack grew by " + (cx.stack.size() - size) + " elements during call");
return ret;
} finally {
- if (saved == null) Context.currentFunction.remove(Thread.currentThread());
- else Context.currentFunction.put(Thread.currentThread(), saved);
+ cx.currentCompiledFunction = saved;
}
}
int pc = 0;
void eval(JS.Scope s) {
- final Vec t = Context.getContextForThread(Thread.currentThread()).stack;
+ final Vec t = JS.Thread.fromJavaThread(java.lang.Thread.currentThread()).stack;
OUTER: for(pc=0; pc<size; pc++) {
String label = null;
switch(op[pc]) {
case LABEL: break;
case LOOP: {
t.push(s);
- t.push(new Context.LoopMarker(pc, pc > 0 && op[pc - 1] == LABEL ? (String)arg[pc - 1] : (String)null));
+ t.push(new LoopMarker(pc, pc > 0 && op[pc - 1] == LABEL ? (String)arg[pc - 1] : (String)null));
t.push(Boolean.TRUE);
break;
}
case CONTINUE:
while(t.size() > 0) {
Object o = t.pop();
- if (o instanceof Context.CallMarker) ee("break or continue not within a loop");
- if (o != null && o instanceof Context.LoopMarker) {
- if (arg[pc] == null || arg[pc].equals(((Context.LoopMarker)o).label)) {
- int loopInstructionLocation = ((Context.LoopMarker)o).location;
+ if (o instanceof CallMarker) ee("break or continue not within a loop");
+ if (o != null && o instanceof LoopMarker) {
+ if (arg[pc] == null || arg[pc].equals(((LoopMarker)o).label)) {
+ int loopInstructionLocation = ((LoopMarker)o).location;
int endOfLoop = ((Integer)arg[loopInstructionLocation]).intValue() + loopInstructionLocation;
s = (JS.Scope)t.pop();
if (op[pc] == CONTINUE) { t.push(s); t.push(o); t.push(Boolean.FALSE); }
throw new Error("CONTINUE/BREAK invoked but couldn't find a LoopMarker at " + sourceName + ":" + line);
case TRY: {
- t.push(new Context.TryMarker(pc + ((Integer)arg[pc]).intValue(), s));
+ t.push(new TryMarker(pc + ((Integer)arg[pc]).intValue(), s));
break;
}
Object retval = t.pop();
while(t.size() > 0) {
Object o = t.pop();
- if (o != null && o instanceof Context.CallMarker) {
+ if (o != null && o instanceof CallMarker) {
t.push(retval);
return;
}
Object exn = t.pop();
while(t.size() > 0) {
Object o = t.pop();
- if (o instanceof Context.TryMarker) {
+ if (o instanceof TryMarker) {
t.push(exn);
- pc = ((Context.TryMarker)o).location - 1;
- s = ((Context.TryMarker)o).scope;
+ pc = ((TryMarker)o).location - 1;
+ s = ((TryMarker)o).scope;
continue OUTER;
}
}
return super.get(key);
}
}
+
+
+ // Markers //////////////////////////////////////////////////////////////////////
+
+ public static class CallMarker { public CallMarker() { } }
+ public static class LoopMarker {
+ public int location;
+ public String label;
+ public LoopMarker(int location, String label) {
+ this.location = location;
+ this.label = label;
+ }
+ }
+ public static class TryMarker {
+ public int location;
+ public JS.Scope scope;
+ public TryMarker(int location, JS.Scope scope) {
+ this.location = location;
+ this.scope = scope;
+ }
+ }
+
}