Bug 1179063 - Cleanup: rename top -> innermost, down -> enclosing in StmtInfoStack. (r=efaust)

This commit is contained in:
Shu-yu Guo 2015-07-30 22:17:04 -07:00
parent 800641205c
commit fa0e58c4ac
5 changed files with 127 additions and 129 deletions

View File

@ -55,8 +55,8 @@ using mozilla::UniquePtr;
struct frontend::StmtInfoBCE : public StmtInfoBase
{
StmtInfoBCE* down; /* info for enclosing statement */
StmtInfoBCE* downScope; /* next enclosing lexical scope */
StmtInfoBCE* enclosing;
StmtInfoBCE* enclosingScope;
ptrdiff_t update; /* loop update offset (top if none) */
ptrdiff_t breaks; /* offset of last break in loop */
@ -384,17 +384,17 @@ static_assert(MOZ_ARRAY_LENGTH(statementName) == uint16_t(StmtType::LIMIT),
"statementName array and StmtType enum must be consistent");
static const char*
StatementName(StmtInfoBCE* topStmt)
StatementName(StmtInfoBCE* stmt)
{
if (!topStmt)
if (!stmt)
return js_script_str;
return statementName[uint16_t(topStmt->type)];
return statementName[uint16_t(stmt->type)];
}
static void
ReportStatementTooLarge(TokenStream& ts, StmtInfoBCE* topStmt)
ReportStatementTooLarge(TokenStream& ts, StmtInfoBCE* stmt)
{
ts.reportError(JSMSG_NEED_DIET, StatementName(topStmt));
ts.reportError(JSMSG_NEED_DIET, StatementName(stmt));
}
/*
@ -509,7 +509,7 @@ BytecodeEmitter::emitLoopEntry(ParseNode* nextpn)
return false;
}
LoopStmtInfo* loop = LoopStmtInfo::fromStmtInfo(topStmt());
LoopStmtInfo* loop = LoopStmtInfo::fromStmtInfo(innermostStmt());
MOZ_ASSERT(loop->loopDepth > 0);
uint8_t loopDepthAndFlags = PackLoopEntryDepthHintAndFlags(loop->loopDepth, loop->canIonOsr);
@ -574,7 +574,7 @@ class NonLocalExitScope {
savedDepth(bce->stackDepth),
openScopeIndex(UINT32_MAX)
{
if (StmtInfoBCE* stmt = bce->topScopeStmt())
if (StmtInfoBCE* stmt = bce->innermostScopeStmt())
openScopeIndex = stmt->blockScopeIndex;
}
~NonLocalExitScope() {
@ -606,7 +606,7 @@ NonLocalExitScope::prepareForNonLocalJump(StmtInfoBCE* toStmt)
#define FLUSH_POPS() if (npops && !bce->flushPops(&npops)) return false
for (StmtInfoBCE* stmt = bce->topStmt(); stmt != toStmt; stmt = stmt->down) {
for (StmtInfoBCE* stmt = bce->innermostStmt(); stmt != toStmt; stmt = stmt->enclosing) {
switch (stmt->type) {
case StmtType::FINALLY:
FLUSH_POPS();
@ -721,16 +721,16 @@ BytecodeEmitter::pushLoopStatement(LoopStmtInfo* stmt, StmtType type, ptrdiff_t
pushStatementInner(stmt, type, top);
MOZ_ASSERT(stmt->isLoop());
LoopStmtInfo* downLoop = nullptr;
for (StmtInfoBCE* outer = stmt->down; outer; outer = outer->down) {
LoopStmtInfo* enclosingLoop = nullptr;
for (StmtInfoBCE* outer = stmt->enclosing; outer; outer = outer->enclosing) {
if (outer->isLoop()) {
downLoop = LoopStmtInfo::fromStmtInfo(outer);
enclosingLoop = LoopStmtInfo::fromStmtInfo(outer);
break;
}
}
stmt->stackDepth = this->stackDepth;
stmt->loopDepth = downLoop ? downLoop->loopDepth + 1 : 1;
stmt->loopDepth = enclosingLoop ? enclosingLoop->loopDepth + 1 : 1;
int loopSlots;
if (type == StmtType::SPREAD)
@ -742,17 +742,18 @@ BytecodeEmitter::pushLoopStatement(LoopStmtInfo* stmt, StmtType type, ptrdiff_t
MOZ_ASSERT(loopSlots <= stmt->stackDepth);
if (downLoop)
stmt->canIonOsr = (downLoop->canIonOsr &&
stmt->stackDepth == downLoop->stackDepth + loopSlots);
else
if (enclosingLoop) {
stmt->canIonOsr = (enclosingLoop->canIonOsr &&
stmt->stackDepth == enclosingLoop->stackDepth + loopSlots);
} else {
stmt->canIonOsr = stmt->stackDepth == loopSlots;
}
}
JSObject*
BytecodeEmitter::enclosingStaticScope()
{
if (StmtInfoBCE* stmt = topScopeStmt())
if (StmtInfoBCE* stmt = innermostScopeStmt())
return stmt->staticScope;
if (!sc->isFunctionBox()) {
@ -820,7 +821,7 @@ BytecodeEmitter::computeLocalOffset(Handle<StaticBlockObject*> blockObj)
: 0;
unsigned localOffset = nbodyfixed;
if (StmtInfoBCE* stmt = topScopeStmt()) {
if (StmtInfoBCE* stmt = innermostScopeStmt()) {
Rooted<NestedScopeObject*> outer(cx, stmt->staticScope);
for (; outer; outer = outer->enclosingNestedScope()) {
if (outer->is<StaticBlockObject>()) {
@ -920,7 +921,7 @@ BytecodeEmitter::enterNestedScope(StmtInfoBCE* stmt, ObjectBox* objbox, StmtType
}
uint32_t parent = BlockScopeNote::NoBlockScopeIndex;
if (StmtInfoBCE* stmt = topScopeStmt())
if (StmtInfoBCE* stmt = innermostScopeStmt())
parent = stmt->blockScopeIndex;
stmt->blockScopeIndex = blockScopeList.length();
@ -929,7 +930,7 @@ BytecodeEmitter::enterNestedScope(StmtInfoBCE* stmt, ObjectBox* objbox, StmtType
pushStatement(stmt, stmtType, offset());
scopeObj->initEnclosingNestedScope(enclosingStaticScope());
stmtStack.linkAsTopScopal(stmt, *scopeObj);
stmtStack.linkAsInnermostScopal(stmt, *scopeObj);
MOZ_ASSERT(stmt->linksScope());
stmt->isBlockScope = (stmtType == StmtType::BLOCK);
@ -941,9 +942,9 @@ BytecodeEmitter::enterNestedScope(StmtInfoBCE* stmt, ObjectBox* objbox, StmtType
void
BytecodeEmitter::popStatement()
{
if (!topStmt()->isTrying()) {
backPatch(topStmt()->breaks, code().end(), JSOP_GOTO);
backPatch(topStmt()->continues, code(topStmt()->update), JSOP_GOTO);
if (!innermostStmt()->isTrying()) {
backPatch(innermostStmt()->breaks, code().end(), JSOP_GOTO);
backPatch(innermostStmt()->continues, code(innermostStmt()->update), JSOP_GOTO);
}
stmtStack.pop();
@ -952,7 +953,7 @@ BytecodeEmitter::popStatement()
bool
BytecodeEmitter::leaveNestedScope(StmtInfoBCE* stmt)
{
MOZ_ASSERT(stmt == topScopeStmt());
MOZ_ASSERT(stmt == innermostScopeStmt());
MOZ_ASSERT(stmt->isBlockScope == !(stmt->type == StmtType::WITH));
uint32_t blockScopeIndex = stmt->blockScopeIndex;
@ -1162,7 +1163,7 @@ unsigned
BytecodeEmitter::dynamicNestedScopeDepth()
{
unsigned depth = 0;
if (StmtInfoBCE* stmt = topScopeStmt()) {
if (StmtInfoBCE* stmt = innermostScopeStmt()) {
for (NestedScopeObject* b = stmt->staticScope; b; b = b->enclosingNestedScope()) {
if (!b->is<StaticBlockObject>() || b->as<StaticBlockObject>().needsClone())
++depth;
@ -1306,8 +1307,8 @@ BytecodeEmitter::emitAliasedVarOp(JSOp op, ParseNode* pn)
JS_ALWAYS_TRUE(bceOfDef->lookupAliasedNameSlot(pn->name(), &sc));
} else {
MOZ_ASSERT_IF(this->sc->isFunctionBox(), local <= bceOfDef->script->bindings.numLocals());
MOZ_ASSERT(bceOfDef->topScopeStmt()->staticScope->is<StaticBlockObject>());
StmtInfoBCE* stmt = bceOfDef->topScopeStmt();
MOZ_ASSERT(bceOfDef->innermostScopeStmt()->staticScope->is<StaticBlockObject>());
StmtInfoBCE* stmt = bceOfDef->innermostScopeStmt();
Rooted<StaticBlockObject*> b(cx, &stmt->staticScope->as<StaticBlockObject>());
local = bceOfDef->localsToFrameSlots_[local];
while (local < b->localOffset()) {
@ -1513,7 +1514,7 @@ BytecodeEmitter::tryConvertFreeName(ParseNode* pn)
if (emitterMode == BytecodeEmitter::LazyFunction) {
// The only statements within a lazy function which can push lexical
// scopes are try/catch blocks. Use generic ops in this case.
for (StmtInfoBCE* stmt = topStmt(); stmt; stmt = stmt->down) {
for (StmtInfoBCE* stmt = innermostStmt(); stmt; stmt = stmt->enclosing) {
if (stmt->type == StmtType::CATCH)
return true;
}
@ -2312,7 +2313,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
bool
BytecodeEmitter::isInLoop()
{
for (StmtInfoBCE* stmt = topStmt(); stmt; stmt = stmt->down) {
for (StmtInfoBCE* stmt = innermostStmt(); stmt; stmt = stmt->enclosing) {
if (stmt->isLoop())
return true;
}
@ -2340,7 +2341,7 @@ BytecodeEmitter::needsImplicitThis()
if (sc->inWith())
return true;
for (StmtInfoBCE* stmt = topStmt(); stmt; stmt = stmt->down) {
for (StmtInfoBCE* stmt = innermostStmt(); stmt; stmt = stmt->enclosing) {
if (stmt->type == StmtType::WITH)
return true;
}
@ -4766,12 +4767,12 @@ BytecodeEmitter::emitCatch(ParseNode* pn)
* Morph StmtType::BLOCK to StmtType::CATCH, note the block entry code offset,
* and save the block object atom.
*/
StmtInfoBCE* stmt = topStmt();
StmtInfoBCE* stmt = innermostStmt();
MOZ_ASSERT(stmt->type == StmtType::BLOCK && stmt->isBlockScope);
stmt->type = StmtType::CATCH;
/* Go up one statement info record to the TRY or FINALLY record. */
stmt = stmt->down;
stmt = stmt->enclosing;
MOZ_ASSERT(stmt->type == StmtType::TRY || stmt->type == StmtType::FINALLY);
/* Pick up the pending exception and bind it to the catch variable. */
@ -5354,7 +5355,7 @@ BytecodeEmitter::emitForOf(StmtType type, ParseNode* pn, ptrdiff_t top)
StmtInfoBCE* stmt = &stmtInfo;
do {
stmt->update = offset();
} while ((stmt = stmt->down) != nullptr && stmt->type == StmtType::LABEL);
} while ((stmt = stmt->enclosing) != nullptr && stmt->type == StmtType::LABEL);
} else {
if (!emit1(JSOP_INITELEM_INC)) // ITER ARR (I+1)
return false;
@ -5396,7 +5397,7 @@ BytecodeEmitter::emitForOf(StmtType type, ParseNode* pn, ptrdiff_t top)
return false;
// Fixup breaks and continues.
// For StmtType::SPREAD, just pop pc->topStmt.
// For StmtType::SPREAD, just pop innermostStmt().
popStatement();
if (!tryNoteList.append(JSTRY_FOR_OF, stackDepth, top, offset()))
@ -5495,7 +5496,7 @@ BytecodeEmitter::emitForIn(ParseNode* pn, ptrdiff_t top)
StmtInfoBCE* stmt = &stmtInfo;
do {
stmt->update = offset();
} while ((stmt = stmt->down) != nullptr && stmt->type == StmtType::LABEL);
} while ((stmt = stmt->enclosing) != nullptr && stmt->type == StmtType::LABEL);
/*
* Fixup the goto that starts the loop to jump down to JSOP_MOREITER.
@ -5616,21 +5617,21 @@ BytecodeEmitter::emitNormalFor(ParseNode* pn, ptrdiff_t top)
StmtInfoBCE* stmt = &stmtInfo;
do {
stmt->update = offset();
} while ((stmt = stmt->down) != nullptr && stmt->type == StmtType::LABEL);
} while ((stmt = stmt->enclosing) != nullptr && stmt->type == StmtType::LABEL);
// Freshen the block on the scope chain to expose distinct bindings for each loop
// iteration.
if (forLoopRequiresFreshening) {
// The scope chain only includes an actual block *if* the scope object
// is captured and therefore requires cloning. Get the static block
// object from the parent let-block statement (which *must* be the
// object from the enclosing let-block statement (which *must* be the
// let-statement for the guarding condition to have held) and freshen
// if the block object needs cloning.
StmtInfoBCE* parent = stmtInfo.down;
MOZ_ASSERT(parent->type == StmtType::BLOCK);
MOZ_ASSERT(parent->isBlockScope);
StmtInfoBCE* enclosing = stmtInfo.enclosing;
MOZ_ASSERT(enclosing->type == StmtType::BLOCK);
MOZ_ASSERT(enclosing->isBlockScope);
if (parent->staticScope->as<StaticBlockObject>().needsClone()) {
if (enclosing->staticScope->as<StaticBlockObject>().needsClone()) {
if (!emit1(JSOP_FRESHENBLOCKSCOPE))
return false;
}
@ -5844,7 +5845,7 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
if (!sc->isFunctionBox()) {
MOZ_ASSERT(pn->pn_cookie.isFree());
MOZ_ASSERT(pn->getOp() == JSOP_NOP);
MOZ_ASSERT(!topStmt());
MOZ_ASSERT(!innermostStmt());
switchToPrologue();
if (!emitIndex32(JSOP_DEFFUN, index))
return false;
@ -5907,7 +5908,7 @@ BytecodeEmitter::emitDo(ParseNode* pn)
StmtInfoBCE* stmt = &stmtInfo;
do {
stmt->update = off;
} while ((stmt = stmt->down) != nullptr && stmt->type == StmtType::LABEL);
} while ((stmt = stmt->enclosing) != nullptr && stmt->type == StmtType::LABEL);
/* Compile the loop condition, now that continues know where to go. */
if (!emitTree(pn->pn_right))
@ -5993,15 +5994,15 @@ BytecodeEmitter::emitWhile(ParseNode* pn, ptrdiff_t top)
bool
BytecodeEmitter::emitBreak(PropertyName* label)
{
StmtInfoBCE* stmt = topStmt();
StmtInfoBCE* stmt = innermostStmt();
SrcNoteType noteType;
if (label) {
while (stmt->type != StmtType::LABEL || stmt->label != label)
stmt = stmt->down;
stmt = stmt->enclosing;
noteType = SRC_BREAK2LABEL;
} else {
while (!stmt->isLoop() && stmt->type != StmtType::SWITCH)
stmt = stmt->down;
stmt = stmt->enclosing;
noteType = (stmt->type == StmtType::SWITCH) ? SRC_SWITCHBREAK : SRC_BREAK;
}
@ -6011,19 +6012,19 @@ BytecodeEmitter::emitBreak(PropertyName* label)
bool
BytecodeEmitter::emitContinue(PropertyName* label)
{
StmtInfoBCE* stmt = topStmt();
StmtInfoBCE* stmt = innermostStmt();
if (label) {
/* Find the loop statement enclosed by the matching label. */
StmtInfoBCE* loop = nullptr;
while (stmt->type != StmtType::LABEL || stmt->label != label) {
if (stmt->isLoop())
loop = stmt;
stmt = stmt->down;
stmt = stmt->enclosing;
}
stmt = loop;
} else {
while (!stmt->isLoop())
stmt = stmt->down;
stmt = stmt->enclosing;
}
return emitGoto(stmt, &stmt->continues, SRC_CONTINUE);
@ -6032,7 +6033,7 @@ BytecodeEmitter::emitContinue(PropertyName* label)
bool
BytecodeEmitter::inTryBlockWithFinally()
{
for (StmtInfoBCE* stmt = topStmt(); stmt; stmt = stmt->down) {
for (StmtInfoBCE* stmt = innermostStmt(); stmt; stmt = stmt->enclosing) {
if (stmt->type == StmtType::FINALLY)
return true;
}
@ -6372,13 +6373,13 @@ BytecodeEmitter::emitStatement(ParseNode* pn)
/*
* Don't eliminate apparently useless expressions if they are
* labeled expression statements. The pc->topStmt->update test
* labeled expression statements. The innermostStmt()->update test
* catches the case where we are nesting in emitTree for a labeled
* compound statement.
*/
if (topStmt() &&
topStmt()->type == StmtType::LABEL &&
topStmt()->update >= offset())
if (innermostStmt() &&
innermostStmt()->type == StmtType::LABEL &&
innermostStmt()->update >= offset())
{
useful = true;
}
@ -8126,7 +8127,7 @@ bool
BytecodeEmitter::setSrcNoteOffset(unsigned index, unsigned which, ptrdiff_t offset)
{
if (!SN_REPRESENTABLE_OFFSET(offset)) {
ReportStatementTooLarge(parser->tokenStream, topStmt());
ReportStatementTooLarge(parser->tokenStream, innermostStmt());
return false;
}

View File

@ -219,8 +219,8 @@ struct BytecodeEmitter
bool init();
bool updateLocalsToFrameSlots();
StmtInfoBCE* topStmt() const { return stmtStack.top(); }
StmtInfoBCE* topScopeStmt() const { return stmtStack.topScopal(); }
StmtInfoBCE* innermostStmt() const { return stmtStack.innermost(); }
StmtInfoBCE* innermostScopeStmt() const { return stmtStack.innermostScopal(); }
bool isAliasedName(ParseNode* pn);

View File

@ -1284,8 +1284,8 @@ LexicalLookup(ContextT* ct, HandleAtom atom, StmtInfoPC* stmt = nullptr)
RootedId id(ct->sc->context, AtomToId(atom));
if (!stmt)
stmt = ct->topScopeStmt();
for (; stmt; stmt = stmt->downScope) {
stmt = ct->innermostScopeStmt();
for (; stmt; stmt = stmt->enclosingScope) {
/*
* With-statements introduce dynamic bindings. Since dynamic bindings
* can potentially override any static bindings introduced by statements
@ -3141,11 +3141,12 @@ template <typename ParseHandler>
static void
AccumulateBlockScopeDepth(ParseContext<ParseHandler>* pc)
{
uint32_t innerDepth = pc->topStmt()->innerBlockScopeDepth;
StmtInfoPC* outer = pc->topStmt()->down;
StmtInfoPC* stmt = pc->innermostStmt();
uint32_t innerDepth = stmt->innerBlockScopeDepth;
StmtInfoPC* outer = stmt->enclosing;
if (pc->topStmt()->isBlockScope)
innerDepth += pc->topStmt()->staticScope->template as<StaticBlockObject>().numVariables();
if (stmt->isBlockScope)
innerDepth += stmt->staticScope->template as<StaticBlockObject>().numVariables();
if (outer) {
if (outer->innerBlockScopeDepth < innerDepth)
@ -3175,7 +3176,7 @@ Parser<ParseHandler>::AutoPushStmtInfoPC::AutoPushStmtInfoPC(Parser<ParseHandler
{
stmt_.blockid = parser.pc->blockid();
NestedScopeObject* enclosing = nullptr;
if (StmtInfoPC* stmt = parser.pc->topScopeStmt())
if (StmtInfoPC* stmt = parser.pc->innermostScopeStmt())
enclosing = stmt->staticScope;
staticScope.initEnclosingNestedScopeFromParser(enclosing);
parser.pc->stmtStack.pushNestedScope(&stmt_, type, staticScope);
@ -3192,7 +3193,7 @@ Parser<ParseHandler>::AutoPushStmtInfoPC::~AutoPushStmtInfoPC()
ParseContext<ParseHandler>* pc = parser_.pc;
TokenStream& ts = parser_.tokenStream;
MOZ_ASSERT(pc->topStmt() == &stmt_);
MOZ_ASSERT(pc->innermostStmt() == &stmt_);
RootedNestedScopeObject scopeObj(parser_.context, stmt_.staticScope);
AccumulateBlockScopeDepth(pc);
@ -3217,10 +3218,10 @@ Parser<ParseHandler>::AutoPushStmtInfoPC::generateBlockId()
template <typename ParseHandler>
bool
Parser<ParseHandler>::AutoPushStmtInfoPC::makeTopLexicalScope(StaticBlockObject& blockObj)
Parser<ParseHandler>::AutoPushStmtInfoPC::makeInnermostLexicalScope(StaticBlockObject& blockObj)
{
MOZ_ASSERT(parser_.pc->stmtStack.top() == &stmt_);
parser_.pc->stmtStack.makeTopLexicalScope(blockObj);
MOZ_ASSERT(parser_.pc->stmtStack.innermost() == &stmt_);
parser_.pc->stmtStack.makeInnermostLexicalScope(blockObj);
return generateBlockId();
}
@ -3228,8 +3229,8 @@ template <typename ParseHandler>
static inline bool
OuterLet(ParseContext<ParseHandler>* pc, StmtInfoPC* stmt, HandleAtom atom)
{
while (stmt->downScope) {
stmt = LexicalLookup(pc, atom, stmt->downScope);
while (stmt->enclosingScope) {
stmt = LexicalLookup(pc, atom, stmt->enclosingScope);
if (!stmt)
return false;
if (stmt->type == StmtType::BLOCK)
@ -3677,7 +3678,7 @@ Parser<ParseHandler>::pushLexicalScope(HandleStaticBlockObject blockObj,
if (!pn)
return null();
if (!stmt.makeTopLexicalScope(*blockObj))
if (!stmt.makeInnermostLexicalScope(*blockObj))
return null();
handler.setBlockId(pn, stmt->blockid);
return pn;
@ -4065,7 +4066,7 @@ Parser<FullParseHandler>::checkAndPrepareLexical(bool isConst, const TokenPos& e
* enclosing maybe-scope StmtInfoPC isn't yet a scope statement) then
* we also need to set pc->blockNode to be our PNK_LEXICALSCOPE.
*/
StmtInfoPC* stmt = pc->topStmt();
StmtInfoPC* stmt = pc->innermostStmt();
if (stmt && (!stmt->maybeScope() || stmt->isForLetBlock)) {
reportWithOffset(ParseError, false, errorPos.begin, JSMSG_LEXICAL_DECL_NOT_IN_BLOCK,
isConst ? "const" : "lexical");
@ -4086,7 +4087,7 @@ Parser<FullParseHandler>::checkAndPrepareLexical(bool isConst, const TokenPos& e
* conflicting slots. Forbid top-level let declarations to
* prevent such conflicts from ever occurring.
*/
bool isGlobal = !pc->sc->isFunctionBox() && stmt == pc->topScopeStmt();
bool isGlobal = !pc->sc->isFunctionBox() && stmt == pc->innermostScopeStmt();
if (options().selfHostingMode && isGlobal) {
report(ParseError, false, null(), JSMSG_SELFHOSTED_TOP_LEVEL_LEXICAL,
isConst ? "'const'" : "'let'");
@ -4097,14 +4098,14 @@ Parser<FullParseHandler>::checkAndPrepareLexical(bool isConst, const TokenPos& e
if (stmt->isBlockScope) {
// Nothing to do, the top statement already has a block scope.
MOZ_ASSERT(pc->topScopeStmt() == stmt);
MOZ_ASSERT(pc->innermostScopeStmt() == stmt);
} else {
/* Convert the block statement into a scope statement. */
StaticBlockObject* blockObj = StaticBlockObject::create(context);
if (!blockObj)
return false;
NestedScopeObject* enclosing = nullptr;
if (StmtInfoPC* stmt = pc->topScopeStmt())
if (StmtInfoPC* stmt = pc->innermostScopeStmt())
enclosing = stmt->staticScope;
blockObj->initEnclosingNestedScopeFromParser(enclosing);
@ -4118,7 +4119,7 @@ Parser<FullParseHandler>::checkAndPrepareLexical(bool isConst, const TokenPos& e
* catch block (catch is a lexical scope by definition).
*/
MOZ_ASSERT(stmt->canBeBlockScope() && stmt->type != StmtType::CATCH);
pc->stmtStack.makeTopLexicalScope(*blockObj);
pc->stmtStack.makeInnermostLexicalScope(*blockObj);
#ifdef DEBUG
ParseNode* tmp = pc->blockNode;
@ -4138,7 +4139,7 @@ static StaticBlockObject*
CurrentLexicalStaticBlock(ParseContext<FullParseHandler>* pc)
{
return pc->atBodyLevel() ? nullptr :
&pc->topStmt()->staticScope->as<StaticBlockObject>();
&pc->innermostStmt()->staticScope->as<StaticBlockObject>();
}
template <>
@ -5279,7 +5280,7 @@ Parser<ParseHandler>::switchStatement(YieldHandling yieldHandling)
AutoPushStmtInfoPC stmtInfo(*this, StmtType::SWITCH);
if (!GenerateBlockId(tokenStream, pc, pc->topStmt()->blockid))
if (!GenerateBlockId(tokenStream, pc, pc->innermostStmt()->blockid))
return null();
Node caseList = handler.newStatementList(pc->blockid(), pos());
@ -5405,9 +5406,9 @@ Parser<ParseHandler>::continueStatement(YieldHandling yieldHandling)
if (!matchLabel(yieldHandling, &label))
return null();
StmtInfoPC* stmt = pc->topStmt();
StmtInfoPC* stmt = pc->innermostStmt();
if (label) {
for (StmtInfoPC* stmt2 = nullptr; ; stmt = stmt->down) {
for (StmtInfoPC* stmt2 = nullptr; ; stmt = stmt->enclosing) {
if (!stmt) {
report(ParseError, false, null(), JSMSG_LABEL_NOT_FOUND);
return null();
@ -5425,7 +5426,7 @@ Parser<ParseHandler>::continueStatement(YieldHandling yieldHandling)
}
}
} else {
for (; ; stmt = stmt->down) {
for (; ; stmt = stmt->enclosing) {
if (!stmt) {
report(ParseError, false, null(), JSMSG_BAD_CONTINUE);
return null();
@ -5451,9 +5452,9 @@ Parser<ParseHandler>::breakStatement(YieldHandling yieldHandling)
RootedPropertyName label(context);
if (!matchLabel(yieldHandling, &label))
return null();
StmtInfoPC* stmt = pc->topStmt();
StmtInfoPC* stmt = pc->innermostStmt();
if (label) {
for (; ; stmt = stmt->down) {
for (; ; stmt = stmt->enclosing) {
if (!stmt) {
report(ParseError, false, null(), JSMSG_LABEL_NOT_FOUND);
return null();
@ -5462,7 +5463,7 @@ Parser<ParseHandler>::breakStatement(YieldHandling yieldHandling)
break;
}
} else {
for (; ; stmt = stmt->down) {
for (; ; stmt = stmt->enclosing) {
if (!stmt) {
report(ParseError, false, null(), JSMSG_TOUGH_BREAK);
return null();
@ -5744,7 +5745,7 @@ Parser<ParseHandler>::labeledStatement(YieldHandling yieldHandling)
{
uint32_t begin = pos().begin;
RootedPropertyName label(context, tokenStream.currentName());
for (StmtInfoPC* stmt = pc->topStmt(); stmt; stmt = stmt->down) {
for (StmtInfoPC* stmt = pc->innermostStmt(); stmt; stmt = stmt->enclosing) {
if (stmt->type == StmtType::LABEL && stmt->label == label) {
report(ParseError, false, null(), JSMSG_DUPLICATE_LABEL);
return null();
@ -5874,7 +5875,7 @@ Parser<ParseHandler>::tryStatement(YieldHandling yieldHandling)
* an intentional change that anticipates ECMA Ed. 4.
*/
data.initLexical(HoistVars,
&pc->topScopeStmt()->staticScope->template as<StaticBlockObject>(),
&stmtInfo->staticScope->template as<StaticBlockObject>(),
JSMSG_TOO_MANY_CATCH_VARS);
MOZ_ASSERT(data.let.blockObj);
@ -7043,7 +7044,7 @@ LegacyCompExprTransplanter::transplant(ParseNode* pn)
RootedAtom atom(parser->context, pn->pn_atom);
#ifdef DEBUG
StmtInfoPC* stmt = LexicalLookup(pc, atom);
MOZ_ASSERT(!stmt || stmt != pc->topStmt());
MOZ_ASSERT(!stmt || stmt != pc->innermostStmt());
#endif
if (isGenexp && !dn->isOp(JSOP_CALLEE)) {
MOZ_ASSERT_IF(!pc->sc->isDotVariable(atom), !pc->decls().lookupFirst(atom));
@ -7152,7 +7153,7 @@ template <typename ParseHandler>
static unsigned
LegacyComprehensionHeadBlockScopeDepth(ParseContext<ParseHandler>* pc)
{
return pc->topStmt() ? pc->topStmt()->innerBlockScopeDepth : pc->blockScopeDepth;
return pc->innermostStmt() ? pc->innermostStmt()->innerBlockScopeDepth : pc->blockScopeDepth;
}
/*
@ -7242,9 +7243,10 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode* bodyExpr, unsigned
if (!transplanter.transplant(bodyExpr))
return null();
MOZ_ASSERT(pc->topScopeStmt() && pc->topScopeStmt()->staticScope == pn->pn_objbox->object);
MOZ_ASSERT(pc->innermostScopeStmt() &&
pc->innermostScopeStmt()->staticScope == pn->pn_objbox->object);
data.initLexical(HoistVars,
&pc->topScopeStmt()->staticScope->as<StaticBlockObject>(),
&pc->innermostScopeStmt()->staticScope->as<StaticBlockObject>(),
JSMSG_ARRAY_INIT_TOO_BIG);
while (true) {
@ -7418,7 +7420,7 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode* bodyExpr, unsigned
*pnp = bodyStmt;
pc->topStmt()->innerBlockScopeDepth += innerBlockScopeDepth;
pc->innermostStmt()->innerBlockScopeDepth += innerBlockScopeDepth;
handler.setEndPosition(pn, pos().end);

View File

@ -25,8 +25,8 @@ namespace frontend {
struct StmtInfoPC : public StmtInfoBase
{
StmtInfoPC* down; /* info for enclosing statement */
StmtInfoPC* downScope; /* next enclosing lexical scope */
StmtInfoPC* enclosing;
StmtInfoPC* enclosingScope;
uint32_t blockid; /* for simplified dominance computation */
uint32_t innerBlockScopeDepth; /* maximum depth of nested block scopes, in slots */
@ -284,10 +284,10 @@ struct ParseContext : public GenericParseContext
bool init(TokenStream& ts);
unsigned blockid() { return stmtStack.top() ? stmtStack.top()->blockid : bodyid; }
unsigned blockid() { return stmtStack.innermost() ? stmtStack.innermost()->blockid : bodyid; }
StmtInfoPC* topStmt() const { return stmtStack.top(); }
StmtInfoPC* topScopeStmt() const { return stmtStack.topScopal(); }
StmtInfoPC* innermostStmt() const { return stmtStack.innermost(); }
StmtInfoPC* innermostScopeStmt() const { return stmtStack.innermostScopal(); }
// True if we are at the topmost level of a entire script or function body.
// For example, while parsing this code we would encounter f1 and f2 at
@ -296,8 +296,8 @@ struct ParseContext : public GenericParseContext
// function f1() { function f2() { } }
// if (cond) { function f3() { if (cond) { function f4() { } } } }
//
bool atBodyLevel() { return !topStmt(); }
bool atGlobalLevel() { return atBodyLevel() && !sc->isFunctionBox() && !topScopeStmt(); }
bool atBodyLevel() { return !innermostStmt(); }
bool atGlobalLevel() { return atBodyLevel() && !sc->isFunctionBox() && !innermostScopeStmt(); }
// True if this is the ParseContext for the body of a function created by
// the Function constructor.
@ -354,7 +354,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
~AutoPushStmtInfoPC();
bool generateBlockId();
bool makeTopLexicalScope(StaticBlockObject& blockObj);
bool makeInnermostLexicalScope(StaticBlockObject& blockObj);
StmtInfoPC& operator*() { return stmt_; }
StmtInfoPC* operator->() { return &stmt_; }

View File

@ -555,24 +555,19 @@ template <class StmtInfo>
class MOZ_STACK_CLASS StmtInfoStack
{
// Top of the stack.
StmtInfo* topStmt_;
StmtInfo* innermostStmt_;
// Top scope statement with a nested scope.
StmtInfo* topScopeStmt_;
StmtInfo* innermostScopeStmt_;
public:
explicit StmtInfoStack(ExclusiveContext* cx)
: topStmt_(nullptr),
topScopeStmt_(nullptr)
: innermostStmt_(nullptr),
innermostScopeStmt_(nullptr)
{ }
StmtInfo* top() const { return topStmt_; }
StmtInfo* topScopal() const { return topScopeStmt_; }
NestedScopeObject* topStaticScope() const {
if (!topScopal())
return nullptr;
return topScopal()->staticScope;
}
StmtInfo* innermost() const { return innermostStmt_; }
StmtInfo* innermostScopal() const { return innermostScopeStmt_; }
void push(StmtInfo* stmt, StmtType type) {
stmt->type = type;
@ -580,36 +575,36 @@ class MOZ_STACK_CLASS StmtInfoStack
stmt->isForLetBlock = false;
stmt->label = nullptr;
stmt->staticScope = nullptr;
stmt->down = topStmt_;
stmt->downScope = nullptr;
topStmt_ = stmt;
stmt->enclosing = innermostStmt_;
stmt->enclosingScope = nullptr;
innermostStmt_ = stmt;
}
void pushNestedScope(StmtInfo* stmt, StmtType type, NestedScopeObject& staticScope) {
push(stmt, type);
linkAsTopScopal(stmt, staticScope);
linkAsInnermostScopal(stmt, staticScope);
}
void pop() {
StmtInfo* stmt = topStmt_;
topStmt_ = stmt->down;
StmtInfo* stmt = innermostStmt_;
innermostStmt_ = stmt->enclosing;
if (stmt->linksScope())
topScopeStmt_ = stmt->downScope;
innermostScopeStmt_ = stmt->enclosingScope;
}
void linkAsTopScopal(StmtInfo* stmt, NestedScopeObject& staticScope) {
MOZ_ASSERT(stmt != topScopal());
MOZ_ASSERT(!stmt->downScope);
stmt->downScope = topScopeStmt_;
topScopeStmt_ = stmt;
void linkAsInnermostScopal(StmtInfo* stmt, NestedScopeObject& staticScope) {
MOZ_ASSERT(stmt != innermostScopal());
MOZ_ASSERT(!stmt->enclosingScope);
stmt->enclosingScope = innermostScopeStmt_;
innermostScopeStmt_ = stmt;
stmt->staticScope = &staticScope;
}
void makeTopLexicalScope(StaticBlockObject& blockObj) {
MOZ_ASSERT(!topStmt_->isBlockScope);
MOZ_ASSERT(topStmt_->canBeBlockScope());
topStmt_->isBlockScope = true;
linkAsTopScopal(topStmt_, blockObj);
void makeInnermostLexicalScope(StaticBlockObject& blockObj) {
MOZ_ASSERT(!innermostStmt_->isBlockScope);
MOZ_ASSERT(innermostStmt_->canBeBlockScope());
innermostStmt_->isBlockScope = true;
linkAsInnermostScopal(innermostStmt_, blockObj);
}
};