X-Git-Url: http://git.megacz.com/?p=org.ibex.core.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fjs%2FInterpreter.java;fp=src%2Forg%2Fibex%2Fjs%2FInterpreter.java;h=15d42bef09438020b6da6b243cd8defe181cc333;hp=6fc452b15dafab5c660de01ec900e506278a81f3;hb=b1c3851aa91d7da83b62c267596ecacb6ac73868;hpb=599add0066bcc10afa60b11d5b11b522f47d4335 diff --git a/src/org/ibex/js/Interpreter.java b/src/org/ibex/js/Interpreter.java index 6fc452b..15d42be 100644 --- a/src/org/ibex/js/Interpreter.java +++ b/src/org/ibex/js/Interpreter.java @@ -170,26 +170,28 @@ class Interpreter implements ByteCodes, Tokens { } else if (o instanceof CallMarker) { if (o instanceof TrapMarker) { // handles return component of a read trap TrapMarker tm = (TrapMarker) o; - boolean cascade = tm.t.writeTrap() && !tm.cascadeHappened && !JS.toBoolean(retval); + boolean cascade = tm.t.isWriteTrap() && !tm.cascadeHappened && !JS.toBoolean(retval); if(cascade) { - Trap t = tm.t.next; - while(t != null && t.readTrap()) t = t.next; + Trap t = tm.t.nextWriteTrap(); + if(t == null && tm.target instanceof JS.Clone) { + tm.target = ((JS.Clone)tm.target).clonee; + t = tm.target.getTrap(tm.key); + if(t != null) t = t.writeTrap(); + } if(t != null) { - tm.t = t; - stack.push(tm); - stack.push(new JSArgs(tm.val,t.f)); - f = t.f; - scope = new JSScope(f.parentScope); - pc = -1; + tm.t = t; // we reuse the old trap marker + setupTrap(t,tm.val,tm); + pc--; // we increment it on the next iter continue OUTER; } else { - tm.trapee.put(tm.key,tm.val); + tm.target.put(tm.key,tm.val); } } } - scope = ((CallMarker)o).scope; - pc = ((CallMarker)o).pc - 1; - f = (JSFunction)((CallMarker)o).f; + CallMarker cm = (CallMarker) o; + scope = cm.scope; + pc = cm.pc - 1; + f = cm.f; stack.push(retval); if (pausecount > initialPauseCount) { pc++; return null; } // we were paused if(f == null) return retval; @@ -212,28 +214,29 @@ class Interpreter implements ByteCodes, Tokens { CallMarker o = stack.findCall(); if(o instanceof TrapMarker) { tm = (TrapMarker) o; - target = tm.trapee; + target = tm.target; key = tm.key; tm.cascadeHappened = true; t = tm.t; - 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; + if(t.isReadTrap()) throw new JSExn("can't do a write cascade in a read trap"); + t = t.nextWriteTrap(); } } - if(tm == null) { // didn't find a trap marker, try to find a trap - t = target instanceof JSScope ? t = ((JSScope)target).top().getTrap(key) : ((JS)target).getTrap(key); - while(t != null && t.readTrap()) t = t.next; + if(tm == null) { // not cascading + t = target instanceof JSScope ? t = ((JSScope)target).top().getTrap(key) : target.getTrap(key); + if(t != null) t = t.writeTrap(); + } + if(t == null && target instanceof JS.Clone) { + target = ((JS.Clone)target).clonee; + t = target.getTrap(key); + if(t != null) t = t.writeTrap(); } stack.push(val); if(t != null) { - stack.push(new TrapMarker(this,t,target,key,val)); - stack.push(new JSArgs(val,t.f)); - f = t.f; - scope = new TrapScope(f.parentScope,target,f,key); - pc = -1; + setupTrap(t,val,new TrapMarker(this,t,target,key,val)); + pc--; // we increment later break; } else { target.put(key,val); @@ -263,26 +266,26 @@ class Interpreter implements ByteCodes, Tokens { CallMarker o = stack.findCall(); if(o instanceof TrapMarker) { tm = (TrapMarker) o; - target = tm.trapee; + target = tm.target; key = tm.key; t = tm.t; - 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; + if(t.isWriteTrap()) throw new JSExn("can't do a read cascade in a write trap"); + t = t.nextReadTrap(); } } - if(tm == null) { // didn't find a trap marker, try to find a trap + if(tm == null) { // not cascading t = target instanceof JSScope ? t = ((JSScope)target).top().getTrap(key) : ((JS)target).getTrap(key); - while(t != null && t.writeTrap()) t = t.next; + if(t != null) t = t.readTrap(); + } + if(t == null && target instanceof JS.Clone) { + target = ((JS.Clone)target).clonee; + t = target.getTrap(key); + if(t != null) t = t.readTrap(); } if(t != null) { - stack.push(new TrapMarker(this,t,(JS)target,key,null)); - stack.push(new JSArgs(t.f)); - f = t.f; - scope = new TrapScope(f.parentScope,target,f,key); - pc = -1; + setupTrap(t,null,new TrapMarker(this,t,target,key,null)); + pc--; // we increment later break; } else { ret = target.get(key); @@ -513,6 +516,13 @@ class Interpreter implements ByteCodes, Tokens { throw e; } + void setupTrap(Trap t, JS val, CallMarker cm) throws JSExn { + stack.push(cm); + stack.push(t.isWriteTrap() ? new JSArgs(val,t.f) : new JSArgs(t.f)); + f = t.f; + scope = new TrapScope(t.f.parentScope,t.target,t.f,t.key); + pc = 0; + } // Markers ////////////////////////////////////////////////////////////////////// @@ -534,14 +544,14 @@ class Interpreter implements ByteCodes, Tokens { static class TrapMarker extends CallMarker { Trap t; - final JS trapee; + JS target; final JS key; final JS val; boolean cascadeHappened; - public TrapMarker(Interpreter cx, Trap t, JS trapee, JS key, JS val) { + public TrapMarker(Interpreter cx, Trap t, JS target, JS key, JS val) { super(cx); this.t = t; - this.trapee = trapee; + this.target = target; this.key = key; this.val = val; }