mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 759246 (part 4) - Don't share inForInit between Parser and BCE. r=jorendorff.
--HG-- extra : rebase_source : e96817e8d326a2f8f034e6166f70a05b86aaa49c
This commit is contained in:
parent
669c9daf03
commit
0d58fdbb5f
@ -83,7 +83,8 @@ BytecodeEmitter::BytecodeEmitter(Parser *parser, SharedContext *sc, unsigned lin
|
||||
typesetCount(0),
|
||||
noScriptRval(noScriptRval),
|
||||
needScriptGlobal(needScriptGlobal),
|
||||
hasSingletons(false)
|
||||
hasSingletons(false),
|
||||
inForInit(false)
|
||||
{
|
||||
memset(&prolog, 0, sizeof prolog);
|
||||
memset(&main, 0, sizeof main);
|
||||
@ -1220,7 +1221,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* Don't generate upvars on the left side of a for loop. See
|
||||
* bug 470758.
|
||||
*/
|
||||
if (bce->sc->inForInit)
|
||||
if (bce->inForInit)
|
||||
return JS_TRUE;
|
||||
|
||||
JS_ASSERT(caller->isScriptFrame());
|
||||
@ -1653,11 +1654,11 @@ EmitXMLName(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||
JS_ASSERT(op == JSOP_XMLNAME || op == JSOP_CALLXMLNAME);
|
||||
|
||||
ParseNode *pn2 = pn->pn_kid;
|
||||
bool oldInForInit = bce->sc->inForInit;
|
||||
bce->sc->inForInit = false;
|
||||
bool oldInForInit = bce->inForInit;
|
||||
bce->inForInit = false;
|
||||
if (!EmitTree(cx, bce, pn2))
|
||||
return false;
|
||||
bce->sc->inForInit = oldInForInit;
|
||||
bce->inForInit = oldInForInit;
|
||||
if (NewSrcNote2(cx, bce, SRC_PCBASE, bce->offset() - pn2->pn_offset) < 0)
|
||||
return false;
|
||||
|
||||
@ -3346,11 +3347,11 @@ EmitVariables(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
bool oldInForInit = bce->sc->inForInit;
|
||||
bce->sc->inForInit = false;
|
||||
bool oldInForInit = bce->inForInit;
|
||||
bce->inForInit = false;
|
||||
if (!EmitTree(cx, bce, pn3))
|
||||
return JS_FALSE;
|
||||
bce->sc->inForInit = oldInForInit;
|
||||
bce->inForInit = oldInForInit;
|
||||
} else if (letNotes) {
|
||||
/* JSOP_ENTERLETx expects at least 1 slot to have been pushed. */
|
||||
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
|
||||
@ -4499,10 +4500,10 @@ EmitForIn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
if (pn1) {
|
||||
ParseNode *decl = letDecl ? pn1->pn_expr : pn1;
|
||||
JS_ASSERT(decl->isKind(PNK_VAR) || decl->isKind(PNK_LET));
|
||||
bce->sc->inForInit = true;
|
||||
bce->inForInit = true;
|
||||
if (!EmitVariables(cx, bce, decl, DefineVars))
|
||||
return false;
|
||||
bce->sc->inForInit = false;
|
||||
bce->inForInit = false;
|
||||
}
|
||||
|
||||
/* Compile the object expression to the right of 'in'. */
|
||||
@ -4642,7 +4643,7 @@ EmitNormalFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
/* No initializer: emit an annotated nop for the decompiler. */
|
||||
op = JSOP_NOP;
|
||||
} else {
|
||||
bce->sc->inForInit = true;
|
||||
bce->inForInit = true;
|
||||
#if JS_HAS_DESTRUCTURING
|
||||
if (pn3->isKind(PNK_ASSIGN)) {
|
||||
JS_ASSERT(pn3->isOp(JSOP_NOP));
|
||||
@ -4665,7 +4666,7 @@ EmitNormalFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
op = JSOP_NOP;
|
||||
}
|
||||
}
|
||||
bce->sc->inForInit = false;
|
||||
bce->inForInit = false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5327,13 +5328,13 @@ EmitCallOrNew(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
* JSOP_NEW bytecode with a two-byte immediate telling how many args
|
||||
* were pushed on the operand stack.
|
||||
*/
|
||||
bool oldInForInit = bce->sc->inForInit;
|
||||
bce->sc->inForInit = false;
|
||||
bool oldInForInit = bce->inForInit;
|
||||
bce->inForInit = false;
|
||||
for (ParseNode *pn3 = pn2->pn_next; pn3; pn3 = pn3->pn_next) {
|
||||
if (!EmitTree(cx, bce, pn3))
|
||||
return false;
|
||||
}
|
||||
bce->sc->inForInit = oldInForInit;
|
||||
bce->inForInit = oldInForInit;
|
||||
if (NewSrcNote2(cx, bce, SRC_PCBASE, bce->offset() - off) < 0)
|
||||
return false;
|
||||
|
||||
@ -5813,12 +5814,12 @@ EmitUnary(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
if (op == JSOP_TYPEOF && !pn2->isKind(PNK_NAME))
|
||||
op = JSOP_TYPEOFEXPR;
|
||||
|
||||
bool oldInForInit = bce->sc->inForInit;
|
||||
bce->sc->inForInit = false;
|
||||
bool oldInForInit = bce->inForInit;
|
||||
bce->inForInit = false;
|
||||
if (!EmitTree(cx, bce, pn2))
|
||||
return false;
|
||||
|
||||
bce->sc->inForInit = oldInForInit;
|
||||
bce->inForInit = oldInForInit;
|
||||
return Emit1(cx, bce, op) >= 0;
|
||||
}
|
||||
|
||||
@ -6220,8 +6221,8 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* possibly including a let (a = b) ... expression. We must clear
|
||||
* inForInit to avoid mis-compiling such beasts.
|
||||
*/
|
||||
bool oldInForInit = bce->sc->inForInit;
|
||||
bce->sc->inForInit = false;
|
||||
bool oldInForInit = bce->inForInit;
|
||||
bce->inForInit = false;
|
||||
#endif
|
||||
|
||||
/* Binary operators that evaluate both operands unconditionally. */
|
||||
@ -6230,7 +6231,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
if (!EmitTree(cx, bce, pn->pn_right))
|
||||
return JS_FALSE;
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
bce->sc->inForInit = oldInForInit;
|
||||
bce->inForInit = oldInForInit;
|
||||
#endif
|
||||
if (Emit1(cx, bce, pn->getOp()) < 0)
|
||||
return JS_FALSE;
|
||||
@ -6245,11 +6246,11 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
} else {
|
||||
JSOp op = pn->getOp();
|
||||
JS_ASSERT(op == JSOP_BINDXMLNAME || op == JSOP_SETXMLNAME);
|
||||
bool oldInForInit = bce->sc->inForInit;
|
||||
bce->sc->inForInit = false;
|
||||
bool oldInForInit = bce->inForInit;
|
||||
bce->inForInit = false;
|
||||
if (!EmitTree(cx, bce, pn->pn_kid))
|
||||
return false;
|
||||
bce->sc->inForInit = oldInForInit;
|
||||
bce->inForInit = oldInForInit;
|
||||
if (Emit1(cx, bce, op) < 0)
|
||||
return false;
|
||||
}
|
||||
|
@ -127,6 +127,8 @@ struct BytecodeEmitter
|
||||
|
||||
bool hasSingletons:1; /* script contains singleton initializer JSOP_OBJECT */
|
||||
|
||||
bool inForInit:1; /* emitting init expr of for; exclude 'in' */
|
||||
|
||||
BytecodeEmitter(Parser *parser, SharedContext *sc, unsigned lineno,
|
||||
bool noScriptRval, bool needScriptGlobal);
|
||||
bool init();
|
||||
|
@ -3151,7 +3151,7 @@ Parser::forStatement()
|
||||
* expressions involving an 'in' operator are illegal in the init
|
||||
* clause of an ordinary for loop.
|
||||
*/
|
||||
tc->sc->inForInit = true;
|
||||
tc->inForInit = true;
|
||||
if (tt == TOK_VAR || tt == TOK_CONST) {
|
||||
forDecl = true;
|
||||
tokenStream.consumeKnownToken(tt);
|
||||
@ -3174,7 +3174,7 @@ Parser::forStatement()
|
||||
else {
|
||||
pn1 = expr();
|
||||
}
|
||||
tc->sc->inForInit = false;
|
||||
tc->inForInit = false;
|
||||
if (!pn1)
|
||||
return NULL;
|
||||
}
|
||||
@ -3192,7 +3192,7 @@ Parser::forStatement()
|
||||
* We can be sure that it's a for/in loop if there's still an 'in'
|
||||
* keyword here, even if JavaScript recognizes 'in' as an operator,
|
||||
* as we've excluded 'in' from being parsed in RelExpr by setting
|
||||
* tc->sc->inForInit.
|
||||
* tc->inForInit.
|
||||
*/
|
||||
ParseNode *forHead; /* initialized by both branches. */
|
||||
StmtInfo letStmt(context); /* used if blockObj != NULL. */
|
||||
@ -4255,7 +4255,7 @@ Parser::variables(ParseNodeKind kind, StaticBlockObject *blockObj, VarContext va
|
||||
if (!CheckDestructuring(context, &data, pn2, this))
|
||||
return NULL;
|
||||
bool ignored;
|
||||
if (tc->sc->inForInit && matchInOrOf(&ignored)) {
|
||||
if (tc->inForInit && matchInOrOf(&ignored)) {
|
||||
tokenStream.ungetToken();
|
||||
pn->append(pn2);
|
||||
continue;
|
||||
@ -4462,8 +4462,8 @@ BEGIN_EXPR_PARSER(relExpr1)
|
||||
* Uses of the in operator in shiftExprs are always unambiguous,
|
||||
* so unset the flag that prohibits recognizing it.
|
||||
*/
|
||||
bool oldInForInit = tc->sc->inForInit;
|
||||
tc->sc->inForInit = false;
|
||||
bool oldInForInit = tc->inForInit;
|
||||
tc->inForInit = false;
|
||||
|
||||
ParseNode *pn = shiftExpr1i();
|
||||
while (pn &&
|
||||
@ -4479,7 +4479,7 @@ BEGIN_EXPR_PARSER(relExpr1)
|
||||
pn = ParseNode::newBinaryOrAppend(kind, op, pn, shiftExpr1n(), this);
|
||||
}
|
||||
/* Restore previous state of inForInit flag. */
|
||||
tc->sc->inForInit |= oldInForInit;
|
||||
tc->inForInit |= oldInForInit;
|
||||
|
||||
return pn;
|
||||
}
|
||||
@ -4573,10 +4573,10 @@ Parser::condExpr1()
|
||||
* where it's unambiguous, even if we might be parsing the init of a
|
||||
* for statement.
|
||||
*/
|
||||
bool oldInForInit = tc->sc->inForInit;
|
||||
tc->sc->inForInit = false;
|
||||
bool oldInForInit = tc->inForInit;
|
||||
tc->inForInit = false;
|
||||
ParseNode *thenExpr = assignExpr();
|
||||
tc->sc->inForInit = oldInForInit;
|
||||
tc->inForInit = oldInForInit;
|
||||
if (!thenExpr)
|
||||
return NULL;
|
||||
|
||||
@ -5874,10 +5874,10 @@ Parser::bracketedExpr()
|
||||
* where it's unambiguous, even if we might be parsing the init of a
|
||||
* for statement.
|
||||
*/
|
||||
bool oldInForInit = tc->sc->inForInit;
|
||||
tc->sc->inForInit = false;
|
||||
bool oldInForInit = tc->inForInit;
|
||||
tc->inForInit = false;
|
||||
ParseNode *pn = expr();
|
||||
tc->sc->inForInit = oldInForInit;
|
||||
tc->inForInit = oldInForInit;
|
||||
return pn;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,6 @@ SharedContext::SharedContext(JSContext *cx, JSObject *scopeChain, JSFunction *fu
|
||||
staticLevel(0),
|
||||
bindings(cx),
|
||||
bindingsRoot(cx, &bindings),
|
||||
inForInit(false),
|
||||
cxFlags(cx)
|
||||
{
|
||||
JS_ASSERT((fun && !scopeChain_) || (!fun && !funbox));
|
||||
@ -78,6 +77,7 @@ TreeContext::TreeContext(Parser *prs, SharedContext *sc)
|
||||
funcStmts(NULL),
|
||||
hasReturnExpr(false),
|
||||
hasReturnVoid(false),
|
||||
inForInit(false),
|
||||
inDeclDestructuring(false)
|
||||
{
|
||||
prs->tc = this;
|
||||
|
@ -156,8 +156,6 @@ struct SharedContext {
|
||||
arguments if we're compiling a function */
|
||||
Bindings::AutoRooter bindingsRoot; /* root for stack allocated bindings. */
|
||||
|
||||
bool inForInit:1; /* parsing/emitting init expr of for; exclude 'in' */
|
||||
|
||||
ContextFlags cxFlags;
|
||||
|
||||
// If it's function code, fun must be non-NULL and scopeChain must be NULL.
|
||||
@ -256,6 +254,8 @@ struct TreeContext { /* tree context for semantic checks */
|
||||
bool hasReturnExpr:1; /* function has 'return <expr>;' */
|
||||
bool hasReturnVoid:1; /* function has 'return;' */
|
||||
|
||||
bool inForInit:1; /* parsing init expr of for; exclude 'in' */
|
||||
|
||||
// Set when parsing a declaration-like destructuring pattern. This flag
|
||||
// causes PrimaryExpr to create PN_NAME parse nodes for variable references
|
||||
// which are not hooked into any definition's use chain, added to any tree
|
||||
|
Loading…
Reference in New Issue
Block a user