зеркало из https://github.com/mozilla/gecko-dev.git
Bug 753249 (part 2) - Remove TCF_IN_FOR_INIT from TreeContextFlags. r=luke.
--HG-- extra : rebase_source : f70060e47de0130c558c798a572d83c9184f82c5
This commit is contained in:
Родитель
48cdc0227e
Коммит
1c5be94e4d
|
@ -1252,7 +1252,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||||
* Don't generate upvars on the left side of a for loop. See
|
* Don't generate upvars on the left side of a for loop. See
|
||||||
* bug 470758.
|
* bug 470758.
|
||||||
*/
|
*/
|
||||||
if (bce->sc->flags & TCF_IN_FOR_INIT)
|
if (bce->sc->inForInit)
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
|
|
||||||
JS_ASSERT(caller->isScriptFrame());
|
JS_ASSERT(caller->isScriptFrame());
|
||||||
|
@ -1682,11 +1682,11 @@ EmitXMLName(JSContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
|
||||||
JS_ASSERT(op == JSOP_XMLNAME || op == JSOP_CALLXMLNAME);
|
JS_ASSERT(op == JSOP_XMLNAME || op == JSOP_CALLXMLNAME);
|
||||||
|
|
||||||
ParseNode *pn2 = pn->pn_kid;
|
ParseNode *pn2 = pn->pn_kid;
|
||||||
unsigned oldflags = bce->sc->flags;
|
bool oldInForInit = bce->sc->inForInit;
|
||||||
bce->sc->flags &= ~TCF_IN_FOR_INIT;
|
bce->sc->inForInit = false;
|
||||||
if (!EmitTree(cx, bce, pn2))
|
if (!EmitTree(cx, bce, pn2))
|
||||||
return false;
|
return false;
|
||||||
bce->sc->flags |= oldflags & TCF_IN_FOR_INIT;
|
bce->sc->inForInit = oldInForInit;
|
||||||
if (NewSrcNote2(cx, bce, SRC_PCBASE, bce->offset() - pn2->pn_offset) < 0)
|
if (NewSrcNote2(cx, bce, SRC_PCBASE, bce->offset() - pn2->pn_offset) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -3375,11 +3375,11 @@ EmitVariables(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmitOption
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned oldflags = bce->sc->flags;
|
bool oldInForInit = bce->sc->inForInit;
|
||||||
bce->sc->flags &= ~TCF_IN_FOR_INIT;
|
bce->sc->inForInit = false;
|
||||||
if (!EmitTree(cx, bce, pn3))
|
if (!EmitTree(cx, bce, pn3))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
bce->sc->flags |= oldflags & TCF_IN_FOR_INIT;
|
bce->sc->inForInit = oldInForInit;
|
||||||
} else if (letNotes) {
|
} else if (letNotes) {
|
||||||
/* JSOP_ENTERLETx expects at least 1 slot to have been pushed. */
|
/* JSOP_ENTERLETx expects at least 1 slot to have been pushed. */
|
||||||
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
|
if (Emit1(cx, bce, JSOP_UNDEFINED) < 0)
|
||||||
|
@ -4526,10 +4526,10 @@ EmitForIn(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||||
if (pn1) {
|
if (pn1) {
|
||||||
ParseNode *decl = letDecl ? pn1->pn_expr : pn1;
|
ParseNode *decl = letDecl ? pn1->pn_expr : pn1;
|
||||||
JS_ASSERT(decl->isKind(PNK_VAR) || decl->isKind(PNK_LET));
|
JS_ASSERT(decl->isKind(PNK_VAR) || decl->isKind(PNK_LET));
|
||||||
bce->sc->flags |= TCF_IN_FOR_INIT;
|
bce->sc->inForInit = true;
|
||||||
if (!EmitVariables(cx, bce, decl, DefineVars))
|
if (!EmitVariables(cx, bce, decl, DefineVars))
|
||||||
return false;
|
return false;
|
||||||
bce->sc->flags &= ~TCF_IN_FOR_INIT;
|
bce->sc->inForInit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compile the object expression to the right of 'in'. */
|
/* Compile the object expression to the right of 'in'. */
|
||||||
|
@ -4669,7 +4669,7 @@ EmitNormalFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||||
/* No initializer: emit an annotated nop for the decompiler. */
|
/* No initializer: emit an annotated nop for the decompiler. */
|
||||||
op = JSOP_NOP;
|
op = JSOP_NOP;
|
||||||
} else {
|
} else {
|
||||||
bce->sc->flags |= TCF_IN_FOR_INIT;
|
bce->sc->inForInit = true;
|
||||||
#if JS_HAS_DESTRUCTURING
|
#if JS_HAS_DESTRUCTURING
|
||||||
if (pn3->isKind(PNK_ASSIGN)) {
|
if (pn3->isKind(PNK_ASSIGN)) {
|
||||||
JS_ASSERT(pn3->isOp(JSOP_NOP));
|
JS_ASSERT(pn3->isOp(JSOP_NOP));
|
||||||
|
@ -4692,7 +4692,7 @@ EmitNormalFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||||
op = JSOP_NOP;
|
op = JSOP_NOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bce->sc->flags &= ~TCF_IN_FOR_INIT;
|
bce->sc->inForInit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5394,13 +5394,13 @@ EmitCallOrNew(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||||
* JSOP_NEW bytecode with a two-byte immediate telling how many args
|
* JSOP_NEW bytecode with a two-byte immediate telling how many args
|
||||||
* were pushed on the operand stack.
|
* were pushed on the operand stack.
|
||||||
*/
|
*/
|
||||||
unsigned oldflags = bce->sc->flags;
|
bool oldInForInit = bce->sc->inForInit;
|
||||||
bce->sc->flags &= ~TCF_IN_FOR_INIT;
|
bce->sc->inForInit = false;
|
||||||
for (ParseNode *pn3 = pn2->pn_next; pn3; pn3 = pn3->pn_next) {
|
for (ParseNode *pn3 = pn2->pn_next; pn3; pn3 = pn3->pn_next) {
|
||||||
if (!EmitTree(cx, bce, pn3))
|
if (!EmitTree(cx, bce, pn3))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bce->sc->flags |= oldflags & TCF_IN_FOR_INIT;
|
bce->sc->inForInit = oldInForInit;
|
||||||
if (NewSrcNote2(cx, bce, SRC_PCBASE, bce->offset() - off) < 0)
|
if (NewSrcNote2(cx, bce, SRC_PCBASE, bce->offset() - off) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -5880,12 +5880,12 @@ EmitUnary(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||||
if (op == JSOP_TYPEOF && !pn2->isKind(PNK_NAME))
|
if (op == JSOP_TYPEOF && !pn2->isKind(PNK_NAME))
|
||||||
op = JSOP_TYPEOFEXPR;
|
op = JSOP_TYPEOFEXPR;
|
||||||
|
|
||||||
unsigned oldflags = bce->sc->flags;
|
bool oldInForInit = bce->sc->inForInit;
|
||||||
bce->sc->flags &= ~TCF_IN_FOR_INIT;
|
bce->sc->inForInit = false;
|
||||||
if (!EmitTree(cx, bce, pn2))
|
if (!EmitTree(cx, bce, pn2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bce->sc->flags |= oldflags & TCF_IN_FOR_INIT;
|
bce->sc->inForInit = oldInForInit;
|
||||||
return Emit1(cx, bce, op) >= 0;
|
return Emit1(cx, bce, op) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6116,7 +6116,6 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if JS_HAS_XML_SUPPORT
|
#if JS_HAS_XML_SUPPORT
|
||||||
unsigned oldflags;
|
|
||||||
|
|
||||||
case PNK_DBLCOLON:
|
case PNK_DBLCOLON:
|
||||||
JS_ASSERT(pn->getOp() != JSOP_XMLNAME);
|
JS_ASSERT(pn->getOp() != JSOP_XMLNAME);
|
||||||
|
@ -6131,10 +6130,10 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||||
/*
|
/*
|
||||||
* Binary :: has a right operand that brackets arbitrary code,
|
* Binary :: has a right operand that brackets arbitrary code,
|
||||||
* possibly including a let (a = b) ... expression. We must clear
|
* possibly including a let (a = b) ... expression. We must clear
|
||||||
* TCF_IN_FOR_INIT to avoid mis-compiling such beasts.
|
* inForInit to avoid mis-compiling such beasts.
|
||||||
*/
|
*/
|
||||||
oldflags = bce->sc->flags;
|
bool oldInForInit = bce->sc->inForInit;
|
||||||
bce->sc->flags &= ~TCF_IN_FOR_INIT;
|
bce->sc->inForInit = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Binary operators that evaluate both operands unconditionally. */
|
/* Binary operators that evaluate both operands unconditionally. */
|
||||||
|
@ -6143,7 +6142,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||||
if (!EmitTree(cx, bce, pn->pn_right))
|
if (!EmitTree(cx, bce, pn->pn_right))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
#if JS_HAS_XML_SUPPORT
|
#if JS_HAS_XML_SUPPORT
|
||||||
bce->sc->flags |= oldflags & TCF_IN_FOR_INIT;
|
bce->sc->inForInit = oldInForInit;
|
||||||
#endif
|
#endif
|
||||||
if (Emit1(cx, bce, pn->getOp()) < 0)
|
if (Emit1(cx, bce, pn->getOp()) < 0)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
@ -6158,11 +6157,11 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||||
} else {
|
} else {
|
||||||
JSOp op = pn->getOp();
|
JSOp op = pn->getOp();
|
||||||
JS_ASSERT(op == JSOP_BINDXMLNAME || op == JSOP_SETXMLNAME);
|
JS_ASSERT(op == JSOP_BINDXMLNAME || op == JSOP_SETXMLNAME);
|
||||||
unsigned oldflags = bce->sc->flags;
|
bool oldInForInit = bce->sc->inForInit;
|
||||||
bce->sc->flags &= ~TCF_IN_FOR_INIT;
|
bce->sc->inForInit = false;
|
||||||
if (!EmitTree(cx, bce, pn->pn_kid))
|
if (!EmitTree(cx, bce, pn->pn_kid))
|
||||||
return false;
|
return false;
|
||||||
bce->sc->flags |= oldflags & TCF_IN_FOR_INIT;
|
bce->sc->inForInit = oldInForInit;
|
||||||
if (Emit1(cx, bce, op) < 0)
|
if (Emit1(cx, bce, op) < 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3104,7 +3104,7 @@ Parser::forStatement()
|
||||||
/*
|
/*
|
||||||
* Set pn1 to a var list or an initializing expression.
|
* Set pn1 to a var list or an initializing expression.
|
||||||
*
|
*
|
||||||
* Set the TCF_IN_FOR_INIT flag during parsing of the first clause
|
* Set the inForInit flag during parsing of the first clause
|
||||||
* of the for statement. This flag will be used by the RelExpr
|
* of the for statement. This flag will be used by the RelExpr
|
||||||
* production; if it is set, then the 'in' keyword will not be
|
* production; if it is set, then the 'in' keyword will not be
|
||||||
* recognized as an operator, leaving it available to be parsed as
|
* recognized as an operator, leaving it available to be parsed as
|
||||||
|
@ -3114,7 +3114,7 @@ Parser::forStatement()
|
||||||
* expressions involving an 'in' operator are illegal in the init
|
* expressions involving an 'in' operator are illegal in the init
|
||||||
* clause of an ordinary for loop.
|
* clause of an ordinary for loop.
|
||||||
*/
|
*/
|
||||||
tc->sc->flags |= TCF_IN_FOR_INIT;
|
tc->sc->inForInit = true;
|
||||||
if (tt == TOK_VAR || tt == TOK_CONST) {
|
if (tt == TOK_VAR || tt == TOK_CONST) {
|
||||||
forDecl = true;
|
forDecl = true;
|
||||||
tokenStream.consumeKnownToken(tt);
|
tokenStream.consumeKnownToken(tt);
|
||||||
|
@ -3137,7 +3137,7 @@ Parser::forStatement()
|
||||||
else {
|
else {
|
||||||
pn1 = expr();
|
pn1 = expr();
|
||||||
}
|
}
|
||||||
tc->sc->flags &= ~TCF_IN_FOR_INIT;
|
tc->sc->inForInit = false;
|
||||||
if (!pn1)
|
if (!pn1)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -3155,7 +3155,7 @@ Parser::forStatement()
|
||||||
* We can be sure that it's a for/in loop if there's still an 'in'
|
* 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,
|
* keyword here, even if JavaScript recognizes 'in' as an operator,
|
||||||
* as we've excluded 'in' from being parsed in RelExpr by setting
|
* as we've excluded 'in' from being parsed in RelExpr by setting
|
||||||
* the TCF_IN_FOR_INIT flag in our TreeContext.
|
* tc->sc->inForInit.
|
||||||
*/
|
*/
|
||||||
ParseNode *forHead; /* initialized by both branches. */
|
ParseNode *forHead; /* initialized by both branches. */
|
||||||
StmtInfo letStmt(context); /* used if blockObj != NULL. */
|
StmtInfo letStmt(context); /* used if blockObj != NULL. */
|
||||||
|
@ -4217,7 +4217,7 @@ Parser::variables(ParseNodeKind kind, StaticBlockObject *blockObj, VarContext va
|
||||||
if (!CheckDestructuring(context, &data, pn2, this))
|
if (!CheckDestructuring(context, &data, pn2, this))
|
||||||
return NULL;
|
return NULL;
|
||||||
bool ignored;
|
bool ignored;
|
||||||
if ((tc->sc->flags & TCF_IN_FOR_INIT) && matchInOrOf(&ignored)) {
|
if (tc->sc->inForInit && matchInOrOf(&ignored)) {
|
||||||
tokenStream.ungetToken();
|
tokenStream.ungetToken();
|
||||||
pn->append(pn2);
|
pn->append(pn2);
|
||||||
continue;
|
continue;
|
||||||
|
@ -4420,13 +4420,12 @@ RelationalTokenToParseNodeKind(const Token &token)
|
||||||
|
|
||||||
BEGIN_EXPR_PARSER(relExpr1)
|
BEGIN_EXPR_PARSER(relExpr1)
|
||||||
{
|
{
|
||||||
unsigned inForInitFlag = tc->sc->flags & TCF_IN_FOR_INIT;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Uses of the in operator in shiftExprs are always unambiguous,
|
* Uses of the in operator in shiftExprs are always unambiguous,
|
||||||
* so unset the flag that prohibits recognizing it.
|
* so unset the flag that prohibits recognizing it.
|
||||||
*/
|
*/
|
||||||
tc->sc->flags &= ~TCF_IN_FOR_INIT;
|
bool oldInForInit = tc->sc->inForInit;
|
||||||
|
tc->sc->inForInit = false;
|
||||||
|
|
||||||
ParseNode *pn = shiftExpr1i();
|
ParseNode *pn = shiftExpr1i();
|
||||||
while (pn &&
|
while (pn &&
|
||||||
|
@ -4435,14 +4434,14 @@ BEGIN_EXPR_PARSER(relExpr1)
|
||||||
* Recognize the 'in' token as an operator only if we're not
|
* Recognize the 'in' token as an operator only if we're not
|
||||||
* currently in the init expr of a for loop.
|
* currently in the init expr of a for loop.
|
||||||
*/
|
*/
|
||||||
(inForInitFlag == 0 && tokenStream.isCurrentTokenType(TOK_IN)) ||
|
(oldInForInit == 0 && tokenStream.isCurrentTokenType(TOK_IN)) ||
|
||||||
tokenStream.isCurrentTokenType(TOK_INSTANCEOF))) {
|
tokenStream.isCurrentTokenType(TOK_INSTANCEOF))) {
|
||||||
ParseNodeKind kind = RelationalTokenToParseNodeKind(tokenStream.currentToken());
|
ParseNodeKind kind = RelationalTokenToParseNodeKind(tokenStream.currentToken());
|
||||||
JSOp op = tokenStream.currentToken().t_op;
|
JSOp op = tokenStream.currentToken().t_op;
|
||||||
pn = ParseNode::newBinaryOrAppend(kind, op, pn, shiftExpr1n(), this);
|
pn = ParseNode::newBinaryOrAppend(kind, op, pn, shiftExpr1n(), this);
|
||||||
}
|
}
|
||||||
/* Restore previous state of inForInit flag. */
|
/* Restore previous state of inForInit flag. */
|
||||||
tc->sc->flags |= inForInitFlag;
|
tc->sc->inForInit |= oldInForInit;
|
||||||
|
|
||||||
return pn;
|
return pn;
|
||||||
}
|
}
|
||||||
|
@ -4536,10 +4535,12 @@ Parser::condExpr1()
|
||||||
* where it's unambiguous, even if we might be parsing the init of a
|
* where it's unambiguous, even if we might be parsing the init of a
|
||||||
* for statement.
|
* for statement.
|
||||||
*/
|
*/
|
||||||
unsigned oldflags = tc->sc->flags;
|
uint32_t oldflags = tc->sc->flags;
|
||||||
tc->sc->flags &= ~TCF_IN_FOR_INIT;
|
bool oldInForInit = tc->sc->inForInit;
|
||||||
|
tc->sc->inForInit = false;
|
||||||
ParseNode *thenExpr = assignExpr();
|
ParseNode *thenExpr = assignExpr();
|
||||||
tc->sc->flags = oldflags | (tc->sc->flags & TCF_FUN_FLAGS);
|
tc->sc->flags = oldflags | (tc->sc->flags & TCF_FUN_FLAGS);
|
||||||
|
tc->sc->inForInit = oldInForInit;
|
||||||
if (!thenExpr)
|
if (!thenExpr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -5803,18 +5804,17 @@ Parser::memberExpr(JSBool allowCallSyntax)
|
||||||
ParseNode *
|
ParseNode *
|
||||||
Parser::bracketedExpr()
|
Parser::bracketedExpr()
|
||||||
{
|
{
|
||||||
unsigned oldflags;
|
|
||||||
ParseNode *pn;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Always accept the 'in' operator in a parenthesized expression,
|
* Always accept the 'in' operator in a parenthesized expression,
|
||||||
* where it's unambiguous, even if we might be parsing the init of a
|
* where it's unambiguous, even if we might be parsing the init of a
|
||||||
* for statement.
|
* for statement.
|
||||||
*/
|
*/
|
||||||
oldflags = tc->sc->flags;
|
uint32_t oldflags = tc->sc->flags;
|
||||||
tc->sc->flags &= ~TCF_IN_FOR_INIT;
|
bool oldInForInit = tc->sc->inForInit;
|
||||||
pn = expr();
|
tc->sc->inForInit = false;
|
||||||
|
ParseNode *pn = expr();
|
||||||
tc->sc->flags = oldflags | (tc->sc->flags & TCF_FUN_FLAGS);
|
tc->sc->flags = oldflags | (tc->sc->flags & TCF_FUN_FLAGS);
|
||||||
|
tc->sc->inForInit = oldInForInit;
|
||||||
return pn;
|
return pn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,8 @@ SharedContext::SharedContext(JSContext *cx, bool inFunction)
|
||||||
functionList(NULL),
|
functionList(NULL),
|
||||||
bindings(cx),
|
bindings(cx),
|
||||||
bindingsRoot(cx, &bindings),
|
bindingsRoot(cx, &bindings),
|
||||||
inFunction(inFunction)
|
inFunction(inFunction),
|
||||||
|
inForInit(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,24 +58,21 @@ namespace js {
|
||||||
|
|
||||||
JS_ENUM_HEADER(TreeContextFlags, uint32_t)
|
JS_ENUM_HEADER(TreeContextFlags, uint32_t)
|
||||||
{
|
{
|
||||||
// parsing init expr of for; exclude 'in'
|
|
||||||
TCF_IN_FOR_INIT = 0x1,
|
|
||||||
|
|
||||||
// function needs Call object per call
|
// function needs Call object per call
|
||||||
TCF_FUN_HEAVYWEIGHT = 0x2,
|
TCF_FUN_HEAVYWEIGHT = 0x1,
|
||||||
|
|
||||||
// parsed yield statement in function
|
// parsed yield statement in function
|
||||||
TCF_FUN_IS_GENERATOR = 0x4,
|
TCF_FUN_IS_GENERATOR = 0x2,
|
||||||
|
|
||||||
// flag lambda from generator expression
|
// flag lambda from generator expression
|
||||||
TCF_GENEXP_LAMBDA = 0x8,
|
TCF_GENEXP_LAMBDA = 0x4,
|
||||||
|
|
||||||
// This function/global/eval code body contained a Use Strict Directive.
|
// This function/global/eval code body contained a Use Strict Directive.
|
||||||
// Treat certain strict warnings as errors, and forbid the use of 'with'.
|
// Treat certain strict warnings as errors, and forbid the use of 'with'.
|
||||||
// See also TSF_STRICT_MODE_CODE, JSScript::strictModeCode, and
|
// See also TSF_STRICT_MODE_CODE, JSScript::strictModeCode, and
|
||||||
// JSREPORT_STRICT_ERROR.
|
// JSREPORT_STRICT_ERROR.
|
||||||
//
|
//
|
||||||
TCF_STRICT_MODE_CODE = 0x10,
|
TCF_STRICT_MODE_CODE = 0x8,
|
||||||
|
|
||||||
// The (static) bindings of this script need to support dynamic name
|
// The (static) bindings of this script need to support dynamic name
|
||||||
// read/write access. Here, 'dynamic' means dynamic dictionary lookup on
|
// read/write access. Here, 'dynamic' means dynamic dictionary lookup on
|
||||||
|
@ -97,17 +94,17 @@ JS_ENUM_HEADER(TreeContextFlags, uint32_t)
|
||||||
// taken not to turn off the whole 'arguments' optimization). To answer the
|
// taken not to turn off the whole 'arguments' optimization). To answer the
|
||||||
// more general "is this argument aliased" question, script->needsArgsObj
|
// more general "is this argument aliased" question, script->needsArgsObj
|
||||||
// should be tested (see JSScript::argIsAlised).
|
// should be tested (see JSScript::argIsAlised).
|
||||||
TCF_BINDINGS_ACCESSED_DYNAMICALLY = 0x20,
|
TCF_BINDINGS_ACCESSED_DYNAMICALLY = 0x10,
|
||||||
|
|
||||||
// The function or a function that encloses it may define new local names
|
// The function or a function that encloses it may define new local names
|
||||||
// at runtime through means other than calling eval.
|
// at runtime through means other than calling eval.
|
||||||
TCF_FUN_MIGHT_ALIAS_LOCALS = 0x40,
|
TCF_FUN_MIGHT_ALIAS_LOCALS = 0x20,
|
||||||
|
|
||||||
// The script contains singleton initialiser JSOP_OBJECT.
|
// The script contains singleton initialiser JSOP_OBJECT.
|
||||||
TCF_HAS_SINGLETONS = 0x80,
|
TCF_HAS_SINGLETONS = 0x40,
|
||||||
|
|
||||||
// Some enclosing scope is a with-statement or E4X filter-expression.
|
// Some enclosing scope is a with-statement or E4X filter-expression.
|
||||||
TCF_IN_WITH = 0x100,
|
TCF_IN_WITH = 0x80,
|
||||||
|
|
||||||
// This function does something that can extend the set of bindings in its
|
// This function does something that can extend the set of bindings in its
|
||||||
// call objects --- it does a direct eval in non-strict code, or includes a
|
// call objects --- it does a direct eval in non-strict code, or includes a
|
||||||
|
@ -116,7 +113,7 @@ JS_ENUM_HEADER(TreeContextFlags, uint32_t)
|
||||||
// This flag is *not* inherited by enclosed or enclosing functions; it
|
// This flag is *not* inherited by enclosed or enclosing functions; it
|
||||||
// applies only to the function in whose flags it appears.
|
// applies only to the function in whose flags it appears.
|
||||||
//
|
//
|
||||||
TCF_FUN_EXTENSIBLE_SCOPE = 0x200,
|
TCF_FUN_EXTENSIBLE_SCOPE = 0x100,
|
||||||
|
|
||||||
// Technically, every function has a binding named 'arguments'. Internally,
|
// Technically, every function has a binding named 'arguments'. Internally,
|
||||||
// this binding is only added when 'arguments' is mentioned by the function
|
// this binding is only added when 'arguments' is mentioned by the function
|
||||||
|
@ -139,7 +136,7 @@ JS_ENUM_HEADER(TreeContextFlags, uint32_t)
|
||||||
// have no special semantics: the initial value is unconditionally the
|
// have no special semantics: the initial value is unconditionally the
|
||||||
// actual argument (or undefined if nactual < nformal).
|
// actual argument (or undefined if nactual < nformal).
|
||||||
//
|
//
|
||||||
TCF_ARGUMENTS_HAS_LOCAL_BINDING = 0x400,
|
TCF_ARGUMENTS_HAS_LOCAL_BINDING = 0x200,
|
||||||
|
|
||||||
// In many cases where 'arguments' has a local binding (as described above)
|
// In many cases where 'arguments' has a local binding (as described above)
|
||||||
// we do not need to actually create an arguments object in the function
|
// we do not need to actually create an arguments object in the function
|
||||||
|
@ -150,7 +147,7 @@ JS_ENUM_HEADER(TreeContextFlags, uint32_t)
|
||||||
// be unsound in several cases. The frontend filters out such cases by
|
// be unsound in several cases. The frontend filters out such cases by
|
||||||
// setting this flag which eagerly sets script->needsArgsObj to true.
|
// setting this flag which eagerly sets script->needsArgsObj to true.
|
||||||
//
|
//
|
||||||
TCF_DEFINITELY_NEEDS_ARGS_OBJ = 0x800
|
TCF_DEFINITELY_NEEDS_ARGS_OBJ = 0x400
|
||||||
|
|
||||||
} JS_ENUM_FOOTER(TreeContextFlags);
|
} JS_ENUM_FOOTER(TreeContextFlags);
|
||||||
|
|
||||||
|
@ -198,7 +195,9 @@ struct SharedContext {
|
||||||
arguments if we're compiling a function */
|
arguments if we're compiling a function */
|
||||||
Bindings::StackRoot bindingsRoot; /* root for stack allocated bindings. */
|
Bindings::StackRoot bindingsRoot; /* root for stack allocated bindings. */
|
||||||
|
|
||||||
const bool inFunction; /* parsing/emitting inside function body */
|
const bool inFunction:1; /* parsing/emitting inside function body */
|
||||||
|
|
||||||
|
bool inForInit:1; /* parsing/emitting init expr of for; exclude 'in' */
|
||||||
|
|
||||||
inline SharedContext(JSContext *cx, bool inFunction);
|
inline SharedContext(JSContext *cx, bool inFunction);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче