From: megacz Date: Fri, 30 Jan 2004 07:41:18 +0000 (+0000) Subject: 2003/11/13 09:15:12 X-Git-Tag: RC3~355 X-Git-Url: http://git.megacz.com/?p=org.ibex.core.git;a=commitdiff_plain;h=c150258fc143a468aa2adc63d4e0b94b8e884580 2003/11/13 09:15:12 darcs-hash:20040130074118-2ba56-e6e75c475a5a50b7c523782e312c46977914ab91.gz --- diff --git a/src/org/xwt/js/ByteCodes.java b/src/org/xwt/js/ByteCodes.java index a5955a5..d364d8c 100644 --- a/src/org/xwt/js/ByteCodes.java +++ b/src/org/xwt/js/ByteCodes.java @@ -51,13 +51,13 @@ interface ByteCodes { /** discard the top stack element */ static public final byte POP = -14; - /** pop two elements; call stack[-n](stack[-n+1], stack[-n+2]...) where n is the number of args to the function */ + /** pop element; call stack[top](stack[-n], stack[-n+1]...) where n is the number of args to the function */ public static final byte CALL = -15; /** pop an element; push a JS.JSArray containing the keys of the popped element */ public static final byte PUSHKEYS = -16; - /** swap the top two elements on the stack */ + /** pops [arg+2] elements, pushes the former top element, then pushes back the rest (retaining order) */ public static final byte SWAP = -17; /** execute the ForthBlock pointed to by the literal in a fresh scope with parentJSScope==THIS */ @@ -76,8 +76,7 @@ interface ByteCodes { * and FALSE for all subsequent iterations */ public static final byte LOOP = -22; - /** pop three elements off the stack; method arguments, method name, and an object to call the method on, then calls the method - Has a similar effect a a GET followed by a CALL */ + /** similar effect a a GET followed by a CALL */ public static final byte CALLMETHOD = -23; /** finish a finally block and carry out whatever instruction initiated the finally block */ diff --git a/src/org/xwt/js/JSContext.java b/src/org/xwt/js/JSContext.java index 4e2d0b0..625c834 100644 --- a/src/org/xwt/js/JSContext.java +++ b/src/org/xwt/js/JSContext.java @@ -23,12 +23,12 @@ public class JSContext { * eval() */ int pausecount = 0; + boolean pauseable; - JSFunction f = null; ///< the currently-executing JSFunction - JSScope scope = null; + JSFunction f; ///< the currently-executing JSFunction + JSScope scope; Vec stack = new Vec(); ///< the object stack int pc = 0; ///< the program counter - boolean pauseable; public static void invokePauseable(JSFunction function) { new JSContext(function, true).invoke(new JSArray()); } @@ -39,7 +39,10 @@ public class JSContext { } void invoke(JSArray args) { + JSFunction tf = f; + f = null; stack.push(new JSFunction.CallMarker(this)); + f = tf; stack.push(args); resume(); } diff --git a/src/org/xwt/js/JSFunction.java b/src/org/xwt/js/JSFunction.java index 66b2e72..11f8031 100644 --- a/src/org/xwt/js/JSFunction.java +++ b/src/org/xwt/js/JSFunction.java @@ -112,7 +112,13 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens { case JF: if (!JS.toBoolean(cx.stack.pop())) cx.pc += JS.toNumber(arg).intValue() - 1; break; case JMP: cx.pc += JS.toNumber(arg).intValue() - 1; break; case POP: cx.stack.pop(); break; - case SWAP: { Object o1 = cx.stack.pop(); Object o2 = cx.stack.pop(); cx.stack.push(o1); cx.stack.push(o2); break; } + case SWAP: { + int depth = (1 + (arg == null ? 1 : toInt(arg))); + Object save = cx.stack.elementAt(cx.stack.size() - 1); + for(int i=cx.stack.size() - 1; i > cx.stack.size() - depth; i--) + cx.stack.setElementAt(cx.stack.elementAt(i-1), i); + cx.stack.setElementAt(save, cx.stack.size() - depth); + break; } case DUP: cx.stack.push(cx.stack.peek()); break; case NEWSCOPE: cx.scope = new JSScope(cx.scope); break; case OLDSCOPE: cx.scope = cx.scope.getParentJSScope(); break; @@ -274,8 +280,8 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens { cx.stack.push(v); } Object ret = null; - if (o == null) throw je("tried to get property \"" + v + "\" from the null value"); if (v == null) throw je("tried to get the null key from " + o); + if (o == null) throw je("tried to get property \"" + v + "\" from the null value"); if (o instanceof String || o instanceof Number || o instanceof Boolean) { ret = Internal.getFromPrimitive(o,v); cx.stack.push(ret); @@ -309,7 +315,10 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens { } case CALL: case CALLMETHOD: { - int numArgs = JS.toNumber(arg).intValue(); + int numArgs = JS.toInt(arg); + JSArray arguments = null; + Object arg0 = null; + Object arg1 = null; Object o = cx.stack.pop(); if(o == null) throw je("attempted to call null"); Object ret; @@ -318,14 +327,19 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens { method = o; if (method == null) throw new JS.Exn("cannot call the null method"); o = cx.stack.pop(); + System.out.println("o == " + o); + System.out.println("method == " + method); if(o instanceof String || o instanceof Number || o instanceof Boolean) { - JSArray arguments = new JSArray(); + arguments = new JSArray(); for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(cx.stack.pop(), j); - ret = Internal.callMethodOnPrimitive(o,method,arguments); + System.out.println(cx.f.dump()); + System.out.println(cx.pc); + ret = Internal.callMethodOnPrimitive(o, method, arguments); cx.stack.push(ret); cx.pc += 2; // skip the GET and CALL break; } else if (o instanceof JSCallable) { + cx.pc += 2; // skip the GET and CALL // fall through } else { // put the args back on the stack and let the GET followed by CALL happen @@ -336,7 +350,7 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens { } else if (o instanceof JSFunction) { // FEATURE: use something similar to call0/call1/call2 here - JSArray arguments = new JSArray(); + arguments = new JSArray(); for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(cx.stack.pop(), j); cx.stack.push(new CallMarker(cx)); cx.stack.push(arguments); @@ -346,13 +360,14 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens { break; } + if (!(o instanceof JSCallable)) throw new JS.Exn("can't call " + o + " @ " + cx.pc + "\n" + cx.f.dump()); JSCallable c = ((JSCallable)o); switch(numArgs) { case 0: ret = c.call0(method); break; case 1: ret = c.call1(method, cx.stack.pop()); break; - case 2: ret = c.call2(method, cx.stack.pop(), cx.stack.pop()); break; + case 2: { Object first = cx.stack.pop(); ret = c.call2(method, cx.stack.pop(), first); break; } default: { - JSArray arguments = new JSArray(); + arguments = new JSArray(); for(int j=numArgs - 1; j >= 0; j--) arguments.setElementAt(cx.stack.pop(), j); ret = c.call(method, arguments); if (cx.pausecount > initialPauseCount) return null; // we were paused @@ -360,7 +375,6 @@ public class JSFunction extends JSCallable implements ByteCodes, Tokens { } } cx.stack.push(ret); - if (method != null) cx.pc += 2; // skip the GET and CALL if this was a GETCALL break; } diff --git a/src/org/xwt/js/Parser.java b/src/org/xwt/js/Parser.java index ffb12d8..b3c1742 100644 --- a/src/org/xwt/js/Parser.java +++ b/src/org/xwt/js/Parser.java @@ -350,9 +350,9 @@ class Parser extends Lexer implements ByteCodes { break; } case LP: { - int n = parseArgs(b, false); + int n = parseArgs(b); - // if the object supports GETCALL, we use this, and jump over the following two instructions + // if the object supports CALLMETHOD, we use this, and jump over the following two instructions b.add(parserLine,CALLMETHOD,new Integer(n)); b.add(parserLine,GET); b.add(parserLine,CALL,new Integer(n)); @@ -397,7 +397,7 @@ class Parser extends Lexer implements ByteCodes { switch (tok) { case LP: { // invocation (not grouping) - int n = parseArgs(b, true); + int n = parseArgs(b); b.add(parserLine, CALL, new Integer(n)); break; } @@ -476,13 +476,13 @@ class Parser extends Lexer implements ByteCodes { // parse a set of comma separated function arguments, assume LP has already been consumed // if swap is true, (because the function is already on the stack) we will SWAP after each argument to keep it on top - private int parseArgs(JSFunction b, boolean swap) throws IOException { + private int parseArgs(JSFunction b) throws IOException { int i = 0; while(peekToken() != RP) { i++; if (peekToken() != COMMA) { startExpr(b, NO_COMMA); - if (swap) b.add(parserLine, SWAP); + b.add(parserLine, SWAP, new Integer(2)); if (peekToken() == RP) break; } consume(COMMA); diff --git a/src/org/xwt/plat/AWT.java b/src/org/xwt/plat/AWT.java index cca1209..dac9e57 100644 --- a/src/org/xwt/plat/AWT.java +++ b/src/org/xwt/plat/AWT.java @@ -280,6 +280,7 @@ public class AWT extends JVM { AWTSurface(Box root, boolean framed) { super(root); + System.out.println("Y"); try { if (framed) window = frame = new InnerFrame(); else window = new InnerWindow(); diff --git a/src/org/xwt/util/Preprocessor.java b/src/org/xwt/util/Preprocessor.java index 47c3134..5232be5 100644 --- a/src/org/xwt/util/Preprocessor.java +++ b/src/org/xwt/util/Preprocessor.java @@ -141,7 +141,7 @@ public class Preprocessor { String prefixPlusOne = ((String)keys.elementAt(i)).substring(0, prefix.length() + 1); if (i