From db9fd9570a6e8302a34e6fc32d04d58b59e39a99 Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 6 Apr 2004 22:05:31 +0000 Subject: [PATCH] bugs 520 and 524 darcs-hash:20040406220531-24bed-fb85c795b391757083ad3b352b15754a572d247f.gz --- src/org/ibex/js/JSArray.java | 4 ++-- src/org/ibex/js/JSExn.java | 2 +- src/org/ibex/js/JSFunction.java | 3 +-- src/org/ibex/js/Parser.java | 45 ++++++++++++++++++++++++++------------- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/org/ibex/js/JSArray.java b/src/org/ibex/js/JSArray.java index f29b79a..bf54947 100644 --- a/src/org/ibex/js/JSArray.java +++ b/src/org/ibex/js/JSArray.java @@ -99,8 +99,8 @@ public class JSArray extends JS { public Enumeration keys() { return new Enumeration() { - int cur = 0; - public boolean hasMoreElements() { return cur >= size(); } + private int cur = 0; + public boolean hasMoreElements() { return cur < size(); } public Object nextElement() { if (cur >= size()) throw new NoSuchElementException(); return new Integer(cur++); diff --git a/src/org/ibex/js/JSExn.java b/src/org/ibex/js/JSExn.java index 8c1362d..b39d6c8 100644 --- a/src/org/ibex/js/JSExn.java +++ b/src/org/ibex/js/JSExn.java @@ -23,7 +23,7 @@ public class JSExn extends Exception { if (element instanceof Interpreter.CallMarker) { Interpreter.CallMarker cm = (Interpreter.CallMarker)element; if (cm.f != null) - addBacktrace(cm.f.sourceName + ":" + cm.f.line[cm.pc]); + addBacktrace(cm.f.sourceName + ":" + cm.f.line[cm.pc-1]); if (cm.scope != null && cm.scope instanceof Trap.TrapScope) addBacktrace("trap on property \"" + ((Trap.TrapScope)cm.scope).t.name + "\""); } diff --git a/src/org/ibex/js/JSFunction.java b/src/org/ibex/js/JSFunction.java index 4e6a48d..1455d38 100644 --- a/src/org/ibex/js/JSFunction.java +++ b/src/org/ibex/js/JSFunction.java @@ -108,8 +108,7 @@ class JSFunction extends JS implements ByteCodes, Tokens, org.ibex.Scheduler.Tas StringBuffer sb = new StringBuffer(1024); sb.append("\n" + sourceName + ": " + firstLine + "\n"); for (int i=0; i < size; i++) { - sb.append(i); - sb.append(": "); + sb.append(i).append(" (").append(line[i]).append(") :"); if (op[i] < 0) sb.append(bytecodeToString[-op[i]]); else sb.append(codeToString[op[i]]); sb.append(" "); diff --git a/src/org/ibex/js/Parser.java b/src/org/ibex/js/Parser.java index aad793e..51b23b8 100644 --- a/src/org/ibex/js/Parser.java +++ b/src/org/ibex/js/Parser.java @@ -835,58 +835,73 @@ class Parser extends Lexer implements ByteCodes { pushBackToken(tok, varName); if (forIn) { - b.add(parserLine, NEWSCOPE); - b.add(parserLine, DECLARE, varName); - b.add(parserLine, POP); - consume(NAME); consume(IN); startExpr(b,-1); consume(RP); + b.add(parserLine, PUSHKEYS); b.add(parserLine, DUP); b.add(parserLine, LITERAL, "length"); b.add(parserLine, GET); + // Stack is now: n, keys, obj, ... int size = b.size; b.add(parserLine, LOOP); b.add(parserLine, POP); + // Stack is now: LoopMarker, n, keys, obj, ... + // NOTE: This will break if the interpreter ever becomes more strict + // and prevents bytecode from messing with the Markers b.add(parserLine, SWAP, JS.N(3)); + // Stack is now: Tn, keys, obj, LoopMarker, ... b.add(parserLine, LITERAL, JS.N(1)); b.add(parserLine, SUB); b.add(parserLine, DUP); + // Stack is now: index, keys, obj, LoopMarker b.add(parserLine, LITERAL, JS.ZERO); b.add(parserLine, LT); + // Stack is now index<0, index, keys, obj, LoopMarker, ... - b.add(parserLine, JF, JS.N(5)); + b.add(parserLine, JF, JS.N(5)); // if we're >= 0 jump 5 down (to NEWSCOPE) + // Move the LoopMarker back into place - this is sort of ugly b.add(parserLine, SWAP, JS.N(3)); b.add(parserLine, SWAP, JS.N(3)); b.add(parserLine, SWAP, JS.N(3)); + // Stack is now: LoopMarker, -1, keys, obj, ... b.add(parserLine, BREAK); - b.add(parserLine, GET_PRESERVE); - b.add(parserLine, TOPSCOPE); - b.add(parserLine, SWAP); - b.add(parserLine, LITERAL, varName); - b.add(parserLine, SWAP); - b.add(parserLine, PUT); - b.add(parserLine, POP); - b.add(parserLine, POP); + b.add(parserLine, NEWSCOPE); + if(hadVar) { + b.add(parserLine, DECLARE, varName); + b.add(parserLine, POP); + } + + // Stack is now: index, keys, obj, LoopMarker, ... + b.add(parserLine, GET_PRESERVE); // key, index, keys, obj, LoopMarker, ... + b.add(parserLine, TOPSCOPE); // scope, key, index, keys, obj, LoopMarker, ... + b.add(parserLine, SWAP); // key, scope, index, keys, obj, LoopMarker, ... + b.add(parserLine, LITERAL, varName); // varName, key, scope, index, keys, obj, LoopMaker, ... + b.add(parserLine, SWAP); // key, varName, scope, index, keys, obj, LoopMarker, ... + b.add(parserLine, PUT); // key, scope, index, keys, obj, LoopMarker, ... + b.add(parserLine, POP); // scope, index, keys, obj, LoopMarker + b.add(parserLine, POP); // index, keys, obj, LoopMarker, ... + // Move the LoopMarker back into place - this is sort of ugly b.add(parserLine, SWAP, JS.N(3)); b.add(parserLine, SWAP, JS.N(3)); b.add(parserLine, SWAP, JS.N(3)); parseStatement(b, null); + b.add(parserLine, OLDSCOPE); b.add(parserLine, CONTINUE); + // jump here on break b.set(size, JS.N(b.size - size)); b.add(parserLine, POP); // N b.add(parserLine, POP); // KEYS b.add(parserLine, POP); // OBJ - b.add(parserLine, OLDSCOPE); - + } else { if (hadVar) pushBackToken(VAR, null); // yeah, this actually matters b.add(parserLine, NEWSCOPE); // grab a fresh scope -- 1.7.10.4