X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fjs%2FParser.java;h=51b23b889a8df0b233b7a3184af3724e795a26ef;hb=b857cf06b4b1fe9a5f6200728cc1e5f94903b05a;hp=a4621db77c4810331d247712cbc26672d1d38eca;hpb=b5f5696f48099cede3bb5f2331b406f6ded1fe4a;p=org.ibex.core.git diff --git a/src/org/ibex/js/Parser.java b/src/org/ibex/js/Parser.java index a4621db..51b23b8 100644 --- a/src/org/ibex/js/Parser.java +++ b/src/org/ibex/js/Parser.java @@ -408,7 +408,7 @@ class Parser extends Lexer implements ByteCodes { b.add(parserLine, SWAP, null); b.add(parserLine, POP, null); b.add(parserLine, LITERAL, JS.N(1)); - b.add(parserLine, tok == INC ? SUB : ADD, null); // undo what we just did, since this is postfix + b.add(parserLine, tok == INC ? SUB : ADD, JS.N(2)); // undo what we just did, since this is postfix break; } case ASSIGN: { @@ -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