Revision: 4767 http://sourceforge.net/p/vexi/code/4767 Author: mkpg2 Date: 2015-02-26 04:12:07 +0000 (Thu, 26 Feb 2015) Log Message: ----------- Pause in trap execution support/testing.
Modified Paths: -------------- branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Interpreter.java branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Scheduler.java branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/Scripting.java branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/TestJSThreading.java Added Paths: ----------- branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/test_threading.js Removed Paths: ------------- branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/script.js Modified: branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Interpreter.java =================================================================== --- branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Interpreter.java 2015-02-26 02:07:11 UTC (rev 4766) +++ branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Interpreter.java 2015-02-26 04:12:07 UTC (rev 4767) @@ -111,14 +111,14 @@ Interpreter(Thread thread, JS.Trap t, JS val, boolean pauseOnCascade, JS trapname) { this(thread); this.pausecount = -1; - setupTrapSafe(new TrapMarker(this, t,val,pauseOnCascade), trapname); + setupTrapSafe(new TrapMarker(null, t,val,pauseOnCascade), trapname); } -// -// Interpreter(Thread thread, TrapMarker marker, JS trapname) { -// this(thread); -// this.pausecount = thread.pauseable ? 0 : -1; -// setupTrapSafe(marker,trapname); -// } + + Interpreter(Thread thread, TrapMarker marker, JS trapname) { + this(thread); + this.pausecount = thread.pauseable ? 0 : -1; + setupTrapSafe(marker,trapname); + } private boolean get = false; // FIXME: split this stuff out into a Script instance control object @@ -148,8 +148,10 @@ } pausecount++; switch(f.op[pc]) { - case Tokens.RETURN: case ByteCodes.PUT: get = false; break; + case Tokens.RETURN: case ByteCodes.PUT: get = false; break; case ByteCodes.GET: case ByteCodes.GET_PRESERVE: case ByteCodes.CALLMETHOD: case ByteCodes.CALL: get = true; break; + case Tokens.CASCADE: /* handled in CASCADE */ break; + default: throw new Error("paused on unexpected bytecode: " + f.op[pc]); } } @@ -359,15 +361,16 @@ } else { thread.faction.cascadedTo = tm.trapargs.trapname; if(write) { - if (tm.pauseOnCascade) { pc++; return val; } - target.put(key,val); + get = false; + if (tm.pauseOnCascade) { pc++; return val; } + else { target.put(key,val); } } else { + get = true; if (tm.pauseOnCascade) { // FIXME should move this to setup of interpreter // we need it true for when we restart the interpreter - get = true; - pc++; return null; } - else{ + pc++; return null; + }else{ JS ret = target.get(key); if (ret != null && ret == JS.METHOD) ret = new Stub(target, key); stack.push(ret); @@ -772,6 +775,7 @@ JS val; JSArgsTrap trapargs; final boolean pauseOnCascade; // FOOTNOTE 2 + public TrapMarker(JS.Trap t, JS val) { this(null, t, val, false); } public TrapMarker(Interpreter cx, JS.Trap t, JS val, boolean pauseOnCascade) { super(cx); this.t = t; Modified: branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Scheduler.java =================================================================== --- branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Scheduler.java 2015-02-26 02:07:11 UTC (rev 4766) +++ branches/vexi3/org.vexi-library.js/src/main/java/org/ibex/js/Scheduler.java 2015-02-26 04:12:07 UTC (rev 4767) @@ -6,6 +6,7 @@ import java.util.concurrent.CountDownLatch; +import org.ibex.js.Interpreter.TrapMarker; import org.ibex.js.JS.Trap; import org.ibex.util.Basket; import org.ibex.util.Callable; @@ -170,12 +171,12 @@ thread.currentInterpreter = new Interpreter(thread, (JSFunction)function, true, args); add(thread); } -// public void runInNew(Trap trap, JS put, Callable<Object, JS> onPut, Callable<Object, JS> callback) throws JSExn { -// Thread thread = new Thread(this, "background/wtrap", trap.function(), true, callback); -// thread.currentInterpreter = new Interpreter(thread, (JSFunction)trap.function(), true); -// -// add(new Thread(this, "background/trap", function, args, true, callback)); -// } + public void runInNew(Trap trap, JS trapname, JS put, Callable<Object, JS> callback) throws JSExn { + Thread thread = new Thread(this, "background/wtrap", trap.function(), true, callback); + TrapMarker marker = new TrapMarker(trap, put); + thread.currentInterpreter = new Interpreter(thread, marker, trapname); + add(thread); + } @@ -452,8 +453,29 @@ } } + public JS syncCall(Trap trap, JS trapname, JS put) throws JSExn, InterruptedException { + final CountDownLatch latch0 = new CountDownLatch(1); + final Object[] retArr = new Object[1]; + runInNew(trap, trapname, put, new Callable<Object, JS>() { + public JS run(Object ret) throws Exception { + retArr[0] = ret; + latch0.countDown(); + return null; + } + }); + + latch0.await(); + Object ret = retArr[0]; + if(ret==null || ret instanceof JS){ + return (JS)ret; + }else if(ret instanceof JSExn){ + throw (JSExn)ret; + }else{ + throw new JSExn((Throwable)ret); + } - + } + public void scheduleJustTriggerTraps(final JS.Obj obj, final JS key, final JS value) { add(new Callable() { public Object run(Object o) throws Exception { Modified: branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/Scripting.java =================================================================== --- branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/Scripting.java 2015-02-26 02:07:11 UTC (rev 4766) +++ branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/Scripting.java 2015-02-26 04:12:07 UTC (rev 4767) @@ -6,6 +6,7 @@ import org.ibex.js.ExecParser; import org.ibex.js.JS; +import org.ibex.js.JS.Trap; import org.ibex.js.JSExn; import org.ibex.js.JSFunction; import org.ibex.js.JSON; @@ -21,6 +22,11 @@ final public Set<String> logged = new LinkedHashSet(); + + private Trap readable; + private Trap writeable; + private Callable readableAction; + private Callable writeableAction; private JSFunction method; final JS LOG = new JS.Immutable(){ @@ -29,9 +35,33 @@ }; }; final JS TESTOBJ = new JS.Immutable(){ + @Override public void addTrap(JS keyJS, JS function) throws JSExn { + String key = JSU.toString(keyJS); + if("Readable".equals(key)){ + readable = new JS.TrapHolder(this,keyJS,function,readable); + } else if("Writeable".equals(key)){ + writeable = new JS.TrapHolder(this,keyJS,function,readable); + }else{ + super.addTrap(keyJS, function); + } + } + + public JS get(JS keyJS) throws JSExn { + String key = JSU.toString(keyJS); + if("Readable".equals(key)){ + Scheduler sched = Scheduler.expectCurrent(); + sched.backgroundCall("Readable", readableAction); + return null; + } + return super.get(keyJS); + } + @Override public void put(JS keyJS, JS val) throws JSExn { String key = JSU.toString(keyJS); - if("method".equals(key)){ + if("Writeable".equals(key)){ + Scheduler sched = Scheduler.expectCurrent(); + sched.backgroundCall("Writeable", writeableAction); + }else if("method".equals(key)){ method = (JSFunction)val; }else{ super.put(keyJS, val); @@ -91,4 +121,16 @@ } return SCHEDULER.syncCall(method, new JS[]{JSU.B(throwexn)}); } + + + public void triggerWrite(JS value, Callable action) throws Exception{ + this.writeableAction = action; + SCHEDULER.syncCall(writeable, JSU.S("Writeable"), value); + } + + + public JS triggerRead(Callable action) throws Exception{ + this.readableAction = action; + return SCHEDULER.syncCall(readable, JSU.S("Readable"), null); + } } Modified: branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/TestJSThreading.java =================================================================== --- branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/TestJSThreading.java 2015-02-26 02:07:11 UTC (rev 4766) +++ branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/TestJSThreading.java 2015-02-26 04:12:07 UTC (rev 4767) @@ -3,14 +3,17 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.util.concurrent.CountDownLatch; import junit.framework.Assert; import junit.framework.TestCase; import org.ibex.js.Fountain; +import org.ibex.js.JS; import org.ibex.js.JSExn; import org.ibex.js.JSTestUtil; import org.ibex.js.JSU; +import org.ibex.util.Callable; public class TestJSThreading extends TestCase{ @@ -37,7 +40,7 @@ @Override protected void setUp() throws Exception { if(scripting==null){ scripting = new Scripting(); - InputStream is = ((Fountain)jspath.get(JSU.S("script.js"))).getInputStream(true); + InputStream is = ((Fountain)jspath.get(JSU.S("test_threading.js"))).getInputStream(true); Reader reader = new InputStreamReader(is); scripting.run("script.js", reader); } @@ -66,4 +69,101 @@ printLogged(); } + + + + + + + + + + + public void testWrite() throws Exception{ + final Boolean[] cascaded = new Boolean[]{false}; + scripting.triggerWrite(JSU.B(false), new Callable<Object, JS>() { + public JS run(Object A) throws Exception { + cascaded[0] = true; + return null; + } + }); + + assertTrue(cascaded[0]); + + assertLogged("writeBefore,writeAfter,writeFinally"); + + printLogged(); + } + + + + public void testWriteExn() throws Exception{ + boolean exn = false; + try{ + scripting.triggerWrite(JSU.B(false), new Callable<Object, JS>() { + public JS run(Object A) throws Exception { + throw new JSExn("!"); + } + }); + }catch(Exception e){ + exn = true; + } + printLogged(); + assertLogged("writeBefore,writeCatch,writeFinally"); + if(!exn) fail("Exception not passed out"); + + } + + + + public void testWritePause() throws Exception{ + final CountDownLatch latch0 = new CountDownLatch(1); + final CountDownLatch latch1 = new CountDownLatch(1); + final CountDownLatch latch2 = new CountDownLatch(1); + + new Thread(){ + public void run() { + try { + scripting.triggerWrite(JSU.B(false), new Callable<Object, JS>() { + public JS run(Object A) throws Exception { + latch0.countDown(); + latch1.await(); + return null; + } + }); + latch2.countDown(); + } catch (Exception e) { + e.printStackTrace(); + } + }; + }.start(); + + + latch0.await(); + scripting.callMethod(false); + latch1.countDown(); + latch2.await(); + + assertLogged("writeBefore,method1,method2,method3,writeAfter,writeFinally"); + + printLogged(); + } + + + public void testRead() throws Exception{ + final Boolean[] cascaded = new Boolean[]{false}; + scripting.triggerRead(new Callable<Object, JS>() { + public JS run(Object A) throws Exception { + cascaded[0] = true; + return JSU.B(true); + } + }); + + assertTrue(cascaded[0]); + + assertLogged("readBefore,readAfter,readFinally"); + + printLogged(); + } + } Deleted: branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/script.js =================================================================== --- branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/script.js 2015-02-26 02:07:11 UTC (rev 4766) +++ branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/script.js 2015-02-26 04:12:07 UTC (rev 4767) @@ -1,17 +0,0 @@ - - -TESTOBJ.method = function(throwexn){ - LOG.method1 = true; - pause(); - LOG.method2 = true; - try{ - if(throwexn){ - throw "exn"; - }else{ - return "done"; - } - }finally{ - LOG.method3 = true; - } -}; -print("setup"); Copied: branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/test_threading.js (from rev 4765, branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/script.js) =================================================================== --- branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/test_threading.js (rev 0) +++ branches/vexi3/org.vexi-library.js/src/test/java/test/js/threading/test_threading.js 2015-02-26 04:12:07 UTC (rev 4767) @@ -0,0 +1,54 @@ + + +TESTOBJ.method = function(throwexn){ + LOG.method1 = true; + pause(); + LOG.method2 = true; + try{ + if(throwexn){ + throw "exn"; + }else{ + return "done"; + } + }finally{ + LOG.method3 = true; + } +}; + + + + +TESTOBJ.Writeable ++= function(v){ + LOG.writeBefore = true; + try{ + cascade = v; + LOG.writeAfter = true; + + }catch(e){ + LOG.writeCatch = true; + throw e; + }finally{ + LOG.writeFinally = true; + } +}; + +TESTOBJ.Readable ++= function(){ + LOG.readBefore = true; + try{ + var r = cascade; + LOG.readAfter = true; + return r; + }catch(e){ + LOG.readCatch = true; + throw e; + }finally{ + LOG.readFinally = true; + } +}; + + + + + + +print("setup"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Dive into the World of Parallel Programming The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn