tor-browser

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

Scope.cpp (60276B)


      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 "vm/Scope.h"
      8 
      9 #include <new>
     10 
     11 #include "jsnum.h"
     12 
     13 #include "frontend/CompilationStencil.h"  // ScopeStencilRef, CompilationStencil, CompilationState, CompilationAtomCache
     14 #include "frontend/ParserAtom.h"  // frontend::ParserAtomsTable, frontend::ParserAtom
     15 #include "frontend/ScriptIndex.h"  // ScriptIndex
     16 #include "frontend/Stencil.h"
     17 #include "util/StringBuilder.h"
     18 #include "vm/EnvironmentObject.h"
     19 #include "vm/ErrorReporting.h"  // MaybePrintAndClearPendingException
     20 #include "vm/JSScript.h"
     21 #include "wasm/WasmDebug.h"
     22 #include "wasm/WasmInstance.h"
     23 
     24 #include "gc/BufferAllocator-inl.h"
     25 #include "gc/GCContext-inl.h"
     26 #include "gc/ObjectKind-inl.h"
     27 #include "gc/TraceMethods-inl.h"
     28 #include "vm/JSContext-inl.h"
     29 #include "wasm/WasmInstance-inl.h"
     30 
     31 using namespace js;
     32 using namespace js::frontend;
     33 
     34 const char* js::BindingKindString(BindingKind kind) {
     35  switch (kind) {
     36    case BindingKind::Import:
     37      return "import";
     38    case BindingKind::FormalParameter:
     39      return "formal parameter";
     40    case BindingKind::Var:
     41      return "var";
     42    case BindingKind::Let:
     43      return "let";
     44    case BindingKind::Const:
     45      return "const";
     46    case BindingKind::NamedLambdaCallee:
     47      return "named lambda callee";
     48    case BindingKind::Synthetic:
     49      return "synthetic";
     50    case BindingKind::PrivateMethod:
     51      return "private method";
     52 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
     53    case BindingKind::Using:
     54      return "using";
     55 #endif
     56  }
     57  MOZ_CRASH("Bad BindingKind");
     58 }
     59 
     60 const char* js::ScopeKindString(ScopeKind kind) {
     61  switch (kind) {
     62    case ScopeKind::Function:
     63      return "function";
     64    case ScopeKind::FunctionBodyVar:
     65      return "function body var";
     66    case ScopeKind::Lexical:
     67      return "lexical";
     68    case ScopeKind::SimpleCatch:
     69    case ScopeKind::Catch:
     70      return "catch";
     71    case ScopeKind::NamedLambda:
     72      return "named lambda";
     73    case ScopeKind::StrictNamedLambda:
     74      return "strict named lambda";
     75    case ScopeKind::FunctionLexical:
     76      return "function lexical";
     77    case ScopeKind::ClassBody:
     78      return "class body";
     79    case ScopeKind::With:
     80      return "with";
     81    case ScopeKind::Eval:
     82      return "eval";
     83    case ScopeKind::StrictEval:
     84      return "strict eval";
     85    case ScopeKind::Global:
     86      return "global";
     87    case ScopeKind::NonSyntactic:
     88      return "non-syntactic";
     89    case ScopeKind::Module:
     90      return "module";
     91    case ScopeKind::WasmInstance:
     92      return "wasm instance";
     93    case ScopeKind::WasmFunction:
     94      return "wasm function";
     95  }
     96  MOZ_CRASH("Bad ScopeKind");
     97 }
     98 
     99 SharedShape* js::EmptyEnvironmentShape(JSContext* cx, const JSClass* cls,
    100                                       uint32_t numSlots,
    101                                       ObjectFlags objectFlags) {
    102  // Put as many slots into the object header as possible.
    103  uint32_t numFixed = gc::GetGCKindSlots(gc::GetGCObjectKind(numSlots));
    104  return SharedShape::getInitialShape(
    105      cx, cls, cx->realm(), TaggedProto(nullptr), numFixed, objectFlags);
    106 }
    107 
    108 static bool AddToEnvironmentMap(JSContext* cx, const JSClass* clasp,
    109                                HandleId id, BindingKind bindKind,
    110                                uint32_t slot,
    111                                MutableHandle<SharedPropMap*> map,
    112                                uint32_t* mapLength, ObjectFlags* objectFlags) {
    113  PropertyFlags propFlags = {PropertyFlag::Enumerable};
    114  switch (bindKind) {
    115    case BindingKind::Const:
    116    case BindingKind::NamedLambdaCallee:
    117      // Non-writable.
    118      break;
    119    default:
    120      propFlags.setFlag(PropertyFlag::Writable);
    121      break;
    122  }
    123 
    124  return SharedPropMap::addPropertyWithKnownSlot(cx, clasp, map, mapLength, id,
    125                                                 propFlags, slot, objectFlags);
    126 }
    127 
    128 SharedShape* js::CreateEnvironmentShape(JSContext* cx, BindingIter& bi,
    129                                        const JSClass* cls, uint32_t numSlots,
    130                                        ObjectFlags objectFlags) {
    131  Rooted<SharedPropMap*> map(cx);
    132  uint32_t mapLength = 0;
    133 
    134  RootedId id(cx);
    135  for (; bi; bi++) {
    136    BindingLocation loc = bi.location();
    137    if (loc.kind() == BindingLocation::Kind::Environment) {
    138      JSAtom* name = bi.name();
    139      MOZ_ASSERT(AtomIsMarked(cx->zone(), name));
    140      id = NameToId(name->asPropertyName());
    141      if (!AddToEnvironmentMap(cx, cls, id, bi.kind(), loc.slot(), &map,
    142                               &mapLength, &objectFlags)) {
    143        return nullptr;
    144      }
    145    }
    146  }
    147 
    148  uint32_t numFixed = gc::GetGCKindSlots(gc::GetGCObjectKind(numSlots));
    149  return SharedShape::getInitialOrPropMapShape(cx, cls, cx->realm(),
    150                                               TaggedProto(nullptr), numFixed,
    151                                               map, mapLength, objectFlags);
    152 }
    153 
    154 SharedShape* js::CreateEnvironmentShapeForSyntheticModule(
    155    JSContext* cx, const JSClass* cls, uint32_t numSlots,
    156    Handle<ModuleObject*> module) {
    157  Rooted<SharedPropMap*> map(cx);
    158  uint32_t mapLength = 0;
    159 
    160  PropertyFlags propFlags = {PropertyFlag::Enumerable};
    161  ObjectFlags objectFlags = ModuleEnvironmentObject::OBJECT_FLAGS;
    162 
    163  RootedId id(cx);
    164  uint32_t slotIndex = numSlots;
    165  for (JSAtom* exportName : module->syntheticExportNames()) {
    166    id = NameToId(exportName->asPropertyName());
    167    if (!SharedPropMap::addPropertyWithKnownSlot(cx, cls, &map, &mapLength, id,
    168                                                 propFlags, slotIndex,
    169                                                 &objectFlags)) {
    170      return nullptr;
    171    }
    172    slotIndex++;
    173  }
    174 
    175  uint32_t numFixed = gc::GetGCKindSlots(gc::GetGCObjectKind(numSlots));
    176  return SharedShape::getInitialOrPropMapShape(cx, cls, cx->realm(),
    177                                               TaggedProto(nullptr), numFixed,
    178                                               map, mapLength, objectFlags);
    179 }
    180 
    181 template <class DataT>
    182 inline size_t SizeOfAllocatedData(DataT* data) {
    183  return SizeOfScopeData<DataT>(data->length);
    184 }
    185 
    186 template <typename ConcreteScope>
    187 static void MarkParserScopeData(typename ConcreteScope::ParserData* data,
    188                                frontend::CompilationState& compilationState) {
    189  auto names = GetScopeDataTrailingNames(data);
    190  for (auto& binding : names) {
    191    auto index = binding.name();
    192    if (!index) {
    193      continue;
    194    }
    195    compilationState.parserAtoms.markUsedByStencil(
    196        index, frontend::ParserAtom::Atomize::Yes);
    197  }
    198 }
    199 
    200 template <typename ConcreteScope, typename EnvironmentT>
    201 static void PrepareScopeData(ParserBindingIter& bi,
    202                             typename ConcreteScope::ParserData* data,
    203                             uint32_t firstFrameSlot,
    204                             mozilla::Maybe<uint32_t>* envShape) {
    205  const JSClass* cls = &EnvironmentT::class_;
    206 
    207  // Iterate through all bindings. This counts the number of environment
    208  // slots needed and computes the maximum frame slot.
    209  while (bi) {
    210    bi++;
    211  }
    212  data->slotInfo.nextFrameSlot =
    213      bi.canHaveFrameSlots() ? bi.nextFrameSlot() : LOCALNO_LIMIT;
    214 
    215  // Make a new environment shape if any environment slots were used.
    216  if (bi.nextEnvironmentSlot() != JSSLOT_FREE(cls)) {
    217    envShape->emplace(bi.nextEnvironmentSlot());
    218  }
    219 }
    220 
    221 template <typename ConcreteScope>
    222 static typename ConcreteScope::ParserData* NewEmptyParserScopeData(
    223    FrontendContext* fc, LifoAlloc& alloc, uint32_t length = 0) {
    224  using Data = typename ConcreteScope::ParserData;
    225 
    226  size_t dataSize = SizeOfScopeData<Data>(length);
    227  void* raw = alloc.alloc(dataSize);
    228  if (!raw) {
    229    js::ReportOutOfMemory(fc);
    230    return nullptr;
    231  }
    232 
    233  return new (raw) Data(length);
    234 }
    235 
    236 template <typename ConcreteScope>
    237 static typename ConcreteScope::RuntimeData* NewEmptyScopeData(
    238    JSContext* cx, uint32_t length = 0) {
    239  using Data = typename ConcreteScope::RuntimeData;
    240 
    241  size_t dataSize = SizeOfScopeData<Data>(length);
    242  Data* data = gc::NewBuffer<Data>(cx->zone(), dataSize, false, length);
    243  if (!data) {
    244    ReportOutOfMemory(cx);
    245    return nullptr;
    246  }
    247 
    248  return data;
    249 }
    250 
    251 template <typename ConcreteScope>
    252 static typename ConcreteScope::RuntimeData* LiftParserScopeData(
    253    JSContext* cx, frontend::CompilationAtomCache& atomCache,
    254    BaseParserScopeData* baseData) {
    255  using ConcreteData = typename ConcreteScope::RuntimeData;
    256 
    257  auto* data = static_cast<typename ConcreteScope::ParserData*>(baseData);
    258 
    259  // Convert all scope ParserAtoms to rooted JSAtoms.
    260  // Rooting is necessary as conversion can gc.
    261  JS::RootedVector<JSAtom*> jsatoms(cx);
    262  if (!jsatoms.reserve(data->length)) {
    263    return nullptr;
    264  }
    265  auto names = GetScopeDataTrailingNames(data);
    266  for (size_t i = 0; i < names.size(); i++) {
    267    JSAtom* jsatom = nullptr;
    268    if (names[i].name()) {
    269      jsatom = atomCache.getExistingAtomAt(cx, names[i].name());
    270      MOZ_ASSERT(jsatom);
    271    }
    272    jsatoms.infallibleAppend(jsatom);
    273  }
    274 
    275  // Allocate a new scope-data of the right kind.
    276  ConcreteData* scopeData = NewEmptyScopeData<ConcreteScope>(cx, data->length);
    277  if (!scopeData) {
    278    return nullptr;
    279  }
    280 
    281  // NOTE: There shouldn't be any fallible operation or GC between setting
    282  //       `length` and filling `trailingNames`.
    283  scopeData->length = data->length;
    284 
    285  memcpy(&scopeData->slotInfo, &data->slotInfo,
    286         sizeof(typename ConcreteScope::SlotInfo));
    287 
    288  // Initialize new scoped names.
    289  auto namesOut = GetScopeDataTrailingNames(scopeData);
    290  MOZ_ASSERT(data->length == namesOut.size());
    291  for (size_t i = 0; i < namesOut.size(); i++) {
    292    namesOut[i] = names[i].copyWithNewAtom(jsatoms[i].get());
    293  }
    294 
    295  return scopeData;
    296 }
    297 
    298 /* static */
    299 Scope* Scope::create(JSContext* cx, ScopeKind kind, Handle<Scope*> enclosing,
    300                     Handle<SharedShape*> envShape) {
    301  return cx->newCell<Scope>(kind, enclosing, envShape);
    302 }
    303 
    304 template <typename ConcreteScope>
    305 /* static */
    306 ConcreteScope* Scope::create(
    307    JSContext* cx, ScopeKind kind, Handle<Scope*> enclosing,
    308    Handle<SharedShape*> envShape,
    309    HandleBuffer<typename ConcreteScope::RuntimeData> data) {
    310  Scope* scope = create(cx, kind, enclosing, envShape);
    311  if (!scope) {
    312    return nullptr;
    313  }
    314 
    315  // It is an invariant that all Scopes that have data (currently, all
    316  // ScopeKinds except With) must have non-null data.
    317  MOZ_ASSERT(data);
    318  scope->initData<ConcreteScope>(data);
    319 
    320  return &scope->as<ConcreteScope>();
    321 }
    322 
    323 template <typename ConcreteScope>
    324 inline void Scope::initData(
    325    HandleBuffer<typename ConcreteScope::RuntimeData> data) {
    326  MOZ_ASSERT(is<ConcreteScope>());
    327  MOZ_ASSERT(!rawData());
    328 
    329  setHeaderPtr(data);
    330 }
    331 
    332 void Scope::updateEnvShapeIfRequired(mozilla::Maybe<uint32_t>* envShape,
    333                                     bool needsEnvironment) {
    334  if (envShape->isNothing() && needsEnvironment) {
    335    uint32_t numSlots = 0;
    336    envShape->emplace(numSlots);
    337  }
    338 }
    339 
    340 uint32_t Scope::firstFrameSlot() const {
    341  switch (kind()) {
    342    case ScopeKind::Lexical:
    343    case ScopeKind::SimpleCatch:
    344    case ScopeKind::Catch:
    345    case ScopeKind::FunctionLexical:
    346      // For intra-frame scopes, find the enclosing scope's next frame slot.
    347      MOZ_ASSERT(is<LexicalScope>());
    348      return LexicalScope::nextFrameSlot(enclosing());
    349 
    350    case ScopeKind::NamedLambda:
    351    case ScopeKind::StrictNamedLambda:
    352      // Named lambda scopes cannot have frame slots.
    353      return LOCALNO_LIMIT;
    354 
    355    case ScopeKind::ClassBody:
    356      MOZ_ASSERT(is<ClassBodyScope>());
    357      return ClassBodyScope::nextFrameSlot(enclosing());
    358 
    359    case ScopeKind::FunctionBodyVar:
    360      if (enclosing()->is<FunctionScope>()) {
    361        return enclosing()->as<FunctionScope>().nextFrameSlot();
    362      }
    363      break;
    364 
    365    default:
    366      break;
    367  }
    368  return 0;
    369 }
    370 
    371 uint32_t Scope::chainLength() const {
    372  uint32_t length = 0;
    373  for (ScopeIter si(const_cast<Scope*>(this)); si; si++) {
    374    length++;
    375  }
    376  return length;
    377 }
    378 
    379 uint32_t Scope::environmentChainLength() const {
    380  uint32_t length = 0;
    381  for (ScopeIter si(const_cast<Scope*>(this)); si; si++) {
    382    if (si.hasSyntacticEnvironment()) {
    383      length++;
    384    }
    385  }
    386  return length;
    387 }
    388 
    389 size_t Scope::sizeOfExcludingThis() const {
    390  if (rawData()) {
    391    return gc::GetAllocSize(zone(), rawData());
    392  }
    393  return 0;
    394 }
    395 
    396 void Scope::dump() {
    397  JSContext* cx = TlsContext.get();
    398  if (!cx) {
    399    fprintf(stderr, "*** can't get JSContext for current thread\n");
    400    return;
    401  }
    402  for (Rooted<ScopeIter> si(cx, ScopeIter(this)); si; si++) {
    403    fprintf(stderr, "- %s [%p]\n", ScopeKindString(si.kind()), si.scope());
    404    DumpBindings(cx, si.scope());
    405    fprintf(stderr, "\n");
    406  }
    407  fprintf(stderr, "\n");
    408 }
    409 
    410 #if defined(DEBUG) || defined(JS_JITSPEW)
    411 
    412 /* static */
    413 bool Scope::dumpForDisassemble(JSContext* cx, JS::Handle<Scope*> scope,
    414                               GenericPrinter& out, const char* indent) {
    415  out.put(ScopeKindString(scope->kind()));
    416  out.put(" {");
    417 
    418  size_t i = 0;
    419  for (Rooted<BindingIter> bi(cx, BindingIter(scope)); bi; bi++, i++) {
    420    if (i == 0) {
    421      out.put("\n");
    422    }
    423    UniqueChars bytes = AtomToPrintableString(cx, bi.name());
    424    if (!bytes) {
    425      return false;
    426    }
    427    out.put(indent);
    428    out.printf("  %2zu: %s %s ", i, BindingKindString(bi.kind()), bytes.get());
    429    switch (bi.location().kind()) {
    430      case BindingLocation::Kind::Global:
    431        if (bi.isTopLevelFunction()) {
    432          out.put("(global function)\n");
    433        } else {
    434          out.put("(global)\n");
    435        }
    436        break;
    437      case BindingLocation::Kind::Argument:
    438        out.printf("(arg slot %u)\n", bi.location().argumentSlot());
    439        break;
    440      case BindingLocation::Kind::Frame:
    441        out.printf("(frame slot %u)\n", bi.location().slot());
    442        break;
    443      case BindingLocation::Kind::Environment:
    444        out.printf("(env slot %u)\n", bi.location().slot());
    445        break;
    446      case BindingLocation::Kind::NamedLambdaCallee:
    447        out.put("(named lambda callee)\n");
    448        break;
    449      case BindingLocation::Kind::Import:
    450        out.put("(import)\n");
    451        break;
    452    }
    453  }
    454  if (i > 0) {
    455    out.put(indent);
    456  }
    457  out.put("}");
    458 
    459  ScopeIter si(scope);
    460  si++;
    461  for (; si; si++) {
    462    out.put(" -> ");
    463    out.put(ScopeKindString(si.kind()));
    464  }
    465  return true;
    466 }
    467 
    468 #endif /* defined(DEBUG) || defined(JS_JITSPEW) */
    469 
    470 static uint32_t NextFrameSlot(Scope* scope) {
    471  for (ScopeIter si(scope); si; si++) {
    472    switch (si.kind()) {
    473      case ScopeKind::With:
    474        continue;
    475 
    476      case ScopeKind::Function:
    477        return si.scope()->as<FunctionScope>().nextFrameSlot();
    478 
    479      case ScopeKind::FunctionBodyVar:
    480        return si.scope()->as<VarScope>().nextFrameSlot();
    481 
    482      case ScopeKind::Lexical:
    483      case ScopeKind::SimpleCatch:
    484      case ScopeKind::Catch:
    485      case ScopeKind::FunctionLexical:
    486        return si.scope()->as<LexicalScope>().nextFrameSlot();
    487 
    488      case ScopeKind::ClassBody:
    489        return si.scope()->as<ClassBodyScope>().nextFrameSlot();
    490 
    491      case ScopeKind::NamedLambda:
    492      case ScopeKind::StrictNamedLambda:
    493        // Named lambda scopes cannot have frame slots.
    494        return 0;
    495 
    496      case ScopeKind::Eval:
    497      case ScopeKind::StrictEval:
    498        return si.scope()->as<EvalScope>().nextFrameSlot();
    499 
    500      case ScopeKind::Global:
    501      case ScopeKind::NonSyntactic:
    502        return 0;
    503 
    504      case ScopeKind::Module:
    505        return si.scope()->as<ModuleScope>().nextFrameSlot();
    506 
    507      case ScopeKind::WasmInstance:
    508      case ScopeKind::WasmFunction:
    509        // Invalid; MOZ_CRASH below.
    510        break;
    511    }
    512  }
    513  MOZ_CRASH("Not an enclosing intra-frame Scope");
    514 }
    515 
    516 /* static */
    517 uint32_t LexicalScope::nextFrameSlot(Scope* scope) {
    518  return NextFrameSlot(scope);
    519 }
    520 
    521 /* static */
    522 uint32_t ClassBodyScope::nextFrameSlot(Scope* scope) {
    523  return NextFrameSlot(scope);
    524 }
    525 
    526 /* static */
    527 void LexicalScope::prepareForScopeCreation(ScopeKind kind,
    528                                           uint32_t firstFrameSlot,
    529                                           LexicalScope::ParserData* data,
    530                                           mozilla::Maybe<uint32_t>* envShape) {
    531  bool isNamedLambda =
    532      kind == ScopeKind::NamedLambda || kind == ScopeKind::StrictNamedLambda;
    533 
    534  MOZ_ASSERT_IF(isNamedLambda, firstFrameSlot == LOCALNO_LIMIT);
    535 
    536  ParserBindingIter bi(*data, firstFrameSlot, isNamedLambda);
    537  PrepareScopeData<LexicalScope, BlockLexicalEnvironmentObject>(
    538      bi, data, firstFrameSlot, envShape);
    539 }
    540 
    541 /* static */
    542 SharedShape* LexicalScope::getEmptyExtensibleEnvironmentShape(JSContext* cx) {
    543  const JSClass* cls = &LexicalEnvironmentObject::class_;
    544  return EmptyEnvironmentShape(cx, cls, JSSLOT_FREE(cls), ObjectFlags());
    545 }
    546 
    547 /* static */
    548 void ClassBodyScope::prepareForScopeCreation(
    549    ScopeKind kind, uint32_t firstFrameSlot, ClassBodyScope::ParserData* data,
    550    mozilla::Maybe<uint32_t>* envShape) {
    551  MOZ_ASSERT(kind == ScopeKind::ClassBody);
    552 
    553  ParserBindingIter bi(*data, firstFrameSlot);
    554  PrepareScopeData<ClassBodyScope, BlockLexicalEnvironmentObject>(
    555      bi, data, firstFrameSlot, envShape);
    556 }
    557 
    558 /* static */
    559 void FunctionScope::prepareForScopeCreation(
    560    FunctionScope::ParserData* data, bool hasParameterExprs,
    561    bool needsEnvironment, mozilla::Maybe<uint32_t>* envShape) {
    562  uint32_t firstFrameSlot = 0;
    563  ParserBindingIter bi(*data, hasParameterExprs);
    564  PrepareScopeData<FunctionScope, CallObject>(bi, data, firstFrameSlot,
    565                                              envShape);
    566 
    567  if (hasParameterExprs) {
    568    data->slotInfo.setHasParameterExprs();
    569  }
    570 
    571  // An environment may be needed regardless of existence of any closed over
    572  // bindings:
    573  //   - Extensible scopes (i.e., due to direct eval)
    574  //   - Needing a home object
    575  //   - Being a derived class constructor
    576  //   - Being a generator or async function
    577  // Also see |FunctionBox::needsExtraBodyVarEnvironmentRegardlessOfBindings()|.
    578  updateEnvShapeIfRequired(envShape, needsEnvironment);
    579 }
    580 
    581 JSScript* FunctionScope::script() const {
    582  return canonicalFunction()->nonLazyScript();
    583 }
    584 
    585 /* static */
    586 bool FunctionScope::isSpecialName(frontend::TaggedParserAtomIndex name) {
    587  return name == frontend::TaggedParserAtomIndex::WellKnown::arguments() ||
    588         name == frontend::TaggedParserAtomIndex::WellKnown::dot_this_() ||
    589         name == frontend::TaggedParserAtomIndex::WellKnown::dot_newTarget_() ||
    590         name == frontend::TaggedParserAtomIndex::WellKnown::dot_generator_();
    591 }
    592 
    593 /* static */
    594 void VarScope::prepareForScopeCreation(ScopeKind kind,
    595                                       VarScope::ParserData* data,
    596                                       uint32_t firstFrameSlot,
    597                                       bool needsEnvironment,
    598                                       mozilla::Maybe<uint32_t>* envShape) {
    599  ParserBindingIter bi(*data, firstFrameSlot);
    600  PrepareScopeData<VarScope, VarEnvironmentObject>(bi, data, firstFrameSlot,
    601                                                   envShape);
    602 
    603  // An environment may be needed regardless of existence of any closed over
    604  // bindings:
    605  //   - Extensible scopes (i.e., due to direct eval)
    606  //   - Being a generator
    607  updateEnvShapeIfRequired(envShape, needsEnvironment);
    608 }
    609 
    610 GlobalScope* GlobalScope::createEmpty(JSContext* cx, ScopeKind kind) {
    611  RootedBuffer<RuntimeData> data(cx, NewEmptyScopeData<GlobalScope>(cx));
    612  if (!data) {
    613    return nullptr;
    614  }
    615 
    616  return createWithData(cx, kind, data);
    617 }
    618 
    619 /* static */
    620 GlobalScope* GlobalScope::createWithData(JSContext* cx, ScopeKind kind,
    621                                         HandleBuffer<RuntimeData> data) {
    622  MOZ_ASSERT(data);
    623 
    624  // The global scope has no environment shape. Its environment is the
    625  // global lexical scope and the global object or non-syntactic objects
    626  // created by embedding, all of which are not only extensible but may
    627  // have names on them deleted.
    628  return Scope::create<GlobalScope>(cx, kind, nullptr, nullptr, data);
    629 }
    630 
    631 /* static */
    632 WithScope* WithScope::create(JSContext* cx, Handle<Scope*> enclosing) {
    633  Scope* scope = Scope::create(cx, ScopeKind::With, enclosing, nullptr);
    634  return static_cast<WithScope*>(scope);
    635 }
    636 
    637 /* static */
    638 void EvalScope::prepareForScopeCreation(ScopeKind scopeKind,
    639                                        EvalScope::ParserData* data,
    640                                        mozilla::Maybe<uint32_t>* envShape) {
    641  if (scopeKind == ScopeKind::StrictEval) {
    642    uint32_t firstFrameSlot = 0;
    643    ParserBindingIter bi(*data, true);
    644    PrepareScopeData<EvalScope, VarEnvironmentObject>(bi, data, firstFrameSlot,
    645                                                      envShape);
    646  }
    647 }
    648 
    649 /* static */
    650 Scope* EvalScope::nearestVarScopeForDirectEval(Scope* scope) {
    651  for (ScopeIter si(scope); si; si++) {
    652    switch (si.kind()) {
    653      case ScopeKind::Function:
    654      case ScopeKind::FunctionBodyVar:
    655      case ScopeKind::Global:
    656      case ScopeKind::NonSyntactic:
    657        return scope;
    658      default:
    659        break;
    660    }
    661  }
    662  return nullptr;
    663 }
    664 
    665 ModuleScope::RuntimeData::RuntimeData(size_t length) {
    666  PoisonNames(this, length);
    667 }
    668 
    669 /* static */
    670 void ModuleScope::prepareForScopeCreation(ModuleScope::ParserData* data,
    671                                          mozilla::Maybe<uint32_t>* envShape) {
    672  uint32_t firstFrameSlot = 0;
    673  ParserBindingIter bi(*data);
    674  PrepareScopeData<ModuleScope, ModuleEnvironmentObject>(
    675      bi, data, firstFrameSlot, envShape);
    676 
    677  // Modules always need an environment object for now.
    678  bool needsEnvironment = true;
    679  updateEnvShapeIfRequired(envShape, needsEnvironment);
    680 }
    681 
    682 template <size_t ArrayLength>
    683 static JSAtom* GenerateWasmName(JSContext* cx,
    684                                const char (&prefix)[ArrayLength],
    685                                uint32_t index) {
    686  StringBuilder sb(cx);
    687  if (!sb.append(prefix)) {
    688    return nullptr;
    689  }
    690  if (!NumberValueToStringBuilder(NumberValue(index), sb)) {
    691    return nullptr;
    692  }
    693 
    694  return sb.finishAtom();
    695 }
    696 
    697 static void InitializeTrailingName(AbstractBindingName<JSAtom>* trailingNames,
    698                                   size_t i, JSAtom* name) {
    699  void* trailingName = &trailingNames[i];
    700  new (trailingName) BindingName(name, false);
    701 }
    702 
    703 template <class DataT>
    704 static void InitializeNextTrailingName(RootedBuffer<DataT>& data,
    705                                       JSAtom* name) {
    706  InitializeTrailingName(GetScopeDataTrailingNamesPointer(data.get()),
    707                         data->length, name);
    708  data->length++;
    709 }
    710 
    711 WasmInstanceScope::RuntimeData::RuntimeData(size_t length) {
    712  PoisonNames(this, length);
    713 }
    714 
    715 /* static */
    716 WasmInstanceScope* WasmInstanceScope::create(
    717    JSContext* cx, Handle<WasmInstanceObject*> instance) {
    718  size_t namesCount = 0;
    719 
    720  size_t memoriesStart = namesCount;
    721  size_t memoriesCount = instance->instance().codeMeta().memories.length();
    722  namesCount += memoriesCount;
    723 
    724  size_t globalsStart = namesCount;
    725  size_t globalsCount = instance->instance().codeMeta().globals.length();
    726  namesCount += globalsCount;
    727 
    728  Rooted<Scope*> enclosing(cx, &cx->global()->emptyGlobalScope());
    729  Rooted<Scope*> scope(cx, Scope::create(cx, ScopeKind::WasmInstance, enclosing,
    730                                         /* envShape = */ nullptr));
    731  if (!scope) {
    732    return nullptr;
    733  }
    734 
    735  RootedBuffer<RuntimeData> data(
    736      cx, NewEmptyScopeData<WasmInstanceScope>(cx, namesCount));
    737  if (!data) {
    738    return nullptr;
    739  }
    740 
    741  for (size_t i = 0; i < memoriesCount; i++) {
    742    JSAtom* wasmName = GenerateWasmName(cx, "memory", i);
    743    if (!wasmName) {
    744      return nullptr;
    745    }
    746 
    747    InitializeNextTrailingName(data, wasmName);
    748  }
    749 
    750  for (size_t i = 0; i < globalsCount; i++) {
    751    JSAtom* wasmName = GenerateWasmName(cx, "global", i);
    752    if (!wasmName) {
    753      return nullptr;
    754    }
    755 
    756    InitializeNextTrailingName(data, wasmName);
    757  }
    758 
    759  MOZ_ASSERT(data->length == namesCount);
    760 
    761  data->instance.init(instance);
    762  data->slotInfo.memoriesStart = memoriesStart;
    763  data->slotInfo.globalsStart = globalsStart;
    764 
    765  WasmInstanceScope* concreteScope = &scope->as<WasmInstanceScope>();
    766  concreteScope->initData<WasmInstanceScope>(data);
    767  return concreteScope;
    768 }
    769 
    770 /* static */
    771 WasmFunctionScope* WasmFunctionScope::create(JSContext* cx,
    772                                             Handle<Scope*> enclosing,
    773                                             uint32_t funcIndex) {
    774  MOZ_ASSERT(enclosing->is<WasmInstanceScope>());
    775 
    776  Rooted<WasmFunctionScope*> wasmFunctionScope(cx);
    777 
    778  Rooted<WasmInstanceObject*> instance(
    779      cx, enclosing->as<WasmInstanceScope>().instance());
    780 
    781  // TODO pull the local variable names from the wasm function definition.
    782  wasm::ValTypeVector locals;
    783  size_t argsLength;
    784  wasm::StackResults unusedStackResults;
    785  if (!instance->instance().debug().debugGetLocalTypes(
    786          funcIndex, &locals, &argsLength, &unusedStackResults)) {
    787    return nullptr;
    788  }
    789  uint32_t namesCount = locals.length();
    790 
    791  RootedBuffer<RuntimeData> data(
    792      cx, NewEmptyScopeData<WasmFunctionScope>(cx, namesCount));
    793  if (!data) {
    794    return nullptr;
    795  }
    796 
    797  for (size_t i = 0; i < namesCount; i++) {
    798    JSAtom* wasmName = GenerateWasmName(cx, "var", i);
    799    if (!wasmName) {
    800      return nullptr;
    801    }
    802 
    803    InitializeNextTrailingName(data, wasmName);
    804  }
    805  MOZ_ASSERT(data->length == namesCount);
    806 
    807  return Scope::create<WasmFunctionScope>(cx, ScopeKind::WasmFunction,
    808                                          enclosing,
    809                                          /* envShape = */ nullptr, data);
    810 }
    811 
    812 ScopeIter::ScopeIter(JSScript* script) : scope_(script->bodyScope()) {}
    813 
    814 bool ScopeIter::hasSyntacticEnvironment() const {
    815  return scope()->hasEnvironment() &&
    816         scope()->kind() != ScopeKind::NonSyntactic;
    817 }
    818 
    819 AbstractBindingIter<JSAtom>::AbstractBindingIter(ScopeKind kind,
    820                                                 BaseScopeData* data,
    821                                                 uint32_t firstFrameSlot)
    822    : BaseAbstractBindingIter<JSAtom>() {
    823  switch (kind) {
    824    case ScopeKind::Lexical:
    825    case ScopeKind::SimpleCatch:
    826    case ScopeKind::Catch:
    827    case ScopeKind::FunctionLexical:
    828      init(*static_cast<LexicalScope::RuntimeData*>(data), firstFrameSlot, 0);
    829      break;
    830    case ScopeKind::NamedLambda:
    831    case ScopeKind::StrictNamedLambda:
    832      init(*static_cast<LexicalScope::RuntimeData*>(data), LOCALNO_LIMIT,
    833           IsNamedLambda);
    834      break;
    835    case ScopeKind::ClassBody:
    836      init(*static_cast<ClassBodyScope::RuntimeData*>(data), firstFrameSlot);
    837      break;
    838    case ScopeKind::With:
    839      // With scopes do not have bindings.
    840      index_ = length_ = 0;
    841      MOZ_ASSERT(done());
    842      break;
    843    case ScopeKind::Function: {
    844      uint8_t flags = IgnoreDestructuredFormalParameters;
    845      if (static_cast<FunctionScope::RuntimeData*>(data)
    846              ->slotInfo.hasParameterExprs()) {
    847        flags |= HasFormalParameterExprs;
    848      }
    849      init(*static_cast<FunctionScope::RuntimeData*>(data), flags);
    850      break;
    851    }
    852    case ScopeKind::FunctionBodyVar:
    853      init(*static_cast<VarScope::RuntimeData*>(data), firstFrameSlot);
    854      break;
    855    case ScopeKind::Eval:
    856    case ScopeKind::StrictEval:
    857      init(*static_cast<EvalScope::RuntimeData*>(data),
    858           kind == ScopeKind::StrictEval);
    859      break;
    860    case ScopeKind::Global:
    861    case ScopeKind::NonSyntactic:
    862      init(*static_cast<GlobalScope::RuntimeData*>(data));
    863      break;
    864    case ScopeKind::Module:
    865      init(*static_cast<ModuleScope::RuntimeData*>(data));
    866      break;
    867    case ScopeKind::WasmInstance:
    868      init(*static_cast<WasmInstanceScope::RuntimeData*>(data));
    869      break;
    870    case ScopeKind::WasmFunction:
    871      init(*static_cast<WasmFunctionScope::RuntimeData*>(data));
    872      break;
    873  }
    874 }
    875 
    876 AbstractBindingIter<JSAtom>::AbstractBindingIter(Scope* scope)
    877    : AbstractBindingIter<JSAtom>(scope->kind(), scope->rawData(),
    878                                  scope->firstFrameSlot()) {}
    879 
    880 AbstractBindingIter<JSAtom>::AbstractBindingIter(JSScript* script)
    881    : AbstractBindingIter<JSAtom>(script->bodyScope()) {}
    882 
    883 AbstractBindingIter<frontend::TaggedParserAtomIndex>::AbstractBindingIter(
    884    const frontend::ScopeStencilRef& ref)
    885    : Base() {
    886  const ScopeStencil& scope = ref.scope();
    887  BaseParserScopeData* data = ref.context()->scopeNames[ref.scopeIndex_];
    888  switch (scope.kind()) {
    889    case ScopeKind::Lexical:
    890    case ScopeKind::SimpleCatch:
    891    case ScopeKind::Catch:
    892    case ScopeKind::FunctionLexical:
    893      init(*static_cast<LexicalScope::ParserData*>(data),
    894           scope.firstFrameSlot(), 0);
    895      break;
    896    case ScopeKind::NamedLambda:
    897    case ScopeKind::StrictNamedLambda:
    898      init(*static_cast<LexicalScope::ParserData*>(data), LOCALNO_LIMIT,
    899           IsNamedLambda);
    900      break;
    901    case ScopeKind::ClassBody:
    902      init(*static_cast<ClassBodyScope::ParserData*>(data),
    903           scope.firstFrameSlot());
    904      break;
    905    case ScopeKind::With:
    906      // With scopes do not have bindings.
    907      index_ = length_ = 0;
    908      MOZ_ASSERT(done());
    909      break;
    910    case ScopeKind::Function: {
    911      uint8_t flags = IgnoreDestructuredFormalParameters;
    912      if (static_cast<FunctionScope::ParserData*>(data)
    913              ->slotInfo.hasParameterExprs()) {
    914        flags |= HasFormalParameterExprs;
    915      }
    916      init(*static_cast<FunctionScope::ParserData*>(data), flags);
    917      break;
    918    }
    919    case ScopeKind::FunctionBodyVar:
    920      init(*static_cast<VarScope::ParserData*>(data), scope.firstFrameSlot());
    921      break;
    922    case ScopeKind::Eval:
    923    case ScopeKind::StrictEval:
    924      init(*static_cast<EvalScope::ParserData*>(data),
    925           scope.kind() == ScopeKind::StrictEval);
    926      break;
    927    case ScopeKind::Global:
    928    case ScopeKind::NonSyntactic:
    929      init(*static_cast<GlobalScope::ParserData*>(data));
    930      break;
    931    case ScopeKind::Module:
    932      init(*static_cast<ModuleScope::ParserData*>(data));
    933      break;
    934    case ScopeKind::WasmInstance:
    935      init(*static_cast<WasmInstanceScope::ParserData*>(data));
    936      break;
    937    case ScopeKind::WasmFunction:
    938      init(*static_cast<WasmFunctionScope::ParserData*>(data));
    939      break;
    940  }
    941 }
    942 
    943 template <typename NameT>
    944 void BaseAbstractBindingIter<NameT>::init(
    945    LexicalScope::AbstractData<NameT>& data, uint32_t firstFrameSlot,
    946    uint8_t flags) {
    947  auto& slotInfo = data.slotInfo;
    948 
    949  // Named lambda scopes can only have environment slots. If the callee
    950  // isn't closed over, it is accessed via JSOp::Callee.
    951  if (flags & IsNamedLambda) {
    952    // Named lambda binding is weird. Normal BindingKind ordering rules
    953    // don't apply.
    954    init(/* positionalFormalStart= */ 0,
    955         /* nonPositionalFormalStart= */ 0,
    956         /* varStart= */ 0,
    957         /* letStart= */ 0,
    958         /* constStart= */ 0,
    959 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
    960         /* usingStart= */ data.length,
    961 #endif
    962         /* syntheticStart= */ data.length,
    963         /* privageMethodStart= */ data.length,
    964         /* flags= */ CanHaveEnvironmentSlots | flags,
    965         /* firstFrameSlot= */ firstFrameSlot,
    966         /* firstEnvironmentSlot= */
    967         JSSLOT_FREE(&LexicalEnvironmentObject::class_),
    968         /* names= */ GetScopeDataTrailingNames(&data));
    969  } else {
    970    //            imports - [0, 0)
    971    // positional formals - [0, 0)
    972    //      other formals - [0, 0)
    973    //               vars - [0, 0)
    974    //               lets - [0, slotInfo.constStart)
    975    //             consts - [slotInfo.constStart, data.length)
    976    //          synthetic - [data.length, data.length)
    977    //    private methods - [data.length, data.length)
    978    //
    979    // If ENABLE_EXPLICIT_RESOURCE_MANAGEMENT is set, the consts range is split
    980    // into the following:
    981    //             consts - [slotInfo.constStart, slotInfo.usingStart)
    982    //             usings - [slotInfo.usingStart, data.length)
    983    init(/* positionalFormalStart= */ 0,
    984         /* nonPositionalFormalStart= */ 0,
    985         /* varStart= */ 0,
    986         /* letStart= */ 0,
    987         /* constStart= */ slotInfo.constStart,
    988 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
    989         /* usingStart= */ slotInfo.usingStart,
    990 #endif
    991         /* syntheticStart= */ data.length,
    992         /* privateMethodStart= */ data.length,
    993         /* flags= */ CanHaveFrameSlots | CanHaveEnvironmentSlots | flags,
    994         /* firstFrameSlot= */ firstFrameSlot,
    995         /* firstEnvironmentSlot= */
    996         JSSLOT_FREE(&LexicalEnvironmentObject::class_),
    997         /* names= */ GetScopeDataTrailingNames(&data));
    998  }
    999 }
   1000 
   1001 template void BaseAbstractBindingIter<JSAtom>::init(
   1002    LexicalScope::AbstractData<JSAtom>&, uint32_t, uint8_t);
   1003 template void BaseAbstractBindingIter<frontend::TaggedParserAtomIndex>::init(
   1004    LexicalScope::AbstractData<frontend::TaggedParserAtomIndex>&, uint32_t,
   1005    uint8_t);
   1006 
   1007 template <typename NameT>
   1008 void BaseAbstractBindingIter<NameT>::init(
   1009    ClassBodyScope::AbstractData<NameT>& data, uint32_t firstFrameSlot) {
   1010  auto& slotInfo = data.slotInfo;
   1011 
   1012  //            imports - [0, 0)
   1013  // positional formals - [0, 0)
   1014  //      other formals - [0, 0)
   1015  //               vars - [0, 0)
   1016  //               lets - [0, 0)
   1017  //             consts - [0, 0)
   1018  //          synthetic - [0, slotInfo.privateMethodStart)
   1019  //    private methods - [slotInfo.privateMethodStart, data.length)
   1020  init(/* positionalFormalStart= */ 0,
   1021       /* nonPositionalFormalStart= */ 0,
   1022       /* varStart= */ 0,
   1023       /* letStart= */ 0,
   1024       /* constStart= */ 0,
   1025 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1026       /* usingStart= */ 0,
   1027 #endif
   1028       /* syntheticStart= */ 0,
   1029       /* privateMethodStart= */ slotInfo.privateMethodStart,
   1030       /* flags= */ CanHaveFrameSlots | CanHaveEnvironmentSlots,
   1031       /* firstFrameSlot= */ firstFrameSlot,
   1032       /* firstEnvironmentSlot= */
   1033       JSSLOT_FREE(&ClassBodyLexicalEnvironmentObject::class_),
   1034       /* names= */ GetScopeDataTrailingNames(&data));
   1035 }
   1036 
   1037 template void BaseAbstractBindingIter<JSAtom>::init(
   1038    ClassBodyScope::AbstractData<JSAtom>&, uint32_t);
   1039 template void BaseAbstractBindingIter<frontend::TaggedParserAtomIndex>::init(
   1040    ClassBodyScope::AbstractData<frontend::TaggedParserAtomIndex>&, uint32_t);
   1041 
   1042 template <typename NameT>
   1043 void BaseAbstractBindingIter<NameT>::init(
   1044    FunctionScope::AbstractData<NameT>& data, uint8_t flags) {
   1045  flags = CanHaveFrameSlots | CanHaveEnvironmentSlots | flags;
   1046  if (!(flags & HasFormalParameterExprs)) {
   1047    flags |= CanHaveArgumentSlots;
   1048  }
   1049 
   1050  auto length = data.length;
   1051  auto& slotInfo = data.slotInfo;
   1052 
   1053  //            imports - [0, 0)
   1054  // positional formals - [0, slotInfo.nonPositionalFormalStart)
   1055  //      other formals - [slotInfo.nonPositionalParamStart, slotInfo.varStart)
   1056  //               vars - [slotInfo.varStart, length)
   1057  //               lets - [length, length)
   1058  //             consts - [length, length)
   1059  //          synthetic - [length, length)
   1060  //    private methods - [length, length)
   1061  init(/* positionalFormalStart= */ 0,
   1062       /* nonPositionalFormalStart= */ slotInfo.nonPositionalFormalStart,
   1063       /* varStart= */ slotInfo.varStart,
   1064       /* letStart= */ length,
   1065       /* constStart= */ length,
   1066 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1067       /* usingStart= */ length,
   1068 #endif
   1069       /* syntheticStart= */ length,
   1070       /* privateMethodStart= */ length,
   1071       /* flags= */ flags,
   1072       /* firstFrameSlot= */ 0,
   1073       /* firstEnvironmentSlot= */ JSSLOT_FREE(&CallObject::class_),
   1074       /* names= */ GetScopeDataTrailingNames(&data));
   1075 }
   1076 template void BaseAbstractBindingIter<JSAtom>::init(
   1077    FunctionScope::AbstractData<JSAtom>&, uint8_t);
   1078 template void BaseAbstractBindingIter<frontend::TaggedParserAtomIndex>::init(
   1079    FunctionScope::AbstractData<frontend::TaggedParserAtomIndex>&, uint8_t);
   1080 
   1081 template <typename NameT>
   1082 void BaseAbstractBindingIter<NameT>::init(VarScope::AbstractData<NameT>& data,
   1083                                          uint32_t firstFrameSlot) {
   1084  auto length = data.length;
   1085 
   1086  //            imports - [0, 0)
   1087  // positional formals - [0, 0)
   1088  //      other formals - [0, 0)
   1089  //               vars - [0, length)
   1090  //               lets - [length, length)
   1091  //             consts - [length, length)
   1092  //          synthetic - [length, length)
   1093  //    private methods - [length, length)
   1094  init(/* positionalFormalStart= */ 0,
   1095       /* nonPositionalFormalStart= */ 0,
   1096       /* varStart= */ 0,
   1097       /* letStart= */ length,
   1098       /* constStart= */ length,
   1099 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1100       /* usingStart= */ length,
   1101 #endif
   1102       /* syntheticStart= */ length,
   1103       /* privateMethodStart= */ length,
   1104       /* flags= */ CanHaveFrameSlots | CanHaveEnvironmentSlots,
   1105       /* firstFrameSlot= */ firstFrameSlot,
   1106       /* firstEnvironmentSlot= */ JSSLOT_FREE(&VarEnvironmentObject::class_),
   1107       /* names= */ GetScopeDataTrailingNames(&data));
   1108 }
   1109 template void BaseAbstractBindingIter<JSAtom>::init(
   1110    VarScope::AbstractData<JSAtom>&, uint32_t);
   1111 template void BaseAbstractBindingIter<frontend::TaggedParserAtomIndex>::init(
   1112    VarScope::AbstractData<frontend::TaggedParserAtomIndex>&, uint32_t);
   1113 
   1114 template <typename NameT>
   1115 void BaseAbstractBindingIter<NameT>::init(
   1116    GlobalScope::AbstractData<NameT>& data) {
   1117  auto& slotInfo = data.slotInfo;
   1118 
   1119  //            imports - [0, 0)
   1120  // positional formals - [0, 0)
   1121  //      other formals - [0, 0)
   1122  //               vars - [0, slotInfo.letStart)
   1123  //               lets - [slotInfo.letStart, slotInfo.constStart)
   1124  //             consts - [slotInfo.constStart, data.length)
   1125  //          synthetic - [data.length, data.length)
   1126  //    private methods - [data.length, data.length)
   1127  init(/* positionalFormalStart= */ 0,
   1128       /* nonPositionalFormalStart= */ 0,
   1129       /* varStart= */ 0,
   1130       /* letStart= */ slotInfo.letStart,
   1131       /* constStart= */ slotInfo.constStart,
   1132 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1133       /* usingStart= */ data.length,
   1134 #endif
   1135       /* syntheticStart= */ data.length,
   1136       /* privateMethoodStart= */ data.length,
   1137       /* flags= */ CannotHaveSlots,
   1138       /* firstFrameSlot= */ UINT32_MAX,
   1139       /* firstEnvironmentSlot= */ UINT32_MAX,
   1140       /* names= */ GetScopeDataTrailingNames(&data));
   1141 }
   1142 template void BaseAbstractBindingIter<JSAtom>::init(
   1143    GlobalScope::AbstractData<JSAtom>&);
   1144 template void BaseAbstractBindingIter<frontend::TaggedParserAtomIndex>::init(
   1145    GlobalScope::AbstractData<frontend::TaggedParserAtomIndex>&);
   1146 
   1147 template <typename NameT>
   1148 void BaseAbstractBindingIter<NameT>::init(EvalScope::AbstractData<NameT>& data,
   1149                                          bool strict) {
   1150  uint32_t flags;
   1151  uint32_t firstFrameSlot;
   1152  uint32_t firstEnvironmentSlot;
   1153  if (strict) {
   1154    flags = CanHaveFrameSlots | CanHaveEnvironmentSlots;
   1155    firstFrameSlot = 0;
   1156    firstEnvironmentSlot = JSSLOT_FREE(&VarEnvironmentObject::class_);
   1157  } else {
   1158    flags = CannotHaveSlots;
   1159    firstFrameSlot = UINT32_MAX;
   1160    firstEnvironmentSlot = UINT32_MAX;
   1161  }
   1162 
   1163  auto length = data.length;
   1164 
   1165  //            imports - [0, 0)
   1166  // positional formals - [0, 0)
   1167  //      other formals - [0, 0)
   1168  //               vars - [0, length)
   1169  //               lets - [length, length)
   1170  //             consts - [length, length)
   1171  //          synthetic - [length, length)
   1172  //    private methods - [length, length)
   1173  init(/* positionalFormalStart= */ 0,
   1174       /* nonPositionalFormalStart= */ 0,
   1175       /* varStart= */ 0,
   1176       /* letStart= */ length,
   1177       /* constStart= */ length,
   1178 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1179       /* usingStart= */ length,
   1180 #endif
   1181       /* syntheticStart= */ length,
   1182       /* privateMethodStart= */ length,
   1183       /* flags= */ flags,
   1184       /* firstFrameSlot= */ firstFrameSlot,
   1185       /* firstEnvironmentSlot= */ firstEnvironmentSlot,
   1186       /* names= */ GetScopeDataTrailingNames(&data));
   1187 }
   1188 template void BaseAbstractBindingIter<JSAtom>::init(
   1189    EvalScope::AbstractData<JSAtom>&, bool);
   1190 template void BaseAbstractBindingIter<frontend::TaggedParserAtomIndex>::init(
   1191    EvalScope::AbstractData<frontend::TaggedParserAtomIndex>&, bool);
   1192 
   1193 template <typename NameT>
   1194 void BaseAbstractBindingIter<NameT>::init(
   1195    ModuleScope::AbstractData<NameT>& data) {
   1196  auto& slotInfo = data.slotInfo;
   1197 
   1198  //            imports - [0, slotInfo.varStart)
   1199  // positional formals - [slotInfo.varStart, slotInfo.varStart)
   1200  //      other formals - [slotInfo.varStart, slotInfo.varStart)
   1201  //               vars - [slotInfo.varStart, slotInfo.letStart)
   1202  //               lets - [slotInfo.letStart, slotInfo.constStart)
   1203  //             consts - [slotInfo.constStart, data.length)
   1204  //          synthetic - [data.length, data.length)
   1205  //    private methods - [data.length, data.length)
   1206  //
   1207  // If ENABLE_EXPLICIT_RESOURCE_MANAGEMENT is set, the consts range is split
   1208  // into the following:
   1209  //             consts - [slotInfo.constStart, slotInfo.usingStart)
   1210  //             usings - [slotInfo.usingStart, data.length)
   1211  init(
   1212      /* positionalFormalStart= */ slotInfo.varStart,
   1213      /* nonPositionalFormalStart= */ slotInfo.varStart,
   1214      /* varStart= */ slotInfo.varStart,
   1215      /* letStart= */ slotInfo.letStart,
   1216      /* constStart= */ slotInfo.constStart,
   1217 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1218      /* usingStart= */ slotInfo.usingStart,
   1219 #endif
   1220      /* syntheticStart= */ data.length,
   1221      /* privateMethodStart= */ data.length,
   1222      /* flags= */ CanHaveFrameSlots | CanHaveEnvironmentSlots,
   1223      /* firstFrameSlot= */ 0,
   1224      /* firstEnvironmentSlot= */ JSSLOT_FREE(&ModuleEnvironmentObject::class_),
   1225      /* names= */ GetScopeDataTrailingNames(&data));
   1226 }
   1227 template void BaseAbstractBindingIter<JSAtom>::init(
   1228    ModuleScope::AbstractData<JSAtom>&);
   1229 template void BaseAbstractBindingIter<frontend::TaggedParserAtomIndex>::init(
   1230    ModuleScope::AbstractData<frontend::TaggedParserAtomIndex>&);
   1231 
   1232 template <typename NameT>
   1233 void BaseAbstractBindingIter<NameT>::init(
   1234    WasmInstanceScope::AbstractData<NameT>& data) {
   1235  auto length = data.length;
   1236 
   1237  //            imports - [0, 0)
   1238  // positional formals - [0, 0)
   1239  //      other formals - [0, 0)
   1240  //               vars - [0, length)
   1241  //               lets - [length, length)
   1242  //             consts - [length, length)
   1243  //          synthetic - [length, length)
   1244  //    private methods - [length, length)
   1245  init(/* positionalFormalStart= */ 0,
   1246       /* nonPositionalFormalStart= */ 0,
   1247       /* varStart= */ 0,
   1248       /* letStart= */ length,
   1249       /* constStart= */ length,
   1250 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1251       /* usingStart= */ length,
   1252 #endif
   1253       /* syntheticStart= */ length,
   1254       /* privateMethodStart= */ length,
   1255       /* flags= */ CanHaveFrameSlots | CanHaveEnvironmentSlots,
   1256       /* firstFrameSlot= */ UINT32_MAX,
   1257       /* firstEnvironmentSlot= */ UINT32_MAX,
   1258       /* names= */ GetScopeDataTrailingNames(&data));
   1259 }
   1260 template void BaseAbstractBindingIter<JSAtom>::init(
   1261    WasmInstanceScope::AbstractData<JSAtom>&);
   1262 template void BaseAbstractBindingIter<frontend::TaggedParserAtomIndex>::init(
   1263    WasmInstanceScope::AbstractData<frontend::TaggedParserAtomIndex>&);
   1264 
   1265 template <typename NameT>
   1266 void BaseAbstractBindingIter<NameT>::init(
   1267    WasmFunctionScope::AbstractData<NameT>& data) {
   1268  auto length = data.length;
   1269 
   1270  //            imports - [0, 0)
   1271  // positional formals - [0, 0)
   1272  //      other formals - [0, 0)
   1273  //               vars - [0, length)
   1274  //               lets - [length, length)
   1275  //             consts - [length, length)
   1276  //          synthetic - [length, length)
   1277  //    private methods - [length, length)
   1278  init(/* positionalFormalStart = */ 0,
   1279       /* nonPositionalFormalStart = */ 0,
   1280       /* varStart= */ 0,
   1281       /* letStart= */ length,
   1282       /* constStart= */ length,
   1283 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1284       /* usingStart= */ length,
   1285 #endif
   1286       /* syntheticStart= */ length,
   1287       /* privateMethodStart= */ length,
   1288       /* flags= */ CanHaveFrameSlots | CanHaveEnvironmentSlots,
   1289       /* firstFrameSlot= */ UINT32_MAX,
   1290       /* firstEnvironmentSlot= */ UINT32_MAX,
   1291       /* names= */ GetScopeDataTrailingNames(&data));
   1292 }
   1293 template void BaseAbstractBindingIter<JSAtom>::init(
   1294    WasmFunctionScope::AbstractData<JSAtom>&);
   1295 template void BaseAbstractBindingIter<frontend::TaggedParserAtomIndex>::init(
   1296    WasmFunctionScope::AbstractData<frontend::TaggedParserAtomIndex>&);
   1297 
   1298 AbstractPositionalFormalParameterIter<
   1299    JSAtom>::AbstractPositionalFormalParameterIter(Scope* scope)
   1300    : Base(scope) {
   1301  // Reinit with flags = 0, i.e., iterate over all positional parameters.
   1302  if (scope->is<FunctionScope>()) {
   1303    init(scope->as<FunctionScope>().data(), /* flags = */ 0);
   1304  }
   1305  settle();
   1306 }
   1307 
   1308 AbstractPositionalFormalParameterIter<
   1309    JSAtom>::AbstractPositionalFormalParameterIter(JSScript* script)
   1310    : AbstractPositionalFormalParameterIter(script->bodyScope()) {}
   1311 
   1312 void js::DumpBindings(JSContext* cx, Scope* scopeArg) {
   1313  Rooted<Scope*> scope(cx, scopeArg);
   1314  for (Rooted<BindingIter> bi(cx, BindingIter(scope)); bi; bi++) {
   1315    UniqueChars bytes = AtomToPrintableString(cx, bi.name());
   1316    if (!bytes) {
   1317      MaybePrintAndClearPendingException(cx);
   1318      return;
   1319    }
   1320    fprintf(stderr, "    %s %s ", BindingKindString(bi.kind()), bytes.get());
   1321    switch (bi.location().kind()) {
   1322      case BindingLocation::Kind::Global:
   1323        if (bi.isTopLevelFunction()) {
   1324          fprintf(stderr, "global function\n");
   1325        } else {
   1326          fprintf(stderr, "global\n");
   1327        }
   1328        break;
   1329      case BindingLocation::Kind::Argument:
   1330        fprintf(stderr, "arg slot %u\n", bi.location().argumentSlot());
   1331        break;
   1332      case BindingLocation::Kind::Frame:
   1333        fprintf(stderr, "frame slot %u\n", bi.location().slot());
   1334        break;
   1335      case BindingLocation::Kind::Environment:
   1336        fprintf(stderr, "env slot %u\n", bi.location().slot());
   1337        break;
   1338      case BindingLocation::Kind::NamedLambdaCallee:
   1339        fprintf(stderr, "named lambda callee\n");
   1340        break;
   1341      case BindingLocation::Kind::Import:
   1342        fprintf(stderr, "import\n");
   1343        break;
   1344    }
   1345  }
   1346 }
   1347 
   1348 static JSAtom* GetFrameSlotNameInScope(Scope* scope, uint32_t slot) {
   1349  for (BindingIter bi(scope); bi; bi++) {
   1350    BindingLocation loc = bi.location();
   1351    if (loc.kind() == BindingLocation::Kind::Frame && loc.slot() == slot) {
   1352      return bi.name();
   1353    }
   1354  }
   1355  return nullptr;
   1356 }
   1357 
   1358 JSAtom* js::FrameSlotName(JSScript* script, jsbytecode* pc) {
   1359  MOZ_ASSERT(IsLocalOp(JSOp(*pc)));
   1360  uint32_t slot = GET_LOCALNO(pc);
   1361  MOZ_ASSERT(slot < script->nfixed());
   1362 
   1363  // Look for it in the body scope first.
   1364  if (JSAtom* name = GetFrameSlotNameInScope(script->bodyScope(), slot)) {
   1365    return name;
   1366  }
   1367 
   1368  // If this is a function script and there is an extra var scope, look for
   1369  // it there.
   1370  if (script->functionHasExtraBodyVarScope()) {
   1371    if (JSAtom* name = GetFrameSlotNameInScope(
   1372            script->functionExtraBodyVarScope(), slot)) {
   1373      return name;
   1374    }
   1375  }
   1376  // If not found, look for it in a lexical scope.
   1377  for (ScopeIter si(script->innermostScope(pc)); si; si++) {
   1378    if (!si.scope()->is<LexicalScope>() && !si.scope()->is<ClassBodyScope>()) {
   1379      continue;
   1380    }
   1381 
   1382    // Is the slot within bounds of the current lexical scope?
   1383    if (slot < si.scope()->firstFrameSlot()) {
   1384      continue;
   1385    }
   1386    if (slot >= LexicalScope::nextFrameSlot(si.scope())) {
   1387      break;
   1388    }
   1389 
   1390    // If so, get the name.
   1391    if (JSAtom* name = GetFrameSlotNameInScope(si.scope(), slot)) {
   1392      return name;
   1393    }
   1394  }
   1395 
   1396  MOZ_CRASH("Frame slot not found");
   1397 }
   1398 
   1399 JS::ubi::Node::Size JS::ubi::Concrete<Scope>::size(
   1400    mozilla::MallocSizeOf mallocSizeOf) const {
   1401  return js::gc::Arena::thingSize(get().asTenured().getAllocKind()) +
   1402         get().sizeOfExcludingThis();
   1403 }
   1404 
   1405 template <typename... Args>
   1406 /* static */ bool ScopeStencil::appendScopeStencilAndData(
   1407    FrontendContext* fc, CompilationState& compilationState,
   1408    BaseParserScopeData* data, ScopeIndex* indexOut, Args&&... args) {
   1409  *indexOut = ScopeIndex(compilationState.scopeData.length());
   1410  if (uint32_t(*indexOut) >= TaggedScriptThingIndex::IndexLimit) {
   1411    ReportAllocationOverflow(fc);
   1412    return false;
   1413  }
   1414 
   1415  if (!compilationState.scopeData.emplaceBack(std::forward<Args>(args)...)) {
   1416    js::ReportOutOfMemory(fc);
   1417    return false;
   1418  }
   1419  if (!compilationState.scopeNames.append(data)) {
   1420    compilationState.scopeData.popBack();
   1421    MOZ_ASSERT(compilationState.scopeData.length() ==
   1422               compilationState.scopeNames.length());
   1423 
   1424    js::ReportOutOfMemory(fc);
   1425    return false;
   1426  }
   1427 
   1428  return true;
   1429 }
   1430 
   1431 /* static */
   1432 bool ScopeStencil::createForFunctionScope(
   1433    FrontendContext* fc, frontend::CompilationState& compilationState,
   1434    FunctionScope::ParserData* data, bool hasParameterExprs,
   1435    bool needsEnvironment, ScriptIndex functionIndex, bool isArrow,
   1436    mozilla::Maybe<ScopeIndex> enclosing, ScopeIndex* index) {
   1437  auto kind = ScopeKind::Function;
   1438  using ScopeType = FunctionScope;
   1439  MOZ_ASSERT(matchScopeKind<ScopeType>(kind));
   1440 
   1441  if (data) {
   1442    MarkParserScopeData<ScopeType>(data, compilationState);
   1443  } else {
   1444    data = NewEmptyParserScopeData<ScopeType>(fc, compilationState.alloc);
   1445    if (!data) {
   1446      return false;
   1447    }
   1448  }
   1449 
   1450  uint32_t firstFrameSlot = 0;
   1451  mozilla::Maybe<uint32_t> envShape;
   1452  FunctionScope::prepareForScopeCreation(data, hasParameterExprs,
   1453                                         needsEnvironment, &envShape);
   1454 
   1455  return appendScopeStencilAndData(fc, compilationState, data, index, kind,
   1456                                   enclosing, firstFrameSlot, envShape,
   1457                                   mozilla::Some(functionIndex), isArrow);
   1458 }
   1459 
   1460 /* static */
   1461 bool ScopeStencil::createForLexicalScope(
   1462    FrontendContext* fc, frontend::CompilationState& compilationState,
   1463    ScopeKind kind, LexicalScope::ParserData* data, uint32_t firstFrameSlot,
   1464    mozilla::Maybe<ScopeIndex> enclosing, ScopeIndex* index) {
   1465  using ScopeType = LexicalScope;
   1466  MOZ_ASSERT(matchScopeKind<ScopeType>(kind));
   1467 
   1468  if (data) {
   1469    MarkParserScopeData<ScopeType>(data, compilationState);
   1470  } else {
   1471    data = NewEmptyParserScopeData<ScopeType>(fc, compilationState.alloc);
   1472    if (!data) {
   1473      return false;
   1474    }
   1475  }
   1476 
   1477  mozilla::Maybe<uint32_t> envShape;
   1478  ScopeType::prepareForScopeCreation(kind, firstFrameSlot, data, &envShape);
   1479 
   1480  return appendScopeStencilAndData(fc, compilationState, data, index, kind,
   1481                                   enclosing, firstFrameSlot, envShape);
   1482 }
   1483 
   1484 /* static */
   1485 bool ScopeStencil::createForClassBodyScope(
   1486    FrontendContext* fc, frontend::CompilationState& compilationState,
   1487    ScopeKind kind, ClassBodyScope::ParserData* data, uint32_t firstFrameSlot,
   1488    mozilla::Maybe<ScopeIndex> enclosing, ScopeIndex* index) {
   1489  using ScopeType = ClassBodyScope;
   1490  MOZ_ASSERT(matchScopeKind<ScopeType>(kind));
   1491 
   1492  if (data) {
   1493    MarkParserScopeData<ScopeType>(data, compilationState);
   1494  } else {
   1495    data = NewEmptyParserScopeData<ScopeType>(fc, compilationState.alloc);
   1496    if (!data) {
   1497      return false;
   1498    }
   1499  }
   1500 
   1501  mozilla::Maybe<uint32_t> envShape;
   1502  ScopeType::prepareForScopeCreation(kind, firstFrameSlot, data, &envShape);
   1503 
   1504  return appendScopeStencilAndData(fc, compilationState, data, index, kind,
   1505                                   enclosing, firstFrameSlot, envShape);
   1506 }
   1507 
   1508 bool ScopeStencil::createForVarScope(
   1509    FrontendContext* fc, frontend::CompilationState& compilationState,
   1510    ScopeKind kind, VarScope::ParserData* data, uint32_t firstFrameSlot,
   1511    bool needsEnvironment, mozilla::Maybe<ScopeIndex> enclosing,
   1512    ScopeIndex* index) {
   1513  using ScopeType = VarScope;
   1514  MOZ_ASSERT(matchScopeKind<ScopeType>(kind));
   1515 
   1516  if (data) {
   1517    MarkParserScopeData<ScopeType>(data, compilationState);
   1518  } else {
   1519    data = NewEmptyParserScopeData<ScopeType>(fc, compilationState.alloc);
   1520    if (!data) {
   1521      return false;
   1522    }
   1523  }
   1524 
   1525  mozilla::Maybe<uint32_t> envShape;
   1526  VarScope::prepareForScopeCreation(kind, data, firstFrameSlot,
   1527                                    needsEnvironment, &envShape);
   1528 
   1529  return appendScopeStencilAndData(fc, compilationState, data, index, kind,
   1530                                   enclosing, firstFrameSlot, envShape);
   1531 }
   1532 
   1533 /* static */
   1534 bool ScopeStencil::createForGlobalScope(
   1535    FrontendContext* fc, frontend::CompilationState& compilationState,
   1536    ScopeKind kind, GlobalScope::ParserData* data, ScopeIndex* index) {
   1537  using ScopeType = GlobalScope;
   1538  MOZ_ASSERT(matchScopeKind<ScopeType>(kind));
   1539 
   1540  if (data) {
   1541    MarkParserScopeData<ScopeType>(data, compilationState);
   1542  } else {
   1543    data = NewEmptyParserScopeData<ScopeType>(fc, compilationState.alloc);
   1544    if (!data) {
   1545      return false;
   1546    }
   1547  }
   1548 
   1549  // The global scope has no environment shape. Its environment is the
   1550  // global lexical scope and the global object or non-syntactic objects
   1551  // created by embedding, all of which are not only extensible but may
   1552  // have names on them deleted.
   1553  uint32_t firstFrameSlot = 0;
   1554  mozilla::Maybe<uint32_t> envShape;
   1555 
   1556  mozilla::Maybe<ScopeIndex> enclosing;
   1557 
   1558  return appendScopeStencilAndData(fc, compilationState, data, index, kind,
   1559                                   enclosing, firstFrameSlot, envShape);
   1560 }
   1561 
   1562 /* static */
   1563 bool ScopeStencil::createForEvalScope(
   1564    FrontendContext* fc, frontend::CompilationState& compilationState,
   1565    ScopeKind kind, EvalScope::ParserData* data,
   1566    mozilla::Maybe<ScopeIndex> enclosing, ScopeIndex* index) {
   1567  using ScopeType = EvalScope;
   1568  MOZ_ASSERT(matchScopeKind<ScopeType>(kind));
   1569 
   1570  if (data) {
   1571    MarkParserScopeData<ScopeType>(data, compilationState);
   1572  } else {
   1573    data = NewEmptyParserScopeData<ScopeType>(fc, compilationState.alloc);
   1574    if (!data) {
   1575      return false;
   1576    }
   1577  }
   1578 
   1579  uint32_t firstFrameSlot = 0;
   1580  mozilla::Maybe<uint32_t> envShape;
   1581  EvalScope::prepareForScopeCreation(kind, data, &envShape);
   1582 
   1583  return appendScopeStencilAndData(fc, compilationState, data, index, kind,
   1584                                   enclosing, firstFrameSlot, envShape);
   1585 }
   1586 
   1587 /* static */
   1588 bool ScopeStencil::createForModuleScope(
   1589    FrontendContext* fc, frontend::CompilationState& compilationState,
   1590    ModuleScope::ParserData* data, mozilla::Maybe<ScopeIndex> enclosing,
   1591    ScopeIndex* index) {
   1592  auto kind = ScopeKind::Module;
   1593  using ScopeType = ModuleScope;
   1594  MOZ_ASSERT(matchScopeKind<ScopeType>(kind));
   1595 
   1596  if (data) {
   1597    MarkParserScopeData<ScopeType>(data, compilationState);
   1598  } else {
   1599    data = NewEmptyParserScopeData<ScopeType>(fc, compilationState.alloc);
   1600    if (!data) {
   1601      return false;
   1602    }
   1603  }
   1604 
   1605  MOZ_ASSERT(enclosing.isNothing());
   1606 
   1607  // The data that's passed in is from the frontend and is LifoAlloc'd.
   1608  // Copy it now that we're creating a permanent VM scope.
   1609  uint32_t firstFrameSlot = 0;
   1610  mozilla::Maybe<uint32_t> envShape;
   1611  ModuleScope::prepareForScopeCreation(data, &envShape);
   1612 
   1613  return appendScopeStencilAndData(fc, compilationState, data, index, kind,
   1614                                   enclosing, firstFrameSlot, envShape);
   1615 }
   1616 
   1617 template <typename SpecificEnvironmentT>
   1618 bool ScopeStencil::createSpecificShape(
   1619    JSContext* cx, ScopeKind kind, BaseScopeData* scopeData,
   1620    MutableHandle<SharedShape*> shape) const {
   1621  const JSClass* cls = &SpecificEnvironmentT::class_;
   1622  constexpr ObjectFlags objectFlags = SpecificEnvironmentT::OBJECT_FLAGS;
   1623 
   1624  if (hasEnvironmentShape()) {
   1625    if (numEnvironmentSlots() > 0) {
   1626      BindingIter bi(kind, scopeData, firstFrameSlot_);
   1627      shape.set(CreateEnvironmentShape(cx, bi, cls, numEnvironmentSlots(),
   1628                                       objectFlags));
   1629      return shape;
   1630    }
   1631 
   1632    shape.set(EmptyEnvironmentShape(cx, cls, JSSLOT_FREE(cls), objectFlags));
   1633    return shape;
   1634  }
   1635 
   1636  return true;
   1637 }
   1638 
   1639 /* static */
   1640 bool ScopeStencil::createForWithScope(FrontendContext* fc,
   1641                                      CompilationState& compilationState,
   1642                                      mozilla::Maybe<ScopeIndex> enclosing,
   1643                                      ScopeIndex* index) {
   1644  auto kind = ScopeKind::With;
   1645  MOZ_ASSERT(matchScopeKind<WithScope>(kind));
   1646 
   1647  uint32_t firstFrameSlot = 0;
   1648  mozilla::Maybe<uint32_t> envShape;
   1649 
   1650  return appendScopeStencilAndData(fc, compilationState, nullptr, index, kind,
   1651                                   enclosing, firstFrameSlot, envShape);
   1652 }
   1653 
   1654 template <typename SpecificScopeT>
   1655 typename SpecificScopeT::RuntimeData* ScopeStencil::createSpecificScopeData(
   1656    JSContext* cx, CompilationAtomCache& atomCache,
   1657    BaseParserScopeData* baseData) const {
   1658  return LiftParserScopeData<SpecificScopeT>(cx, atomCache, baseData);
   1659 }
   1660 
   1661 template <>
   1662 FunctionScope::RuntimeData*
   1663 ScopeStencil::createSpecificScopeData<FunctionScope>(
   1664    JSContext* cx, CompilationAtomCache& atomCache,
   1665    BaseParserScopeData* baseData) const {
   1666  // Allocate a new vm function-scope.
   1667  return LiftParserScopeData<FunctionScope>(cx, atomCache, baseData);
   1668 }
   1669 
   1670 template <>
   1671 ModuleScope::RuntimeData* ScopeStencil::createSpecificScopeData<ModuleScope>(
   1672    JSContext* cx, CompilationAtomCache& atomCache,
   1673    BaseParserScopeData* baseData) const {
   1674  // Allocate a new vm module-scope.
   1675  return LiftParserScopeData<ModuleScope>(cx, atomCache, baseData);
   1676 }
   1677 
   1678 // WithScope does not use binding data.
   1679 template <>
   1680 Scope* ScopeStencil::createSpecificScope<WithScope, std::nullptr_t>(
   1681    JSContext* cx, CompilationAtomCache& atomCache,
   1682    Handle<Scope*> enclosingScope, BaseParserScopeData* baseData) const {
   1683  return Scope::create(cx, ScopeKind::With, enclosingScope, nullptr);
   1684 }
   1685 
   1686 // GlobalScope has bindings but no environment shape.
   1687 template <>
   1688 Scope* ScopeStencil::createSpecificScope<GlobalScope, std::nullptr_t>(
   1689    JSContext* cx, CompilationAtomCache& atomCache,
   1690    Handle<Scope*> enclosingScope, BaseParserScopeData* baseData) const {
   1691  RootedBuffer<GlobalScope::RuntimeData> data(
   1692      cx, createSpecificScopeData<GlobalScope>(cx, atomCache, baseData));
   1693  if (!data) {
   1694    return nullptr;
   1695  }
   1696 
   1697  MOZ_ASSERT(!hasEnclosing());
   1698  MOZ_ASSERT(!enclosingScope);
   1699 
   1700  // Because we already baked the data here, we needn't do it again.
   1701  return Scope::create<GlobalScope>(cx, kind(), nullptr, nullptr, data);
   1702 }
   1703 
   1704 template <typename SpecificScopeT, typename SpecificEnvironmentT>
   1705 Scope* ScopeStencil::createSpecificScope(JSContext* cx,
   1706                                         CompilationAtomCache& atomCache,
   1707                                         Handle<Scope*> enclosingScope,
   1708                                         BaseParserScopeData* baseData) const {
   1709  RootedBuffer<typename SpecificScopeT::RuntimeData> data(
   1710      cx, createSpecificScopeData<SpecificScopeT>(cx, atomCache, baseData));
   1711  if (!data) {
   1712    return nullptr;
   1713  }
   1714 
   1715  Rooted<SharedShape*> shape(cx);
   1716  if (!createSpecificShape<SpecificEnvironmentT>(cx, kind(), data, &shape)) {
   1717    return nullptr;
   1718  }
   1719 
   1720  // Because we already baked the data here, we needn't do it again.
   1721  return Scope::create<SpecificScopeT>(cx, kind(), enclosingScope, shape, data);
   1722 }
   1723 
   1724 template Scope* ScopeStencil::createSpecificScope<FunctionScope, CallObject>(
   1725    JSContext* cx, CompilationAtomCache& atomCache,
   1726    Handle<Scope*> enclosingScope, BaseParserScopeData* baseData) const;
   1727 template Scope*
   1728 ScopeStencil::createSpecificScope<LexicalScope, BlockLexicalEnvironmentObject>(
   1729    JSContext* cx, CompilationAtomCache& atomCache,
   1730    Handle<Scope*> enclosingScope, BaseParserScopeData* baseData) const;
   1731 template Scope* ScopeStencil::createSpecificScope<
   1732    ClassBodyScope, BlockLexicalEnvironmentObject>(
   1733    JSContext* cx, CompilationAtomCache& atomCache,
   1734    Handle<Scope*> enclosingScope, BaseParserScopeData* baseData) const;
   1735 template Scope*
   1736 ScopeStencil::createSpecificScope<EvalScope, VarEnvironmentObject>(
   1737    JSContext* cx, CompilationAtomCache& atomCache,
   1738    Handle<Scope*> enclosingScope, BaseParserScopeData* baseData) const;
   1739 template Scope*
   1740 ScopeStencil::createSpecificScope<VarScope, VarEnvironmentObject>(
   1741    JSContext* cx, CompilationAtomCache& atomCache,
   1742    Handle<Scope*> enclosingScope, BaseParserScopeData* baseData) const;
   1743 template Scope*
   1744 ScopeStencil::createSpecificScope<ModuleScope, ModuleEnvironmentObject>(
   1745    JSContext* cx, CompilationAtomCache& atomCache,
   1746    Handle<Scope*> enclosingScope, BaseParserScopeData* baseData) const;