mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 673070 - Fix name lookups in let scopes a bit more ("Assertion failure: sharedBlock" with e4x after fixing bug 646968). r=brendan.
This commit is contained in:
parent
4a430a805c
commit
e5002b3bc3
@ -3093,7 +3093,7 @@ AllocateSwitchConstant(JSContext *cx)
|
||||
/*
|
||||
* Sometimes, let-slots are pushed to the JS stack before we logically enter
|
||||
* the let scope. For example,
|
||||
* for (let x = EXPR;;) BODY
|
||||
* let (x = EXPR) BODY
|
||||
* compiles to roughly {enterblock; EXPR; setlocal x; BODY; leaveblock} even
|
||||
* though EXPR is evaluated in the enclosing scope; it does not see x.
|
||||
*
|
||||
@ -4184,10 +4184,6 @@ EmitVariables(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
|
||||
*/
|
||||
let = (pn->pn_op == JSOP_NOP);
|
||||
forInVar = (pn->pn_xflags & PNX_FORINVAR) != 0;
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
bool popScope = (inLetHead || (let && (cg->flags & TCF_IN_FOR_INIT)));
|
||||
JS_ASSERT_IF(popScope, let);
|
||||
#endif
|
||||
|
||||
off = noteIndex = -1;
|
||||
for (pn2 = pn->pn_head; ; pn2 = next) {
|
||||
@ -4320,23 +4316,11 @@ EmitVariables(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
/* Evaluate expr in the outer lexical scope if requested. */
|
||||
TempPopScope tps;
|
||||
if (popScope && !tps.popBlock(cx, cg))
|
||||
return JS_FALSE;
|
||||
#endif
|
||||
|
||||
oldflags = cg->flags;
|
||||
cg->flags &= ~TCF_IN_FOR_INIT;
|
||||
if (!js_EmitTree(cx, cg, pn3))
|
||||
return JS_FALSE;
|
||||
cg->flags |= oldflags & TCF_IN_FOR_INIT;
|
||||
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
if (popScope && !tps.repushBlock(cx, cg))
|
||||
return JS_FALSE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -6681,8 +6665,18 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
}
|
||||
|
||||
#if JS_HAS_BLOCK_SCOPE
|
||||
case TOK_LET:
|
||||
/* Let statements have their variable declarations on the left. */
|
||||
case TOK_LET: {
|
||||
/*
|
||||
* pn represents one of these syntactic constructs:
|
||||
* let-expression: (let (x = y) EXPR)
|
||||
* let-statement: let (x = y) { ... }
|
||||
* let-declaration in statement context: let x = y;
|
||||
* let-declaration in for-loop head: for (let ...) ...
|
||||
*
|
||||
* Let-expressions and let-statements are represented as binary nodes
|
||||
* with their variable declarations on the left and the body on the
|
||||
* right.
|
||||
*/
|
||||
if (pn->pn_arity == PN_BINARY) {
|
||||
pn2 = pn->pn_right;
|
||||
pn = pn->pn_left;
|
||||
@ -6690,13 +6684,27 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
pn2 = NULL;
|
||||
}
|
||||
|
||||
/* Non-null pn2 means that pn is the variable list from a let head. */
|
||||
/*
|
||||
* Non-null pn2 means that pn is the variable list from a let head.
|
||||
*
|
||||
* Use TempPopScope to evaluate the expressions in the enclosing scope.
|
||||
* This also causes the initializing assignments to be emitted in the
|
||||
* enclosing scope, but the assignment opcodes emitted here
|
||||
* (essentially just setlocal, though destructuring assignment uses
|
||||
* other additional opcodes) do not care about the block chain.
|
||||
*/
|
||||
JS_ASSERT(pn->pn_arity == PN_LIST);
|
||||
TempPopScope tps;
|
||||
bool popScope = pn2 || (cg->flags & TCF_IN_FOR_INIT);
|
||||
if (popScope && !tps.popBlock(cx, cg))
|
||||
return JS_FALSE;
|
||||
if (!EmitVariables(cx, cg, pn, pn2 != NULL, ¬eIndex))
|
||||
return JS_FALSE;
|
||||
tmp = CG_OFFSET(cg);
|
||||
if (popScope && !tps.repushBlock(cx, cg))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Thus non-null pn2 is the body of the let block or expression. */
|
||||
tmp = CG_OFFSET(cg);
|
||||
if (pn2 && !js_EmitTree(cx, cg, pn2))
|
||||
return JS_FALSE;
|
||||
|
||||
@ -6706,6 +6714,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
return JS_FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* JS_HAS_BLOCK_SCOPE */
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
|
@ -2527,6 +2527,15 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
rval = OFF2STR(&ss->sprinter, todo);
|
||||
todo = -2;
|
||||
pc2 = pc + oplen;
|
||||
|
||||
/* Skip a block chain annotation if one appears here. */
|
||||
if (*pc2 == JSOP_NOP) {
|
||||
if (pc2[JSOP_NOP_LENGTH] == JSOP_NULLBLOCKCHAIN)
|
||||
pc2 += JSOP_NOP_LENGTH + JSOP_NULLBLOCKCHAIN_LENGTH;
|
||||
else if (pc2[JSOP_NOP_LENGTH] == JSOP_BLOCKCHAIN)
|
||||
pc2 += JSOP_NOP_LENGTH + JSOP_BLOCKCHAIN_LENGTH;
|
||||
}
|
||||
|
||||
if (*pc2 == JSOP_NOP) {
|
||||
sn = js_GetSrcNote(jp->script, pc2);
|
||||
if (sn) {
|
||||
|
@ -222,7 +222,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
|
||||
* before deserialization of bytecode. If the saved version does not match
|
||||
* the current version, abort deserialization and invalidate the file.
|
||||
*/
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 92)
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 93)
|
||||
|
||||
/*
|
||||
* Library-private functions.
|
||||
|
@ -108,3 +108,6 @@ script regress-643222.js
|
||||
script regress-614714.js
|
||||
script regress-665355.js
|
||||
script regress-666599.js
|
||||
script regress-673070-1.js
|
||||
script regress-673070-2.js
|
||||
script regress-673070-3.js
|
||||
|
8
js/src/tests/js1_8_5/regress/regress-673070-1.js
Normal file
8
js/src/tests/js1_8_5/regress/regress-673070-1.js
Normal file
@ -0,0 +1,8 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
var q = [2];
|
||||
let ([q] = eval("q"))
|
||||
assertEq(q, 2);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
8
js/src/tests/js1_8_5/regress/regress-673070-2.js
Normal file
8
js/src/tests/js1_8_5/regress/regress-673070-2.js
Normal file
@ -0,0 +1,8 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
var q = 1;
|
||||
let ([q] = [eval("q")])
|
||||
assertEq(q, 1);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
8
js/src/tests/js1_8_5/regress/regress-673070-3.js
Normal file
8
js/src/tests/js1_8_5/regress/regress-673070-3.js
Normal file
@ -0,0 +1,8 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
let (x = 1) {
|
||||
let ([] = [<x/>], r = <x/>) {}
|
||||
}
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
Loading…
Reference in New Issue
Block a user