From: megacz Date: Fri, 30 Jan 2004 07:40:43 +0000 (+0000) Subject: 2003/10/31 10:57:24 X-Git-Tag: RC3~389 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=bb38b8569de61718a7be9f728eabdf2c7c240c42;p=org.ibex.core.git 2003/10/31 10:57:24 darcs-hash:20040130074043-2ba56-824ac54b5f1b14cd63e28d2b727f88b106cdb39c.gz --- diff --git a/src/org/xwt/Trap.java b/src/org/xwt/Trap.java index 2895d9f..2f436c4 100644 --- a/src/org/xwt/Trap.java +++ b/src/org/xwt/Trap.java @@ -4,6 +4,7 @@ package org.xwt; import java.util.*; import org.xwt.js.*; import org.xwt.util.*; +import java.io.*; /** * This class encapsulates a single trap placed on a given node. The @@ -106,16 +107,27 @@ public class Trap { return null; } } - + + private static JS.CompiledFunction cascadeHelper = null; + private static String cascadeHelperText = + "return function(q) { var ret = arguments.doTrap;" + + "if (ret != false && !arguments.didCascade) arguments.cascade = q; };"; + static { + try { + cascadeHelper = JS.parse("cascadeHelper", 1, new StringReader(cascadeHelperText)); + cascadeHelper = (JS.CompiledFunction)new JS.Thread(cascadeHelper).resume(); + } catch (Exception e) { + Log.log(Trap.class, e); + } + } + public void perform(Object val) { try { if (f.getNumFormalArgs() == 0) cascade(val); - TrapArgs ta = new TrapArgs(this, val); - JS.Thread.current().setTailCall(f, ta); - // FIXME: re-add autocascades - //if (ret != Boolean.FALSE && !ta.cascadeHappened) cascade(val); + else JS.Thread.current().setTailCall(cascadeHelper, new TrapArgs(this, val)); } catch (Exception e) { Log.log(this, "Exception thrown from within trap: " + e); + e.printStackTrace(); } } @@ -144,6 +156,8 @@ public class Trap { // common case if(!(key instanceof String)) return super.get(key); if (key.equals("trapee")) return t.trapee; + if (key.equals("doTrap")) { JS.Thread.current().setTailCall(t.f, this); return null; } + if (key.equals("didCascade")) return cascadeHappened ? Boolean.TRUE : Boolean.FALSE; if (key.equals("trapname")) return t.name; if (key.equals("cascade")) return t.cascade(); if (key.equals("callee")) return t.f; diff --git a/src/org/xwt/js/CompiledFunctionImpl.java b/src/org/xwt/js/CompiledFunctionImpl.java index df1b621..2c69e1d 100644 --- a/src/org/xwt/js/CompiledFunctionImpl.java +++ b/src/org/xwt/js/CompiledFunctionImpl.java @@ -10,7 +10,7 @@ class CompiledFunctionImpl extends JS.Obj implements ByteCodes, Tokens { // Fields and Accessors /////////////////////////////////////////////// /** the number of formal arguments */ - int numFormalArgs = 0; + int numFormalArgs = 20; /** the source code file that this block was drawn from */ String sourceName; @@ -45,6 +45,7 @@ class CompiledFunctionImpl extends JS.Obj implements ByteCodes, Tokens { ret.arg = this.arg; ret.line = this.line; ret.size = this.size; + ret.numFormalArgs = this.numFormalArgs; return ret; } @@ -96,10 +97,11 @@ class CompiledFunctionImpl extends JS.Obj implements ByteCodes, Tokens { // Invoking the Bytecode /////////////////////////////////////////////////////// /** returns false if the thread has been paused */ - static void eval(final JS.Thread cx) throws JS.Exn { - OUTER: for(; cx.currentCompiledFunction == null || cx.pc<((CompiledFunctionImpl)cx.currentCompiledFunction).size; cx.pc++) { + static Object eval(final JS.Thread cx) throws JS.Exn { + OUTER: for(;; cx.pc++) { try { - if (cx.paused || cx.currentCompiledFunction == null) return; + if (cx.paused) return null; + cx.bind(); if (cx.tailCallFunction != null) { cx.stack.pop(); // discard actual return value cx.pc -= 2; @@ -111,6 +113,8 @@ class CompiledFunctionImpl extends JS.Obj implements ByteCodes, Tokens { cx.scope = new FunctionScope("unknown", cx.currentCompiledFunction.parentScope); cx.pc = 0; } + if (cx.currentCompiledFunction == null) return cx.stack.pop(); + if (cx.pc >= ((CompiledFunctionImpl)cx.currentCompiledFunction).size) return cx.stack.pop(); String label = null; int curOP = cx.currentCompiledFunction.op[cx.pc]; Object curArg = cx.currentCompiledFunction.arg[cx.pc]; @@ -482,8 +486,6 @@ class CompiledFunctionImpl extends JS.Obj implements ByteCodes, Tokens { throw e; } // end try/catch } // end for - // this should never happen, we will ALWAYS have a RETURN at the end of the func - throw new Error("Just fell out of CompiledFunction::eval() loop."); } // Debugging ////////////////////////////////////////////////////////////////////// diff --git a/src/org/xwt/js/JS.java b/src/org/xwt/js/JS.java index 256c33a..ebd2e36 100644 --- a/src/org/xwt/js/JS.java +++ b/src/org/xwt/js/JS.java @@ -240,10 +240,10 @@ public abstract class JS { public static JS.Thread current() { return (JS.Thread)javaThreadToJSThread.get(java.lang.Thread.currentThread()); } - public void resume() { bind(); paused = false; CompiledFunctionImpl.eval(this); } + public Object resume() { bind(); paused = false; Object ret = CompiledFunctionImpl.eval(this); unbind(); return ret; } public void pause() { paused = true; unbind(); } public void bind() { javaThreadToJSThread.put(java.lang.Thread.currentThread(), this); } - public void unbind() { if (current() == this) javaThreadToJSThread.put(java.lang.Thread.currentThread(), this); } + public void unbind() { if (current() == this) javaThreadToJSThread.remove(java.lang.Thread.currentThread()); } public int getLine() { return currentCompiledFunction == null ? -1 : currentCompiledFunction.getLine(this); } public String getSourceName() { return currentCompiledFunction == null ? null : currentCompiledFunction.getSourceName(); } diff --git a/src/org/xwt/js/Parser.java b/src/org/xwt/js/Parser.java index 323d1dc..7360876 100644 --- a/src/org/xwt/js/Parser.java +++ b/src/org/xwt/js/Parser.java @@ -248,12 +248,13 @@ class Parser extends Lexer implements ByteCodes { b2.add(parserLine, PUT); while(peekToken() != RP) { // run through the list of argument names + numArgs++; if (peekToken() == NAME) { consume(NAME); // a named argument String varName = string; b2.add(parserLine, DUP); // dup the args array - b2.add(parserLine, GET, new Integer(numArgs)); // retrieve it from the arguments array + b2.add(parserLine, GET, new Integer(numArgs - 1)); // retrieve it from the arguments array b2.add(parserLine, TOPSCOPE); b2.add(parserLine, SWAP); b2.add(parserLine, DECLARE, varName); // declare the name @@ -264,11 +265,10 @@ class Parser extends Lexer implements ByteCodes { } if (peekToken() == RP) break; consume(COMMA); - numArgs++; } consume(RP); - b2.numFormalArgs = numArgs + 1; + b2.numFormalArgs = numArgs; b2.add(parserLine, POP); // pop off the arguments array b2.add(parserLine, POP); // pop off TOPSCOPE