- } else if (o instanceof JS) {
- Trap t = null;
- if (o instanceof Trap.TrapScope && v.equals("cascade")) {
- t = ((Trap.TrapScope)o).t.next;
- while (t != null && t.f.numFormalArgs != 0) t = t.next;
- if (t == null) { v = ((Trap.TrapScope)o).t.name; o = ((Trap.TrapScope)o).t.trapee; }
-
- } else if (o instanceof JS) {
- if (o instanceof JSScope) {
- JSScope p = (JSScope)o; // search the scope-path for the trap
- t = p.getTrap(v);
- while (t == null && p.getParentScope() != null) { p = p.getParentScope(); t = p.getTrap(v); }
- } else {
- t = ((JS)o).getTrap(v);
- }
- while (t != null && t.f.numFormalArgs != 0) t = t.next; // get first read trap
- }
- if (t != null) {
- stack.push(new CallMarker(this));
- if(stack.size() > MAX_STACK_SIZE) throw new JSExn("stack overflow");
- JSArray args = new JSArray();
- stack.push(args);
- f = t.f;
- scope = new Trap.TrapScope(f.parentScope, t, null);
- ((Trap.TrapScope)scope).cascadeHappened = true;
- pc = -1;
- break;
+ }
+ if(!(target instanceof JS)) throw new Error("should never happen");
+
+ Trap t = null;
+ TrapMarker tm = null;
+ if(target instanceof JSScope && key.equals("cascade")) {
+ Object o=null;
+ int i;
+ for(i=stack.size()-1;i>=0;i--) if((o = stack.elementAt(i)) instanceof CallMarker) break;
+ if(i==0) throw new Error("didn't find a call marker while doing cascade");
+ if(o instanceof TrapMarker) {
+ tm = (TrapMarker) o;
+ 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");
+ t = t.next;
+ while(t != null && t.writeTrap()) t = t.next;
+ if(t != null) tm.cascadeHappened = true;