mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 568593 - Refactor SharedContext; r=jorendorff
This commit is contained in:
parent
f044eb2056
commit
567f771d25
@ -699,12 +699,12 @@ EnclosingStaticScope(BytecodeEmitter *bce)
|
||||
if (bce->blockChain)
|
||||
return bce->blockChain;
|
||||
|
||||
if (!bce->sc->isFunction) {
|
||||
if (!bce->sc->isFunctionBox()) {
|
||||
JS_ASSERT(!bce->parent);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bce->sc->asFunbox()->function();
|
||||
return bce->sc->asFunctionBox()->function();
|
||||
}
|
||||
|
||||
// Push a block scope statement and link blockObj into bce->blockChain.
|
||||
@ -920,7 +920,7 @@ EmitAliasedVarOp(JSContext *cx, JSOp op, ParseNode *pn, BytecodeEmitter *bce)
|
||||
*/
|
||||
for (unsigned i = pn->pn_cookie.level(); i; i--) {
|
||||
skippedScopes += ClonedBlockDepth(bceOfDef);
|
||||
JSFunction *funOfDef = bceOfDef->sc->asFunbox()->function();
|
||||
JSFunction *funOfDef = bceOfDef->sc->asFunctionBox()->function();
|
||||
if (funOfDef->isHeavyweight()) {
|
||||
skippedScopes++;
|
||||
if (funOfDef->isNamedLambda())
|
||||
@ -1082,7 +1082,7 @@ static int
|
||||
AdjustBlockSlot(JSContext *cx, BytecodeEmitter *bce, int slot)
|
||||
{
|
||||
JS_ASSERT((unsigned) slot < bce->maxStackDepth);
|
||||
if (bce->sc->isFunction) {
|
||||
if (bce->sc->isFunctionBox()) {
|
||||
slot += bce->script->bindings.numVars();
|
||||
if ((unsigned) slot >= SLOTNO_LIMIT) {
|
||||
bce->reportError(NULL, JSMSG_TOO_MANY_LOCALS);
|
||||
@ -1180,7 +1180,7 @@ TryConvertToGname(BytecodeEmitter *bce, ParseNode *pn, JSOp *op)
|
||||
}
|
||||
if (bce->script->compileAndGo &&
|
||||
bce->hasGlobalScope &&
|
||||
!(bce->sc->isFunction && bce->sc->asFunbox()->mightAliasLocals()) &&
|
||||
!(bce->sc->isFunctionBox() && bce->sc->asFunctionBox()->mightAliasLocals()) &&
|
||||
!pn->isDeoptimized() &&
|
||||
!bce->sc->strict)
|
||||
{
|
||||
@ -1382,7 +1382,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
if (dn->pn_cookie.level() != bce->script->staticLevel)
|
||||
return true;
|
||||
|
||||
RootedFunction fun(cx, bce->sc->asFunbox()->function());
|
||||
RootedFunction fun(cx, bce->sc->asFunctionBox()->function());
|
||||
JS_ASSERT(fun->isLambda());
|
||||
JS_ASSERT(pn->pn_atom == fun->atom());
|
||||
|
||||
@ -1445,7 +1445,7 @@ BindNameToSlot(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
BytecodeEmitter *bceSkipped = bce;
|
||||
for (unsigned i = 0; i < skip; i++)
|
||||
bceSkipped = bceSkipped->parent;
|
||||
if (!bceSkipped->sc->isFunction)
|
||||
if (!bceSkipped->sc->isFunctionBox())
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1657,7 +1657,7 @@ CheckSideEffects(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool *answe
|
||||
bool
|
||||
BytecodeEmitter::checkSingletonContext()
|
||||
{
|
||||
if (!script->compileAndGo || sc->isFunction)
|
||||
if (!script->compileAndGo || sc->isFunctionBox())
|
||||
return false;
|
||||
for (StmtInfoBCE *stmt = topStmt; stmt; stmt = stmt->down) {
|
||||
if (stmt->isLoop())
|
||||
@ -1673,11 +1673,11 @@ BytecodeEmitter::needsImplicitThis()
|
||||
if (!script->compileAndGo)
|
||||
return true;
|
||||
|
||||
if (sc->isFunction) {
|
||||
if (sc->asFunbox()->inWith)
|
||||
if (sc->isFunctionBox()) {
|
||||
if (sc->asFunctionBox()->inWith)
|
||||
return true;
|
||||
} else {
|
||||
JSObject *scope = sc->asGlobal()->scopeChain();
|
||||
JSObject *scope = sc->asGlobalSharedContext()->scopeChain();
|
||||
while (scope) {
|
||||
if (scope->isWith())
|
||||
return true;
|
||||
@ -2547,7 +2547,7 @@ frontend::EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *bod
|
||||
* execution starts from script->code, so this has no semantic effect.
|
||||
*/
|
||||
|
||||
FunctionBox *funbox = bce->sc->asFunbox();
|
||||
FunctionBox *funbox = bce->sc->asFunctionBox();
|
||||
if (funbox->argumentsHasLocalBinding()) {
|
||||
JS_ASSERT(bce->next() == bce->base()); /* See JSScript::argumentsBytecode. */
|
||||
bce->switchToProlog();
|
||||
@ -2624,7 +2624,7 @@ MaybeEmitVarDecl(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, ParseNode *
|
||||
}
|
||||
|
||||
if (JOF_OPTYPE(pn->getOp()) == JOF_ATOM &&
|
||||
(!bce->sc->isFunction || bce->sc->asFunbox()->function()->isHeavyweight()))
|
||||
(!bce->sc->isFunctionBox() || bce->sc->asFunctionBox()->function()->isHeavyweight()))
|
||||
{
|
||||
bce->switchToProlog();
|
||||
if (!UpdateSourceCoordNotes(cx, bce, pn->pn_pos.begin))
|
||||
@ -4400,7 +4400,7 @@ EmitLexicalScope(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
(stmtInfo.down
|
||||
? stmtInfo.down->type == STMT_BLOCK &&
|
||||
(!stmtInfo.down->down || stmtInfo.down->down->type != STMT_FOR_IN_LOOP)
|
||||
: !bce->sc->isFunction))
|
||||
: !bce->sc->isFunctionBox()))
|
||||
{
|
||||
/* There must be no source note already output for the next op. */
|
||||
JS_ASSERT(bce->noteCount() == 0 ||
|
||||
@ -4793,7 +4793,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* comments in EmitStatementList.
|
||||
*/
|
||||
JS_ASSERT(pn->functionIsHoisted());
|
||||
JS_ASSERT(bce->sc->isFunction);
|
||||
JS_ASSERT(bce->sc->isFunctionBox());
|
||||
return EmitFunctionDefNop(cx, bce, pn->pn_index);
|
||||
}
|
||||
|
||||
@ -4801,7 +4801,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
SharedContext *outersc = bce->sc;
|
||||
FunctionBox *funbox = pn->pn_funbox;
|
||||
|
||||
if (outersc->isFunction && outersc->asFunbox()->mightAliasLocals())
|
||||
if (outersc->isFunctionBox() && outersc->asFunctionBox()->mightAliasLocals())
|
||||
funbox->setMightAliasLocals(); // inherit mightAliasLocals from parent
|
||||
JS_ASSERT_IF(outersc->strict, funbox->strict);
|
||||
|
||||
@ -4854,7 +4854,7 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
* invocation of the emitter and calls to EmitTree for function
|
||||
* definitions can be scheduled before generating the rest of code.
|
||||
*/
|
||||
if (!bce->sc->isFunction) {
|
||||
if (!bce->sc->isFunctionBox()) {
|
||||
JS_ASSERT(pn->pn_cookie.isFree());
|
||||
JS_ASSERT(pn->getOp() == JSOP_NOP);
|
||||
JS_ASSERT(!bce->topStmt);
|
||||
@ -5147,7 +5147,7 @@ EmitStatement(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
*/
|
||||
bool wantval = false;
|
||||
bool useful = false;
|
||||
if (bce->sc->isFunction) {
|
||||
if (bce->sc->isFunctionBox()) {
|
||||
JS_ASSERT(!bce->script->noScriptRval);
|
||||
} else {
|
||||
useful = wantval = !bce->script->noScriptRval;
|
||||
@ -5962,7 +5962,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
|
||||
case PNK_ARGSBODY:
|
||||
{
|
||||
RootedFunction fun(cx, bce->sc->asFunbox()->function());
|
||||
RootedFunction fun(cx, bce->sc->asFunctionBox()->function());
|
||||
ParseNode *pnlast = pn->last();
|
||||
|
||||
// Carefully emit everything in the right order:
|
||||
@ -6000,7 +6000,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
ParseNode *rest = NULL;
|
||||
bool restIsDefn = false;
|
||||
if (fun->hasRest()) {
|
||||
JS_ASSERT(!bce->sc->asFunbox()->argumentsHasLocalBinding());
|
||||
JS_ASSERT(!bce->sc->asFunctionBox()->argumentsHasLocalBinding());
|
||||
// Defaults with a rest parameter need special handling. The
|
||||
// rest parameter needs to be undefined while defaults are being
|
||||
// processed. To do this, we create the rest argument and let it
|
||||
@ -6045,7 +6045,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
return false;
|
||||
if (pn2->pn_next == pnlast && fun->hasRest() && !fun->hasDefaults()) {
|
||||
// Fill rest parameter. We handled the case with defaults above.
|
||||
JS_ASSERT(!bce->sc->asFunbox()->argumentsHasLocalBinding());
|
||||
JS_ASSERT(!bce->sc->asFunctionBox()->argumentsHasLocalBinding());
|
||||
bce->switchToProlog();
|
||||
if (Emit1(cx, bce, JSOP_REST) < 0)
|
||||
return false;
|
||||
@ -6115,7 +6115,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
case PNK_YIELD:
|
||||
JS_ASSERT(bce->sc->isFunction);
|
||||
JS_ASSERT(bce->sc->isFunctionBox());
|
||||
if (pn->pn_kid) {
|
||||
if (!EmitTree(cx, bce, pn->pn_kid))
|
||||
return false;
|
||||
|
@ -805,6 +805,14 @@ ObjectBox::ObjectBox(JSFunction *function, ObjectBox* traceLink)
|
||||
emitLink(NULL)
|
||||
{
|
||||
JS_ASSERT(object->isFunction());
|
||||
JS_ASSERT(asFunctionBox()->function() == function);
|
||||
}
|
||||
|
||||
FunctionBox *
|
||||
ObjectBox::asFunctionBox()
|
||||
{
|
||||
JS_ASSERT(isFunctionBox());
|
||||
return static_cast<FunctionBox *>(this);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1503,7 +1503,7 @@ class ObjectBox {
|
||||
|
||||
ObjectBox(JSObject *object, ObjectBox *traceLink);
|
||||
bool isFunctionBox() { return object->isFunction(); }
|
||||
FunctionBox *asFunctionBox() { JS_ASSERT(isFunctionBox()); return (FunctionBox *)(this); }
|
||||
FunctionBox *asFunctionBox();
|
||||
void trace(JSTracer *trc);
|
||||
|
||||
protected:
|
||||
|
@ -154,7 +154,7 @@ ParseContext::define(JSContext *cx, PropertyName *name, ParseNode *pn, Definitio
|
||||
Definition *dn = (Definition *)pn;
|
||||
switch (kind) {
|
||||
case Definition::ARG:
|
||||
JS_ASSERT(sc->isFunction);
|
||||
JS_ASSERT(sc->isFunctionBox());
|
||||
dn->setOp(JSOP_GETARG);
|
||||
dn->pn_dflags |= PND_BOUND;
|
||||
if (!dn->pn_cookie.set(cx, staticLevel, args_.length()))
|
||||
@ -169,7 +169,7 @@ ParseContext::define(JSContext *cx, PropertyName *name, ParseNode *pn, Definitio
|
||||
|
||||
case Definition::CONST:
|
||||
case Definition::VAR:
|
||||
if (sc->isFunction) {
|
||||
if (sc->isFunctionBox()) {
|
||||
dn->setOp(JSOP_GETLOCAL);
|
||||
dn->pn_dflags |= PND_BOUND;
|
||||
if (!dn->pn_cookie.set(cx, staticLevel, vars_.length()))
|
||||
@ -216,7 +216,7 @@ ParseContext::updateDecl(JSAtom *atom, ParseNode *pn)
|
||||
Definition *newDecl = (Definition *)pn;
|
||||
decls_.updateFirst(atom, newDecl);
|
||||
|
||||
if (!sc->isFunction) {
|
||||
if (!sc->isFunctionBox()) {
|
||||
JS_ASSERT(newDecl->isFreeVar());
|
||||
return;
|
||||
}
|
||||
@ -285,7 +285,7 @@ AppendPackedBindings(const ParseContext *pc, const DeclVector &vec, Binding *dst
|
||||
bool
|
||||
ParseContext::generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*> bindings) const
|
||||
{
|
||||
JS_ASSERT(sc->isFunction);
|
||||
JS_ASSERT(sc->isFunctionBox());
|
||||
|
||||
unsigned count = args_.length() + vars_.length();
|
||||
Binding *packedBindings = cx->tempLifoAlloc().newArrayUninitialized<Binding>(count);
|
||||
@ -303,7 +303,7 @@ ParseContext::generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*>
|
||||
return false;
|
||||
}
|
||||
|
||||
FunctionBox *funbox = sc->asFunbox();
|
||||
FunctionBox *funbox = sc->asFunctionBox();
|
||||
if (bindings->hasAnyAliasedBindings() || funbox->hasExtensibleScope())
|
||||
funbox->function()->setIsHeavyweight();
|
||||
|
||||
@ -373,7 +373,7 @@ Parser::newObjectBox(JSObject *obj)
|
||||
FunctionBox::FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fun,
|
||||
ParseContext *outerpc, bool strict)
|
||||
: ObjectBox(fun, traceListHead),
|
||||
SharedContext(cx, /* isFunction = */ true, strict),
|
||||
SharedContext(cx, strict),
|
||||
bindings(),
|
||||
bufStart(0),
|
||||
bufEnd(0),
|
||||
@ -394,7 +394,7 @@ FunctionBox::FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fu
|
||||
// outerpc->parsingWith is true.
|
||||
inWith = true;
|
||||
|
||||
} else if (!outerpc->sc->isFunction) {
|
||||
} else if (!outerpc->sc->isFunctionBox()) {
|
||||
// This covers the case where a function is nested within an eval()
|
||||
// within a |with| statement.
|
||||
//
|
||||
@ -405,7 +405,7 @@ FunctionBox::FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fu
|
||||
// ParseContext chain, and |parent| is NULL (again because of the
|
||||
// eval(), so we have to look at |outerpc|'s scopeChain.
|
||||
//
|
||||
JSObject *scope = outerpc->sc->asGlobal()->scopeChain();
|
||||
JSObject *scope = outerpc->sc->asGlobalSharedContext()->scopeChain();
|
||||
while (scope) {
|
||||
if (scope->isWith())
|
||||
inWith = true;
|
||||
@ -419,7 +419,7 @@ FunctionBox::FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fu
|
||||
//
|
||||
// In this case, the inner anonymous function needs to inherit the
|
||||
// setting of |inWith| from the outer one.
|
||||
FunctionBox *parent = outerpc->sc->asFunbox();
|
||||
FunctionBox *parent = outerpc->sc->asFunctionBox();
|
||||
if (parent && parent->inWith)
|
||||
inWith = true;
|
||||
}
|
||||
@ -629,7 +629,7 @@ ReportBadReturn(JSContext *cx, Parser *parser, ParseNode *pn, Parser::Reporter r
|
||||
unsigned errnum, unsigned anonerrnum)
|
||||
{
|
||||
JSAutoByteString name;
|
||||
JSAtom *atom = parser->pc->sc->asFunbox()->function()->atom();
|
||||
JSAtom *atom = parser->pc->sc->asFunctionBox()->function()->atom();
|
||||
if (atom) {
|
||||
if (!js_AtomToPrintableString(cx, atom, &name))
|
||||
return false;
|
||||
@ -642,7 +642,7 @@ ReportBadReturn(JSContext *cx, Parser *parser, ParseNode *pn, Parser::Reporter r
|
||||
static bool
|
||||
CheckFinalReturn(JSContext *cx, Parser *parser, ParseNode *pn)
|
||||
{
|
||||
JS_ASSERT(parser->pc->sc->isFunction);
|
||||
JS_ASSERT(parser->pc->sc->isFunctionBox());
|
||||
return HasFinalReturn(pn) == ENDS_IN_RETURN ||
|
||||
ReportBadReturn(cx, parser, pn, &Parser::reportStrictWarning,
|
||||
JSMSG_NO_RETURN_VALUE, JSMSG_ANON_NO_RETURN_VALUE);
|
||||
@ -739,7 +739,7 @@ Parser::standaloneFunctionBody(HandleFunction fun, const AutoNameVector &formals
|
||||
ParseNode *
|
||||
Parser::functionBody(FunctionBodyType type)
|
||||
{
|
||||
JS_ASSERT(pc->sc->isFunction);
|
||||
JS_ASSERT(pc->sc->isFunctionBox());
|
||||
JS_ASSERT(!pc->funHasReturnExpr && !pc->funHasReturnVoid);
|
||||
|
||||
ParseNode *pn;
|
||||
@ -755,7 +755,7 @@ Parser::functionBody(FunctionBodyType type)
|
||||
if (!pn->pn_kid) {
|
||||
pn = NULL;
|
||||
} else {
|
||||
if (pc->sc->asFunbox()->isGenerator()) {
|
||||
if (pc->sc->asFunctionBox()->isGenerator()) {
|
||||
ReportBadReturn(context, this, pn, &Parser::reportError,
|
||||
JSMSG_BAD_GENERATOR_RETURN,
|
||||
JSMSG_BAD_ANON_GENERATOR_RETURN);
|
||||
@ -822,7 +822,7 @@ Parser::functionBody(FunctionBodyType type)
|
||||
Definition *maybeArgDef = pc->decls().lookupFirst(arguments);
|
||||
bool argumentsHasBinding = !!maybeArgDef;
|
||||
bool argumentsHasLocalBinding = maybeArgDef && maybeArgDef->kind() != Definition::ARG;
|
||||
bool hasRest = pc->sc->asFunbox()->function()->hasRest();
|
||||
bool hasRest = pc->sc->asFunctionBox()->function()->hasRest();
|
||||
if (hasRest && argumentsHasLocalBinding) {
|
||||
reportError(NULL, JSMSG_ARGUMENTS_AND_REST);
|
||||
return NULL;
|
||||
@ -849,7 +849,7 @@ Parser::functionBody(FunctionBodyType type)
|
||||
* arguments object. (Also see the flags' comments in ContextFlags.)
|
||||
*/
|
||||
if (argumentsHasLocalBinding) {
|
||||
FunctionBox *funbox = pc->sc->asFunbox();
|
||||
FunctionBox *funbox = pc->sc->asFunctionBox();
|
||||
funbox->setArgumentsHasLocalBinding();
|
||||
|
||||
/* Dynamic scope access destroys all hope of optimization. */
|
||||
@ -1075,7 +1075,7 @@ Parser::newFunction(ParseContext *pc, HandleAtom atom, FunctionSyntaxKind kind)
|
||||
pc = pc->parent;
|
||||
|
||||
RootedObject parent(context);
|
||||
parent = pc->sc->isFunction ? NULL : pc->sc->asGlobal()->scopeChain();
|
||||
parent = pc->sc->isFunctionBox() ? NULL : pc->sc->asGlobalSharedContext()->scopeChain();
|
||||
|
||||
RootedFunction fun(context);
|
||||
JSFunction::Flags flags = (kind == Expression)
|
||||
@ -1143,7 +1143,7 @@ LeaveFunction(ParseNode *fn, Parser *parser, PropertyName *funName = NULL,
|
||||
pc->blockidGen = funpc->blockidGen;
|
||||
|
||||
FunctionBox *funbox = fn->pn_funbox;
|
||||
JS_ASSERT(funbox == funpc->sc->asFunbox());
|
||||
JS_ASSERT(funbox == funpc->sc->asFunctionBox());
|
||||
|
||||
if (!pc->topStmt || pc->topStmt->type == STMT_BLOCK)
|
||||
fn->pn_dflags |= PND_BLOCKCHILD;
|
||||
@ -1330,7 +1330,7 @@ static bool
|
||||
BindDestructuringArg(JSContext *cx, BindData *data, HandlePropertyName name, Parser *parser)
|
||||
{
|
||||
ParseContext *pc = parser->pc;
|
||||
JS_ASSERT(pc->sc->isFunction);
|
||||
JS_ASSERT(pc->sc->isFunctionBox());
|
||||
|
||||
if (pc->decls().lookupFirst(name)) {
|
||||
parser->reportError(NULL, JSMSG_BAD_DUP_ARGS);
|
||||
@ -1352,7 +1352,7 @@ Parser::functionArguments(ParseNode **listp, ParseNode* funcpn, bool &hasRest)
|
||||
return false;
|
||||
}
|
||||
|
||||
FunctionBox *funbox = pc->sc->asFunbox();
|
||||
FunctionBox *funbox = pc->sc->asFunctionBox();
|
||||
funbox->bufStart = tokenStream.offsetOfToken(tokenStream.currentToken());
|
||||
|
||||
hasRest = false;
|
||||
@ -1583,13 +1583,13 @@ Parser::functionDef(HandlePropertyName funName, const TokenStream::Position &sta
|
||||
*/
|
||||
if (bodyLevel) {
|
||||
JS_ASSERT(pn->functionIsHoisted());
|
||||
JS_ASSERT_IF(pc->sc->isFunction, !pn->pn_cookie.isFree());
|
||||
JS_ASSERT_IF(!pc->sc->isFunction, pn->pn_cookie.isFree());
|
||||
JS_ASSERT_IF(pc->sc->isFunctionBox(), !pn->pn_cookie.isFree());
|
||||
JS_ASSERT_IF(!pc->sc->isFunctionBox(), pn->pn_cookie.isFree());
|
||||
} else {
|
||||
JS_ASSERT(!pc->sc->strict);
|
||||
JS_ASSERT(pn->pn_cookie.isFree());
|
||||
if (pc->sc->isFunction) {
|
||||
FunctionBox *funbox = pc->sc->asFunbox();
|
||||
if (pc->sc->isFunctionBox()) {
|
||||
FunctionBox *funbox = pc->sc->asFunctionBox();
|
||||
funbox->setMightAliasLocals();
|
||||
funbox->setHasExtensibleScope();
|
||||
}
|
||||
@ -1876,7 +1876,7 @@ Parser::maybeParseDirective(ParseNode *pn, bool *cont)
|
||||
// had "use strict";
|
||||
pc->sc->setExplicitUseStrict();
|
||||
if (!pc->sc->strict) {
|
||||
if (pc->sc->isFunction) {
|
||||
if (pc->sc->isFunctionBox()) {
|
||||
// Request that this function be reparsed as strict.
|
||||
pc->funBecameStrict = true;
|
||||
return false;
|
||||
@ -1956,7 +1956,7 @@ Parser::statements(bool *hasFunctionStmt)
|
||||
* General deoptimization was done in functionDef, here we just
|
||||
* need to tell TOK_LC in Parser::statement to add braces.
|
||||
*/
|
||||
JS_ASSERT_IF(pc->sc->isFunction, pc->sc->asFunbox()->hasExtensibleScope());
|
||||
JS_ASSERT_IF(pc->sc->isFunctionBox(), pc->sc->asFunctionBox()->hasExtensibleScope());
|
||||
if (hasFunctionStmt)
|
||||
*hasFunctionStmt = true;
|
||||
}
|
||||
@ -2156,8 +2156,8 @@ BindVarOrConst(JSContext *cx, BindData *data, HandlePropertyName name, Parser *p
|
||||
|
||||
if (stmt && stmt->type == STMT_WITH) {
|
||||
pn->pn_dflags |= PND_DEOPTIMIZED;
|
||||
if (pc->sc->isFunction)
|
||||
pc->sc->asFunbox()->setMightAliasLocals();
|
||||
if (pc->sc->isFunctionBox())
|
||||
pc->sc->asFunctionBox()->setMightAliasLocals();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2528,7 +2528,7 @@ ParseNode *
|
||||
Parser::returnOrYield(bool useAssignExpr)
|
||||
{
|
||||
TokenKind tt = tokenStream.currentToken().type;
|
||||
if (!pc->sc->isFunction) {
|
||||
if (!pc->sc->isFunctionBox()) {
|
||||
reportError(NULL, JSMSG_BAD_RETURN_OR_YIELD,
|
||||
(tt == TOK_RETURN) ? js_return_str : js_yield_str);
|
||||
return NULL;
|
||||
@ -2545,7 +2545,7 @@ Parser::returnOrYield(bool useAssignExpr)
|
||||
* a |for| token, so we have to delay flagging the current function.
|
||||
*/
|
||||
if (pc->parenDepth == 0) {
|
||||
pc->sc->asFunbox()->setIsGenerator();
|
||||
pc->sc->asFunctionBox()->setIsGenerator();
|
||||
} else {
|
||||
pc->yieldCount++;
|
||||
pc->yieldNode = pn;
|
||||
@ -2582,7 +2582,7 @@ Parser::returnOrYield(bool useAssignExpr)
|
||||
pc->funHasReturnVoid = true;
|
||||
}
|
||||
|
||||
if (pc->funHasReturnExpr && pc->sc->asFunbox()->isGenerator()) {
|
||||
if (pc->funHasReturnExpr && pc->sc->asFunctionBox()->isGenerator()) {
|
||||
/* As in Python (see PEP-255), disallow return v; in generators. */
|
||||
ReportBadReturn(context, this, pn, &Parser::reportError, JSMSG_BAD_GENERATOR_RETURN,
|
||||
JSMSG_BAD_ANON_GENERATOR_RETURN);
|
||||
@ -4836,11 +4836,11 @@ GenexpGuard::maybeNoteGenerator(ParseNode *pn)
|
||||
{
|
||||
ParseContext *pc = parser->pc;
|
||||
if (pc->yieldCount > 0) {
|
||||
if (!pc->sc->isFunction) {
|
||||
if (!pc->sc->isFunctionBox()) {
|
||||
parser->reportError(NULL, JSMSG_BAD_RETURN_OR_YIELD, js_yield_str);
|
||||
return false;
|
||||
}
|
||||
pc->sc->asFunbox()->setIsGenerator();
|
||||
pc->sc->asFunctionBox()->setIsGenerator();
|
||||
if (pc->funHasReturnExpr) {
|
||||
/* At the time we saw the yield, we might not have set isGenerator yet. */
|
||||
ReportBadReturn(pc->sc->context, parser, pn, &Parser::reportError,
|
||||
@ -5337,8 +5337,8 @@ Parser::generatorExpr(ParseNode *kid)
|
||||
* kid and could be removed from pc->sc.
|
||||
*/
|
||||
genFunbox->anyCxFlags = outerpc->sc->anyCxFlags;
|
||||
if (outerpc->sc->isFunction)
|
||||
genFunbox->funCxFlags = outerpc->sc->asFunbox()->funCxFlags;
|
||||
if (outerpc->sc->isFunctionBox())
|
||||
genFunbox->funCxFlags = outerpc->sc->asFunctionBox()->funCxFlags;
|
||||
|
||||
genFunbox->setIsGenerator();
|
||||
genFunbox->inGenexpLambda = true;
|
||||
@ -5664,8 +5664,8 @@ Parser::memberExpr(bool allowCallSyntax)
|
||||
* In non-strict mode code, direct calls to eval can add
|
||||
* variables to the call object.
|
||||
*/
|
||||
if (pc->sc->isFunction && !pc->sc->strict)
|
||||
pc->sc->asFunbox()->setHasExtensibleScope();
|
||||
if (pc->sc->isFunctionBox() && !pc->sc->strict)
|
||||
pc->sc->asFunctionBox()->setHasExtensibleScope();
|
||||
}
|
||||
} else if (lhs->isOp(JSOP_GETPROP)) {
|
||||
/* Select JSOP_FUNAPPLY given foo.apply(...). */
|
||||
|
@ -81,12 +81,12 @@ struct ParseContext /* tree context for semantic checks */
|
||||
}
|
||||
|
||||
uint32_t numArgs() const {
|
||||
JS_ASSERT(sc->isFunction);
|
||||
JS_ASSERT(sc->isFunctionBox());
|
||||
return args_.length();
|
||||
}
|
||||
|
||||
uint32_t numVars() const {
|
||||
JS_ASSERT(sc->isFunction);
|
||||
JS_ASSERT(sc->isFunctionBox());
|
||||
return vars_.length();
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,8 @@ namespace js {
|
||||
namespace frontend {
|
||||
|
||||
inline
|
||||
SharedContext::SharedContext(JSContext *cx, bool isFun, bool strict)
|
||||
SharedContext::SharedContext(JSContext *cx, bool strict)
|
||||
: context(cx),
|
||||
isFunction(isFun),
|
||||
anyCxFlags(),
|
||||
strict(strict)
|
||||
{
|
||||
@ -30,21 +29,21 @@ SharedContext::needStrictChecks()
|
||||
}
|
||||
|
||||
inline GlobalSharedContext *
|
||||
SharedContext::asGlobal()
|
||||
SharedContext::asGlobalSharedContext()
|
||||
{
|
||||
JS_ASSERT(!isFunction);
|
||||
JS_ASSERT(isGlobalSharedContext());
|
||||
return static_cast<GlobalSharedContext*>(this);
|
||||
}
|
||||
|
||||
inline FunctionBox *
|
||||
SharedContext::asFunbox()
|
||||
SharedContext::asFunctionBox()
|
||||
{
|
||||
JS_ASSERT(isFunction);
|
||||
JS_ASSERT(isFunctionBox());
|
||||
return static_cast<FunctionBox*>(this);
|
||||
}
|
||||
|
||||
GlobalSharedContext::GlobalSharedContext(JSContext *cx, JSObject *scopeChain, bool strict)
|
||||
: SharedContext(cx, /* isFunction = */ false, strict),
|
||||
: SharedContext(cx, strict),
|
||||
scopeChain_(cx, scopeChain)
|
||||
{
|
||||
}
|
||||
|
@ -138,19 +138,18 @@ class SharedContext
|
||||
{
|
||||
public:
|
||||
JSContext *const context;
|
||||
|
||||
const bool isFunction; /* true for function code, false for
|
||||
global code */
|
||||
AnyContextFlags anyCxFlags;
|
||||
|
||||
bool strict;
|
||||
|
||||
// If it's function code, funbox must be non-NULL and scopeChain must be NULL.
|
||||
// If it's global code, funbox must be NULL.
|
||||
inline SharedContext(JSContext *cx, bool isFun, bool strict);
|
||||
inline SharedContext(JSContext *cx, bool strict);
|
||||
|
||||
inline GlobalSharedContext *asGlobal();
|
||||
inline FunctionBox *asFunbox();
|
||||
virtual ObjectBox *toObjectBox() = 0;
|
||||
inline bool isGlobalSharedContext() { return toObjectBox() == NULL; }
|
||||
inline bool isFunctionBox() { return toObjectBox() && toObjectBox()->isFunctionBox(); }
|
||||
inline GlobalSharedContext *asGlobalSharedContext();
|
||||
inline FunctionBox *asFunctionBox();
|
||||
|
||||
bool hasExplicitUseStrict() const { return anyCxFlags.hasExplicitUseStrict; }
|
||||
bool bindingsAccessedDynamically() const { return anyCxFlags.bindingsAccessedDynamically; }
|
||||
@ -170,6 +169,7 @@ class GlobalSharedContext : public SharedContext
|
||||
public:
|
||||
inline GlobalSharedContext(JSContext *cx, JSObject *scopeChain, bool strict);
|
||||
|
||||
ObjectBox *toObjectBox() { return NULL; }
|
||||
JSObject *scopeChain() const { return scopeChain_; }
|
||||
};
|
||||
|
||||
@ -189,6 +189,7 @@ class FunctionBox : public ObjectBox, public SharedContext
|
||||
FunctionBox(JSContext *cx, ObjectBox* traceListHead, JSFunction *fun, ParseContext *pc,
|
||||
bool strict);
|
||||
|
||||
ObjectBox *toObjectBox() { return this; }
|
||||
JSFunction *function() const { return object->toFunction(); }
|
||||
|
||||
bool isGenerator() const { return funCxFlags.isGenerator; }
|
||||
|
@ -1750,7 +1750,7 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
|
||||
script->mainOffset = prologLength;
|
||||
PodCopy<jsbytecode>(script->code, bce->prologBase(), prologLength);
|
||||
PodCopy<jsbytecode>(script->main(), bce->base(), mainLength);
|
||||
uint32_t nfixed = bce->sc->isFunction ? script->bindings.numVars() : 0;
|
||||
uint32_t nfixed = bce->sc->isFunctionBox() ? script->bindings.numVars() : 0;
|
||||
JS_ASSERT(nfixed < SLOTNO_LIMIT);
|
||||
script->nfixed = uint16_t(nfixed);
|
||||
InitAtomMap(cx, bce->atomIndices.getMap(), script->atoms);
|
||||
@ -1768,7 +1768,7 @@ JSScript::fullyInitFromEmitter(JSContext *cx, Handle<JSScript*> script, Bytecode
|
||||
}
|
||||
script->nslots = script->nfixed + bce->maxStackDepth;
|
||||
|
||||
FunctionBox *funbox = bce->sc->isFunction ? bce->sc->asFunbox() : NULL;
|
||||
FunctionBox *funbox = bce->sc->isFunctionBox() ? bce->sc->asFunctionBox() : NULL;
|
||||
|
||||
if (!FinishTakingSrcNotes(cx, bce, script->notes()))
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user