Bug 1179063 - Cleanup: rename top -> innermost, down -> enclosing in StmtInfoStack. (r=efaust)
authorShu-yu Guo <shu@rfrn.org>
Thu, 30 Jul 2015 22:17:04 -0700
changeset 287243 b25c64b684911e6ab59e43aee7f7af581f464440
parent 287242 0722492759ff3e69d63f75ed0b27083b34b1ec5b
child 287244 ab699f666b06a1e75a7efb55a243b6746610b4f7
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersefaust
bugs1179063
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1179063 - Cleanup: rename top -> innermost, down -> enclosing in StmtInfoStack. (r=efaust)
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/frontend/SharedContext.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -50,18 +50,18 @@ using namespace js::frontend;
 
 using mozilla::DebugOnly;
 using mozilla::NumberIsInt32;
 using mozilla::PodCopy;
 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 */
     ptrdiff_t       continues;      /* offset of last continue in loop */
     uint32_t        blockScopeIndex; /* index of scope in BlockScopeArray */
 
     explicit StmtInfoBCE(ExclusiveContext* cx) : StmtInfoBase(cx) {}
 
@@ -379,27 +379,27 @@ static const char * const statementName[
     "while loop",            /* WHILE_LOOP */
     "spread",                /* SPREAD */
 };
 
 static_assert(MOZ_ARRAY_LENGTH(statementName) == uint16_t(StmtType::LIMIT),
               "statementName array and StmtType enum must be consistent");
 
 static const char*
-StatementName(StmtInfoBCE* topStmt)
-{
-    if (!topStmt)
+StatementName(StmtInfoBCE* stmt)
+{
+    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)
-{
-    ts.reportError(JSMSG_NEED_DIET, StatementName(topStmt));
+ReportStatementTooLarge(TokenStream& ts, StmtInfoBCE* stmt)
+{
+    ts.reportError(JSMSG_NEED_DIET, StatementName(stmt));
 }
 
 /*
  * Emit a backpatch op with offset pointing to the previous jump of this type,
  * so that we can walk back up the chain fixing up the op and jump offset.
  */
 bool
 BytecodeEmitter::emitBackPatchOp(ptrdiff_t* lastp)
@@ -504,17 +504,17 @@ BytecodeEmitter::emitLoopEntry(ParseNode
         /* Update the line number, as for LOOPHEAD. */
         MOZ_ASSERT_IF(nextpn->isKind(PNK_STATEMENTLIST), nextpn->isArity(PN_LIST));
         if (nextpn->isKind(PNK_STATEMENTLIST) && nextpn->pn_head)
             nextpn = nextpn->pn_head;
         if (!updateSourceCoordNotes(nextpn->pn_pos.begin))
             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);
     return emit2(JSOP_LOOPENTRY, loopDepthAndFlags);
 }
 
 void
 BytecodeEmitter::checkTypeSet(JSOp op)
@@ -569,17 +569,17 @@ class NonLocalExitScope {
 
   public:
     explicit NonLocalExitScope(BytecodeEmitter* bce_)
       : bce(bce_),
         savedScopeIndex(bce->blockScopeList.length()),
         savedDepth(bce->stackDepth),
         openScopeIndex(UINT32_MAX)
     {
-        if (StmtInfoBCE* stmt = bce->topScopeStmt())
+        if (StmtInfoBCE* stmt = bce->innermostScopeStmt())
             openScopeIndex = stmt->blockScopeIndex;
     }
     ~NonLocalExitScope() {
         for (uint32_t n = savedScopeIndex; n < bce->blockScopeList.length(); n++)
             bce->blockScopeList.recordEnd(n, bce->offset());
         bce->stackDepth = savedDepth;
     }
 
@@ -601,17 +601,17 @@ class NonLocalExitScope {
  */
 bool
 NonLocalExitScope::prepareForNonLocalJump(StmtInfoBCE* toStmt)
 {
     int npops = 0;
 
 #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();
             if (!bce->emitBackPatchOp(&stmt->gosubs()))
                 return false;
             break;
 
           case StmtType::WITH:
@@ -716,48 +716,49 @@ BytecodeEmitter::pushStatement(StmtInfoB
 }
 
 void
 BytecodeEmitter::pushLoopStatement(LoopStmtInfo* stmt, StmtType type, ptrdiff_t top)
 {
     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)
         loopSlots = 3;
     else if (type == StmtType::FOR_IN_LOOP || type == StmtType::FOR_OF_LOOP)
         loopSlots = 2;
     else
         loopSlots = 0;
 
     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()) {
         MOZ_ASSERT(!parent);
 
         // Top-level eval scripts have a placeholder static scope so that
         // StaticScopeIter may iterate through evals.
         return sc->asGlobalSharedContext()->topStaticScope();
@@ -815,17 +816,17 @@ BytecodeEmitter::computeAliasedSlots(Han
 void
 BytecodeEmitter::computeLocalOffset(Handle<StaticBlockObject*> blockObj)
 {
     unsigned nbodyfixed = sc->isFunctionBox()
                           ? script->bindings.numUnaliasedBodyLevelLocals()
                           : 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>()) {
                 StaticBlockObject& outerBlock = outer->as<StaticBlockObject>();
                 localOffset = outerBlock.localOffset() + outerBlock.numVariables();
                 break;
             }
         }
@@ -915,49 +916,49 @@ BytecodeEmitter::enterNestedScope(StmtIn
         if (!emitInternedObjectOp(scopeObjectIndex, JSOP_ENTERWITH))
             return false;
         break;
       default:
         MOZ_CRASH("Unexpected scope statement");
     }
 
     uint32_t parent = BlockScopeNote::NoBlockScopeIndex;
-    if (StmtInfoBCE* stmt = topScopeStmt())
+    if (StmtInfoBCE* stmt = innermostScopeStmt())
         parent = stmt->blockScopeIndex;
 
     stmt->blockScopeIndex = blockScopeList.length();
     if (!blockScopeList.append(scopeObjectIndex, offset(), parent))
         return false;
 
     pushStatement(stmt, stmtType, offset());
     scopeObj->initEnclosingNestedScope(enclosingStaticScope());
-    stmtStack.linkAsTopScopal(stmt, *scopeObj);
+    stmtStack.linkAsInnermostScopal(stmt, *scopeObj);
     MOZ_ASSERT(stmt->linksScope());
     stmt->isBlockScope = (stmtType == StmtType::BLOCK);
 
     return true;
 }
 
 // Patches |breaks| and |continues| unless the top statement info record
 // represents a try-catch-finally suite.
 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();
 }
 
 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;
 
 #ifdef DEBUG
     MOZ_ASSERT(blockScopeList.list[blockScopeIndex].length == 0);
     uint32_t blockObjIndex = blockScopeList.list[blockScopeIndex].index;
     ObjectBox* blockObjBox = objectList.find(blockObjIndex);
     NestedScopeObject* staticScope = &blockObjBox->object->as<NestedScopeObject>();
@@ -1157,17 +1158,17 @@ BytecodeEmitter::emitAliasedVarOp(JSOp o
 
     return emitScopeCoordOp(op, sc);
 }
 
 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;
         }
     }
 
     return depth;
 }
@@ -1301,18 +1302,18 @@ BytecodeEmitter::emitAliasedVarOp(JSOp o
         MOZ_ASSERT(IsLocalOp(pn->getOp()) || pn->isKind(PNK_FUNCTION));
         uint32_t local = pn->pn_cookie.slot();
         if (local < bceOfDef->script->bindings.numBodyLevelLocals()) {
             if (!assignHops(pn, skippedScopes + bceOfDef->dynamicNestedScopeDepth(), &sc))
                 return false;
             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()) {
                 if (b->needsClone())
                     skippedScopes++;
                 b = &b->enclosingNestedScope()->as<StaticBlockObject>();
             }
             if (!assignHops(pn, skippedScopes, &sc))
@@ -1508,17 +1509,17 @@ BytecodeEmitter::tryConvertFreeName(Pars
     /*
      * When parsing inner functions lazily, parse nodes for outer functions no
      * longer exist and only the function's scope chain is available for
      * resolving upvar accesses within the inner function.
      */
     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;
         }
 
         size_t hops = 0;
         FunctionBox* funbox = sc->asFunctionBox();
         if (funbox->hasExtensibleScope())
             return false;
@@ -2307,17 +2308,17 @@ BytecodeEmitter::checkSideEffects(ParseN
 
     MOZ_CRASH("invalid, unenumerated ParseNodeKind value encountered in "
               "BytecodeEmitter::checkSideEffects");
 }
 
 bool
 BytecodeEmitter::isInLoop()
 {
-    for (StmtInfoBCE* stmt = topStmt(); stmt; stmt = stmt->down) {
+    for (StmtInfoBCE* stmt = innermostStmt(); stmt; stmt = stmt->enclosing) {
         if (stmt->isLoop())
             return true;
     }
     return false;
 }
 
 bool
 BytecodeEmitter::checkSingletonContext()
@@ -2335,17 +2336,17 @@ BytecodeEmitter::checkRunOnceContext()
 }
 
 bool
 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;
     }
 
     return false;
 }
 
 void
@@ -4761,22 +4762,22 @@ class EmitLevelManager
 
 bool
 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. */
     if (!emit1(JSOP_EXCEPTION))
         return false;
 
     /*
      * Dup the exception object if there is a guard for rethrowing to use
@@ -5349,17 +5350,17 @@ BytecodeEmitter::emitForOf(StmtType type
         // Emit code for the loop body.
         if (!emitTree(forBody))
             return false;
 
         // Set loop and enclosing "update" offsets, for continue.
         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;
 
         MOZ_ASSERT(this->stackDepth == loopDepth - 1);
 
         // StmtType::SPREAD never contain continue, so do not set "update" offset.
     }
@@ -5391,17 +5392,17 @@ BytecodeEmitter::emitForOf(StmtType type
 
     MOZ_ASSERT(this->stackDepth == loopDepth);
 
     // Let Ion know where the closing jump of this loop is.
     if (!setSrcNoteOffset(noteIndex, 0, beq - jmp))
         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()))
         return false;
 
     if (letDecl) {
         if (!leaveNestedScope(&letStmt))
             return false;
@@ -5490,17 +5491,17 @@ BytecodeEmitter::emitForIn(ParseNode* pn
     /* Emit code for the loop body. */
     if (!emitTree(forBody))
         return false;
 
     /* Set loop and enclosing "update" offsets, for continue. */
     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.
      */
     setJumpOffsetAt(jmp);
     if (!emitLoopEntry(nullptr))
         return false;
     if (!emit1(JSOP_POP))
@@ -5611,31 +5612,31 @@ BytecodeEmitter::emitNormalFor(ParseNode
     ptrdiff_t tmp2 = offset();
 
     // Set loop and enclosing "update" offsets, for continue.  Note that we
     // continue to immediately *before* the block-freshening: continuing must
     // refresh the block.
     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);
-
-        if (parent->staticScope->as<StaticBlockObject>().needsClone()) {
+        StmtInfoBCE* enclosing = stmtInfo.enclosing;
+        MOZ_ASSERT(enclosing->type == StmtType::BLOCK);
+        MOZ_ASSERT(enclosing->isBlockScope);
+
+        if (enclosing->staticScope->as<StaticBlockObject>().needsClone()) {
             if (!emit1(JSOP_FRESHENBLOCKSCOPE))
                 return false;
         }
     }
 
     /* Check for update code to do before the condition (if any). */
     if (ParseNode* update = forHead->pn_kid3) {
         if (!updateSourceCoordNotes(update->pn_pos.begin))
@@ -5839,17 +5840,17 @@ BytecodeEmitter::emitFunction(ParseNode*
      * is executed. This extra work for top-level scripts is not necessary
      * when we emit the code for a function. It is fully parsed prior to
      * invocation of the emitter and calls to emitTree for function
      * definitions can be scheduled before generating the rest of code.
      */
     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;
         if (!updateSourceCoordNotes(pn->pn_pos.begin))
             return false;
         switchToMain();
     } else {
 #ifdef DEBUG
@@ -5902,17 +5903,17 @@ BytecodeEmitter::emitDo(ParseNode* pn)
     if (!emitTree(pn->pn_left))
         return false;
 
     /* Set loop and enclosing label update offsets, for continue. */
     ptrdiff_t off = offset();
     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))
         return false;
 
     ptrdiff_t beq;
     if (!emitJump(JSOP_IFNE, top - offset(), &beq))
         return false;
@@ -5988,56 +5989,56 @@ BytecodeEmitter::emitWhile(ParseNode* pn
 
     popStatement();
     return true;
 }
 
 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;
     }
 
     return emitGoto(stmt, &stmt->breaks, noteType);
 }
 
 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);
 }
 
 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;
     }
     return false;
 }
 
 bool
 BytecodeEmitter::emitReturn(ParseNode* pn)
@@ -6367,23 +6368,23 @@ BytecodeEmitter::emitStatement(ParseNode
 
     /* Don't eliminate expressions with side effects. */
     if (!useful) {
         if (!checkSideEffects(pn2, &useful))
             return false;
 
         /*
          * 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;
         }
     }
 
     if (useful) {
         JSOp op = wantval ? JSOP_SETRVAL : JSOP_POP;
         MOZ_ASSERT_IF(pn2->isKind(PNK_ASSIGN), pn2->isOp(JSOP_NOP));
@@ -8121,17 +8122,17 @@ BytecodeEmitter::addToSrcNoteDelta(jssrc
     }
     return true;
 }
 
 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;
     }
 
     SrcNotesVector& notes = this->notes();
 
     /* Find the offset numbered which (i.e., skip exactly which offsets). */
     jssrcnote* sn = &notes[index];
     MOZ_ASSERT(SN_TYPE(sn) != SRC_XDELTA);
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -214,18 +214,18 @@ struct BytecodeEmitter
      */
     BytecodeEmitter(BytecodeEmitter* parent, Parser<FullParseHandler>* parser, SharedContext* sc,
                     HandleScript script, Handle<LazyScript*> lazyScript,
                     bool insideEval, HandleScript evalCaller,
                     bool insideNonGlobalEval, uint32_t lineNum, EmitterMode emitterMode = Normal);
     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);
 
     MOZ_ALWAYS_INLINE
     bool makeAtomIndex(JSAtom* atom, jsatomid* indexp) {
         AtomIndexAddPtr p = atomIndices->lookupForAdd(atom);
         if (p) {
             *indexp = p.value();
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -1279,18 +1279,18 @@ MatchOrInsertSemicolon(TokenStream& ts)
  */
 template <class ContextT>
 static StmtInfoPC*
 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
          * further up the stack, we have to abort the search.
          */
         if (stmt->type == StmtType::WITH && !ct->sc->isDotVariable(atom))
             break;
 
@@ -3136,21 +3136,22 @@ struct PopLetDecl {
 // update the maximum block scope depth of the outer statement or parse
 // context.  In the end, pc->blockScopeDepth will indicate the number of slots
 // to reserve in the fixed part of a stack frame.
 //
 template <typename ParseHandler>
 static void
 AccumulateBlockScopeDepth(ParseContext<ParseHandler>* pc)
 {
-    uint32_t innerDepth = pc->topStmt()->innerBlockScopeDepth;
-    StmtInfoPC* outer = pc->topStmt()->down;
-
-    if (pc->topStmt()->isBlockScope)
-        innerDepth += pc->topStmt()->staticScope->template as<StaticBlockObject>().numVariables();
+    StmtInfoPC* stmt = pc->innermostStmt();
+    uint32_t innerDepth = stmt->innerBlockScopeDepth;
+    StmtInfoPC* outer = stmt->enclosing;
+
+    if (stmt->isBlockScope)
+        innerDepth += stmt->staticScope->template as<StaticBlockObject>().numVariables();
 
     if (outer) {
         if (outer->innerBlockScopeDepth < innerDepth)
             outer->innerBlockScopeDepth = innerDepth;
     } else {
         if (pc->blockScopeDepth < innerDepth)
             pc->blockScopeDepth = innerDepth;
     }
@@ -3170,34 +3171,34 @@ template <typename ParseHandler>
 Parser<ParseHandler>::AutoPushStmtInfoPC::AutoPushStmtInfoPC(Parser<ParseHandler>& parser,
                                                              StmtType type,
                                                              NestedScopeObject& staticScope)
   : parser_(parser),
     stmt_(parser.context)
 {
     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);
 }
 
 template <typename ParseHandler>
 Parser<ParseHandler>::AutoPushStmtInfoPC::~AutoPushStmtInfoPC()
 {
     // While this destructor is infallible, it is preferable to fail fast on
     // aborted syntax parses.
     if (parser_.hadAbortedSyntaxParse())
         return;
 
     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);
     pc->stmtStack.pop();
 
     if (scopeObj) {
         if (scopeObj->is<StaticBlockObject>()) {
             RootedStaticBlockObject blockObj(parser_.context, &scopeObj->as<StaticBlockObject>());
@@ -3212,29 +3213,29 @@ template <typename ParseHandler>
 bool
 Parser<ParseHandler>::AutoPushStmtInfoPC::generateBlockId()
 {
     return GenerateBlockId(parser_.tokenStream, parser_.pc, stmt_.blockid);
 }
 
 template <typename ParseHandler>
 bool
-Parser<ParseHandler>::AutoPushStmtInfoPC::makeTopLexicalScope(StaticBlockObject& blockObj)
-{
-    MOZ_ASSERT(parser_.pc->stmtStack.top() == &stmt_);
-    parser_.pc->stmtStack.makeTopLexicalScope(blockObj);
+Parser<ParseHandler>::AutoPushStmtInfoPC::makeInnermostLexicalScope(StaticBlockObject& blockObj)
+{
+    MOZ_ASSERT(parser_.pc->stmtStack.innermost() == &stmt_);
+    parser_.pc->stmtStack.makeInnermostLexicalScope(blockObj);
     return generateBlockId();
 }
 
 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)
             return true;
     }
     return false;
 }
 
@@ -3672,17 +3673,17 @@ Parser<ParseHandler>::pushLexicalScope(H
     ObjectBox* blockbox = newObjectBox(blockObj);
     if (!blockbox)
         return null();
 
     Node pn = handler.newLexicalScope(blockbox);
     if (!pn)
         return null();
 
-    if (!stmt.makeTopLexicalScope(*blockObj))
+    if (!stmt.makeInnermostLexicalScope(*blockObj))
         return null();
     handler.setBlockId(pn, stmt->blockid);
     return pn;
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::pushLexicalScope(AutoPushStmtInfoPC& stmt)
@@ -4060,17 +4061,17 @@ Parser<FullParseHandler>::checkAndPrepar
      * 'for (let ...)'. If we pass this error test, make the enclosing
      * StmtInfoPC be our scope. Further let declarations in this block will
      * find this scope statement and use the same block object.
      *
      * If we are the first let declaration in this block (i.e., when the
      * 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");
         return false;
     }
 
     if (!stmt) {
         MOZ_ASSERT(pc->atBodyLevel());
@@ -4081,49 +4082,49 @@ Parser<FullParseHandler>::checkAndPrepar
          * before the global object in the overall chain.  This extra
          * object is present in the scope chain for all code in that
          * global, including self-hosted code.  But self-hosted code
          * must be usable against *any* global object, including ones
          * with other let variables -- variables possibly placed in
          * 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'");
             return false;
         }
         return true;
     }
 
     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);
 
         ObjectBox* blockbox = newObjectBox(blockObj);
         if (!blockbox)
             return false;
 
         /*
          * Some obvious assertions here, but they may help clarify the
          * situation. This stmt is not yet a scope, so it must not be a
          * 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;
         MOZ_ASSERT(!tmp || !tmp->isKind(PNK_LEXICALSCOPE));
 #endif
 
         /* Create a new lexical scope node for these statements. */
         ParseNode* pn1 = handler.new_<LexicalScopeNode>(blockbox, pc->blockNode);
@@ -4133,17 +4134,17 @@ Parser<FullParseHandler>::checkAndPrepar
     }
     return true;
 }
 
 static StaticBlockObject*
 CurrentLexicalStaticBlock(ParseContext<FullParseHandler>* pc)
 {
     return pc->atBodyLevel() ? nullptr :
-           &pc->topStmt()->staticScope->as<StaticBlockObject>();
+           &pc->innermostStmt()->staticScope->as<StaticBlockObject>();
 }
 
 template <>
 ParseNode*
 Parser<FullParseHandler>::makeInitializedLexicalBinding(HandlePropertyName name, bool isConst,
                                                         const TokenPos& pos)
 {
     // Handle the silliness of global and body level lexical decls.
@@ -5274,17 +5275,17 @@ Parser<ParseHandler>::switchStatement(Yi
     if (!discriminant)
         return null();
 
     MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_SWITCH);
     MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_SWITCH);
 
     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());
     if (!caseList)
         return null();
 
     Node saveBlock = pc->blockNode;
     pc->blockNode = caseList;
@@ -5400,19 +5401,19 @@ Parser<ParseHandler>::continueStatement(
 {
     MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_CONTINUE));
     uint32_t begin = pos().begin;
 
     RootedPropertyName label(context);
     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();
             }
             if (stmt->type == StmtType::LABEL) {
                 if (stmt->label == label) {
                     if (!stmt2 || !stmt2->isLoop()) {
                         report(ParseError, false, null(), JSMSG_BAD_CONTINUE);
@@ -5420,17 +5421,17 @@ Parser<ParseHandler>::continueStatement(
                     }
                     break;
                 }
             } else {
                 stmt2 = stmt;
             }
         }
     } else {
-        for (; ; stmt = stmt->down) {
+        for (; ; stmt = stmt->enclosing) {
             if (!stmt) {
                 report(ParseError, false, null(), JSMSG_BAD_CONTINUE);
                 return null();
             }
             if (stmt->isLoop())
                 break;
         }
     }
@@ -5446,28 +5447,28 @@ typename ParseHandler::Node
 Parser<ParseHandler>::breakStatement(YieldHandling yieldHandling)
 {
     MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_BREAK));
     uint32_t begin = pos().begin;
 
     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();
             }
             if (stmt->type == StmtType::LABEL && stmt->label == label)
                 break;
         }
     } else {
-        for (; ; stmt = stmt->down) {
+        for (; ; stmt = stmt->enclosing) {
             if (!stmt) {
                 report(ParseError, false, null(), JSMSG_TOUGH_BREAK);
                 return null();
             }
             if (stmt->isLoop() || stmt->type == StmtType::SWITCH)
                 break;
         }
     }
@@ -5739,17 +5740,17 @@ Parser<SyntaxParseHandler>::withStatemen
 }
 
 template <typename ParseHandler>
 typename ParseHandler::Node
 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();
         }
     }
 
     tokenStream.consumeKnownToken(TOK_COLON);
 
@@ -5869,17 +5870,17 @@ Parser<ParseHandler>::tryStatement(Yield
             MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_CATCH);
 
             /*
              * Contrary to ECMA Ed. 3, the catch variable is lexically
              * scoped, not a property of a new Object instance.  This is
              * 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);
 
             if (!tokenStream.getToken(&tt))
                 return null();
             Node catchName;
             switch (tt) {
               case TOK_LB:
@@ -7038,17 +7039,17 @@ LegacyCompExprTransplanter::transplant(P
                     return false;
                 if (!AdjustBlockId(parser->tokenStream, dn, adjust, pc))
                     return false;
             }
 
             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));
 
                 if (pc->sc->isDotVariable(atom)) {
                     if (dn->dn_uses == pn) {
                         if (!BumpStaticLevel(parser->tokenStream, dn, pc))
                             return false;
@@ -7147,17 +7148,17 @@ LegacyCompExprTransplanter::transplant(P
 // information we keep is the maximum nested depth within a statement, so we
 // just conservatively propagate the maximum nested depth from the top statement
 // to the comprehension tail.
 //
 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;
 }
 
 /*
  * Starting from a |for| keyword after the first array initialiser element or
  * an expression in an open parenthesis, parse the tail of the comprehension
  * or generator expression signified by this |for| keyword in context.
  *
  * Return null on failure, else return the top-most parse node for the array
@@ -7237,19 +7238,20 @@ Parser<FullParseHandler>::legacyComprehe
 
     LegacyCompExprTransplanter transplanter(bodyExpr, this, outerpc, comprehensionKind, adjust);
     if (!transplanter.init())
         return null();
 
     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) {
         /*
          * FOR node is binary, left is loop control and right is body.  Use
          * index to count each block-local let-variable on the left-hand side
          * of the in/of.
          */
@@ -7413,17 +7415,17 @@ Parser<FullParseHandler>::legacyComprehe
         bodyStmt = handler.newUnary(PNK_ARRAYPUSH, JSOP_ARRAYPUSH,
                                     bodyExpr->pn_pos.begin, bodyExpr);
         if (!bodyStmt)
             return null();
     }
 
     *pnp = bodyStmt;
 
-    pc->topStmt()->innerBlockScopeDepth += innerBlockScopeDepth;
+    pc->innermostStmt()->innerBlockScopeDepth += innerBlockScopeDepth;
 
     handler.setEndPosition(pn, pos().end);
 
     return pn;
 }
 
 template <>
 SyntaxParseHandler::Node
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -20,18 +20,18 @@
 #include "frontend/SharedContext.h"
 #include "frontend/SyntaxParseHandler.h"
 
 namespace js {
 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 */
 
     // Lexical declarations inside switches are tricky because the block id
     // doesn't convey dominance information. Record what index the current
     // case's lexical declarations start at so we may generate dead zone
     // checks for other cases' declarations.
@@ -279,30 +279,30 @@ struct ParseContext : public GenericPars
     {
         prs->pc = this;
     }
 
     ~ParseContext();
 
     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
     // body level, but we would not encounter f3 or f4 at body level:
     //
     //   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.
     bool isFunctionConstructorBody() const {
         return sc->isFunctionBox() && staticLevel == 0;
     }
 
     inline bool useAsmOrInsideUseAsm() const {
@@ -349,17 +349,17 @@ class Parser : private JS::AutoGCRooter,
 
       public:
         AutoPushStmtInfoPC(Parser<ParseHandler>& parser, StmtType type);
         AutoPushStmtInfoPC(Parser<ParseHandler>& parser, StmtType type,
                            NestedScopeObject& staticScope);
         ~AutoPushStmtInfoPC();
 
         bool generateBlockId();
-        bool makeTopLexicalScope(StaticBlockObject& blockObj);
+        bool makeInnermostLexicalScope(StaticBlockObject& blockObj);
 
         StmtInfoPC& operator*() { return stmt_; }
         StmtInfoPC* operator->() { return &stmt_; }
         operator StmtInfoPC*() { return &stmt_; }
     };
 
   public:
     ExclusiveContext* const context;
--- a/js/src/frontend/SharedContext.h
+++ b/js/src/frontend/SharedContext.h
@@ -550,71 +550,66 @@ struct StmtInfoBase
         return StmtType::TRY <= type && type <= StmtType::SUBROUTINE;
     }
 };
 
 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;
         stmt->isBlockScope = false;
         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);
     }
 };
 
 } // namespace frontend
 
 } // namespace js
 
 #endif /* frontend_SharedContext_h */