final Stack stack = new Stack(); ///< the object stack
int pc = 0; ///< the program counter
- Interpreter(JSFunction f, boolean pauseable, JSArray args) {
+ Interpreter(JSFunction f, boolean pauseable, JSArgs args) {
this.f = f;
this.pausecount = pauseable ? 0 : -1;
this.scope = new JSScope(f.parentScope);
if(t != null) {
tm.t = t;
stack.push(tm);
- JSArray args = new JSArray();
- args.addElement(tm.val);
- stack.push(args);
+ stack.push(new JSArgs(tm.val,t.f));
f = t.f;
scope = new JSScope(f.parentScope);
pc = -1;
if(t != null) {
stack.push(new TrapMarker(this,t,target,key,val));
- JSArray args = new JSArray();
- args.addElement(val);
- stack.push(args);
+ stack.push(new JSArgs(t.f));
f = t.f;
scope = new TrapScope(f.parentScope,target,f,key);
pc = -1;
if(t != null) {
stack.push(new TrapMarker(this,t,(JS)target,key,null));
- stack.push(new JSArray());
+ stack.push(new JSArgs(t.f));
f = t.f;
scope = new TrapScope(f.parentScope,target,f,key);
pc = -1;
case CALL: case CALLMETHOD: {
int numArgs = JS.toInt((JS)arg);
+
+ JS[] rest = numArgs > 3 ? new JS[numArgs - 3] : null;
+ for(int i=numArgs - 1; i>2; i--) rest[i-3] = stack.pop();
+ JS a2 = numArgs <= 2 ? null : stack.pop();
+ JS a1 = numArgs <= 1 ? null : stack.pop();
+ JS a0 = numArgs <= 0 ? null : stack.pop();
+
JS method = null;
JS ret = null;
JS object = stack.pop();
stack.pop();
}
}
- JS[] rest = numArgs > 3 ? new JS[numArgs - 3] : null;
- for(int i=numArgs - 1; i>2; i--) rest[i-3] = stack.pop();
- JS a2 = numArgs <= 2 ? null : stack.pop();
- JS a1 = numArgs <= 1 ? null : stack.pop();
- JS a0 = numArgs <= 0 ? null : stack.pop();
-
if (object instanceof JSFunction) {
- // FIXME: use something similar to call0/call1/call2 here
- JSArray arguments = new JSArray();
- for(int i=0; i<numArgs; i++) arguments.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
stack.push(new CallMarker(this));
- stack.push(arguments);
+ stack.push(new JSArgs(a0,a1,a2,rest,numArgs,object));
f = (JSFunction)object;
scope = new JSScope(f.parentScope);
pc = -1;
return super.get(key);
}
}
+
+ static class JSArgs extends JS {
+ private final JS a0;
+ private final JS a1;
+ private final JS a2;
+ private final JS[] rest;
+ private final int nargs;
+ private final JS callee;
+
+ public JSArgs(JS callee) { this(null,null,null,null,0,callee); }
+ public JSArgs(JS a0, JS callee) { this(a0,null,null,null,1,callee); }
+ public JSArgs(JS a0, JS a1, JS a2, JS[] rest, int nargs, JS callee) {
+ this.a0 = a0; this.a1 = a1; this.a2 = a2;
+ this.rest = rest; this.nargs = nargs;
+ this.callee = callee;
+ }
+
+ public JS get(JS key) throws JSExn {
+ if(JS.isInt(key)) {
+ int n = JS.toInt(key);
+ switch(n) {
+ case 0: return a0;
+ case 1: return a1;
+ case 2: return a2;
+ default: return n>= 0 && n < nargs ? rest[n-3] : null;
+ }
+ }
+ //#switch(JS.toString(key))
+ case "callee": return callee;
+ case "length": return JS.N(nargs);
+ //#end
+ return super.get(key);
+ }
+ }
static class Stub extends JS {
private JS method;
JS[] stack2 = new JS[stack.length * 2];
System.arraycopy(stack,0,stack2,0,stack.length);
}
- // FIXME: Eliminate all uses of SWAP n>1 so we don't need this
public int size() { return sp; }
- public void setElementAt(JS o, int i) { stack[i] = o; }
public JS elementAt(int i) { return stack[i]; }
+
+ // FIXME: Eliminate all uses of SWAP n>1 so we don't need this
+ public void setElementAt(JS o, int i) { stack[i] = o; }
}
}