key = tm.key;
tm.cascadeHappened = true;
t = tm.t;
- if(t.readTrap()) throw new JSExn("can't put to cascade in a read trap");
+ if(t.readTrap()) throw new JSExn("can't do a write cascade in a read trap");
t = t.next;
while(t != null && t.readTrap()) t = t.next;
}
args.addElement(val);
stack.push(args);
f = t.f;
- scope = new JSScope(f.parentScope);
+ scope = new TrapScope(f.parentScope,target,f,key);
pc = -1;
break;
} else {
target = tm.trapee;
key = tm.key;
t = tm.t;
- if(t.writeTrap()) throw new JSExn("can't do a write cascade in a read trap");
+ if(t.writeTrap()) throw new JSExn("can't do a read cascade in a write trap");
t = t.next;
while(t != null && t.writeTrap()) t = t.next;
if(t != null) tm.cascadeHappened = true;
stack.push(new TrapMarker(this,t,(JS)target,key,null));
stack.push(new JSArray());
f = t.f;
- scope = new JSScope(f.parentScope);
+ scope = new TrapScope(f.parentScope,target,f,key);
pc = -1;
break;
} else {
method = stack.pop();
object = stack.pop();
} else if (object == null) {
- Object name = stack.pop();
- stack.pop();
- throw new JSExn("function '"+name+"' not found");
+ method = stack.pop();
+ object = stack.pop();
+ throw new JSExn("function '"+JS.debugToString(method)+"' not found in " + object.getClass().getName());
} else {
stack.pop();
stack.pop();
public FinallyData(JSExn exn) { this.exn = exn; this.op = -1; this.arg = null; } // Just throw this exn
}
+ static class TrapScope extends JSScope {
+ JS trapee;
+ JS callee;
+ JS trapname;
+ public TrapScope(JSScope parent, JS trapee, JS callee, JS trapname) {
+ super(parent); this.trapee = trapee; this.callee = callee; this.trapname = trapname;
+ }
+ public JS get(JS key) throws JSExn {
+ if(JS.isString(key)) {
+ //#switch(JS.toString(key))
+ case "trapee": return trapee;
+ case "callee": return callee;
+ case "trapname": return trapname;
+ //#end
+ }
+ return super.get(key);
+ }
+ }
// Operations on Primitives //////////////////////////////////////////////////////////////////////