tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

EmitterScope.cpp (38903B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "frontend/EmitterScope.h"
      8 
      9 #include "frontend/AbstractScopePtr.h"
     10 #include "frontend/BytecodeControlStructures.h"
     11 #include "frontend/BytecodeEmitter.h"
     12 #include "frontend/ModuleSharedContext.h"
     13 #include "frontend/TDZCheckCache.h"
     14 #include "frontend/UsingEmitter.h"
     15 #include "js/friend/ErrorMessages.h"  // JSMSG_*
     16 #include "vm/EnvironmentObject.h"     // ClassBodyLexicalEnvironmentObject
     17 
     18 using namespace js;
     19 using namespace js::frontend;
     20 
     21 using mozilla::DebugOnly;
     22 using mozilla::Maybe;
     23 using mozilla::Nothing;
     24 using mozilla::Some;
     25 
     26 EmitterScope::EmitterScope(BytecodeEmitter* bce)
     27    : Nestable<EmitterScope>(&bce->innermostEmitterScope_),
     28      nameCache_(bce->fc->nameCollectionPool()),
     29      hasEnvironment_(false),
     30      environmentChainLength_(0),
     31      nextFrameSlot_(0),
     32      scopeIndex_(ScopeNote::NoScopeIndex),
     33      noteIndex_(ScopeNote::NoScopeNoteIndex) {}
     34 
     35 bool EmitterScope::ensureCache(BytecodeEmitter* bce) {
     36  return nameCache_.acquire(bce->fc);
     37 }
     38 
     39 bool EmitterScope::checkSlotLimits(BytecodeEmitter* bce,
     40                                   const ParserBindingIter& bi) {
     41  if (bi.nextFrameSlot() >= LOCALNO_LIMIT ||
     42      bi.nextEnvironmentSlot() >= ENVCOORD_SLOT_LIMIT) {
     43    bce->reportError(nullptr, JSMSG_TOO_MANY_LOCALS);
     44    return false;
     45  }
     46  return true;
     47 }
     48 
     49 bool EmitterScope::checkEnvironmentChainLength(BytecodeEmitter* bce) {
     50  uint32_t hops;
     51  if (EmitterScope* emitterScope = enclosing(&bce)) {
     52    hops = emitterScope->environmentChainLength_;
     53  } else if (!bce->compilationState.input.enclosingScope.isNull()) {
     54    hops =
     55        bce->compilationState.scopeContext.enclosingScopeEnvironmentChainLength;
     56  } else {
     57    // If we're compiling module, enclosingScope is nullptr and it means empty
     58    // global scope.
     59    // See also the assertion in CompilationStencil::instantiateStencils.
     60    //
     61    // Global script also uses enclosingScope == nullptr, but it shouldn't call
     62    // checkEnvironmentChainLength.
     63    MOZ_ASSERT(bce->sc->isModule());
     64    hops = ModuleScope::EnclosingEnvironmentChainLength;
     65  }
     66 
     67  if (hops >= ENVCOORD_HOPS_LIMIT - 1) {
     68    bce->reportError(nullptr, JSMSG_TOO_DEEP, "function");
     69    return false;
     70  }
     71 
     72  environmentChainLength_ = mozilla::AssertedCast<uint16_t>(hops + 1);
     73  return true;
     74 }
     75 
     76 void EmitterScope::updateFrameFixedSlots(BytecodeEmitter* bce,
     77                                         const ParserBindingIter& bi) {
     78  nextFrameSlot_ = bi.nextFrameSlot();
     79  if (nextFrameSlot_ > bce->maxFixedSlots) {
     80    bce->maxFixedSlots = nextFrameSlot_;
     81  }
     82 }
     83 
     84 bool EmitterScope::putNameInCache(BytecodeEmitter* bce,
     85                                  TaggedParserAtomIndex name,
     86                                  NameLocation loc) {
     87  NameLocationMap& cache = *nameCache_;
     88  NameLocationMap::AddPtr p = cache.lookupForAdd(name);
     89  MOZ_ASSERT(!p);
     90  if (!cache.add(p, name, loc)) {
     91    ReportOutOfMemory(bce->fc);
     92    return false;
     93  }
     94  return true;
     95 }
     96 
     97 Maybe<NameLocation> EmitterScope::lookupInCache(BytecodeEmitter* bce,
     98                                                TaggedParserAtomIndex name) {
     99  if (NameLocationMap::Ptr p = nameCache_->lookup(name)) {
    100    return Some(p->value().wrapped);
    101  }
    102  if (fallbackFreeNameLocation_ && nameCanBeFree(bce, name)) {
    103    return fallbackFreeNameLocation_;
    104  }
    105  return Nothing();
    106 }
    107 
    108 EmitterScope* EmitterScope::enclosing(BytecodeEmitter** bce) const {
    109  // There is an enclosing scope with access to the same frame.
    110  if (EmitterScope* inFrame = enclosingInFrame()) {
    111    return inFrame;
    112  }
    113 
    114  // We are currently compiling the enclosing script, look in the
    115  // enclosing BCE.
    116  if ((*bce)->parent) {
    117    *bce = (*bce)->parent;
    118    return (*bce)->innermostEmitterScopeNoCheck();
    119  }
    120 
    121  return nullptr;
    122 }
    123 
    124 mozilla::Maybe<ScopeIndex> EmitterScope::enclosingScopeIndex(
    125    BytecodeEmitter* bce) const {
    126  if (EmitterScope* es = enclosing(&bce)) {
    127    // NOTE: A value of Nothing for the ScopeIndex will occur when the enclosing
    128    // scope is the empty-global-scope. This is only allowed for self-hosting
    129    // code.
    130    MOZ_ASSERT_IF(es->scopeIndex(bce).isNothing(),
    131                  bce->emitterMode == BytecodeEmitter::SelfHosting);
    132    return es->scopeIndex(bce);
    133  }
    134 
    135  // The enclosing script is already compiled or the current script is the
    136  // global script.
    137  return mozilla::Nothing();
    138 }
    139 
    140 /* static */
    141 bool EmitterScope::nameCanBeFree(BytecodeEmitter* bce,
    142                                 TaggedParserAtomIndex name) {
    143  // '.generator' cannot be accessed by name.
    144  return name != TaggedParserAtomIndex::WellKnown::dot_generator_();
    145 }
    146 
    147 NameLocation EmitterScope::searchAndCache(BytecodeEmitter* bce,
    148                                          TaggedParserAtomIndex name) {
    149  Maybe<NameLocation> loc;
    150  uint16_t hops = hasEnvironment() ? 1 : 0;
    151  DebugOnly<bool> inCurrentScript = enclosingInFrame();
    152 
    153  // Start searching in the current compilation.
    154  for (EmitterScope* es = enclosing(&bce); es; es = es->enclosing(&bce)) {
    155    loc = es->lookupInCache(bce, name);
    156    if (loc) {
    157      if (loc->kind() == NameLocation::Kind::EnvironmentCoordinate) {
    158        *loc = loc->addHops(hops);
    159      }
    160      break;
    161    }
    162 
    163    if (es->hasEnvironment()) {
    164      hops++;
    165    }
    166 
    167 #ifdef DEBUG
    168    if (!es->enclosingInFrame()) {
    169      inCurrentScript = false;
    170    }
    171 #endif
    172  }
    173 
    174  // If the name is not found in the current compilation, walk the Scope
    175  // chain encompassing the compilation.
    176  if (!loc) {
    177    MOZ_ASSERT(bce->compilationState.input.target ==
    178                   CompilationInput::CompilationTarget::Delazification ||
    179               bce->compilationState.input.target ==
    180                   CompilationInput::CompilationTarget::Eval);
    181    inCurrentScript = false;
    182    loc = Some(bce->compilationState.scopeContext.searchInEnclosingScope(
    183        bce->fc, bce->compilationState.input, bce->parserAtoms(), name));
    184    if (loc->kind() == NameLocation::Kind::EnvironmentCoordinate) {
    185      *loc = loc->addHops(hops);
    186    }
    187  }
    188 
    189  // Each script has its own frame. A free name that is accessed
    190  // from an inner script must not be a frame slot access. If this
    191  // assertion is hit, it is a bug in the free name analysis in the
    192  // parser.
    193  MOZ_ASSERT_IF(!inCurrentScript, loc->kind() != NameLocation::Kind::FrameSlot);
    194 
    195  // It is always correct to not cache the location. Ignore OOMs to make
    196  // lookups infallible.
    197  if (!putNameInCache(bce, name, *loc)) {
    198    bce->fc->recoverFromOutOfMemory();
    199  }
    200 
    201  return *loc;
    202 }
    203 
    204 bool EmitterScope::internEmptyGlobalScopeAsBody(BytecodeEmitter* bce) {
    205  // Only the self-hosted top-level script uses this. If this changes, you must
    206  // update ScopeStencil::enclosing.
    207  MOZ_ASSERT(bce->emitterMode == BytecodeEmitter::SelfHosting);
    208 
    209  hasEnvironment_ = Scope::hasEnvironment(ScopeKind::Global);
    210 
    211  bce->bodyScopeIndex =
    212      GCThingIndex(bce->perScriptData().gcThingList().length());
    213  return bce->perScriptData().gcThingList().appendEmptyGlobalScope(
    214      &scopeIndex_);
    215 }
    216 
    217 bool EmitterScope::internScopeStencil(BytecodeEmitter* bce,
    218                                      ScopeIndex scopeIndex) {
    219  ScopeStencil& scope = bce->compilationState.scopeData[scopeIndex.index];
    220  hasEnvironment_ = scope.hasEnvironment();
    221  return bce->perScriptData().gcThingList().append(scopeIndex, &scopeIndex_);
    222 }
    223 
    224 bool EmitterScope::internBodyScopeStencil(BytecodeEmitter* bce,
    225                                          ScopeIndex scopeIndex) {
    226  MOZ_ASSERT(bce->bodyScopeIndex == ScopeNote::NoScopeIndex,
    227             "There can be only one body scope");
    228  bce->bodyScopeIndex =
    229      GCThingIndex(bce->perScriptData().gcThingList().length());
    230  return internScopeStencil(bce, scopeIndex);
    231 }
    232 
    233 bool EmitterScope::appendScopeNote(BytecodeEmitter* bce) {
    234  MOZ_ASSERT(ScopeKindIsInBody(scope(bce).kind()) && enclosingInFrame(),
    235             "Scope notes are not needed for body-level scopes.");
    236  noteIndex_ = bce->bytecodeSection().scopeNoteList().length();
    237  return bce->bytecodeSection().scopeNoteList().append(
    238      index(), bce->bytecodeSection().offset(),
    239      enclosingInFrame() ? enclosingInFrame()->noteIndex()
    240                         : ScopeNote::NoScopeNoteIndex);
    241 }
    242 
    243 bool EmitterScope::clearFrameSlotRange(BytecodeEmitter* bce, JSOp opcode,
    244                                       uint32_t slotStart,
    245                                       uint32_t slotEnd) const {
    246  MOZ_ASSERT(opcode == JSOp::Uninitialized || opcode == JSOp::Undefined);
    247 
    248  // Lexical bindings throw ReferenceErrors if they are used before
    249  // initialization. See ES6 8.1.1.1.6.
    250  //
    251  // For completeness, lexical bindings are initialized in ES6 by calling
    252  // InitializeBinding, after which touching the binding will no longer
    253  // throw reference errors. See 13.1.11, 9.2.13, 13.6.3.4, 13.6.4.6,
    254  // 13.6.4.8, 13.14.5, 15.1.8, and 15.2.0.15.
    255  //
    256  // This code is also used to reset `var`s to `undefined` when entering an
    257  // extra body var scope; and to clear slots when leaving a block, in
    258  // generators and async functions, to avoid keeping garbage alive
    259  // indefinitely.
    260  if (slotStart != slotEnd) {
    261    if (!bce->emit1(opcode)) {
    262      return false;
    263    }
    264    for (uint32_t slot = slotStart; slot < slotEnd; slot++) {
    265      if (!bce->emitLocalOp(JSOp::InitLexical, slot)) {
    266        return false;
    267      }
    268    }
    269    if (!bce->emit1(JSOp::Pop)) {
    270      return false;
    271    }
    272  }
    273 
    274  return true;
    275 }
    276 
    277 void EmitterScope::dump(BytecodeEmitter* bce) {
    278  fprintf(stdout, "EmitterScope [%s] %p\n", ScopeKindString(scope(bce).kind()),
    279          this);
    280 
    281  for (NameLocationMap::Range r = nameCache_->all(); !r.empty(); r.popFront()) {
    282    const NameLocation& l = r.front().value();
    283 
    284    auto atom = r.front().key();
    285    UniqueChars bytes = bce->parserAtoms().toPrintableString(atom);
    286    if (!bytes) {
    287      ReportOutOfMemory(bce->fc);
    288      return;
    289    }
    290    if (l.kind() != NameLocation::Kind::Dynamic) {
    291      fprintf(stdout, "  %s %s ", BindingKindString(l.bindingKind()),
    292              bytes.get());
    293    } else {
    294      fprintf(stdout, "  %s ", bytes.get());
    295    }
    296 
    297    switch (l.kind()) {
    298      case NameLocation::Kind::Dynamic:
    299        fprintf(stdout, "dynamic\n");
    300        break;
    301      case NameLocation::Kind::Global:
    302        fprintf(stdout, "global\n");
    303        break;
    304      case NameLocation::Kind::Intrinsic:
    305        fprintf(stdout, "intrinsic\n");
    306        break;
    307      case NameLocation::Kind::NamedLambdaCallee:
    308        fprintf(stdout, "named lambda callee\n");
    309        break;
    310      case NameLocation::Kind::Import:
    311        fprintf(stdout, "import\n");
    312        break;
    313      case NameLocation::Kind::ArgumentSlot:
    314        fprintf(stdout, "arg slot=%u\n", l.argumentSlot());
    315        break;
    316      case NameLocation::Kind::FrameSlot:
    317        fprintf(stdout, "frame slot=%u\n", l.frameSlot());
    318        break;
    319      case NameLocation::Kind::EnvironmentCoordinate:
    320        fprintf(stdout, "environment hops=%u slot=%u\n",
    321                l.environmentCoordinate().hops(),
    322                l.environmentCoordinate().slot());
    323        break;
    324      case NameLocation::Kind::DebugEnvironmentCoordinate:
    325        fprintf(stdout, "debugEnvironment hops=%u slot=%u\n",
    326                l.environmentCoordinate().hops(),
    327                l.environmentCoordinate().slot());
    328        break;
    329      case NameLocation::Kind::DynamicAnnexBVar:
    330        fprintf(stdout, "dynamic annex b var\n");
    331        break;
    332    }
    333  }
    334 
    335  fprintf(stdout, "\n");
    336 }
    337 
    338 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
    339 bool EmitterScope::prepareForDisposableScopeBody(BytecodeEmitter* bce) {
    340  if (hasDisposables()) {
    341    if (!usingEmitter_->prepareForDisposableScopeBody(blockKind_)) {
    342      return false;
    343    }
    344  }
    345  return true;
    346 }
    347 
    348 bool EmitterScope::prepareForModuleDisposableScopeBody(BytecodeEmitter* bce) {
    349  return prepareForDisposableScopeBody(bce);
    350 }
    351 
    352 bool EmitterScope::prepareForDisposableAssignment(UsingHint hint) {
    353  MOZ_ASSERT(hasDisposables());
    354  return usingEmitter_->prepareForAssignment(hint);
    355 }
    356 
    357 bool EmitterScope::emitDisposableScopeBodyEnd(BytecodeEmitter* bce) {
    358  // For-of loops emit the dispose loop in the different place and timing.
    359  // (See ForOfEmitter::emitInitialize,
    360  // ForOfLoopControl::emitPrepareForNonLocalJumpFromScope and
    361  // ForOfLoopControl::emitEndCodeNeedingIteratorClose())
    362  if (hasDisposables() && (blockKind_ != BlockKind::ForOf)) {
    363    if (!usingEmitter_->emitEnd()) {
    364      return false;
    365    }
    366  }
    367  return true;
    368 }
    369 
    370 bool EmitterScope::emitModuleDisposableScopeBodyEnd(BytecodeEmitter* bce) {
    371  return emitDisposableScopeBodyEnd(bce);
    372 }
    373 #endif
    374 
    375 bool EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind,
    376                                LexicalScope::ParserData* bindings
    377 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
    378                                ,
    379                                BlockKind blockKind
    380 #endif
    381 ) {
    382  MOZ_ASSERT(kind != ScopeKind::NamedLambda &&
    383             kind != ScopeKind::StrictNamedLambda);
    384  MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
    385 
    386  if (!ensureCache(bce)) {
    387    return false;
    388  }
    389 
    390  // Resolve bindings.
    391  TDZCheckCache* tdzCache = bce->innermostTDZCheckCache;
    392  uint32_t firstFrameSlot = frameSlotStart();
    393  ParserBindingIter bi(*bindings, firstFrameSlot, /* isNamedLambda = */ false);
    394  for (; bi; bi++) {
    395    if (!checkSlotLimits(bce, bi)) {
    396      return false;
    397    }
    398 
    399    NameLocation loc = bi.nameLocation();
    400    if (!putNameInCache(bce, bi.name(), loc)) {
    401      return false;
    402    }
    403 
    404    if (!tdzCache->noteTDZCheck(bce, bi.name(), CheckTDZ)) {
    405      return false;
    406    }
    407 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
    408    if (bi.kind() == BindingKind::Using) {
    409      setHasDisposables(bce);
    410    }
    411 #endif
    412  }
    413 
    414  updateFrameFixedSlots(bce, bi);
    415 
    416  ScopeIndex scopeIndex;
    417  if (!ScopeStencil::createForLexicalScope(
    418          bce->fc, bce->compilationState, kind, bindings, firstFrameSlot,
    419          enclosingScopeIndex(bce), &scopeIndex)) {
    420    return false;
    421  }
    422  if (!internScopeStencil(bce, scopeIndex)) {
    423    return false;
    424  }
    425 
    426  if (ScopeKindIsInBody(kind) && hasEnvironment()) {
    427    // After interning the VM scope we can get the scope index.
    428    if (!bce->emitInternedScopeOp(index(), JSOp::PushLexicalEnv)) {
    429      return false;
    430    }
    431  }
    432 
    433  // Lexical scopes need notes to be mapped from a pc.
    434  if (!appendScopeNote(bce)) {
    435    return false;
    436  }
    437 
    438  // Put frame slots in TDZ. Environment slots are poisoned during
    439  // environment creation.
    440  //
    441  // This must be done after appendScopeNote to be considered in the extent
    442  // of the scope.
    443  if (!deadZoneFrameSlotRange(bce, firstFrameSlot, frameSlotEnd())) {
    444    return false;
    445  }
    446 
    447 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
    448  MOZ_ASSERT_IF(blockKind_ != BlockKind::Other, kind == ScopeKind::Lexical);
    449  MOZ_ASSERT_IF(kind != ScopeKind::Lexical, blockKind_ == BlockKind::Other);
    450 
    451  blockKind_ = blockKind;
    452 
    453  if (!prepareForDisposableScopeBody(bce)) {
    454    return false;
    455  }
    456 #endif
    457 
    458  return checkEnvironmentChainLength(bce);
    459 }
    460 
    461 bool EmitterScope::enterClassBody(BytecodeEmitter* bce, ScopeKind kind,
    462                                  ClassBodyScope::ParserData* bindings) {
    463  MOZ_ASSERT(kind == ScopeKind::ClassBody);
    464  MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
    465 
    466  if (!ensureCache(bce)) {
    467    return false;
    468  }
    469 
    470  // Resolve bindings.
    471  TDZCheckCache* tdzCache = bce->innermostTDZCheckCache;
    472  uint32_t firstFrameSlot = frameSlotStart();
    473  ParserBindingIter bi(*bindings, firstFrameSlot);
    474  for (; bi; bi++) {
    475    if (!checkSlotLimits(bce, bi)) {
    476      return false;
    477    }
    478 
    479    NameLocation loc = bi.nameLocation();
    480    if (!putNameInCache(bce, bi.name(), loc)) {
    481      return false;
    482    }
    483 
    484    if (!tdzCache->noteTDZCheck(bce, bi.name(), CheckTDZ)) {
    485      return false;
    486    }
    487  }
    488 
    489  updateFrameFixedSlots(bce, bi);
    490 
    491  ScopeIndex scopeIndex;
    492  if (!ScopeStencil::createForClassBodyScope(
    493          bce->fc, bce->compilationState, kind, bindings, firstFrameSlot,
    494          enclosingScopeIndex(bce), &scopeIndex)) {
    495    return false;
    496  }
    497  if (!internScopeStencil(bce, scopeIndex)) {
    498    return false;
    499  }
    500 
    501  if (ScopeKindIsInBody(kind) && hasEnvironment()) {
    502    // After interning the VM scope we can get the scope index.
    503    //
    504    // ClassBody uses PushClassBodyEnv, however, PopLexicalEnv supports both
    505    // cases and doesn't need extra specialization.
    506    if (!bce->emitInternedScopeOp(index(), JSOp::PushClassBodyEnv)) {
    507      return false;
    508    }
    509  }
    510 
    511  // Lexical scopes need notes to be mapped from a pc.
    512  if (!appendScopeNote(bce)) {
    513    return false;
    514  }
    515 
    516  return checkEnvironmentChainLength(bce);
    517 }
    518 
    519 bool EmitterScope::enterNamedLambda(BytecodeEmitter* bce, FunctionBox* funbox) {
    520  MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
    521  MOZ_ASSERT(funbox->namedLambdaBindings());
    522 
    523  if (!ensureCache(bce)) {
    524    return false;
    525  }
    526 
    527  ParserBindingIter bi(*funbox->namedLambdaBindings(), LOCALNO_LIMIT,
    528                       /* isNamedLambda = */ true);
    529  MOZ_ASSERT(bi.kind() == BindingKind::NamedLambdaCallee);
    530 
    531  // The lambda name, if not closed over, is accessed via JSOp::Callee and
    532  // not a frame slot. Do not update frame slot information.
    533  NameLocation loc = bi.nameLocation();
    534  if (!putNameInCache(bce, bi.name(), loc)) {
    535    return false;
    536  }
    537 
    538  bi++;
    539  MOZ_ASSERT(!bi, "There should be exactly one binding in a NamedLambda scope");
    540 
    541  ScopeKind scopeKind =
    542      funbox->strict() ? ScopeKind::StrictNamedLambda : ScopeKind::NamedLambda;
    543 
    544  ScopeIndex scopeIndex;
    545  if (!ScopeStencil::createForLexicalScope(
    546          bce->fc, bce->compilationState, scopeKind,
    547          funbox->namedLambdaBindings(), LOCALNO_LIMIT,
    548          enclosingScopeIndex(bce), &scopeIndex)) {
    549    return false;
    550  }
    551  if (!internScopeStencil(bce, scopeIndex)) {
    552    return false;
    553  }
    554 
    555  return checkEnvironmentChainLength(bce);
    556 }
    557 
    558 bool EmitterScope::enterFunction(BytecodeEmitter* bce, FunctionBox* funbox) {
    559  MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
    560 
    561  // If there are parameter expressions, there is an extra var scope.
    562  if (!funbox->functionHasExtraBodyVarScope()) {
    563    bce->setVarEmitterScope(this);
    564  }
    565 
    566  if (!ensureCache(bce)) {
    567    return false;
    568  }
    569 
    570  // Resolve body-level bindings, if there are any.
    571  auto bindings = funbox->functionScopeBindings();
    572  if (bindings) {
    573    NameLocationMap& cache = *nameCache_;
    574 
    575    ParserBindingIter bi(*bindings, funbox->hasParameterExprs);
    576    for (; bi; bi++) {
    577      if (!checkSlotLimits(bce, bi)) {
    578        return false;
    579      }
    580 
    581      NameLocation loc = bi.nameLocation();
    582      NameLocationMap::AddPtr p = cache.lookupForAdd(bi.name());
    583 
    584      // The only duplicate bindings that occur are simple formal
    585      // parameters, in which case the last position counts, so update the
    586      // location.
    587      if (p) {
    588        MOZ_ASSERT(bi.kind() == BindingKind::FormalParameter);
    589        MOZ_ASSERT(!funbox->hasDestructuringArgs);
    590        MOZ_ASSERT(!funbox->hasRest());
    591        p->value() = loc;
    592        continue;
    593      }
    594 
    595      if (!cache.add(p, bi.name(), loc)) {
    596        ReportOutOfMemory(bce->fc);
    597        return false;
    598      }
    599    }
    600 
    601    updateFrameFixedSlots(bce, bi);
    602  } else {
    603    nextFrameSlot_ = 0;
    604  }
    605 
    606  // If the function's scope may be extended at runtime due to sloppy direct
    607  // eval, any names beyond the function scope must be accessed dynamically as
    608  // we don't know if the name will become a 'var' binding due to direct eval.
    609  if (funbox->funHasExtensibleScope()) {
    610    fallbackFreeNameLocation_ = Some(NameLocation::Dynamic());
    611  } else if (funbox->isStandalone) {
    612    // If the function is standalone, the enclosing scope is either an empty
    613    // global or non-syntactic scope, and there's no static bindings.
    614    if (bce->compilationState.input.target ==
    615        CompilationInput::CompilationTarget::
    616            StandaloneFunctionInNonSyntacticScope) {
    617      fallbackFreeNameLocation_ = Some(NameLocation::Dynamic());
    618    } else {
    619      fallbackFreeNameLocation_ = Some(NameLocation::Global(BindingKind::Var));
    620    }
    621  }
    622 
    623  // In case of parameter expressions, the parameters are lexical
    624  // bindings and have TDZ.
    625  if (funbox->hasParameterExprs && nextFrameSlot_) {
    626    uint32_t paramFrameSlotEnd = 0;
    627    for (ParserBindingIter bi(*bindings, true); bi; bi++) {
    628      if (!BindingKindIsLexical(bi.kind())) {
    629        break;
    630      }
    631 
    632      NameLocation loc = bi.nameLocation();
    633      if (loc.kind() == NameLocation::Kind::FrameSlot) {
    634        MOZ_ASSERT(paramFrameSlotEnd <= loc.frameSlot());
    635        paramFrameSlotEnd = loc.frameSlot() + 1;
    636      }
    637    }
    638 
    639    if (!deadZoneFrameSlotRange(bce, 0, paramFrameSlotEnd)) {
    640      return false;
    641    }
    642  }
    643 
    644  ScopeIndex scopeIndex;
    645  if (!ScopeStencil::createForFunctionScope(
    646          bce->fc, bce->compilationState, funbox->functionScopeBindings(),
    647          funbox->hasParameterExprs,
    648          funbox->needsCallObjectRegardlessOfBindings(), funbox->index(),
    649          funbox->isArrow(), enclosingScopeIndex(bce), &scopeIndex)) {
    650    return false;
    651  }
    652  if (!internBodyScopeStencil(bce, scopeIndex)) {
    653    return false;
    654  }
    655 
    656  return checkEnvironmentChainLength(bce);
    657 }
    658 
    659 bool EmitterScope::enterFunctionExtraBodyVar(BytecodeEmitter* bce,
    660                                             FunctionBox* funbox) {
    661  MOZ_ASSERT(funbox->hasParameterExprs);
    662  MOZ_ASSERT(funbox->extraVarScopeBindings() ||
    663             funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings());
    664  MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
    665 
    666  // The extra var scope is never popped once it's entered. It replaces the
    667  // function scope as the var emitter scope.
    668  bce->setVarEmitterScope(this);
    669 
    670  if (!ensureCache(bce)) {
    671    return false;
    672  }
    673 
    674  // Resolve body-level bindings, if there are any.
    675  uint32_t firstFrameSlot = frameSlotStart();
    676  if (auto bindings = funbox->extraVarScopeBindings()) {
    677    ParserBindingIter bi(*bindings, firstFrameSlot);
    678    for (; bi; bi++) {
    679      if (!checkSlotLimits(bce, bi)) {
    680        return false;
    681      }
    682 
    683      NameLocation loc = bi.nameLocation();
    684      MOZ_ASSERT(bi.kind() == BindingKind::Var);
    685      if (!putNameInCache(bce, bi.name(), loc)) {
    686        return false;
    687      }
    688    }
    689 
    690    uint32_t priorEnd = bce->maxFixedSlots;
    691    updateFrameFixedSlots(bce, bi);
    692 
    693    // If any of the bound slots were previously used, reset them to undefined.
    694    // This doesn't break TDZ for let/const/class bindings because there aren't
    695    // any in extra body var scopes. We assert above that bi.kind() is Var.
    696    uint32_t end = std::min(priorEnd, nextFrameSlot_);
    697    if (firstFrameSlot < end) {
    698      if (!clearFrameSlotRange(bce, JSOp::Undefined, firstFrameSlot, end)) {
    699        return false;
    700      }
    701    }
    702  } else {
    703    nextFrameSlot_ = firstFrameSlot;
    704  }
    705 
    706  // If the extra var scope may be extended at runtime due to sloppy
    707  // direct eval, any names beyond the var scope must be accessed
    708  // dynamically as we don't know if the name will become a 'var' binding
    709  // due to direct eval.
    710  if (funbox->funHasExtensibleScope()) {
    711    fallbackFreeNameLocation_ = Some(NameLocation::Dynamic());
    712  }
    713 
    714  // Create and intern the VM scope.
    715  ScopeIndex scopeIndex;
    716  if (!ScopeStencil::createForVarScope(
    717          bce->fc, bce->compilationState, ScopeKind::FunctionBodyVar,
    718          funbox->extraVarScopeBindings(), firstFrameSlot,
    719          funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings(),
    720          enclosingScopeIndex(bce), &scopeIndex)) {
    721    return false;
    722  }
    723  if (!internScopeStencil(bce, scopeIndex)) {
    724    return false;
    725  }
    726 
    727  if (hasEnvironment()) {
    728    if (!bce->emitInternedScopeOp(index(), JSOp::PushVarEnv)) {
    729      return false;
    730    }
    731  }
    732 
    733  // The extra var scope needs a note to be mapped from a pc.
    734  if (!appendScopeNote(bce)) {
    735    return false;
    736  }
    737 
    738  return checkEnvironmentChainLength(bce);
    739 }
    740 
    741 bool EmitterScope::enterGlobal(BytecodeEmitter* bce,
    742                               GlobalSharedContext* globalsc) {
    743  MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
    744 
    745  // TODO-Stencil
    746  //   This is another snapshot-sensitive location.
    747  //   The incoming atoms from the global scope object should be snapshotted.
    748  //   For now, converting them to ParserAtoms here individually.
    749 
    750  bce->setVarEmitterScope(this);
    751 
    752  if (!ensureCache(bce)) {
    753    return false;
    754  }
    755 
    756  if (bce->emitterMode == BytecodeEmitter::SelfHosting) {
    757    // In self-hosting, it is incorrect to consult the global scope because
    758    // self-hosted scripts are cloned into their target compartments before
    759    // they are run. Instead of Global, Intrinsic is used for all names.
    760    //
    761    // Intrinsic lookups are redirected to the special intrinsics holder
    762    // in the global object, into which any missing values are cloned
    763    // lazily upon first access.
    764    fallbackFreeNameLocation_ = Some(NameLocation::Intrinsic());
    765 
    766    return internEmptyGlobalScopeAsBody(bce);
    767  }
    768 
    769  ScopeIndex scopeIndex;
    770  if (!ScopeStencil::createForGlobalScope(bce->fc, bce->compilationState,
    771                                          globalsc->scopeKind(),
    772                                          globalsc->bindings, &scopeIndex)) {
    773    return false;
    774  }
    775  if (!internBodyScopeStencil(bce, scopeIndex)) {
    776    return false;
    777  }
    778 
    779  // See: JSScript::outermostScope.
    780  MOZ_ASSERT(bce->bodyScopeIndex == GCThingIndex::outermostScopeIndex(),
    781             "Global scope must be index 0");
    782 
    783  // Resolve binding names.
    784  //
    785  // NOTE: BytecodeEmitter::emitDeclarationInstantiation will emit the
    786  //       redeclaration check and initialize these bindings.
    787  if (globalsc->bindings) {
    788    for (ParserBindingIter bi(*globalsc->bindings); bi; bi++) {
    789      NameLocation loc = bi.nameLocation();
    790      if (!putNameInCache(bce, bi.name(), loc)) {
    791        return false;
    792      }
    793    }
    794  }
    795 
    796  // Note that to save space, we don't add free names to the cache for
    797  // global scopes. They are assumed to be global vars in the syntactic
    798  // global scope, dynamic accesses under non-syntactic global scope.
    799  if (globalsc->scopeKind() == ScopeKind::Global) {
    800    fallbackFreeNameLocation_ = Some(NameLocation::Global(BindingKind::Var));
    801  } else {
    802    fallbackFreeNameLocation_ = Some(NameLocation::Dynamic());
    803  }
    804 
    805  return true;
    806 }
    807 
    808 bool EmitterScope::enterEval(BytecodeEmitter* bce, EvalSharedContext* evalsc) {
    809  MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
    810 
    811  bce->setVarEmitterScope(this);
    812 
    813  if (!ensureCache(bce)) {
    814    return false;
    815  }
    816 
    817  // Create the `var` scope. Note that there is also a lexical scope, created
    818  // separately in emitScript().
    819  ScopeKind scopeKind =
    820      evalsc->strict() ? ScopeKind::StrictEval : ScopeKind::Eval;
    821 
    822  ScopeIndex scopeIndex;
    823  if (!ScopeStencil::createForEvalScope(
    824          bce->fc, bce->compilationState, scopeKind, evalsc->bindings,
    825          enclosingScopeIndex(bce), &scopeIndex)) {
    826    return false;
    827  }
    828  if (!internBodyScopeStencil(bce, scopeIndex)) {
    829    return false;
    830  }
    831 
    832  if (evalsc->strict()) {
    833    if (evalsc->bindings) {
    834      ParserBindingIter bi(*evalsc->bindings, true);
    835      for (; bi; bi++) {
    836        if (!checkSlotLimits(bce, bi)) {
    837          return false;
    838        }
    839 
    840        NameLocation loc = bi.nameLocation();
    841        if (!putNameInCache(bce, bi.name(), loc)) {
    842          return false;
    843        }
    844      }
    845 
    846      updateFrameFixedSlots(bce, bi);
    847    }
    848  } else {
    849    // For simplicity, treat all free name lookups in nonstrict eval scripts as
    850    // dynamic.
    851    fallbackFreeNameLocation_ = Some(NameLocation::Dynamic());
    852  }
    853 
    854  if (hasEnvironment()) {
    855    if (!bce->emitInternedScopeOp(index(), JSOp::PushVarEnv)) {
    856      return false;
    857    }
    858  } else {
    859    // NOTE: BytecodeEmitter::emitDeclarationInstantiation will emit the
    860    //       redeclaration check and initialize these bindings for sloppy
    861    //       eval.
    862 
    863    // As an optimization, if the eval does not have its own var
    864    // environment and is directly enclosed in a global scope, then all
    865    // free name lookups are global.
    866    if (scope(bce).enclosing().is<GlobalScope>()) {
    867      fallbackFreeNameLocation_ = Some(NameLocation::Global(BindingKind::Var));
    868    }
    869  }
    870 
    871  return checkEnvironmentChainLength(bce);
    872 }
    873 
    874 bool EmitterScope::enterModule(BytecodeEmitter* bce,
    875                               ModuleSharedContext* modulesc) {
    876  MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
    877 
    878  bce->setVarEmitterScope(this);
    879 
    880  if (!ensureCache(bce)) {
    881    return false;
    882  }
    883 
    884  // Resolve body-level bindings, if there are any.
    885  TDZCheckCache* tdzCache = bce->innermostTDZCheckCache;
    886  Maybe<uint32_t> firstLexicalFrameSlot;
    887  if (ModuleScope::ParserData* bindings = modulesc->bindings) {
    888    ParserBindingIter bi(*bindings);
    889    for (; bi; bi++) {
    890      if (!checkSlotLimits(bce, bi)) {
    891        return false;
    892      }
    893 
    894      NameLocation loc = bi.nameLocation();
    895      if (!putNameInCache(bce, bi.name(), loc)) {
    896        return false;
    897      }
    898 
    899      if (BindingKindIsLexical(bi.kind())) {
    900        if (loc.kind() == NameLocation::Kind::FrameSlot &&
    901            !firstLexicalFrameSlot) {
    902          firstLexicalFrameSlot = Some(loc.frameSlot());
    903        }
    904 
    905        if (!tdzCache->noteTDZCheck(bce, bi.name(), CheckTDZ)) {
    906          return false;
    907        }
    908      }
    909 
    910 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
    911      if (bi.kind() == BindingKind::Using) {
    912        setHasDisposables(bce);
    913      }
    914 #endif
    915    }
    916 
    917    updateFrameFixedSlots(bce, bi);
    918  } else {
    919    nextFrameSlot_ = 0;
    920  }
    921 
    922  // Modules are toplevel, so any free names are global.
    923  fallbackFreeNameLocation_ = Some(NameLocation::Global(BindingKind::Var));
    924 
    925  // Put lexical frame slots in TDZ. Environment slots are poisoned during
    926  // environment creation.
    927  if (firstLexicalFrameSlot) {
    928    if (!deadZoneFrameSlotRange(bce, *firstLexicalFrameSlot, frameSlotEnd())) {
    929      return false;
    930    }
    931  }
    932 
    933  // Create and intern the VM scope creation data.
    934  ScopeIndex scopeIndex;
    935  if (!ScopeStencil::createForModuleScope(
    936          bce->fc, bce->compilationState, modulesc->bindings,
    937          enclosingScopeIndex(bce), &scopeIndex)) {
    938    return false;
    939  }
    940  if (!internBodyScopeStencil(bce, scopeIndex)) {
    941    return false;
    942  }
    943 
    944  return checkEnvironmentChainLength(bce);
    945 }
    946 
    947 bool EmitterScope::enterWith(BytecodeEmitter* bce) {
    948  MOZ_ASSERT(this == bce->innermostEmitterScopeNoCheck());
    949 
    950  if (!ensureCache(bce)) {
    951    return false;
    952  }
    953 
    954  // 'with' make all accesses dynamic and unanalyzable.
    955  fallbackFreeNameLocation_ = Some(NameLocation::Dynamic());
    956 
    957  ScopeIndex scopeIndex;
    958  if (!ScopeStencil::createForWithScope(bce->fc, bce->compilationState,
    959                                        enclosingScopeIndex(bce),
    960                                        &scopeIndex)) {
    961    return false;
    962  }
    963 
    964  if (!internScopeStencil(bce, scopeIndex)) {
    965    return false;
    966  }
    967 
    968  if (!bce->emitInternedScopeOp(index(), JSOp::EnterWith)) {
    969    return false;
    970  }
    971 
    972  if (!appendScopeNote(bce)) {
    973    return false;
    974  }
    975 
    976  return checkEnvironmentChainLength(bce);
    977 }
    978 
    979 bool EmitterScope::deadZoneFrameSlots(BytecodeEmitter* bce) const {
    980  return deadZoneFrameSlotRange(bce, frameSlotStart(), frameSlotEnd());
    981 }
    982 
    983 bool EmitterScope::leave(BytecodeEmitter* bce, bool nonLocal) {
    984  // If we aren't leaving the scope due to a non-local jump (e.g., break),
    985  // we must be the innermost scope.
    986  MOZ_ASSERT_IF(!nonLocal, this == bce->innermostEmitterScopeNoCheck());
    987 
    988  ScopeKind kind = scope(bce).kind();
    989  switch (kind) {
    990    case ScopeKind::Lexical:
    991    case ScopeKind::SimpleCatch:
    992    case ScopeKind::Catch:
    993    case ScopeKind::FunctionLexical:
    994    case ScopeKind::ClassBody:
    995 
    996 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
    997      if (!nonLocal) {
    998        if (!emitDisposableScopeBodyEnd(bce)) {
    999          return false;
   1000        }
   1001      }
   1002 #endif
   1003 
   1004      if (bce->sc->isFunctionBox() &&
   1005          bce->sc->asFunctionBox()->needsClearSlotsOnExit()) {
   1006        if (!deadZoneFrameSlots(bce)) {
   1007          return false;
   1008        }
   1009      }
   1010 
   1011      if (!bce->emit1(hasEnvironment() ? JSOp::PopLexicalEnv
   1012                                       : JSOp::DebugLeaveLexicalEnv)) {
   1013        return false;
   1014      }
   1015      break;
   1016 
   1017    case ScopeKind::With:
   1018      if (!bce->emit1(JSOp::LeaveWith)) {
   1019        return false;
   1020      }
   1021      break;
   1022 
   1023    case ScopeKind::Function:
   1024    case ScopeKind::FunctionBodyVar:
   1025    case ScopeKind::NamedLambda:
   1026    case ScopeKind::StrictNamedLambda:
   1027    case ScopeKind::Eval:
   1028    case ScopeKind::StrictEval:
   1029    case ScopeKind::Global:
   1030    case ScopeKind::NonSyntactic:
   1031    case ScopeKind::Module:
   1032      break;
   1033 
   1034    case ScopeKind::WasmInstance:
   1035    case ScopeKind::WasmFunction:
   1036      MOZ_CRASH("No wasm function scopes in JS");
   1037  }
   1038 
   1039  // Finish up the scope if we are leaving it in LIFO fashion.
   1040  if (!nonLocal) {
   1041    // Popping scopes due to non-local jumps generate additional scope
   1042    // notes. See NonLocalExitControl::prepareForNonLocalJump.
   1043    if (ScopeKindIsInBody(kind)) {
   1044      if (kind == ScopeKind::FunctionBodyVar) {
   1045        // The extra function var scope is never popped once it's pushed,
   1046        // so its scope note extends until the end of any possible code.
   1047        bce->bytecodeSection().scopeNoteList().recordEndFunctionBodyVar(
   1048            noteIndex_);
   1049      } else {
   1050        bce->bytecodeSection().scopeNoteList().recordEnd(
   1051            noteIndex_, bce->bytecodeSection().offset());
   1052      }
   1053    }
   1054  }
   1055 
   1056  return true;
   1057 }
   1058 
   1059 AbstractScopePtr EmitterScope::scope(const BytecodeEmitter* bce) const {
   1060  return bce->perScriptData().gcThingList().getScope(index());
   1061 }
   1062 
   1063 mozilla::Maybe<ScopeIndex> EmitterScope::scopeIndex(
   1064    const BytecodeEmitter* bce) const {
   1065  return bce->perScriptData().gcThingList().getScopeIndex(index());
   1066 }
   1067 
   1068 NameLocation EmitterScope::lookup(BytecodeEmitter* bce,
   1069                                  TaggedParserAtomIndex name) {
   1070  if (Maybe<NameLocation> loc = lookupInCache(bce, name)) {
   1071    return *loc;
   1072  }
   1073  return searchAndCache(bce, name);
   1074 }
   1075 
   1076 /* static */
   1077 uint32_t EmitterScope::CountEnclosingCompilationEnvironments(
   1078    BytecodeEmitter* bce, EmitterScope* emitterScope) {
   1079  uint32_t environments = emitterScope->hasEnvironment() ? 1 : 0;
   1080  while ((emitterScope = emitterScope->enclosing(&bce))) {
   1081    if (emitterScope->hasEnvironment()) {
   1082      environments++;
   1083    }
   1084  }
   1085  return environments;
   1086 }
   1087 
   1088 void EmitterScope::lookupPrivate(BytecodeEmitter* bce,
   1089                                 TaggedParserAtomIndex name, NameLocation& loc,
   1090                                 mozilla::Maybe<NameLocation>& brandLoc) {
   1091  loc = lookup(bce, name);
   1092 
   1093  // Private Brand checking relies on the ability to construct a new
   1094  // environment coordinate for a name at a fixed offset, which will
   1095  // correspond to the private brand for that class.
   1096  //
   1097  // If our name lookup isn't a fixed location, we must construct a
   1098  // new environment coordinate, using information available from our private
   1099  // field cache. (See cachePrivateFieldsForEval, and Bug 1638309).
   1100  //
   1101  // This typically involves a DebugEnvironmentProxy, so we need to use a
   1102  // DebugEnvironmentCoordinate.
   1103  //
   1104  // See also Bug 793345 which argues that we should remove the
   1105  // DebugEnvironmentProxy.
   1106  if (loc.kind() != NameLocation::Kind::EnvironmentCoordinate &&
   1107      loc.kind() != NameLocation::Kind::FrameSlot) {
   1108    MOZ_ASSERT(loc.kind() == NameLocation::Kind::Dynamic ||
   1109               loc.kind() == NameLocation::Kind::Global);
   1110    // Private fields don't require brand checking and can be correctly
   1111    // code-generated with dynamic name lookup bytecode we have today. However,
   1112    // for that to happen we first need to figure out if we have a Private
   1113    // method or private field, which we cannot disambiguate based on the
   1114    // dynamic lookup.
   1115    //
   1116    // However, this is precisely the case that the private field eval case can
   1117    // help us handle. It knows the truth about these private bindings.
   1118    mozilla::Maybe<NameLocation> cacheEntry =
   1119        bce->compilationState.scopeContext.getPrivateFieldLocation(name);
   1120    MOZ_ASSERT(cacheEntry);
   1121 
   1122    if (cacheEntry->bindingKind() == BindingKind::PrivateMethod) {
   1123      MOZ_ASSERT(cacheEntry->kind() ==
   1124                 NameLocation::Kind::DebugEnvironmentCoordinate);
   1125      // To construct the brand check there are two hop values required:
   1126      //
   1127      // 1. Compilation Hops: The number of environment hops required to get to
   1128      //    the compilation enclosing environment.
   1129      // 2. "external hops", to get from compilation enclosing debug environment
   1130      //     to the environment that actually contains our brand. This is
   1131      //     determined by the cacheEntry. This traversal will bypass a Debug
   1132      //     environment proxy, which is why need to use
   1133      //     DebugEnvironmentCoordinate.
   1134 
   1135      uint32_t compilation_hops =
   1136          CountEnclosingCompilationEnvironments(bce, this);
   1137 
   1138      uint32_t external_hops = cacheEntry->environmentCoordinate().hops();
   1139 
   1140      brandLoc = Some(NameLocation::DebugEnvironmentCoordinate(
   1141          BindingKind::Synthetic, compilation_hops + external_hops,
   1142          ClassBodyLexicalEnvironmentObject::privateBrandSlot()));
   1143    } else {
   1144      brandLoc = Nothing();
   1145    }
   1146    return;
   1147  }
   1148 
   1149  if (loc.bindingKind() == BindingKind::PrivateMethod) {
   1150    uint32_t hops = 0;
   1151    if (loc.kind() == NameLocation::Kind::EnvironmentCoordinate) {
   1152      hops = loc.environmentCoordinate().hops();
   1153    } else {
   1154      // If we have a FrameSlot, then our innermost emitter scope must be a
   1155      // class body scope, and we can generate an environment coordinate with
   1156      // hops=0 to find the associated brand location.
   1157      MOZ_ASSERT(bce->innermostScope().is<ClassBodyScope>());
   1158    }
   1159 
   1160    brandLoc = Some(NameLocation::EnvironmentCoordinate(
   1161        BindingKind::Synthetic, hops,
   1162        ClassBodyLexicalEnvironmentObject::privateBrandSlot()));
   1163  } else {
   1164    brandLoc = Nothing();
   1165  }
   1166 }
   1167 
   1168 Maybe<NameLocation> EmitterScope::locationBoundInScope(
   1169    TaggedParserAtomIndex name, EmitterScope* target) {
   1170  // The target scope must be an intra-frame enclosing scope of this
   1171  // one. Count the number of extra hops to reach it.
   1172  uint16_t extraHops = 0;
   1173  for (EmitterScope* es = this; es != target; es = es->enclosingInFrame()) {
   1174    if (es->hasEnvironment()) {
   1175      extraHops++;
   1176    }
   1177  }
   1178 
   1179  // Caches are prepopulated with bound names. So if the name is bound in a
   1180  // particular scope, it must already be in the cache. Furthermore, don't
   1181  // consult the fallback location as we only care about binding names.
   1182  Maybe<NameLocation> loc;
   1183  if (NameLocationMap::Ptr p = target->nameCache_->lookup(name)) {
   1184    NameLocation l = p->value().wrapped;
   1185    if (l.kind() == NameLocation::Kind::EnvironmentCoordinate) {
   1186      loc = Some(l.addHops(extraHops));
   1187    } else {
   1188      loc = Some(l);
   1189    }
   1190  }
   1191  return loc;
   1192 }