tor-browser

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

BytecodeEmitter.cpp (396503B)


      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 /*
      8 * JS bytecode generation.
      9 */
     10 
     11 #include "frontend/BytecodeEmitter.h"
     12 
     13 #include "mozilla/Casting.h"    // mozilla::AssertedCast
     14 #include "mozilla/DebugOnly.h"  // mozilla::DebugOnly
     15 #include "mozilla/FloatingPoint.h"  // mozilla::NumberEqualsInt32, mozilla::NumberIsInt32
     16 #include "mozilla/HashTable.h"  // mozilla::HashSet
     17 #include "mozilla/Maybe.h"      // mozilla::{Maybe,Nothing,Some}
     18 #include "mozilla/Saturate.h"
     19 #include "mozilla/Variant.h"  // mozilla::AsVariant
     20 
     21 #include <algorithm>
     22 #include <iterator>
     23 #include <string.h>
     24 
     25 #include "jstypes.h"  // JS_BIT
     26 
     27 #include "frontend/AbstractScopePtr.h"           // ScopeIndex
     28 #include "frontend/BytecodeControlStructures.h"  // NestableControl, BreakableControl, LabelControl, LoopControl, TryFinallyControl
     29 #include "frontend/CallOrNewEmitter.h"           // CallOrNewEmitter
     30 #include "frontend/CForEmitter.h"                // CForEmitter
     31 #include "frontend/DecoratorEmitter.h"           // DecoratorEmitter
     32 #include "frontend/DefaultEmitter.h"             // DefaultEmitter
     33 #include "frontend/DoWhileEmitter.h"             // DoWhileEmitter
     34 #include "frontend/ElemOpEmitter.h"              // ElemOpEmitter
     35 #include "frontend/EmitterScope.h"               // EmitterScope
     36 #include "frontend/ExpressionStatementEmitter.h"  // ExpressionStatementEmitter
     37 #include "frontend/ForInEmitter.h"                // ForInEmitter
     38 #include "frontend/ForOfEmitter.h"                // ForOfEmitter
     39 #include "frontend/FunctionEmitter.h"  // FunctionEmitter, FunctionScriptEmitter, FunctionParamsEmitter
     40 #include "frontend/IfEmitter.h"     // IfEmitter, InternalIfEmitter, CondEmitter
     41 #include "frontend/LabelEmitter.h"  // LabelEmitter
     42 #include "frontend/LexicalScopeEmitter.h"  // LexicalScopeEmitter
     43 #include "frontend/ModuleSharedContext.h"  // ModuleSharedContext
     44 #include "frontend/NameAnalysisTypes.h"    // PrivateNameKind
     45 #include "frontend/NameFunctions.h"        // NameFunctions
     46 #include "frontend/NameOpEmitter.h"        // NameOpEmitter
     47 #include "frontend/ObjectEmitter.h"  // PropertyEmitter, ObjectEmitter, ClassEmitter
     48 #include "frontend/OptionalEmitter.h"  // OptionalEmitter
     49 #include "frontend/ParseContext.h"     // ParseContext::Scope
     50 #include "frontend/ParseNode.h"   // ParseNodeKind, ParseNode and subclasses
     51 #include "frontend/Parser.h"      // Parser
     52 #include "frontend/ParserAtom.h"  // ParserAtomsTable, ParserAtom
     53 #include "frontend/PrivateOpEmitter.h"  // PrivateOpEmitter
     54 #include "frontend/PropOpEmitter.h"     // PropOpEmitter
     55 #include "frontend/SourceNotes.h"       // SrcNote, SrcNoteType, SrcNoteWriter
     56 #include "frontend/SwitchEmitter.h"     // SwitchEmitter
     57 #include "frontend/TaggedParserAtomIndexHasher.h"  // TaggedParserAtomIndexHasher
     58 #include "frontend/TDZCheckCache.h"                // TDZCheckCache
     59 #include "frontend/TryEmitter.h"                   // TryEmitter
     60 #include "frontend/UsingEmitter.h"                 // UsingEmitter
     61 #include "frontend/WhileEmitter.h"                 // WhileEmitter
     62 #include "js/ColumnNumber.h"  // JS::LimitedColumnNumberOneOrigin, JS::ColumnNumberOffset
     63 #include "js/friend/ErrorMessages.h"  // JSMSG_*
     64 #include "js/friend/StackLimits.h"    // AutoCheckRecursionLimit
     65 #include "util/StringBuilder.h"       // StringBuilder
     66 #include "vm/BytecodeUtil.h"  // JOF_*, IsArgOp, IsLocalOp, SET_UINT24, SET_ICINDEX, BytecodeFallsThrough, BytecodeIsJumpTarget
     67 #include "vm/CompletionKind.h"          // CompletionKind
     68 #include "vm/ConstantCompareOperand.h"  // ConstantCompareOperand
     69 #include "vm/FunctionPrefixKind.h"      // FunctionPrefixKind
     70 #include "vm/GeneratorObject.h"         // AbstractGeneratorObject
     71 #include "vm/Opcodes.h"                 // JSOp, JSOpLength_*
     72 #include "vm/PropMap.h"          // SharedPropMap::MaxPropsForNonDictionary
     73 #include "vm/Scope.h"            // GetScopeDataTrailingNames
     74 #include "vm/SharedStencil.h"    // ScopeNote
     75 #include "vm/ThrowMsgKind.h"     // ThrowMsgKind
     76 #include "vm/TypeofEqOperand.h"  // TypeofEqOperand
     77 
     78 using namespace js;
     79 using namespace js::frontend;
     80 
     81 using mozilla::AssertedCast;
     82 using mozilla::AsVariant;
     83 using mozilla::DebugOnly;
     84 using mozilla::Maybe;
     85 using mozilla::Nothing;
     86 using mozilla::NumberEqualsInt32;
     87 using mozilla::NumberIsInt32;
     88 using mozilla::Some;
     89 
     90 static bool ParseNodeRequiresSpecialLineNumberNotes(ParseNode* pn) {
     91  // The few node types listed below are exceptions to the usual
     92  // location-source-note-emitting code in BytecodeEmitter::emitTree().
     93  // Single-line `while` loops and C-style `for` loops require careful
     94  // handling to avoid strange stepping behavior.
     95  // Functions usually shouldn't have location information (bug 1431202).
     96 
     97  ParseNodeKind kind = pn->getKind();
     98  return kind == ParseNodeKind::WhileStmt || kind == ParseNodeKind::ForStmt ||
     99         kind == ParseNodeKind::Function;
    100 }
    101 
    102 static bool NeedsFieldInitializer(ParseNode* member, bool inStaticContext) {
    103  // For the purposes of bytecode emission, StaticClassBlocks are treated as if
    104  // they were static initializers.
    105  return (member->is<StaticClassBlock>() && inStaticContext) ||
    106         (member->is<ClassField>() &&
    107          member->as<ClassField>().isStatic() == inStaticContext);
    108 }
    109 
    110 static bool NeedsAccessorInitializer(ParseNode* member, bool isStatic) {
    111  if (isStatic) {
    112    return false;
    113  }
    114  return member->is<ClassMethod>() &&
    115         member->as<ClassMethod>().name().isKind(ParseNodeKind::PrivateName) &&
    116         !member->as<ClassMethod>().isStatic() &&
    117         member->as<ClassMethod>().accessorType() != AccessorType::None;
    118 }
    119 
    120 static bool ShouldSuppressBreakpointsAndSourceNotes(
    121    SharedContext* sc, BytecodeEmitter::EmitterMode emitterMode) {
    122  // Suppress for all self-hosting code.
    123  if (emitterMode == BytecodeEmitter::EmitterMode::SelfHosting) {
    124    return true;
    125  }
    126 
    127  // Suppress for synthesized class constructors.
    128  if (sc->isFunctionBox()) {
    129    FunctionBox* funbox = sc->asFunctionBox();
    130    return funbox->isSyntheticFunction() && funbox->isClassConstructor();
    131  }
    132 
    133  return false;
    134 }
    135 
    136 BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent, FrontendContext* fc,
    137                                 SharedContext* sc,
    138                                 const ErrorReporter& errorReporter,
    139                                 CompilationState& compilationState,
    140                                 EmitterMode emitterMode)
    141    : sc(sc),
    142      fc(fc),
    143      parent(parent),
    144      bytecodeSection_(fc, sc->extent().lineno,
    145                       JS::LimitedColumnNumberOneOrigin(sc->extent().column)),
    146      perScriptData_(fc, compilationState),
    147      errorReporter_(errorReporter),
    148      compilationState(compilationState),
    149      suppressBreakpointsAndSourceNotes(
    150          ShouldSuppressBreakpointsAndSourceNotes(sc, emitterMode)),
    151      emitterMode(emitterMode) {
    152  MOZ_ASSERT_IF(parent, fc == parent->fc);
    153 }
    154 
    155 BytecodeEmitter::BytecodeEmitter(BytecodeEmitter* parent, SharedContext* sc)
    156    : BytecodeEmitter(parent, parent->fc, sc, parent->errorReporter_,
    157                      parent->compilationState, parent->emitterMode) {}
    158 
    159 BytecodeEmitter::BytecodeEmitter(FrontendContext* fc,
    160                                 const EitherParser& parser, SharedContext* sc,
    161                                 CompilationState& compilationState,
    162                                 EmitterMode emitterMode)
    163    : BytecodeEmitter(nullptr, fc, sc, parser.errorReporter(), compilationState,
    164                      emitterMode) {
    165  ep_.emplace(parser);
    166 }
    167 
    168 void BytecodeEmitter::initFromBodyPosition(TokenPos bodyPosition) {
    169  setScriptStartOffsetIfUnset(bodyPosition.begin);
    170  setFunctionBodyEndPos(bodyPosition.end);
    171 }
    172 
    173 bool BytecodeEmitter::init() {
    174  if (!parent) {
    175    if (!compilationState.prepareSharedDataStorage(fc)) {
    176      return false;
    177    }
    178  }
    179  return perScriptData_.init(fc);
    180 }
    181 
    182 bool BytecodeEmitter::init(TokenPos bodyPosition) {
    183  initFromBodyPosition(bodyPosition);
    184  return init();
    185 }
    186 
    187 template <typename T>
    188 T* BytecodeEmitter::findInnermostNestableControl() const {
    189  return NestableControl::findNearest<T>(innermostNestableControl);
    190 }
    191 
    192 template <typename T, typename Predicate /* (T*) -> bool */>
    193 T* BytecodeEmitter::findInnermostNestableControl(Predicate predicate) const {
    194  return NestableControl::findNearest<T>(innermostNestableControl, predicate);
    195 }
    196 
    197 NameLocation BytecodeEmitter::lookupName(TaggedParserAtomIndex name) {
    198  return innermostEmitterScope()->lookup(this, name);
    199 }
    200 
    201 void BytecodeEmitter::lookupPrivate(TaggedParserAtomIndex name,
    202                                    NameLocation& loc,
    203                                    Maybe<NameLocation>& brandLoc) {
    204  innermostEmitterScope()->lookupPrivate(this, name, loc, brandLoc);
    205 }
    206 
    207 Maybe<NameLocation> BytecodeEmitter::locationOfNameBoundInScope(
    208    TaggedParserAtomIndex name, EmitterScope* target) {
    209  return innermostEmitterScope()->locationBoundInScope(name, target);
    210 }
    211 
    212 template <typename T>
    213 Maybe<NameLocation> BytecodeEmitter::locationOfNameBoundInScopeType(
    214    TaggedParserAtomIndex name, EmitterScope* source) {
    215  EmitterScope* aScope = source;
    216  while (!aScope->scope(this).is<T>()) {
    217    aScope = aScope->enclosingInFrame();
    218  }
    219  return source->locationBoundInScope(name, aScope);
    220 }
    221 
    222 bool BytecodeEmitter::markStepBreakpoint() {
    223  if (skipBreakpointSrcNotes()) {
    224    return true;
    225  }
    226 
    227  if (!newSrcNote(SrcNoteType::BreakpointStepSep)) {
    228    return false;
    229  }
    230 
    231  // We track the location of the most recent separator for use in
    232  // markSimpleBreakpoint. Note that this means that the position must already
    233  // be set before markStepBreakpoint is called.
    234  bytecodeSection().updateSeparatorPosition();
    235 
    236  return true;
    237 }
    238 
    239 bool BytecodeEmitter::markSimpleBreakpoint() {
    240  if (skipBreakpointSrcNotes()) {
    241    return true;
    242  }
    243 
    244  // If a breakable call ends up being the same location as the most recent
    245  // expression start, we need to skip marking it breakable in order to avoid
    246  // having two breakpoints with the same line/column position.
    247  // Note: This assumes that the position for the call has already been set.
    248  if (!bytecodeSection().isDuplicateLocation()) {
    249    if (!newSrcNote(SrcNoteType::Breakpoint)) {
    250      return false;
    251    }
    252  }
    253 
    254  return true;
    255 }
    256 
    257 bool BytecodeEmitter::emitCheck(JSOp op, ptrdiff_t delta,
    258                                BytecodeOffset* offset) {
    259  size_t oldLength = bytecodeSection().code().length();
    260  *offset = BytecodeOffset(oldLength);
    261 
    262  size_t newLength = oldLength + size_t(delta);
    263  if (MOZ_UNLIKELY(newLength > MaxBytecodeLength)) {
    264    ReportAllocationOverflow(fc);
    265    return false;
    266  }
    267 
    268  if (!bytecodeSection().code().growByUninitialized(delta)) {
    269    return false;
    270  }
    271 
    272  if (BytecodeOpHasIC(op)) {
    273    // Even if every bytecode op is a JOF_IC op and the function has ARGC_LIMIT
    274    // arguments, numICEntries cannot overflow.
    275    static_assert(MaxBytecodeLength + 1 /* this */ + ARGC_LIMIT <= UINT32_MAX,
    276                  "numICEntries must not overflow");
    277    bytecodeSection().incrementNumICEntries();
    278  }
    279 
    280  return true;
    281 }
    282 
    283 #ifdef DEBUG
    284 bool BytecodeEmitter::checkStrictOrSloppy(JSOp op) const {
    285  if (IsCheckStrictOp(op) && !sc->strict()) {
    286    return false;
    287  }
    288  if (IsCheckSloppyOp(op) && sc->strict()) {
    289    return false;
    290  }
    291  return true;
    292 }
    293 #endif
    294 
    295 bool BytecodeEmitter::emit1(JSOp op) {
    296  MOZ_ASSERT(checkStrictOrSloppy(op));
    297  MOZ_ASSERT(GetOpLength(op) == 1);
    298 
    299  BytecodeOffset offset;
    300  if (!emitCheck(op, 1, &offset)) {
    301    return false;
    302  }
    303 
    304  jsbytecode* code = bytecodeSection().code(offset);
    305  code[0] = jsbytecode(op);
    306  bytecodeSection().updateDepth(op, offset);
    307  return true;
    308 }
    309 
    310 bool BytecodeEmitter::emit2(JSOp op, uint8_t op1) {
    311  MOZ_ASSERT(checkStrictOrSloppy(op));
    312  MOZ_ASSERT(GetOpLength(op) == 2);
    313 
    314  BytecodeOffset offset;
    315  if (!emitCheck(op, 2, &offset)) {
    316    return false;
    317  }
    318 
    319  jsbytecode* code = bytecodeSection().code(offset);
    320  code[0] = jsbytecode(op);
    321  code[1] = jsbytecode(op1);
    322  bytecodeSection().updateDepth(op, offset);
    323  return true;
    324 }
    325 
    326 bool BytecodeEmitter::emit3(JSOp op, jsbytecode op1, jsbytecode op2) {
    327  MOZ_ASSERT(checkStrictOrSloppy(op));
    328  MOZ_ASSERT(GetOpLength(op) == 3);
    329 
    330  /* These should filter through emitVarOp. */
    331  MOZ_ASSERT(!IsArgOp(op));
    332  MOZ_ASSERT(!IsLocalOp(op));
    333 
    334  BytecodeOffset offset;
    335  if (!emitCheck(op, 3, &offset)) {
    336    return false;
    337  }
    338 
    339  jsbytecode* code = bytecodeSection().code(offset);
    340  code[0] = jsbytecode(op);
    341  code[1] = op1;
    342  code[2] = op2;
    343  bytecodeSection().updateDepth(op, offset);
    344  return true;
    345 }
    346 
    347 bool BytecodeEmitter::emitN(JSOp op, size_t extra, BytecodeOffset* offset) {
    348  MOZ_ASSERT(checkStrictOrSloppy(op));
    349  ptrdiff_t length = 1 + ptrdiff_t(extra);
    350 
    351  BytecodeOffset off;
    352  if (!emitCheck(op, length, &off)) {
    353    return false;
    354  }
    355 
    356  jsbytecode* code = bytecodeSection().code(off);
    357  code[0] = jsbytecode(op);
    358  /* The remaining |extra| bytes are set by the caller */
    359 
    360  /*
    361   * Don't updateDepth if op's use-count comes from the immediate
    362   * operand yet to be stored in the extra bytes after op.
    363   */
    364  if (CodeSpec(op).nuses >= 0) {
    365    bytecodeSection().updateDepth(op, off);
    366  }
    367 
    368  if (offset) {
    369    *offset = off;
    370  }
    371  return true;
    372 }
    373 
    374 bool BytecodeEmitter::emitJumpTargetOp(JSOp op, BytecodeOffset* off) {
    375  MOZ_ASSERT(BytecodeIsJumpTarget(op));
    376 
    377  // Record the current IC-entry index at start of this op.
    378  uint32_t numEntries = bytecodeSection().numICEntries();
    379 
    380  size_t n = GetOpLength(op) - 1;
    381  MOZ_ASSERT(GetOpLength(op) >= 1 + ICINDEX_LEN);
    382 
    383  if (!emitN(op, n, off)) {
    384    return false;
    385  }
    386 
    387  SET_ICINDEX(bytecodeSection().code(*off), numEntries);
    388  return true;
    389 }
    390 
    391 bool BytecodeEmitter::emitJumpTarget(JumpTarget* target) {
    392  BytecodeOffset off = bytecodeSection().offset();
    393 
    394  // Alias consecutive jump targets.
    395  if (bytecodeSection().lastTargetOffset().valid() &&
    396      off == bytecodeSection().lastTargetOffset() +
    397                 BytecodeOffsetDiff(JSOpLength_JumpTarget)) {
    398    target->offset = bytecodeSection().lastTargetOffset();
    399    return true;
    400  }
    401 
    402  target->offset = off;
    403  bytecodeSection().setLastTargetOffset(off);
    404 
    405  BytecodeOffset opOff;
    406  return emitJumpTargetOp(JSOp::JumpTarget, &opOff);
    407 }
    408 
    409 bool BytecodeEmitter::emitJumpNoFallthrough(JSOp op, JumpList* jump) {
    410  BytecodeOffset offset;
    411  if (!emitCheck(op, 5, &offset)) {
    412    return false;
    413  }
    414 
    415  jsbytecode* code = bytecodeSection().code(offset);
    416  code[0] = jsbytecode(op);
    417  MOZ_ASSERT(!jump->offset.valid() ||
    418             (0 <= jump->offset.value() && jump->offset < offset));
    419  jump->push(bytecodeSection().code(BytecodeOffset(0)), offset);
    420  bytecodeSection().updateDepth(op, offset);
    421  return true;
    422 }
    423 
    424 bool BytecodeEmitter::emitJump(JSOp op, JumpList* jump) {
    425  if (!emitJumpNoFallthrough(op, jump)) {
    426    return false;
    427  }
    428  if (BytecodeFallsThrough(op)) {
    429    JumpTarget fallthrough;
    430    if (!emitJumpTarget(&fallthrough)) {
    431      return false;
    432    }
    433  }
    434  return true;
    435 }
    436 
    437 void BytecodeEmitter::patchJumpsToTarget(JumpList jump, JumpTarget target) {
    438  MOZ_ASSERT(
    439      !jump.offset.valid() ||
    440      (0 <= jump.offset.value() && jump.offset <= bytecodeSection().offset()));
    441  MOZ_ASSERT(0 <= target.offset.value() &&
    442             target.offset <= bytecodeSection().offset());
    443  MOZ_ASSERT_IF(
    444      jump.offset.valid() &&
    445          target.offset + BytecodeOffsetDiff(4) <= bytecodeSection().offset(),
    446      BytecodeIsJumpTarget(JSOp(*bytecodeSection().code(target.offset))));
    447  jump.patchAll(bytecodeSection().code(BytecodeOffset(0)), target);
    448 }
    449 
    450 bool BytecodeEmitter::emitJumpTargetAndPatch(JumpList jump) {
    451  if (!jump.offset.valid()) {
    452    return true;
    453  }
    454  JumpTarget target;
    455  if (!emitJumpTarget(&target)) {
    456    return false;
    457  }
    458  patchJumpsToTarget(jump, target);
    459  return true;
    460 }
    461 
    462 bool BytecodeEmitter::emitCall(JSOp op, uint16_t argc,
    463                               const Maybe<uint32_t>& sourceCoordOffset) {
    464  if (sourceCoordOffset.isSome()) {
    465    if (!updateSourceCoordNotes(*sourceCoordOffset)) {
    466      return false;
    467    }
    468  }
    469  return emit3(op, ARGC_LO(argc), ARGC_HI(argc));
    470 }
    471 
    472 bool BytecodeEmitter::emitCall(JSOp op, uint16_t argc, ParseNode* pn) {
    473  return emitCall(op, argc, pn ? Some(pn->pn_pos.begin) : Nothing());
    474 }
    475 
    476 bool BytecodeEmitter::emitDupAt(unsigned slotFromTop, unsigned count) {
    477  MOZ_ASSERT(slotFromTop < unsigned(bytecodeSection().stackDepth()));
    478  MOZ_ASSERT(slotFromTop + 1 >= count);
    479 
    480  if (slotFromTop == 0 && count == 1) {
    481    return emit1(JSOp::Dup);
    482  }
    483 
    484  if (slotFromTop == 1 && count == 2) {
    485    return emit1(JSOp::Dup2);
    486  }
    487 
    488  if (slotFromTop >= Bit(24)) {
    489    reportError(nullptr, JSMSG_TOO_MANY_LOCALS);
    490    return false;
    491  }
    492 
    493  for (unsigned i = 0; i < count; i++) {
    494    BytecodeOffset off;
    495    if (!emitN(JSOp::DupAt, 3, &off)) {
    496      return false;
    497    }
    498 
    499    jsbytecode* pc = bytecodeSection().code(off);
    500    SET_UINT24(pc, slotFromTop);
    501  }
    502 
    503  return true;
    504 }
    505 
    506 bool BytecodeEmitter::emitPopN(unsigned n) {
    507  MOZ_ASSERT(n != 0);
    508 
    509  if (n == 1) {
    510    return emit1(JSOp::Pop);
    511  }
    512 
    513  // 2 JSOp::Pop instructions (2 bytes) are shorter than JSOp::PopN (3 bytes).
    514  if (n == 2) {
    515    return emit1(JSOp::Pop) && emit1(JSOp::Pop);
    516  }
    517 
    518  return emitUint16Operand(JSOp::PopN, n);
    519 }
    520 
    521 bool BytecodeEmitter::emitPickN(uint8_t n) {
    522  MOZ_ASSERT(n != 0);
    523 
    524  if (n == 1) {
    525    return emit1(JSOp::Swap);
    526  }
    527 
    528  return emit2(JSOp::Pick, n);
    529 }
    530 
    531 bool BytecodeEmitter::emitUnpickN(uint8_t n) {
    532  MOZ_ASSERT(n != 0);
    533 
    534  if (n == 1) {
    535    return emit1(JSOp::Swap);
    536  }
    537 
    538  return emit2(JSOp::Unpick, n);
    539 }
    540 
    541 bool BytecodeEmitter::emitCheckIsObj(CheckIsObjectKind kind) {
    542  return emit2(JSOp::CheckIsObj, uint8_t(kind));
    543 }
    544 
    545 bool BytecodeEmitter::emitBuiltinObject(BuiltinObjectKind kind) {
    546  return emit2(JSOp::BuiltinObject, uint8_t(kind));
    547 }
    548 
    549 /* Updates line number notes, not column notes. */
    550 bool BytecodeEmitter::updateLineNumberNotes(uint32_t offset) {
    551  if (skipLocationSrcNotes()) {
    552    return true;
    553  }
    554 
    555  const ErrorReporter& er = errorReporter();
    556  std::optional<bool> onThisLineStatus =
    557      er.isOnThisLine(offset, bytecodeSection().currentLine());
    558  if (!onThisLineStatus.has_value()) {
    559    er.errorNoOffset(JSMSG_OUT_OF_MEMORY);
    560    return false;
    561  }
    562 
    563  bool onThisLine = *onThisLineStatus;
    564 
    565  if (!onThisLine) {
    566    unsigned line = er.lineAt(offset);
    567    unsigned delta = line - bytecodeSection().currentLine();
    568 
    569    // If we use a `SetLine` note below, we want it to be relative to the
    570    // scripts initial line number for better chance of sharing.
    571    unsigned initialLine = sc->extent().lineno;
    572    MOZ_ASSERT(line >= initialLine);
    573 
    574    /*
    575     * Encode any change in the current source line number by using
    576     * either several SrcNoteType::NewLine notes or just one
    577     * SrcNoteType::SetLine note, whichever consumes less space.
    578     *
    579     * NB: We handle backward line number deltas (possible with for
    580     * loops where the update part is emitted after the body, but its
    581     * line number is <= any line number in the body) here by letting
    582     * unsigned delta_ wrap to a very large number, which triggers a
    583     * SrcNoteType::SetLine.
    584     */
    585    bytecodeSection().setCurrentLine(line, offset);
    586    if (delta >= SrcNote::SetLine::lengthFor(line, initialLine)) {
    587      if (!newSrcNote2(SrcNoteType::SetLine,
    588                       SrcNote::SetLine::toOperand(line, initialLine))) {
    589        return false;
    590      }
    591    } else {
    592      do {
    593        if (!newSrcNote(SrcNoteType::NewLine)) {
    594          return false;
    595        }
    596      } while (--delta != 0);
    597    }
    598 
    599    bytecodeSection().updateSeparatorPositionIfPresent();
    600  }
    601  return true;
    602 }
    603 
    604 /* Updates the line number and column number information in the source notes. */
    605 bool BytecodeEmitter::updateSourceCoordNotes(uint32_t offset) {
    606  if (skipLocationSrcNotes()) {
    607    return true;
    608  }
    609 
    610  if (!updateLineNumberNotes(offset)) {
    611    return false;
    612  }
    613 
    614  JS::LimitedColumnNumberOneOrigin columnIndex =
    615      errorReporter().columnAt(offset);
    616 
    617  // Assert colspan is always representable.
    618  static_assert((0 - ptrdiff_t(JS::LimitedColumnNumberOneOrigin::Limit)) >=
    619                SrcNote::ColSpan::MinColSpan);
    620  static_assert((ptrdiff_t(JS::LimitedColumnNumberOneOrigin::Limit) - 0) <=
    621                SrcNote::ColSpan::MaxColSpan);
    622 
    623  JS::ColumnNumberOffset colspan = columnIndex - bytecodeSection().lastColumn();
    624 
    625  if (colspan != JS::ColumnNumberOffset::zero()) {
    626    if (lastLineOnlySrcNoteIndex != LastSrcNoteIsNotLineOnly) {
    627      MOZ_ASSERT(bytecodeSection().lastColumn() ==
    628                 JS::LimitedColumnNumberOneOrigin());
    629 
    630      const SrcNotesVector& notes = bytecodeSection().notes();
    631      SrcNoteType type = notes[lastLineOnlySrcNoteIndex].type();
    632      if (type == SrcNoteType::NewLine) {
    633        if (!convertLastNewLineToNewLineColumn(columnIndex)) {
    634          return false;
    635        }
    636      } else {
    637        MOZ_ASSERT(type == SrcNoteType::SetLine);
    638        if (!convertLastSetLineToSetLineColumn(columnIndex)) {
    639          return false;
    640        }
    641      }
    642    } else {
    643      if (!newSrcNote2(SrcNoteType::ColSpan,
    644                       SrcNote::ColSpan::toOperand(colspan))) {
    645        return false;
    646      }
    647    }
    648    bytecodeSection().setLastColumn(columnIndex, offset);
    649    bytecodeSection().updateSeparatorPositionIfPresent();
    650  }
    651  return true;
    652 }
    653 
    654 bool BytecodeEmitter::updateSourceCoordNotesIfNonLiteral(ParseNode* node) {
    655  if (node->isLiteral()) {
    656    return true;
    657  }
    658  return updateSourceCoordNotes(node->pn_pos.begin);
    659 }
    660 
    661 uint32_t BytecodeEmitter::getOffsetForLoop(ParseNode* nextpn) const {
    662  // Try to give the JSOp::LoopHead the same line number as the next
    663  // instruction. nextpn is often a block, in which case the next instruction
    664  // typically comes from the first statement inside.
    665  if (nextpn->is<LexicalScopeNode>()) {
    666    nextpn = nextpn->as<LexicalScopeNode>().scopeBody();
    667  }
    668  if (nextpn->isKind(ParseNodeKind::StatementList)) {
    669    if (ParseNode* firstStatement = nextpn->as<ListNode>().head()) {
    670      nextpn = firstStatement;
    671    }
    672  }
    673 
    674  return nextpn->pn_pos.begin;
    675 }
    676 
    677 bool BytecodeEmitter::emitUint16Operand(JSOp op, uint32_t operand) {
    678  MOZ_ASSERT(operand <= UINT16_MAX);
    679  if (!emit3(op, UINT16_LO(operand), UINT16_HI(operand))) {
    680    return false;
    681  }
    682  return true;
    683 }
    684 
    685 bool BytecodeEmitter::emitUint32Operand(JSOp op, uint32_t operand) {
    686  BytecodeOffset off;
    687  if (!emitN(op, 4, &off)) {
    688    return false;
    689  }
    690  SET_UINT32(bytecodeSection().code(off), operand);
    691  return true;
    692 }
    693 
    694 bool BytecodeEmitter::emitGoto(NestableControl* target, GotoKind kind) {
    695  NonLocalExitControl nle(this, kind == GotoKind::Continue
    696                                    ? NonLocalExitKind::Continue
    697                                    : NonLocalExitKind::Break);
    698  return nle.emitNonLocalJump(target);
    699 }
    700 
    701 AbstractScopePtr BytecodeEmitter::innermostScope() const {
    702  return innermostEmitterScope()->scope(this);
    703 }
    704 
    705 ScopeIndex BytecodeEmitter::innermostScopeIndex() const {
    706  return *innermostEmitterScope()->scopeIndex(this);
    707 }
    708 
    709 bool BytecodeEmitter::emitGCIndexOp(JSOp op, GCThingIndex index) {
    710  MOZ_ASSERT(checkStrictOrSloppy(op));
    711 
    712  constexpr size_t OpLength = 1 + GCTHING_INDEX_LEN;
    713  MOZ_ASSERT(GetOpLength(op) == OpLength);
    714 
    715  BytecodeOffset offset;
    716  if (!emitCheck(op, OpLength, &offset)) {
    717    return false;
    718  }
    719 
    720  jsbytecode* code = bytecodeSection().code(offset);
    721  code[0] = jsbytecode(op);
    722  SET_GCTHING_INDEX(code, index);
    723  bytecodeSection().updateDepth(op, offset);
    724  return true;
    725 }
    726 
    727 bool BytecodeEmitter::emitAtomOp(JSOp op, TaggedParserAtomIndex atom) {
    728  MOZ_ASSERT(atom);
    729 
    730  // .generator lookups should be emitted as JSOp::GetAliasedVar instead of
    731  // JSOp::GetName etc, to bypass |with| objects on the scope chain.
    732  // It's safe to emit .this lookups though because |with| objects skip
    733  // those.
    734  MOZ_ASSERT_IF(op == JSOp::GetName || op == JSOp::GetGName,
    735                atom != TaggedParserAtomIndex::WellKnown::dot_generator_());
    736 
    737  GCThingIndex index;
    738  if (!makeAtomIndex(atom, ParserAtom::Atomize::Yes, &index)) {
    739    return false;
    740  }
    741 
    742  return emitAtomOp(op, index);
    743 }
    744 
    745 bool BytecodeEmitter::emitAtomOp(JSOp op, GCThingIndex atomIndex) {
    746  MOZ_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
    747 #ifdef DEBUG
    748  auto atom = perScriptData().gcThingList().getAtom(atomIndex);
    749  MOZ_ASSERT(compilationState.parserAtoms.isInstantiatedAsJSAtom(atom));
    750 #endif
    751  return emitGCIndexOp(op, atomIndex);
    752 }
    753 
    754 bool BytecodeEmitter::emitStringOp(JSOp op, TaggedParserAtomIndex atom) {
    755  MOZ_ASSERT(atom);
    756  GCThingIndex index;
    757  if (!makeAtomIndex(atom, ParserAtom::Atomize::No, &index)) {
    758    return false;
    759  }
    760 
    761  return emitStringOp(op, index);
    762 }
    763 
    764 bool BytecodeEmitter::emitStringOp(JSOp op, GCThingIndex atomIndex) {
    765  MOZ_ASSERT(JOF_OPTYPE(op) == JOF_STRING);
    766  return emitGCIndexOp(op, atomIndex);
    767 }
    768 
    769 bool BytecodeEmitter::emitInternedScopeOp(GCThingIndex index, JSOp op) {
    770  MOZ_ASSERT(JOF_OPTYPE(op) == JOF_SCOPE);
    771  MOZ_ASSERT(index < perScriptData().gcThingList().length());
    772  return emitGCIndexOp(op, index);
    773 }
    774 
    775 bool BytecodeEmitter::emitInternedObjectOp(GCThingIndex index, JSOp op) {
    776  MOZ_ASSERT(JOF_OPTYPE(op) == JOF_OBJECT);
    777  MOZ_ASSERT(index < perScriptData().gcThingList().length());
    778  return emitGCIndexOp(op, index);
    779 }
    780 
    781 bool BytecodeEmitter::emitRegExp(GCThingIndex index) {
    782  return emitGCIndexOp(JSOp::RegExp, index);
    783 }
    784 
    785 bool BytecodeEmitter::emitLocalOp(JSOp op, uint32_t slot) {
    786  MOZ_ASSERT(JOF_OPTYPE(op) != JOF_ENVCOORD);
    787  MOZ_ASSERT(IsLocalOp(op));
    788 
    789  BytecodeOffset off;
    790  if (!emitN(op, LOCALNO_LEN, &off)) {
    791    return false;
    792  }
    793 
    794  SET_LOCALNO(bytecodeSection().code(off), slot);
    795  return true;
    796 }
    797 
    798 bool BytecodeEmitter::emitArgOp(JSOp op, uint16_t slot) {
    799  MOZ_ASSERT(IsArgOp(op));
    800  BytecodeOffset off;
    801  if (!emitN(op, ARGNO_LEN, &off)) {
    802    return false;
    803  }
    804 
    805  SET_ARGNO(bytecodeSection().code(off), slot);
    806  return true;
    807 }
    808 
    809 bool BytecodeEmitter::emitEnvCoordOp(JSOp op, EnvironmentCoordinate ec) {
    810  MOZ_ASSERT(JOF_OPTYPE(op) == JOF_ENVCOORD ||
    811             JOF_OPTYPE(op) == JOF_DEBUGCOORD);
    812 
    813  constexpr size_t N = ENVCOORD_HOPS_LEN + ENVCOORD_SLOT_LEN;
    814  MOZ_ASSERT(GetOpLength(op) == 1 + N);
    815 
    816  BytecodeOffset off;
    817  if (!emitN(op, N, &off)) {
    818    return false;
    819  }
    820 
    821  jsbytecode* pc = bytecodeSection().code(off);
    822  SET_ENVCOORD_HOPS(pc, ec.hops());
    823  pc += ENVCOORD_HOPS_LEN;
    824  SET_ENVCOORD_SLOT(pc, ec.slot());
    825  pc += ENVCOORD_SLOT_LEN;
    826  return true;
    827 }
    828 
    829 bool BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer) const {
    830  AutoCheckRecursionLimit recursion(fc);
    831  if (!recursion.check(fc)) {
    832    return false;
    833  }
    834 
    835 restart:
    836 
    837  switch (pn->getKind()) {
    838    // Trivial cases with no side effects.
    839    case ParseNodeKind::EmptyStmt:
    840    case ParseNodeKind::TrueExpr:
    841    case ParseNodeKind::FalseExpr:
    842    case ParseNodeKind::NullExpr:
    843    case ParseNodeKind::RawUndefinedExpr:
    844    case ParseNodeKind::Elision:
    845    case ParseNodeKind::Generator:
    846      MOZ_ASSERT(pn->is<NullaryNode>());
    847      *answer = false;
    848      return true;
    849 
    850    case ParseNodeKind::ObjectPropertyName:
    851    case ParseNodeKind::PrivateName:  // no side effects, unlike
    852                                      // ParseNodeKind::Name
    853    case ParseNodeKind::StringExpr:
    854    case ParseNodeKind::TemplateStringExpr:
    855      MOZ_ASSERT(pn->is<NameNode>());
    856      *answer = false;
    857      return true;
    858 
    859    case ParseNodeKind::RegExpExpr:
    860      MOZ_ASSERT(pn->is<RegExpLiteral>());
    861      *answer = false;
    862      return true;
    863 
    864    case ParseNodeKind::NumberExpr:
    865      MOZ_ASSERT(pn->is<NumericLiteral>());
    866      *answer = false;
    867      return true;
    868 
    869    case ParseNodeKind::BigIntExpr:
    870      MOZ_ASSERT(pn->is<BigIntLiteral>());
    871      *answer = false;
    872      return true;
    873 
    874    // |this| can throw in derived class constructors, including nested arrow
    875    // functions or eval.
    876    case ParseNodeKind::ThisExpr:
    877      MOZ_ASSERT(pn->is<UnaryNode>());
    878      *answer = sc->needsThisTDZChecks();
    879      return true;
    880 
    881    // |new.target| doesn't have any side-effects.
    882    case ParseNodeKind::NewTargetExpr: {
    883      MOZ_ASSERT(pn->is<NewTargetNode>());
    884      *answer = false;
    885      return true;
    886    }
    887 
    888    // Trivial binary nodes with more token pos holders.
    889    case ParseNodeKind::ImportMetaExpr: {
    890      MOZ_ASSERT(pn->as<BinaryNode>().left()->isKind(ParseNodeKind::PosHolder));
    891      MOZ_ASSERT(
    892          pn->as<BinaryNode>().right()->isKind(ParseNodeKind::PosHolder));
    893      *answer = false;
    894      return true;
    895    }
    896 
    897    case ParseNodeKind::BreakStmt:
    898      MOZ_ASSERT(pn->is<BreakStatement>());
    899      *answer = true;
    900      return true;
    901 
    902    case ParseNodeKind::ContinueStmt:
    903      MOZ_ASSERT(pn->is<ContinueStatement>());
    904      *answer = true;
    905      return true;
    906 
    907    case ParseNodeKind::DebuggerStmt:
    908      MOZ_ASSERT(pn->is<DebuggerStatement>());
    909      *answer = true;
    910      return true;
    911 
    912    // Watch out for getters!
    913    case ParseNodeKind::OptionalDotExpr:
    914    case ParseNodeKind::DotExpr:
    915    case ParseNodeKind::ArgumentsLength:
    916      MOZ_ASSERT(pn->is<BinaryNode>());
    917      *answer = true;
    918      return true;
    919 
    920    // Unary cases with side effects only if the child has them.
    921    case ParseNodeKind::TypeOfExpr:
    922    case ParseNodeKind::VoidExpr:
    923    case ParseNodeKind::NotExpr:
    924      return checkSideEffects(pn->as<UnaryNode>().kid(), answer);
    925 
    926    // Even if the name expression is effect-free, performing ToPropertyKey on
    927    // it might not be effect-free:
    928    //
    929    //   RegExp.prototype.toString = () => { throw 42; };
    930    //   ({ [/regex/]: 0 }); // ToPropertyKey(/regex/) throws 42
    931    //
    932    //   function Q() {
    933    //     ({ [new.target]: 0 });
    934    //   }
    935    //   Q.toString = () => { throw 17; };
    936    //   new Q; // new.target will be Q, ToPropertyKey(Q) throws 17
    937    case ParseNodeKind::ComputedName:
    938      MOZ_ASSERT(pn->is<UnaryNode>());
    939      *answer = true;
    940      return true;
    941 
    942    // Looking up or evaluating the associated name could throw.
    943    case ParseNodeKind::TypeOfNameExpr:
    944      MOZ_ASSERT(pn->is<UnaryNode>());
    945      *answer = true;
    946      return true;
    947 
    948    // This unary case has side effects on the enclosing object, sure.  But
    949    // that's not the question this function answers: it's whether the
    950    // operation may have a side effect on something *other* than the result
    951    // of the overall operation in which it's embedded.  The answer to that
    952    // is no, because an object literal having a mutated prototype only
    953    // produces a value, without affecting anything else.
    954    case ParseNodeKind::MutateProto:
    955      return checkSideEffects(pn->as<UnaryNode>().kid(), answer);
    956 
    957    // Unary cases with obvious side effects.
    958    case ParseNodeKind::PreIncrementExpr:
    959    case ParseNodeKind::PostIncrementExpr:
    960    case ParseNodeKind::PreDecrementExpr:
    961    case ParseNodeKind::PostDecrementExpr:
    962    case ParseNodeKind::ThrowStmt:
    963      MOZ_ASSERT(pn->is<UnaryNode>());
    964      *answer = true;
    965      return true;
    966 
    967    // These might invoke valueOf/toString, even with a subexpression without
    968    // side effects!  Consider |+{ valueOf: null, toString: null }|.
    969    case ParseNodeKind::BitNotExpr:
    970    case ParseNodeKind::PosExpr:
    971    case ParseNodeKind::NegExpr:
    972      MOZ_ASSERT(pn->is<UnaryNode>());
    973      *answer = true;
    974      return true;
    975 
    976    // This invokes the (user-controllable) iterator protocol.
    977    case ParseNodeKind::Spread:
    978      MOZ_ASSERT(pn->is<UnaryNode>());
    979      *answer = true;
    980      return true;
    981 
    982    case ParseNodeKind::InitialYield:
    983    case ParseNodeKind::YieldStarExpr:
    984    case ParseNodeKind::YieldExpr:
    985    case ParseNodeKind::AwaitExpr:
    986      MOZ_ASSERT(pn->is<UnaryNode>());
    987      *answer = true;
    988      return true;
    989 
    990    // Deletion generally has side effects, even if isolated cases have none.
    991    case ParseNodeKind::DeleteNameExpr:
    992    case ParseNodeKind::DeletePropExpr:
    993    case ParseNodeKind::DeleteElemExpr:
    994    case ParseNodeKind::DeleteOptionalChainExpr:
    995      MOZ_ASSERT(pn->is<UnaryNode>());
    996      *answer = true;
    997      return true;
    998 
    999    // Deletion of a non-Reference expression has side effects only through
   1000    // evaluating the expression.
   1001    case ParseNodeKind::DeleteExpr: {
   1002      ParseNode* expr = pn->as<UnaryNode>().kid();
   1003      return checkSideEffects(expr, answer);
   1004    }
   1005 
   1006    case ParseNodeKind::ExpressionStmt:
   1007      return checkSideEffects(pn->as<UnaryNode>().kid(), answer);
   1008 
   1009    // Binary cases with obvious side effects.
   1010    case ParseNodeKind::InitExpr:
   1011      *answer = true;
   1012      return true;
   1013 
   1014    case ParseNodeKind::AssignExpr:
   1015    case ParseNodeKind::AddAssignExpr:
   1016    case ParseNodeKind::SubAssignExpr:
   1017    case ParseNodeKind::CoalesceAssignExpr:
   1018    case ParseNodeKind::OrAssignExpr:
   1019    case ParseNodeKind::AndAssignExpr:
   1020    case ParseNodeKind::BitOrAssignExpr:
   1021    case ParseNodeKind::BitXorAssignExpr:
   1022    case ParseNodeKind::BitAndAssignExpr:
   1023    case ParseNodeKind::LshAssignExpr:
   1024    case ParseNodeKind::RshAssignExpr:
   1025    case ParseNodeKind::UrshAssignExpr:
   1026    case ParseNodeKind::MulAssignExpr:
   1027    case ParseNodeKind::DivAssignExpr:
   1028    case ParseNodeKind::ModAssignExpr:
   1029    case ParseNodeKind::PowAssignExpr:
   1030      MOZ_ASSERT(pn->is<AssignmentNode>());
   1031      *answer = true;
   1032      return true;
   1033 
   1034    case ParseNodeKind::SetThis:
   1035      MOZ_ASSERT(pn->is<BinaryNode>());
   1036      *answer = true;
   1037      return true;
   1038 
   1039    case ParseNodeKind::StatementList:
   1040    // Strict equality operations and short circuit operators are well-behaved
   1041    // and perform no conversions.
   1042    case ParseNodeKind::CoalesceExpr:
   1043    case ParseNodeKind::OrExpr:
   1044    case ParseNodeKind::AndExpr:
   1045    case ParseNodeKind::StrictEqExpr:
   1046    case ParseNodeKind::StrictNeExpr:
   1047    // Any subexpression of a comma expression could be effectful.
   1048    case ParseNodeKind::CommaExpr:
   1049      MOZ_ASSERT(!pn->as<ListNode>().empty());
   1050      [[fallthrough]];
   1051    // Subcomponents of a literal may be effectful.
   1052    case ParseNodeKind::ArrayExpr:
   1053    case ParseNodeKind::ObjectExpr:
   1054      for (ParseNode* item : pn->as<ListNode>().contents()) {
   1055        if (!checkSideEffects(item, answer)) {
   1056          return false;
   1057        }
   1058        if (*answer) {
   1059          return true;
   1060        }
   1061      }
   1062      return true;
   1063 
   1064 #ifdef ENABLE_DECORATORS
   1065    case ParseNodeKind::DecoratorList:
   1066      MOZ_CRASH("Decorators are not supported yet");
   1067 #endif
   1068 
   1069 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   1070    case ParseNodeKind::UsingDecl:
   1071    case ParseNodeKind::AwaitUsingDecl:
   1072      MOZ_CRASH("Using declarations are not supported yet");
   1073 #endif
   1074 
   1075    // Most other binary operations (parsed as lists in SpiderMonkey) may
   1076    // perform conversions triggering side effects.  Math operations perform
   1077    // ToNumber and may fail invoking invalid user-defined toString/valueOf:
   1078    // |5 < { toString: null }|.  |instanceof| throws if provided a
   1079    // non-object constructor: |null instanceof null|.  |in| throws if given
   1080    // a non-object RHS: |5 in null|.
   1081    case ParseNodeKind::BitOrExpr:
   1082    case ParseNodeKind::BitXorExpr:
   1083    case ParseNodeKind::BitAndExpr:
   1084    case ParseNodeKind::EqExpr:
   1085    case ParseNodeKind::NeExpr:
   1086    case ParseNodeKind::LtExpr:
   1087    case ParseNodeKind::LeExpr:
   1088    case ParseNodeKind::GtExpr:
   1089    case ParseNodeKind::GeExpr:
   1090    case ParseNodeKind::InstanceOfExpr:
   1091    case ParseNodeKind::InExpr:
   1092    case ParseNodeKind::PrivateInExpr:
   1093    case ParseNodeKind::LshExpr:
   1094    case ParseNodeKind::RshExpr:
   1095    case ParseNodeKind::UrshExpr:
   1096    case ParseNodeKind::AddExpr:
   1097    case ParseNodeKind::SubExpr:
   1098    case ParseNodeKind::MulExpr:
   1099    case ParseNodeKind::DivExpr:
   1100    case ParseNodeKind::ModExpr:
   1101    case ParseNodeKind::PowExpr:
   1102      MOZ_ASSERT(pn->as<ListNode>().count() >= 2);
   1103      *answer = true;
   1104      return true;
   1105 
   1106    case ParseNodeKind::PropertyDefinition:
   1107    case ParseNodeKind::Case: {
   1108      BinaryNode* node = &pn->as<BinaryNode>();
   1109      if (!checkSideEffects(node->left(), answer)) {
   1110        return false;
   1111      }
   1112      if (*answer) {
   1113        return true;
   1114      }
   1115      return checkSideEffects(node->right(), answer);
   1116    }
   1117 
   1118    // More getters.
   1119    case ParseNodeKind::ElemExpr:
   1120    case ParseNodeKind::OptionalElemExpr:
   1121      MOZ_ASSERT(pn->is<BinaryNode>());
   1122      *answer = true;
   1123      return true;
   1124 
   1125    // Throws if the operand is not of the right class. Can also call a private
   1126    // getter.
   1127    case ParseNodeKind::PrivateMemberExpr:
   1128    case ParseNodeKind::OptionalPrivateMemberExpr:
   1129      *answer = true;
   1130      return true;
   1131 
   1132    // These affect visible names in this code, or in other code.
   1133    case ParseNodeKind::ImportDecl:
   1134    case ParseNodeKind::ExportFromStmt:
   1135    case ParseNodeKind::ExportDefaultStmt:
   1136      MOZ_ASSERT(pn->is<BinaryNode>());
   1137      *answer = true;
   1138      return true;
   1139 
   1140    // Likewise.
   1141    case ParseNodeKind::ExportStmt:
   1142      MOZ_ASSERT(pn->is<UnaryNode>());
   1143      *answer = true;
   1144      return true;
   1145 
   1146    case ParseNodeKind::CallImportExpr:
   1147    case ParseNodeKind::CallImportSpec:
   1148      MOZ_ASSERT(pn->is<BinaryNode>());
   1149      *answer = true;
   1150      return true;
   1151 
   1152    // Every part of a loop might be effect-free, but looping infinitely *is*
   1153    // an effect.  (Language lawyer trivia: C++ says threads can be assumed
   1154    // to exit or have side effects, C++14 [intro.multithread]p27, so a C++
   1155    // implementation's equivalent of the below could set |*answer = false;|
   1156    // if all loop sub-nodes set |*answer = false|!)
   1157    case ParseNodeKind::DoWhileStmt:
   1158    case ParseNodeKind::WhileStmt:
   1159    case ParseNodeKind::ForStmt:
   1160      MOZ_ASSERT(pn->is<BinaryNode>());
   1161      *answer = true;
   1162      return true;
   1163 
   1164    // Declarations affect the name set of the relevant scope.
   1165    case ParseNodeKind::VarStmt:
   1166    case ParseNodeKind::ConstDecl:
   1167    case ParseNodeKind::LetDecl:
   1168      MOZ_ASSERT(pn->is<ListNode>());
   1169      *answer = true;
   1170      return true;
   1171 
   1172    case ParseNodeKind::IfStmt:
   1173    case ParseNodeKind::ConditionalExpr: {
   1174      TernaryNode* node = &pn->as<TernaryNode>();
   1175      if (!checkSideEffects(node->kid1(), answer)) {
   1176        return false;
   1177      }
   1178      if (*answer) {
   1179        return true;
   1180      }
   1181      if (!checkSideEffects(node->kid2(), answer)) {
   1182        return false;
   1183      }
   1184      if (*answer) {
   1185        return true;
   1186      }
   1187      if ((pn = node->kid3())) {
   1188        goto restart;
   1189      }
   1190      return true;
   1191    }
   1192 
   1193    // Function calls can invoke non-local code.
   1194    case ParseNodeKind::NewExpr:
   1195    case ParseNodeKind::CallExpr:
   1196    case ParseNodeKind::OptionalCallExpr:
   1197    case ParseNodeKind::TaggedTemplateExpr:
   1198    case ParseNodeKind::SuperCallExpr:
   1199      MOZ_ASSERT(pn->is<BinaryNode>());
   1200      *answer = true;
   1201      return true;
   1202 
   1203    // Function arg lists can contain arbitrary expressions. Technically
   1204    // this only causes side-effects if one of the arguments does, but since
   1205    // the call being made will always trigger side-effects, it isn't needed.
   1206    case ParseNodeKind::Arguments:
   1207      MOZ_ASSERT(pn->is<ListNode>());
   1208      *answer = true;
   1209      return true;
   1210 
   1211    case ParseNodeKind::OptionalChain:
   1212      MOZ_ASSERT(pn->is<UnaryNode>());
   1213      *answer = true;
   1214      return true;
   1215 
   1216    // Classes typically introduce names.  Even if no name is introduced,
   1217    // the heritage and/or class body (through computed property names)
   1218    // usually have effects.
   1219    case ParseNodeKind::ClassDecl:
   1220      MOZ_ASSERT(pn->is<ClassNode>());
   1221      *answer = true;
   1222      return true;
   1223 
   1224    // |with| calls |ToObject| on its expression and so throws if that value
   1225    // is null/undefined.
   1226    case ParseNodeKind::WithStmt:
   1227      MOZ_ASSERT(pn->is<BinaryNode>());
   1228      *answer = true;
   1229      return true;
   1230 
   1231    case ParseNodeKind::ReturnStmt:
   1232      MOZ_ASSERT(pn->is<BinaryNode>());
   1233      *answer = true;
   1234      return true;
   1235 
   1236    case ParseNodeKind::Name:
   1237      MOZ_ASSERT(pn->is<NameNode>());
   1238      *answer = true;
   1239      return true;
   1240 
   1241    // Shorthands could trigger getters: the |x| in the object literal in
   1242    // |with ({ get x() { throw 42; } }) ({ x });|, for example, triggers
   1243    // one.  (Of course, it isn't necessary to use |with| for a shorthand to
   1244    // trigger a getter.)
   1245    case ParseNodeKind::Shorthand:
   1246      MOZ_ASSERT(pn->is<BinaryNode>());
   1247      *answer = true;
   1248      return true;
   1249 
   1250    case ParseNodeKind::Function:
   1251      MOZ_ASSERT(pn->is<FunctionNode>());
   1252      /*
   1253       * A named function, contrary to ES3, is no longer effectful, because
   1254       * we bind its name lexically (using JSOp::Callee) instead of creating
   1255       * an Object instance and binding a readonly, permanent property in it
   1256       * (the object and binding can be detected and hijacked or captured).
   1257       * This is a bug fix to ES3; it is fixed in ES3.1 drafts.
   1258       */
   1259      *answer = false;
   1260      return true;
   1261 
   1262    case ParseNodeKind::Module:
   1263      *answer = false;
   1264      return true;
   1265 
   1266    case ParseNodeKind::TryStmt: {
   1267      TryNode* tryNode = &pn->as<TryNode>();
   1268      if (!checkSideEffects(tryNode->body(), answer)) {
   1269        return false;
   1270      }
   1271      if (*answer) {
   1272        return true;
   1273      }
   1274      if (LexicalScopeNode* catchScope = tryNode->catchScope()) {
   1275        if (!checkSideEffects(catchScope, answer)) {
   1276          return false;
   1277        }
   1278        if (*answer) {
   1279          return true;
   1280        }
   1281      }
   1282      if (ParseNode* finallyBlock = tryNode->finallyBlock()) {
   1283        if (!checkSideEffects(finallyBlock, answer)) {
   1284          return false;
   1285        }
   1286      }
   1287      return true;
   1288    }
   1289 
   1290    case ParseNodeKind::Catch: {
   1291      BinaryNode* catchClause = &pn->as<BinaryNode>();
   1292      if (ParseNode* name = catchClause->left()) {
   1293        if (!checkSideEffects(name, answer)) {
   1294          return false;
   1295        }
   1296        if (*answer) {
   1297          return true;
   1298        }
   1299      }
   1300      return checkSideEffects(catchClause->right(), answer);
   1301    }
   1302 
   1303    case ParseNodeKind::SwitchStmt: {
   1304      SwitchStatement* switchStmt = &pn->as<SwitchStatement>();
   1305      if (!checkSideEffects(&switchStmt->discriminant(), answer)) {
   1306        return false;
   1307      }
   1308      return *answer ||
   1309             checkSideEffects(&switchStmt->lexicalForCaseList(), answer);
   1310    }
   1311 
   1312    case ParseNodeKind::LabelStmt:
   1313      return checkSideEffects(pn->as<LabeledStatement>().statement(), answer);
   1314 
   1315    case ParseNodeKind::LexicalScope:
   1316      return checkSideEffects(pn->as<LexicalScopeNode>().scopeBody(), answer);
   1317 
   1318    // We could methodically check every interpolated expression, but it's
   1319    // probably not worth the trouble.  Treat template strings as effect-free
   1320    // only if they don't contain any substitutions.
   1321    case ParseNodeKind::TemplateStringListExpr: {
   1322      ListNode* list = &pn->as<ListNode>();
   1323      MOZ_ASSERT(!list->empty());
   1324      MOZ_ASSERT((list->count() % 2) == 1,
   1325                 "template strings must alternate template and substitution "
   1326                 "parts");
   1327      *answer = list->count() > 1;
   1328      return true;
   1329    }
   1330 
   1331    // This should be unreachable but is left as-is for now.
   1332    case ParseNodeKind::ParamsBody:
   1333      *answer = true;
   1334      return true;
   1335 
   1336    case ParseNodeKind::ForIn:                // by ParseNodeKind::For
   1337    case ParseNodeKind::ForOf:                // by ParseNodeKind::For
   1338    case ParseNodeKind::ForHead:              // by ParseNodeKind::For
   1339    case ParseNodeKind::DefaultConstructor:   // by ParseNodeKind::ClassDecl
   1340    case ParseNodeKind::ClassBodyScope:       // by ParseNodeKind::ClassDecl
   1341    case ParseNodeKind::ClassMethod:          // by ParseNodeKind::ClassDecl
   1342    case ParseNodeKind::ClassField:           // by ParseNodeKind::ClassDecl
   1343    case ParseNodeKind::ClassNames:           // by ParseNodeKind::ClassDecl
   1344    case ParseNodeKind::StaticClassBlock:     // by ParseNodeKind::ClassDecl
   1345    case ParseNodeKind::ClassMemberList:      // by ParseNodeKind::ClassDecl
   1346    case ParseNodeKind::ImportSpecList:       // by ParseNodeKind::Import
   1347    case ParseNodeKind::ImportSpec:           // by ParseNodeKind::Import
   1348    case ParseNodeKind::ImportNamespaceSpec:  // by ParseNodeKind::Import
   1349    case ParseNodeKind::ImportAttribute:      // by ParseNodeKind::Import
   1350    case ParseNodeKind::ImportAttributeList:  // by ParseNodeKind::Import
   1351    case ParseNodeKind::ImportModuleRequest:  // by ParseNodeKind::Import
   1352    case ParseNodeKind::ExportBatchSpecStmt:  // by ParseNodeKind::Export
   1353    case ParseNodeKind::ExportSpecList:       // by ParseNodeKind::Export
   1354    case ParseNodeKind::ExportSpec:           // by ParseNodeKind::Export
   1355    case ParseNodeKind::ExportNamespaceSpec:  // by ParseNodeKind::Export
   1356    case ParseNodeKind::CallSiteObj:       // by ParseNodeKind::TaggedTemplate
   1357    case ParseNodeKind::PosHolder:         // by ParseNodeKind::NewTarget
   1358    case ParseNodeKind::SuperBase:         // by ParseNodeKind::Elem and others
   1359    case ParseNodeKind::PropertyNameExpr:  // by ParseNodeKind::Dot
   1360      MOZ_CRASH("handled by parent nodes");
   1361 
   1362    case ParseNodeKind::LastUnused:
   1363    case ParseNodeKind::Limit:
   1364      MOZ_CRASH("invalid node kind");
   1365  }
   1366 
   1367  MOZ_CRASH(
   1368      "invalid, unenumerated ParseNodeKind value encountered in "
   1369      "BytecodeEmitter::checkSideEffects");
   1370 }
   1371 
   1372 bool BytecodeEmitter::isInLoop() const {
   1373  return findInnermostNestableControl<LoopControl>();
   1374 }
   1375 
   1376 bool BytecodeEmitter::checkSingletonContext() const {
   1377  MOZ_ASSERT_IF(sc->treatAsRunOnce(), sc->isTopLevelContext());
   1378  return sc->treatAsRunOnce() && !isInLoop();
   1379 }
   1380 
   1381 bool BytecodeEmitter::needsImplicitThis() const {
   1382  // Short-circuit if there is an enclosing 'with' scope.
   1383  if (sc->inWith()) {
   1384    return true;
   1385  }
   1386 
   1387  // Otherwise see if the current point is under a 'with'.
   1388  for (EmitterScope* es = innermostEmitterScope(); es;
   1389       es = es->enclosingInFrame()) {
   1390    if (es->scope(this).kind() == ScopeKind::With) {
   1391      return true;
   1392    }
   1393  }
   1394 
   1395  return false;
   1396 }
   1397 
   1398 size_t BytecodeEmitter::countThisEnvironmentHops() const {
   1399  unsigned numHops = 0;
   1400 
   1401  for (const auto* current = this; current; current = current->parent) {
   1402    for (EmitterScope* es = current->innermostEmitterScope(); es;
   1403         es = es->enclosingInFrame()) {
   1404      if (es->scope(current).is<FunctionScope>()) {
   1405        if (!es->scope(current).isArrow()) {
   1406          // The Parser is responsible for marking the environment as either
   1407          // closed-over or used-by-eval which ensure that is must exist.
   1408          MOZ_ASSERT(es->scope(current).hasEnvironment());
   1409          return numHops;
   1410        }
   1411      }
   1412      if (es->scope(current).hasEnvironment()) {
   1413        numHops++;
   1414      }
   1415    }
   1416  }
   1417 
   1418  // The "this" environment exists outside of the compilation, but the
   1419  // `ScopeContext` recorded the number of additional hops needed, so add
   1420  // those in now.
   1421  MOZ_ASSERT(sc->allowSuperProperty());
   1422  numHops += compilationState.scopeContext.enclosingThisEnvironmentHops;
   1423  return numHops;
   1424 }
   1425 
   1426 bool BytecodeEmitter::emitThisEnvironmentCallee() {
   1427  // Get the innermost enclosing function that has a |this| binding.
   1428 
   1429  // Directly load callee from the frame if possible.
   1430  if (sc->isFunctionBox() && !sc->asFunctionBox()->isArrow()) {
   1431    return emit1(JSOp::Callee);
   1432  }
   1433 
   1434  // We have to load the callee from the environment chain.
   1435  size_t numHops = countThisEnvironmentHops();
   1436 
   1437  static_assert(
   1438      ENVCOORD_HOPS_LIMIT - 1 <= UINT16_MAX,
   1439      "JSOp::EnvCallee operand size should match ENVCOORD_HOPS_LIMIT");
   1440 
   1441  MOZ_ASSERT(numHops < ENVCOORD_HOPS_LIMIT - 1);
   1442 
   1443  return emitUint16Operand(JSOp::EnvCallee, numHops);
   1444 }
   1445 
   1446 bool BytecodeEmitter::emitSuperBase() {
   1447  if (!emitThisEnvironmentCallee()) {
   1448    return false;
   1449  }
   1450 
   1451  return emit1(JSOp::SuperBase);
   1452 }
   1453 
   1454 void BytecodeEmitter::reportError(ParseNode* pn, unsigned errorNumber,
   1455                                  ...) const {
   1456  uint32_t offset = pn ? pn->pn_pos.begin : *scriptStartOffset;
   1457 
   1458  va_list args;
   1459  va_start(args, errorNumber);
   1460 
   1461  errorReporter().errorWithNotesAtVA(nullptr, AsVariant(offset), errorNumber,
   1462                                     &args);
   1463 
   1464  va_end(args);
   1465 }
   1466 
   1467 void BytecodeEmitter::reportError(uint32_t offset, unsigned errorNumber,
   1468                                  ...) const {
   1469  va_list args;
   1470  va_start(args, errorNumber);
   1471 
   1472  errorReporter().errorWithNotesAtVA(nullptr, AsVariant(offset), errorNumber,
   1473                                     &args);
   1474 
   1475  va_end(args);
   1476 }
   1477 
   1478 bool BytecodeEmitter::addObjLiteralData(ObjLiteralWriter& writer,
   1479                                        GCThingIndex* outIndex) {
   1480  if (!writer.checkForDuplicatedNames(fc)) {
   1481    return false;
   1482  }
   1483 
   1484  size_t len = writer.getCode().size();
   1485  auto* code = compilationState.alloc.newArrayUninitialized<uint8_t>(len);
   1486  if (!code) {
   1487    js::ReportOutOfMemory(fc);
   1488    return false;
   1489  }
   1490  memcpy(code, writer.getCode().data(), len);
   1491 
   1492  ObjLiteralIndex objIndex(compilationState.objLiteralData.length());
   1493  if (uint32_t(objIndex) >= TaggedScriptThingIndex::IndexLimit) {
   1494    ReportAllocationOverflow(fc);
   1495    return false;
   1496  }
   1497  if (!compilationState.objLiteralData.emplaceBack(code, len, writer.getKind(),
   1498                                                   writer.getFlags(),
   1499                                                   writer.getPropertyCount())) {
   1500    js::ReportOutOfMemory(fc);
   1501    return false;
   1502  }
   1503 
   1504  return perScriptData().gcThingList().append(objIndex, outIndex);
   1505 }
   1506 
   1507 bool BytecodeEmitter::emitPrepareIteratorResult() {
   1508  constexpr JSOp op = JSOp::NewObject;
   1509 
   1510  ObjLiteralWriter writer;
   1511  writer.beginShape(op);
   1512 
   1513  writer.setPropNameNoDuplicateCheck(parserAtoms(),
   1514                                     TaggedParserAtomIndex::WellKnown::value());
   1515  if (!writer.propWithUndefinedValue(fc)) {
   1516    return false;
   1517  }
   1518  writer.setPropNameNoDuplicateCheck(parserAtoms(),
   1519                                     TaggedParserAtomIndex::WellKnown::done());
   1520  if (!writer.propWithUndefinedValue(fc)) {
   1521    return false;
   1522  }
   1523 
   1524  GCThingIndex shape;
   1525  if (!addObjLiteralData(writer, &shape)) {
   1526    return false;
   1527  }
   1528 
   1529  return emitGCIndexOp(op, shape);
   1530 }
   1531 
   1532 bool BytecodeEmitter::emitFinishIteratorResult(bool done) {
   1533  if (!emitAtomOp(JSOp::InitProp, TaggedParserAtomIndex::WellKnown::value())) {
   1534    return false;
   1535  }
   1536  if (!emit1(done ? JSOp::True : JSOp::False)) {
   1537    return false;
   1538  }
   1539  if (!emitAtomOp(JSOp::InitProp, TaggedParserAtomIndex::WellKnown::done())) {
   1540    return false;
   1541  }
   1542  return true;
   1543 }
   1544 
   1545 bool BytecodeEmitter::emitGetNameAtLocation(TaggedParserAtomIndex name,
   1546                                            const NameLocation& loc) {
   1547  NameOpEmitter noe(this, name, loc, NameOpEmitter::Kind::Get);
   1548  if (!noe.emitGet()) {
   1549    return false;
   1550  }
   1551 
   1552  return true;
   1553 }
   1554 
   1555 bool BytecodeEmitter::emitGetName(NameNode* name) {
   1556  MOZ_ASSERT(name->isKind(ParseNodeKind::Name));
   1557 
   1558  return emitGetName(name->name());
   1559 }
   1560 
   1561 bool BytecodeEmitter::emitGetPrivateName(NameNode* name) {
   1562  MOZ_ASSERT(name->isKind(ParseNodeKind::PrivateName));
   1563  return emitGetPrivateName(name->name());
   1564 }
   1565 
   1566 bool BytecodeEmitter::emitGetPrivateName(TaggedParserAtomIndex nameAtom) {
   1567  // The parser ensures the private name is present on the environment chain,
   1568  // but its location can be Dynamic or Global when emitting debugger
   1569  // eval-in-frame code.
   1570  NameLocation location = lookupName(nameAtom);
   1571  MOZ_ASSERT(location.kind() == NameLocation::Kind::FrameSlot ||
   1572             location.kind() == NameLocation::Kind::EnvironmentCoordinate ||
   1573             location.kind() == NameLocation::Kind::Dynamic ||
   1574             location.kind() == NameLocation::Kind::Global);
   1575 
   1576  return emitGetNameAtLocation(nameAtom, location);
   1577 }
   1578 
   1579 bool BytecodeEmitter::emitTDZCheckIfNeeded(TaggedParserAtomIndex name,
   1580                                           const NameLocation& loc,
   1581                                           ValueIsOnStack isOnStack) {
   1582  // Dynamic accesses have TDZ checks built into their VM code and should
   1583  // never emit explicit TDZ checks.
   1584  MOZ_ASSERT(loc.hasKnownSlot());
   1585  MOZ_ASSERT(loc.isLexical() || loc.isPrivateMethod() || loc.isSynthetic());
   1586 
   1587  // Private names are implemented as lexical bindings, but it's just an
   1588  // implementation detail. Per spec there's no TDZ check when using them.
   1589  if (parserAtoms().isPrivateName(name)) {
   1590    return true;
   1591  }
   1592 
   1593  Maybe<MaybeCheckTDZ> check =
   1594      innermostTDZCheckCache->needsTDZCheck(this, name);
   1595  if (!check) {
   1596    return false;
   1597  }
   1598 
   1599  // We've already emitted a check in this basic block.
   1600  if (*check == DontCheckTDZ) {
   1601    return true;
   1602  }
   1603 
   1604  // If the value is not on the stack, we have to load it first.
   1605  if (isOnStack == ValueIsOnStack::No) {
   1606    if (loc.kind() == NameLocation::Kind::FrameSlot) {
   1607      if (!emitLocalOp(JSOp::GetLocal, loc.frameSlot())) {
   1608        return false;
   1609      }
   1610    } else {
   1611      if (!emitEnvCoordOp(JSOp::GetAliasedVar, loc.environmentCoordinate())) {
   1612        return false;
   1613      }
   1614    }
   1615  }
   1616 
   1617  // Emit the lexical check.
   1618  if (loc.kind() == NameLocation::Kind::FrameSlot) {
   1619    if (!emitLocalOp(JSOp::CheckLexical, loc.frameSlot())) {
   1620      return false;
   1621    }
   1622  } else {
   1623    if (!emitEnvCoordOp(JSOp::CheckAliasedLexical,
   1624                        loc.environmentCoordinate())) {
   1625      return false;
   1626    }
   1627  }
   1628 
   1629  // Pop the value if needed.
   1630  if (isOnStack == ValueIsOnStack::No) {
   1631    if (!emit1(JSOp::Pop)) {
   1632      return false;
   1633    }
   1634  }
   1635 
   1636  return innermostTDZCheckCache->noteTDZCheck(this, name, DontCheckTDZ);
   1637 }
   1638 
   1639 bool BytecodeEmitter::emitPropLHS(PropertyAccess* prop) {
   1640  MOZ_ASSERT(!prop->isSuper());
   1641 
   1642  ParseNode* expr = &prop->expression();
   1643 
   1644  if (!expr->is<PropertyAccess>() || expr->as<PropertyAccess>().isSuper()) {
   1645    // The non-optimized case.
   1646    return emitTree(expr);
   1647  }
   1648 
   1649  // If the object operand is also a dotted property reference, reverse the
   1650  // list linked via expression() temporarily so we can iterate over it from
   1651  // the bottom up (reversing again as we go), to avoid excessive recursion.
   1652  PropertyAccess* pndot = &expr->as<PropertyAccess>();
   1653  ParseNode* pnup = nullptr;
   1654  ParseNode* pndown;
   1655  for (;;) {
   1656    // Reverse pndot->expression() to point up, not down.
   1657    pndown = &pndot->expression();
   1658    pndot->setExpression(pnup);
   1659    if (!pndown->is<PropertyAccess>() ||
   1660        pndown->as<PropertyAccess>().isSuper()) {
   1661      break;
   1662    }
   1663    pnup = pndot;
   1664    pndot = &pndown->as<PropertyAccess>();
   1665  }
   1666 
   1667  // pndown is a primary expression, not a dotted property reference.
   1668  if (!emitTree(pndown)) {
   1669    return false;
   1670  }
   1671 
   1672  while (true) {
   1673    // Walk back up the list, emitting annotated name ops.
   1674    if (!emitAtomOp(JSOp::GetProp, pndot->key().atom())) {
   1675      return false;
   1676    }
   1677 
   1678    // Reverse the pndot->expression() link again.
   1679    pnup = pndot->maybeExpression();
   1680    pndot->setExpression(pndown);
   1681    pndown = pndot;
   1682    if (!pnup) {
   1683      break;
   1684    }
   1685    pndot = &pnup->as<PropertyAccess>();
   1686  }
   1687  return true;
   1688 }
   1689 
   1690 bool BytecodeEmitter::emitPropIncDec(UnaryNode* incDec, ValueUsage valueUsage) {
   1691  PropertyAccess* prop = &incDec->kid()->as<PropertyAccess>();
   1692  bool isSuper = prop->isSuper();
   1693  ParseNodeKind kind = incDec->getKind();
   1694  PropOpEmitter poe(
   1695      this,
   1696      kind == ParseNodeKind::PostIncrementExpr
   1697          ? PropOpEmitter::Kind::PostIncrement
   1698      : kind == ParseNodeKind::PreIncrementExpr
   1699          ? PropOpEmitter::Kind::PreIncrement
   1700      : kind == ParseNodeKind::PostDecrementExpr
   1701          ? PropOpEmitter::Kind::PostDecrement
   1702          : PropOpEmitter::Kind::PreDecrement,
   1703      isSuper ? PropOpEmitter::ObjKind::Super : PropOpEmitter::ObjKind::Other);
   1704  if (!poe.prepareForObj()) {
   1705    return false;
   1706  }
   1707  if (isSuper) {
   1708    UnaryNode* base = &prop->expression().as<UnaryNode>();
   1709    if (!emitGetThisForSuperBase(base)) {
   1710      //            [stack] THIS
   1711      return false;
   1712    }
   1713  } else {
   1714    if (!emitPropLHS(prop)) {
   1715      //            [stack] OBJ
   1716      return false;
   1717    }
   1718  }
   1719  if (!poe.emitIncDec(prop->key().atom(), valueUsage)) {
   1720    //              [stack] RESULT
   1721    return false;
   1722  }
   1723 
   1724  return true;
   1725 }
   1726 
   1727 bool BytecodeEmitter::emitNameIncDec(UnaryNode* incDec, ValueUsage valueUsage) {
   1728  MOZ_ASSERT(incDec->kid()->isKind(ParseNodeKind::Name));
   1729 
   1730  ParseNodeKind kind = incDec->getKind();
   1731  NameNode* name = &incDec->kid()->as<NameNode>();
   1732  NameOpEmitter noe(this, name->atom(),
   1733                    kind == ParseNodeKind::PostIncrementExpr
   1734                        ? NameOpEmitter::Kind::PostIncrement
   1735                    : kind == ParseNodeKind::PreIncrementExpr
   1736                        ? NameOpEmitter::Kind::PreIncrement
   1737                    : kind == ParseNodeKind::PostDecrementExpr
   1738                        ? NameOpEmitter::Kind::PostDecrement
   1739                        : NameOpEmitter::Kind::PreDecrement);
   1740  if (!noe.emitIncDec(valueUsage)) {
   1741    return false;
   1742  }
   1743 
   1744  return true;
   1745 }
   1746 
   1747 bool BytecodeEmitter::emitElemObjAndKey(PropertyByValue* elem,
   1748                                        ElemOpEmitter& eoe) {
   1749  ParseNode* exprOrSuper = &elem->expression();
   1750  ParseNode* key = &elem->key();
   1751 
   1752  if (!eoe.prepareForObj()) {
   1753    //              [stack]
   1754    return false;
   1755  }
   1756 
   1757  if (elem->isSuper()) {
   1758    auto* base = &exprOrSuper->as<UnaryNode>();
   1759    if (!emitGetThisForSuperBase(base)) {
   1760      //            [stack] THIS
   1761      return false;
   1762    }
   1763  } else {
   1764    if (!emitTree(exprOrSuper)) {
   1765      //            [stack] OBJ
   1766      return false;
   1767    }
   1768  }
   1769 
   1770  if (!eoe.prepareForKey()) {
   1771    //              [stack] # if Super
   1772    //              [stack] THIS? THIS
   1773    //              [stack] # otherwise
   1774    //              [stack] OBJ? OBJ
   1775    return false;
   1776  }
   1777 
   1778  if (!emitTree(key)) {
   1779    //              [stack] # if Super
   1780    //              [stack] THIS? THIS KEY
   1781    //              [stack] # otherwise
   1782    //              [stack] OBJ? OBJ KEY
   1783    return false;
   1784  }
   1785 
   1786  return true;
   1787 }
   1788 
   1789 bool BytecodeEmitter::emitElemOpBase(JSOp op) {
   1790  if (!emit1(op)) {
   1791    return false;
   1792  }
   1793 
   1794  return true;
   1795 }
   1796 
   1797 static ElemOpEmitter::Kind ConvertIncDecKind(ParseNodeKind kind) {
   1798  switch (kind) {
   1799    case ParseNodeKind::PostIncrementExpr:
   1800      return ElemOpEmitter::Kind::PostIncrement;
   1801    case ParseNodeKind::PreIncrementExpr:
   1802      return ElemOpEmitter::Kind::PreIncrement;
   1803    case ParseNodeKind::PostDecrementExpr:
   1804      return ElemOpEmitter::Kind::PostDecrement;
   1805    case ParseNodeKind::PreDecrementExpr:
   1806      return ElemOpEmitter::Kind::PreDecrement;
   1807    default:
   1808      MOZ_CRASH("unexpected inc/dec node kind");
   1809  }
   1810 }
   1811 
   1812 static PrivateOpEmitter::Kind PrivateConvertIncDecKind(ParseNodeKind kind) {
   1813  switch (kind) {
   1814    case ParseNodeKind::PostIncrementExpr:
   1815      return PrivateOpEmitter::Kind::PostIncrement;
   1816    case ParseNodeKind::PreIncrementExpr:
   1817      return PrivateOpEmitter::Kind::PreIncrement;
   1818    case ParseNodeKind::PostDecrementExpr:
   1819      return PrivateOpEmitter::Kind::PostDecrement;
   1820    case ParseNodeKind::PreDecrementExpr:
   1821      return PrivateOpEmitter::Kind::PreDecrement;
   1822    default:
   1823      MOZ_CRASH("unexpected inc/dec node kind");
   1824  }
   1825 }
   1826 
   1827 bool BytecodeEmitter::emitElemIncDec(UnaryNode* incDec, ValueUsage valueUsage) {
   1828  PropertyByValue* elemExpr = &incDec->kid()->as<PropertyByValue>();
   1829  bool isSuper = elemExpr->isSuper();
   1830  MOZ_ASSERT(!elemExpr->key().isKind(ParseNodeKind::PrivateName));
   1831  ParseNodeKind kind = incDec->getKind();
   1832  ElemOpEmitter eoe(
   1833      this, ConvertIncDecKind(kind),
   1834      isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
   1835  if (!emitElemObjAndKey(elemExpr, eoe)) {
   1836    //              [stack] # if Super
   1837    //              [stack] THIS KEY
   1838    //              [stack] # otherwise
   1839    //              [stack] OBJ KEY
   1840    return false;
   1841  }
   1842  if (!eoe.emitIncDec(valueUsage)) {
   1843    //              [stack] RESULT
   1844    return false;
   1845  }
   1846 
   1847  return true;
   1848 }
   1849 
   1850 bool BytecodeEmitter::emitCallIncDec(UnaryNode* incDec) {
   1851  MOZ_ASSERT(incDec->isKind(ParseNodeKind::PreIncrementExpr) ||
   1852             incDec->isKind(ParseNodeKind::PostIncrementExpr) ||
   1853             incDec->isKind(ParseNodeKind::PreDecrementExpr) ||
   1854             incDec->isKind(ParseNodeKind::PostDecrementExpr));
   1855 
   1856  ParseNode* call = incDec->kid();
   1857  MOZ_ASSERT(call->isKind(ParseNodeKind::CallExpr));
   1858  if (!emitTree(call)) {
   1859    //              [stack] CALLRESULT
   1860    return false;
   1861  }
   1862 
   1863  // The increment/decrement has no side effects, so proceed to throw for
   1864  // invalid assignment target.
   1865  return emit2(JSOp::ThrowMsg, uint8_t(ThrowMsgKind::AssignToCall));
   1866 }
   1867 
   1868 bool BytecodeEmitter::emitPrivateIncDec(UnaryNode* incDec,
   1869                                        ValueUsage valueUsage) {
   1870  PrivateMemberAccess* privateExpr = &incDec->kid()->as<PrivateMemberAccess>();
   1871  ParseNodeKind kind = incDec->getKind();
   1872  PrivateOpEmitter xoe(this, PrivateConvertIncDecKind(kind),
   1873                       privateExpr->privateName().name());
   1874  if (!emitTree(&privateExpr->expression())) {
   1875    //              [stack] OBJ
   1876    return false;
   1877  }
   1878  if (!xoe.emitReference()) {
   1879    //              [stack] OBJ NAME
   1880    return false;
   1881  }
   1882  if (!xoe.emitIncDec(valueUsage)) {
   1883    //              [stack] RESULT
   1884    return false;
   1885  }
   1886 
   1887  return true;
   1888 }
   1889 
   1890 bool BytecodeEmitter::emitDouble(double d) {
   1891  BytecodeOffset offset;
   1892  if (!emitCheck(JSOp::Double, 9, &offset)) {
   1893    return false;
   1894  }
   1895 
   1896  jsbytecode* code = bytecodeSection().code(offset);
   1897  code[0] = jsbytecode(JSOp::Double);
   1898  SET_INLINE_VALUE(code, DoubleValue(d));
   1899  bytecodeSection().updateDepth(JSOp::Double, offset);
   1900  return true;
   1901 }
   1902 
   1903 bool BytecodeEmitter::emitNumberOp(double dval) {
   1904  int32_t ival;
   1905  if (NumberIsInt32(dval, &ival)) {
   1906    if (ival == 0) {
   1907      return emit1(JSOp::Zero);
   1908    }
   1909    if (ival == 1) {
   1910      return emit1(JSOp::One);
   1911    }
   1912    if ((int)(int8_t)ival == ival) {
   1913      return emit2(JSOp::Int8, uint8_t(int8_t(ival)));
   1914    }
   1915 
   1916    uint32_t u = uint32_t(ival);
   1917    if (u < Bit(16)) {
   1918      if (!emitUint16Operand(JSOp::Uint16, u)) {
   1919        return false;
   1920      }
   1921    } else if (u < Bit(24)) {
   1922      BytecodeOffset off;
   1923      if (!emitN(JSOp::Uint24, 3, &off)) {
   1924        return false;
   1925      }
   1926      SET_UINT24(bytecodeSection().code(off), u);
   1927    } else {
   1928      BytecodeOffset off;
   1929      if (!emitN(JSOp::Int32, 4, &off)) {
   1930        return false;
   1931      }
   1932      SET_INT32(bytecodeSection().code(off), ival);
   1933    }
   1934    return true;
   1935  }
   1936 
   1937  return emitDouble(dval);
   1938 }
   1939 
   1940 /*
   1941 * Using MOZ_NEVER_INLINE in here is a workaround for llvm.org/pr14047.
   1942 * LLVM is deciding to inline this function which uses a lot of stack space
   1943 * into emitTree which is recursive and uses relatively little stack space.
   1944 */
   1945 MOZ_NEVER_INLINE bool BytecodeEmitter::emitSwitch(SwitchStatement* switchStmt) {
   1946  LexicalScopeNode& lexical = switchStmt->lexicalForCaseList();
   1947  MOZ_ASSERT(lexical.isKind(ParseNodeKind::LexicalScope));
   1948  ListNode* cases = &lexical.scopeBody()->as<ListNode>();
   1949  MOZ_ASSERT(cases->isKind(ParseNodeKind::StatementList));
   1950 
   1951  SwitchEmitter se(this);
   1952  if (!se.emitDiscriminant(switchStmt->discriminant().pn_pos.begin)) {
   1953    return false;
   1954  }
   1955 
   1956  if (!markStepBreakpoint()) {
   1957    return false;
   1958  }
   1959  if (!emitTree(&switchStmt->discriminant())) {
   1960    return false;
   1961  }
   1962 
   1963  // Enter the scope before pushing the switch BreakableControl since all
   1964  // breaks are under this scope.
   1965 
   1966  if (!lexical.isEmptyScope()) {
   1967    if (!se.emitLexical(lexical.scopeBindings())) {
   1968      return false;
   1969    }
   1970 
   1971    // A switch statement may contain hoisted functions inside its
   1972    // cases. The hasTopLevelFunctionDeclarations flag is propagated from the
   1973    // StatementList bodies of the cases to the case list.
   1974    if (cases->hasTopLevelFunctionDeclarations()) {
   1975      for (ParseNode* item : cases->contents()) {
   1976        CaseClause* caseClause = &item->as<CaseClause>();
   1977        ListNode* statements = caseClause->statementList();
   1978        if (statements->hasTopLevelFunctionDeclarations()) {
   1979          if (!emitHoistedFunctionsInList(statements)) {
   1980            return false;
   1981          }
   1982        }
   1983      }
   1984    }
   1985  } else {
   1986    MOZ_ASSERT(!cases->hasTopLevelFunctionDeclarations());
   1987  }
   1988 
   1989  SwitchEmitter::TableGenerator tableGen(this);
   1990  uint32_t caseCount = cases->count() - (switchStmt->hasDefault() ? 1 : 0);
   1991  if (caseCount == 0) {
   1992    tableGen.finish(0);
   1993  } else {
   1994    for (ParseNode* item : cases->contents()) {
   1995      CaseClause* caseClause = &item->as<CaseClause>();
   1996      if (caseClause->isDefault()) {
   1997        continue;
   1998      }
   1999 
   2000      ParseNode* caseValue = caseClause->caseExpression();
   2001 
   2002      if (caseValue->getKind() != ParseNodeKind::NumberExpr) {
   2003        tableGen.setInvalid();
   2004        break;
   2005      }
   2006 
   2007      int32_t i;
   2008      if (!NumberEqualsInt32(caseValue->as<NumericLiteral>().value(), &i)) {
   2009        tableGen.setInvalid();
   2010        break;
   2011      }
   2012 
   2013      if (!tableGen.addNumber(i)) {
   2014        return false;
   2015      }
   2016    }
   2017 
   2018    tableGen.finish(caseCount);
   2019  }
   2020 
   2021  if (!se.validateCaseCount(caseCount)) {
   2022    return false;
   2023  }
   2024 
   2025  bool isTableSwitch = tableGen.isValid();
   2026  if (isTableSwitch) {
   2027    if (!se.emitTable(tableGen)) {
   2028      return false;
   2029    }
   2030  } else {
   2031    if (!se.emitCond()) {
   2032      return false;
   2033    }
   2034 
   2035    // Emit code for evaluating cases and jumping to case statements.
   2036    for (ParseNode* item : cases->contents()) {
   2037      CaseClause* caseClause = &item->as<CaseClause>();
   2038      if (caseClause->isDefault()) {
   2039        continue;
   2040      }
   2041 
   2042      if (!se.prepareForCaseValue()) {
   2043        return false;
   2044      }
   2045 
   2046      ParseNode* caseValue = caseClause->caseExpression();
   2047      // If the expression is a literal, suppress line number emission so
   2048      // that debugging works more naturally.
   2049      if (!emitTree(
   2050              caseValue, ValueUsage::WantValue,
   2051              caseValue->isLiteral() ? SUPPRESS_LINENOTE : EMIT_LINENOTE)) {
   2052        return false;
   2053      }
   2054 
   2055      if (!se.emitCaseJump()) {
   2056        return false;
   2057      }
   2058    }
   2059  }
   2060 
   2061  // Emit code for each case's statements.
   2062  for (ParseNode* item : cases->contents()) {
   2063    CaseClause* caseClause = &item->as<CaseClause>();
   2064    if (caseClause->isDefault()) {
   2065      if (!se.emitDefaultBody()) {
   2066        return false;
   2067      }
   2068    } else {
   2069      if (isTableSwitch) {
   2070        ParseNode* caseValue = caseClause->caseExpression();
   2071        MOZ_ASSERT(caseValue->isKind(ParseNodeKind::NumberExpr));
   2072 
   2073        NumericLiteral* literal = &caseValue->as<NumericLiteral>();
   2074 #ifdef DEBUG
   2075        // Use NumberEqualsInt32 here because switches compare using
   2076        // strict equality, which will equate -0 and +0.  In contrast
   2077        // NumberIsInt32 would return false for -0.
   2078        int32_t v;
   2079        MOZ_ASSERT(mozilla::NumberEqualsInt32(literal->value(), &v));
   2080 #endif
   2081        int32_t i = int32_t(literal->value());
   2082 
   2083        if (!se.emitCaseBody(i, tableGen)) {
   2084          return false;
   2085        }
   2086      } else {
   2087        if (!se.emitCaseBody()) {
   2088          return false;
   2089        }
   2090      }
   2091    }
   2092 
   2093    if (!emitTree(caseClause->statementList())) {
   2094      return false;
   2095    }
   2096  }
   2097 
   2098  if (!se.emitEnd()) {
   2099    return false;
   2100  }
   2101 
   2102  return true;
   2103 }
   2104 
   2105 bool BytecodeEmitter::allocateResumeIndex(BytecodeOffset offset,
   2106                                          uint32_t* resumeIndex) {
   2107  static constexpr uint32_t MaxResumeIndex = BitMask(24);
   2108 
   2109  static_assert(
   2110      MaxResumeIndex < uint32_t(AbstractGeneratorObject::RESUME_INDEX_RUNNING),
   2111      "resumeIndex should not include magic AbstractGeneratorObject "
   2112      "resumeIndex values");
   2113  static_assert(
   2114      MaxResumeIndex <= INT32_MAX / sizeof(uintptr_t),
   2115      "resumeIndex * sizeof(uintptr_t) must fit in an int32. JIT code relies "
   2116      "on this when loading resume entries from BaselineScript");
   2117 
   2118  *resumeIndex = bytecodeSection().resumeOffsetList().length();
   2119  if (*resumeIndex > MaxResumeIndex) {
   2120    reportError(nullptr, JSMSG_TOO_MANY_RESUME_INDEXES);
   2121    return false;
   2122  }
   2123 
   2124  return bytecodeSection().resumeOffsetList().append(offset.value());
   2125 }
   2126 
   2127 bool BytecodeEmitter::allocateResumeIndexRange(
   2128    mozilla::Span<BytecodeOffset> offsets, uint32_t* firstResumeIndex) {
   2129  *firstResumeIndex = 0;
   2130 
   2131  for (size_t i = 0, len = offsets.size(); i < len; i++) {
   2132    uint32_t resumeIndex;
   2133    if (!allocateResumeIndex(offsets[i], &resumeIndex)) {
   2134      return false;
   2135    }
   2136    if (i == 0) {
   2137      *firstResumeIndex = resumeIndex;
   2138    }
   2139  }
   2140 
   2141  return true;
   2142 }
   2143 
   2144 bool BytecodeEmitter::emitYieldOp(JSOp op) {
   2145  // ParseContext::Scope::setOwnStackSlotCount should check the fixed slot
   2146  // for the following, and it should prevent using fixed slot if there are
   2147  // too many bindings:
   2148  //   * generator or asyn function
   2149  //   * module code after top-level await
   2150  MOZ_ASSERT(innermostEmitterScopeNoCheck()->frameSlotEnd() <=
   2151             ParseContext::Scope::FixedSlotLimit);
   2152 
   2153  if (op == JSOp::FinalYieldRval) {
   2154    return emit1(JSOp::FinalYieldRval);
   2155  }
   2156 
   2157  MOZ_ASSERT(op == JSOp::InitialYield || op == JSOp::Yield ||
   2158             op == JSOp::Await);
   2159 
   2160  BytecodeOffset off;
   2161  if (!emitN(op, 3, &off)) {
   2162    return false;
   2163  }
   2164 
   2165  // InitialYield is always the first yield node.
   2166  MOZ_ASSERT_IF(op == JSOp::InitialYield, bytecodeSection().numYields() == 0);
   2167 
   2168  if (op == JSOp::InitialYield || op == JSOp::Yield) {
   2169    bytecodeSection().addNumYields();
   2170  }
   2171 
   2172  uint32_t resumeIndex;
   2173  if (!allocateResumeIndex(bytecodeSection().offset(), &resumeIndex)) {
   2174    return false;
   2175  }
   2176 
   2177  // InitialYield is the first resumable instruction.
   2178  MOZ_ASSERT_IF(
   2179      op == JSOp::InitialYield,
   2180      resumeIndex == AbstractGeneratorObject::RESUME_INDEX_INITIAL_YIELD);
   2181 
   2182  SET_RESUMEINDEX(bytecodeSection().code(off), resumeIndex);
   2183 
   2184  BytecodeOffset unusedOffset;
   2185  return emitJumpTargetOp(JSOp::AfterYield, &unusedOffset);
   2186 }
   2187 
   2188 bool BytecodeEmitter::emitPushResumeKind(GeneratorResumeKind kind) {
   2189  return emit2(JSOp::ResumeKind, uint8_t(kind));
   2190 }
   2191 
   2192 bool BytecodeEmitter::emitSetThis(BinaryNode* setThisNode) {
   2193  // ParseNodeKind::SetThis is used to update |this| after a super() call
   2194  // in a derived class constructor.
   2195 
   2196  MOZ_ASSERT(setThisNode->isKind(ParseNodeKind::SetThis));
   2197  MOZ_ASSERT(setThisNode->left()->isKind(ParseNodeKind::Name));
   2198 
   2199  auto name = setThisNode->left()->as<NameNode>().name();
   2200 
   2201  // The 'this' binding is not lexical, but due to super() semantics this
   2202  // initialization needs to be treated as a lexical one.
   2203  NameLocation loc = lookupName(name);
   2204  NameLocation lexicalLoc;
   2205  if (loc.kind() == NameLocation::Kind::FrameSlot) {
   2206    lexicalLoc = NameLocation::FrameSlot(BindingKind::Let, loc.frameSlot());
   2207  } else if (loc.kind() == NameLocation::Kind::EnvironmentCoordinate) {
   2208    EnvironmentCoordinate coord = loc.environmentCoordinate();
   2209    uint16_t hops = AssertedCast<uint16_t>(coord.hops());
   2210    lexicalLoc = NameLocation::EnvironmentCoordinate(BindingKind::Let, hops,
   2211                                                     coord.slot());
   2212  } else {
   2213    MOZ_ASSERT(loc.kind() == NameLocation::Kind::Dynamic);
   2214    lexicalLoc = loc;
   2215  }
   2216 
   2217  NameOpEmitter noe(this, name, lexicalLoc, NameOpEmitter::Kind::Initialize);
   2218  if (!noe.prepareForRhs()) {
   2219    //              [stack]
   2220    return false;
   2221  }
   2222 
   2223  // Emit the new |this| value.
   2224  if (!emitTree(setThisNode->right())) {
   2225    //              [stack] NEWTHIS
   2226    return false;
   2227  }
   2228 
   2229  // Get the original |this| and throw if we already initialized
   2230  // it. Do *not* use the NameLocation argument, as that's the special
   2231  // lexical location below to deal with super() semantics.
   2232  if (!emitGetName(name)) {
   2233    //              [stack] NEWTHIS THIS
   2234    return false;
   2235  }
   2236  if (!emit1(JSOp::CheckThisReinit)) {
   2237    //              [stack] NEWTHIS THIS
   2238    return false;
   2239  }
   2240  if (!emit1(JSOp::Pop)) {
   2241    //              [stack] NEWTHIS
   2242    return false;
   2243  }
   2244  if (!noe.emitAssignment()) {
   2245    //              [stack] NEWTHIS
   2246    return false;
   2247  }
   2248 
   2249  if (!emitInitializeInstanceMembers(true)) {
   2250    return false;
   2251  }
   2252 
   2253  return true;
   2254 }
   2255 
   2256 bool BytecodeEmitter::defineHoistedTopLevelFunctions(ParseNode* body) {
   2257  MOZ_ASSERT(inPrologue());
   2258  MOZ_ASSERT(sc->isGlobalContext() || (sc->isEvalContext() && !sc->strict()));
   2259  MOZ_ASSERT(body->is<LexicalScopeNode>() || body->is<ListNode>());
   2260 
   2261  if (body->is<LexicalScopeNode>()) {
   2262    body = body->as<LexicalScopeNode>().scopeBody();
   2263    MOZ_ASSERT(body->is<ListNode>());
   2264  }
   2265 
   2266  if (!body->as<ListNode>().hasTopLevelFunctionDeclarations()) {
   2267    return true;
   2268  }
   2269 
   2270  return emitHoistedFunctionsInList(&body->as<ListNode>());
   2271 }
   2272 
   2273 // For Global and sloppy-Eval scripts, this performs most of the steps of the
   2274 // spec's [GlobalDeclarationInstantiation] and [EvalDeclarationInstantiation]
   2275 // operations.
   2276 //
   2277 // Note that while strict-Eval is handled in the same part of the spec, it never
   2278 // fails for global-redeclaration checks so those scripts initialize directly in
   2279 // their bytecode.
   2280 bool BytecodeEmitter::emitDeclarationInstantiation(ParseNode* body) {
   2281  if (sc->isModuleContext()) {
   2282    // ES Modules have dedicated variable and lexial environments and therefore
   2283    // do not have to perform redeclaration checks. We initialize their bindings
   2284    // elsewhere in bytecode.
   2285    return true;
   2286  }
   2287 
   2288  if (sc->isEvalContext() && sc->strict()) {
   2289    // Strict Eval has a dedicated variables (and lexical) environment and
   2290    // therefore does not have to perform redeclaration checks. We initialize
   2291    // their bindings elsewhere in the bytecode.
   2292    return true;
   2293  }
   2294 
   2295  // If we have no variables bindings, then we are done!
   2296  if (sc->isGlobalContext()) {
   2297    if (!sc->asGlobalContext()->bindings) {
   2298      return true;
   2299    }
   2300  } else {
   2301    MOZ_ASSERT(sc->isEvalContext());
   2302 
   2303    if (!sc->asEvalContext()->bindings) {
   2304      return true;
   2305    }
   2306  }
   2307 
   2308 #if DEBUG
   2309  // There should be no emitted functions yet.
   2310  for (const auto& thing : perScriptData().gcThingList().objects()) {
   2311    MOZ_ASSERT(thing.isEmptyGlobalScope() || thing.isScope());
   2312  }
   2313 #endif
   2314 
   2315  // Emit the hoisted functions to gc-things list. There is no bytecode
   2316  // generated yet to bind them.
   2317  if (!defineHoistedTopLevelFunctions(body)) {
   2318    return false;
   2319  }
   2320 
   2321  // Save the last GCThingIndex emitted. The hoisted functions are contained in
   2322  // the gc-things list up until this point. This set of gc-things also contain
   2323  // initial scopes (of which there must be at least one).
   2324  MOZ_ASSERT(perScriptData().gcThingList().length() > 0);
   2325  GCThingIndex lastFun =
   2326      GCThingIndex(perScriptData().gcThingList().length() - 1);
   2327 
   2328 #if DEBUG
   2329  for (const auto& thing : perScriptData().gcThingList().objects()) {
   2330    MOZ_ASSERT(thing.isEmptyGlobalScope() || thing.isScope() ||
   2331               thing.isFunction());
   2332  }
   2333 #endif
   2334 
   2335  // Check for declaration conflicts and initialize the bindings.
   2336  // NOTE: The self-hosting top-level script should not populate the builtins
   2337  //       directly on the GlobalObject (and instead uses JSOp::GetIntrinsic for
   2338  //       lookups).
   2339  if (emitterMode == BytecodeEmitter::EmitterMode::Normal) {
   2340    if (!emitGCIndexOp(JSOp::GlobalOrEvalDeclInstantiation, lastFun)) {
   2341      return false;
   2342    }
   2343  }
   2344 
   2345  return true;
   2346 }
   2347 
   2348 bool BytecodeEmitter::emitScript(ParseNode* body) {
   2349  setScriptStartOffsetIfUnset(body->pn_pos.begin);
   2350 
   2351  MOZ_ASSERT(inPrologue());
   2352 
   2353  TDZCheckCache tdzCache(this);
   2354  EmitterScope emitterScope(this);
   2355  Maybe<AsyncEmitter> topLevelAwait;
   2356  if (sc->isGlobalContext()) {
   2357    if (!emitterScope.enterGlobal(this, sc->asGlobalContext())) {
   2358      return false;
   2359    }
   2360  } else if (sc->isEvalContext()) {
   2361    if (!emitterScope.enterEval(this, sc->asEvalContext())) {
   2362      return false;
   2363    }
   2364  } else {
   2365    MOZ_ASSERT(sc->isModuleContext());
   2366    if (!emitterScope.enterModule(this, sc->asModuleContext())) {
   2367      return false;
   2368    }
   2369    if (sc->asModuleContext()->isAsync()) {
   2370      topLevelAwait.emplace(this);
   2371    }
   2372  }
   2373 
   2374  setFunctionBodyEndPos(body->pn_pos.end);
   2375 
   2376  bool isSloppyEval = sc->isEvalContext() && !sc->strict();
   2377  if (isSloppyEval && body->is<LexicalScopeNode>() &&
   2378      !body->as<LexicalScopeNode>().isEmptyScope()) {
   2379    // Sloppy eval scripts may emit hoisted functions bindings with a
   2380    // `JSOp::GlobalOrEvalDeclInstantiation` opcode below. If this eval needs a
   2381    // top-level lexical environment, we must ensure that environment is created
   2382    // before those functions are created and bound.
   2383    //
   2384    // This differs from the global-script case below because the global-lexical
   2385    // environment exists outside the script itself. In the case of strict eval
   2386    // scripts, the `emitterScope` above is already sufficient.
   2387    EmitterScope lexicalEmitterScope(this);
   2388    LexicalScopeNode* scope = &body->as<LexicalScopeNode>();
   2389 
   2390    if (!lexicalEmitterScope.enterLexical(this, ScopeKind::Lexical,
   2391                                          scope->scopeBindings())) {
   2392      return false;
   2393    }
   2394 
   2395    if (!emitDeclarationInstantiation(scope->scopeBody())) {
   2396      return false;
   2397    }
   2398 
   2399    switchToMain();
   2400 
   2401    ParseNode* scopeBody = scope->scopeBody();
   2402    if (!emitLexicalScopeBody(scopeBody)) {
   2403      return false;
   2404    }
   2405 
   2406    if (!updateSourceCoordNotes(scopeBody->pn_pos.end)) {
   2407      return false;
   2408    }
   2409 
   2410    if (!lexicalEmitterScope.leave(this)) {
   2411      return false;
   2412    }
   2413  } else {
   2414    if (!emitDeclarationInstantiation(body)) {
   2415      return false;
   2416    }
   2417    if (topLevelAwait) {
   2418      if (!topLevelAwait->prepareForModule()) {
   2419        return false;
   2420      }
   2421    }
   2422 
   2423    switchToMain();
   2424 
   2425 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   2426    if (!emitterScope.prepareForModuleDisposableScopeBody(this)) {
   2427      return false;
   2428    }
   2429 #endif
   2430 
   2431    if (topLevelAwait) {
   2432      if (!topLevelAwait->prepareForBody()) {
   2433        return false;
   2434      }
   2435    }
   2436 
   2437    if (!emitTree(body)) {
   2438      //            [stack]
   2439      return false;
   2440    }
   2441 
   2442    if (!updateSourceCoordNotes(body->pn_pos.end)) {
   2443      return false;
   2444    }
   2445  }
   2446 
   2447 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   2448  if (!emitterScope.emitModuleDisposableScopeBodyEnd(this)) {
   2449    return false;
   2450  }
   2451 #endif
   2452 
   2453  if (topLevelAwait) {
   2454    if (!topLevelAwait->emitEndModule()) {
   2455      return false;
   2456    }
   2457  }
   2458 
   2459  if (!markSimpleBreakpoint()) {
   2460    return false;
   2461  }
   2462 
   2463  if (!emitReturnRval()) {
   2464    return false;
   2465  }
   2466 
   2467  if (!emitterScope.leave(this)) {
   2468    return false;
   2469  }
   2470 
   2471  if (!NameFunctions(fc, parserAtoms(), body)) {
   2472    return false;
   2473  }
   2474 
   2475  // Create a Stencil and convert it into a JSScript.
   2476  return intoScriptStencil(CompilationStencil::TopLevelIndex);
   2477 }
   2478 
   2479 js::UniquePtr<ImmutableScriptData>
   2480 BytecodeEmitter::createImmutableScriptData() {
   2481  uint32_t nslots;
   2482  if (!getNslots(&nslots)) {
   2483    return nullptr;
   2484  }
   2485 
   2486  bool isFunction = sc->isFunctionBox();
   2487  uint16_t funLength = isFunction ? sc->asFunctionBox()->length() : 0;
   2488 
   2489  mozilla::SaturateUint8 propertyCountEstimate = propertyAdditionEstimate;
   2490 
   2491  // Add fields to the property count estimate.
   2492  if (isFunction && sc->asFunctionBox()->useMemberInitializers()) {
   2493    propertyCountEstimate +=
   2494        sc->asFunctionBox()->memberInitializers().numMemberInitializers;
   2495  }
   2496 
   2497  return ImmutableScriptData::new_(
   2498      fc, mainOffset(), maxFixedSlots, nslots, bodyScopeIndex,
   2499      bytecodeSection().numICEntries(), isFunction, funLength,
   2500      propertyCountEstimate.value(), bytecodeSection().code(),
   2501      bytecodeSection().notes(), bytecodeSection().resumeOffsetList().span(),
   2502      bytecodeSection().scopeNoteList().span(),
   2503      bytecodeSection().tryNoteList().span());
   2504 }
   2505 
   2506 #if defined(ENABLE_DECORATORS) || defined(ENABLE_EXPLICIT_RESOURCE_MANAGEMENT)
   2507 bool BytecodeEmitter::emitCheckIsCallable() {
   2508  // This emits code to check if the value at the top of the stack is
   2509  // callable. The value is left on the stack.
   2510  //            [stack] VAL
   2511  if (!emitAtomOp(JSOp::GetIntrinsic,
   2512                  TaggedParserAtomIndex::WellKnown::IsCallable())) {
   2513    //            [stack] VAL ISCALLABLE
   2514    return false;
   2515  }
   2516  if (!emit1(JSOp::Undefined)) {
   2517    //            [stack] VAL ISCALLABLE UNDEFINED
   2518    return false;
   2519  }
   2520  if (!emitDupAt(2)) {
   2521    //            [stack] VAL ISCALLABLE UNDEFINED VAL
   2522    return false;
   2523  }
   2524  return emitCall(JSOp::Call, 1);
   2525  //              [stack] VAL ISCALLABLE_RESULT
   2526 }
   2527 #endif
   2528 
   2529 bool BytecodeEmitter::getNslots(uint32_t* nslots) const {
   2530  uint64_t nslots64 =
   2531      maxFixedSlots + static_cast<uint64_t>(bytecodeSection().maxStackDepth());
   2532  if (nslots64 > UINT32_MAX) {
   2533    reportError(nullptr, JSMSG_NEED_DIET, "script");
   2534    return false;
   2535  }
   2536  *nslots = nslots64;
   2537  return true;
   2538 }
   2539 
   2540 bool BytecodeEmitter::emitFunctionScript(FunctionNode* funNode) {
   2541  MOZ_ASSERT(inPrologue());
   2542  ParamsBodyNode* paramsBody = funNode->body();
   2543  FunctionBox* funbox = sc->asFunctionBox();
   2544 
   2545  setScriptStartOffsetIfUnset(paramsBody->pn_pos.begin);
   2546 
   2547  //                [stack]
   2548 
   2549  FunctionScriptEmitter fse(this, funbox, Some(paramsBody->pn_pos.begin),
   2550                            Some(paramsBody->pn_pos.end));
   2551  if (!fse.prepareForParameters()) {
   2552    //              [stack]
   2553    return false;
   2554  }
   2555 
   2556  if (!emitFunctionFormalParameters(paramsBody)) {
   2557    //              [stack]
   2558    return false;
   2559  }
   2560 
   2561  if (!fse.prepareForBody()) {
   2562    //              [stack]
   2563    return false;
   2564  }
   2565 
   2566  if (!emitTree(paramsBody->body())) {
   2567    //              [stack]
   2568    return false;
   2569  }
   2570 
   2571  if (!fse.emitEndBody()) {
   2572    //              [stack]
   2573    return false;
   2574  }
   2575 
   2576  if (funbox->index() == CompilationStencil::TopLevelIndex) {
   2577    if (!NameFunctions(fc, parserAtoms(), funNode)) {
   2578      return false;
   2579    }
   2580  }
   2581 
   2582  return fse.intoStencil();
   2583 }
   2584 
   2585 class js::frontend::DestructuringLHSRef {
   2586  struct None {
   2587    size_t numReferenceSlots() const { return 0; }
   2588  };
   2589 
   2590  mozilla::Variant<None, NameOpEmitter, PropOpEmitter, ElemOpEmitter,
   2591                   PrivateOpEmitter>
   2592      emitter_ = AsVariant(None{});
   2593 
   2594 public:
   2595  template <typename T>
   2596  void from(T&& emitter) {
   2597    emitter_.emplace<T>(std::forward<T>(emitter));
   2598  }
   2599 
   2600  template <typename T>
   2601  T& emitter() {
   2602    return emitter_.as<T>();
   2603  }
   2604 
   2605  /**
   2606   * Return the number of values pushed onto the stack.
   2607   */
   2608  size_t numReferenceSlots() const {
   2609    return emitter_.match([](auto& e) { return e.numReferenceSlots(); });
   2610  }
   2611 };
   2612 
   2613 bool BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target,
   2614                                              DestructuringFlavor flav,
   2615                                              DestructuringLHSRef& lref) {
   2616 #ifdef DEBUG
   2617  int depth = bytecodeSection().stackDepth();
   2618 #endif
   2619 
   2620  switch (target->getKind()) {
   2621    case ParseNodeKind::ArrayExpr:
   2622    case ParseNodeKind::ObjectExpr:
   2623      // No need to recurse into ParseNodeKind::Array and ParseNodeKind::Object
   2624      // subpatterns here, since emitSetOrInitializeDestructuring does the
   2625      // recursion when setting or initializing the value.
   2626      break;
   2627 
   2628    case ParseNodeKind::Name: {
   2629      auto* name = &target->as<NameNode>();
   2630      NameOpEmitter noe(this, name->atom(),
   2631                        flav == DestructuringFlavor::Assignment
   2632                            ? NameOpEmitter::Kind::SimpleAssignment
   2633                            : NameOpEmitter::Kind::Initialize);
   2634      if (!noe.prepareForRhs()) {
   2635        return false;
   2636      }
   2637 
   2638      lref.from(std::move(noe));
   2639      return true;
   2640    }
   2641 
   2642    case ParseNodeKind::ArgumentsLength:
   2643    case ParseNodeKind::DotExpr: {
   2644      PropertyAccess* prop = &target->as<PropertyAccess>();
   2645      bool isSuper = prop->isSuper();
   2646      PropOpEmitter poe(this, PropOpEmitter::Kind::SimpleAssignment,
   2647                        isSuper ? PropOpEmitter::ObjKind::Super
   2648                                : PropOpEmitter::ObjKind::Other);
   2649      if (!poe.prepareForObj()) {
   2650        return false;
   2651      }
   2652      if (isSuper) {
   2653        UnaryNode* base = &prop->expression().as<UnaryNode>();
   2654        if (!emitGetThisForSuperBase(base)) {
   2655          //        [stack] THIS SUPERBASE
   2656          return false;
   2657        }
   2658      } else {
   2659        if (!emitTree(&prop->expression())) {
   2660          //        [stack] OBJ
   2661          return false;
   2662        }
   2663      }
   2664      if (!poe.prepareForRhs()) {
   2665        //          [stack] # if Super
   2666        //          [stack] THIS SUPERBASE
   2667        //          [stack] # otherwise
   2668        //          [stack] OBJ
   2669        return false;
   2670      }
   2671 
   2672      lref.from(std::move(poe));
   2673      break;
   2674    }
   2675 
   2676    case ParseNodeKind::ElemExpr: {
   2677      PropertyByValue* elem = &target->as<PropertyByValue>();
   2678      bool isSuper = elem->isSuper();
   2679      MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
   2680      ElemOpEmitter eoe(this, ElemOpEmitter::Kind::SimpleAssignment,
   2681                        isSuper ? ElemOpEmitter::ObjKind::Super
   2682                                : ElemOpEmitter::ObjKind::Other);
   2683      if (!emitElemObjAndKey(elem, eoe)) {
   2684        //          [stack] # if Super
   2685        //          [stack] THIS KEY
   2686        //          [stack] # otherwise
   2687        //          [stack] OBJ KEY
   2688        return false;
   2689      }
   2690      if (!eoe.prepareForRhs()) {
   2691        //          [stack] # if Super
   2692        //          [stack] THIS KEY SUPERBASE
   2693        //          [stack] # otherwise
   2694        //          [stack] OBJ KEY
   2695        return false;
   2696      }
   2697 
   2698      lref.from(std::move(eoe));
   2699      break;
   2700    }
   2701 
   2702    case ParseNodeKind::PrivateMemberExpr: {
   2703      PrivateMemberAccess* privateExpr = &target->as<PrivateMemberAccess>();
   2704      PrivateOpEmitter xoe(this, PrivateOpEmitter::Kind::SimpleAssignment,
   2705                           privateExpr->privateName().name());
   2706      if (!emitTree(&privateExpr->expression())) {
   2707        //          [stack] OBJ
   2708        return false;
   2709      }
   2710      if (!xoe.emitReference()) {
   2711        //          [stack] OBJ NAME
   2712        return false;
   2713      }
   2714 
   2715      lref.from(std::move(xoe));
   2716      break;
   2717    }
   2718 
   2719    case ParseNodeKind::CallExpr:
   2720      MOZ_ASSERT_UNREACHABLE(
   2721          "Parser::reportIfNotValidSimpleAssignmentTarget "
   2722          "rejects function calls as assignment "
   2723          "targets in destructuring assignments");
   2724      break;
   2725 
   2726    default:
   2727      MOZ_CRASH("emitDestructuringLHSRef: bad lhs kind");
   2728  }
   2729 
   2730  MOZ_ASSERT(bytecodeSection().stackDepth() ==
   2731             depth + int(lref.numReferenceSlots()));
   2732 
   2733  return true;
   2734 }
   2735 
   2736 bool BytecodeEmitter::emitSetOrInitializeDestructuring(
   2737    ParseNode* target, DestructuringFlavor flav, DestructuringLHSRef& lref) {
   2738  // Now emit the lvalue opcode sequence. If the lvalue is a nested
   2739  // destructuring initialiser-form, call ourselves to handle it, then pop
   2740  // the matched value. Otherwise emit an lvalue bytecode sequence followed
   2741  // by an assignment op.
   2742 
   2743  switch (target->getKind()) {
   2744    case ParseNodeKind::ArrayExpr:
   2745    case ParseNodeKind::ObjectExpr:
   2746      if (!emitDestructuringOps(&target->as<ListNode>(), flav,
   2747                                SelfHostedIter::Deny)) {
   2748        return false;
   2749      }
   2750      // emitDestructuringOps leaves the assigned (to-be-destructured) value on
   2751      // top of the stack.
   2752      break;
   2753 
   2754    case ParseNodeKind::Name: {
   2755      // The environment is already pushed by emitDestructuringLHSRef.
   2756      //            [stack] ENV? VAL
   2757      auto& noe = lref.emitter<NameOpEmitter>();
   2758 
   2759      if (!noe.emitAssignment()) {
   2760        //          [stack] VAL
   2761        return false;
   2762      }
   2763      break;
   2764    }
   2765 
   2766    case ParseNodeKind::ArgumentsLength:
   2767    case ParseNodeKind::DotExpr: {
   2768      // The reference is already pushed by emitDestructuringLHSRef.
   2769      //            [stack] # if Super
   2770      //            [stack] THIS SUPERBASE VAL
   2771      //            [stack] # otherwise
   2772      //            [stack] OBJ VAL
   2773      auto& poe = lref.emitter<PropOpEmitter>();
   2774      auto* prop = &target->as<PropertyAccess>();
   2775 
   2776      if (!poe.emitAssignment(prop->key().atom())) {
   2777        //          [stack] # VAL
   2778        return false;
   2779      }
   2780      break;
   2781    }
   2782 
   2783    case ParseNodeKind::ElemExpr: {
   2784      // The reference is already pushed by emitDestructuringLHSRef.
   2785      //            [stack] # if Super
   2786      //            [stack] THIS KEY SUPERBASE VAL
   2787      //            [stack] # otherwise
   2788      //            [stack] OBJ KEY VAL
   2789      auto& eoe = lref.emitter<ElemOpEmitter>();
   2790 
   2791      if (!eoe.emitAssignment()) {
   2792        //          [stack] VAL
   2793        return false;
   2794      }
   2795      break;
   2796    }
   2797 
   2798    case ParseNodeKind::PrivateMemberExpr: {
   2799      // The reference is already pushed by emitDestructuringLHSRef.
   2800      //            [stack] OBJ NAME VAL
   2801      auto& xoe = lref.emitter<PrivateOpEmitter>();
   2802 
   2803      if (!xoe.emitAssignment()) {
   2804        //          [stack] VAL
   2805        return false;
   2806      }
   2807      break;
   2808    }
   2809 
   2810    case ParseNodeKind::CallExpr:
   2811      MOZ_ASSERT_UNREACHABLE(
   2812          "Parser::reportIfNotValidSimpleAssignmentTarget "
   2813          "rejects function calls as assignment "
   2814          "targets in destructuring assignments");
   2815      break;
   2816 
   2817    default:
   2818      MOZ_CRASH("emitSetOrInitializeDestructuring: bad lhs kind");
   2819  }
   2820 
   2821  // Pop the assigned value.
   2822  if (!emit1(JSOp::Pop)) {
   2823    //              [stack] # empty
   2824    return false;
   2825  }
   2826 
   2827  return true;
   2828 }
   2829 
   2830 JSOp BytecodeEmitter::getIterCallOp(JSOp callOp,
   2831                                    SelfHostedIter selfHostedIter) const {
   2832  if (emitterMode == BytecodeEmitter::SelfHosting) {
   2833    MOZ_ASSERT(selfHostedIter != SelfHostedIter::Deny);
   2834 
   2835    switch (callOp) {
   2836      case JSOp::Call:
   2837        return JSOp::CallContent;
   2838      case JSOp::CallIter:
   2839        return JSOp::CallContentIter;
   2840      default:
   2841        MOZ_CRASH("Unknown iterator call op");
   2842    }
   2843  }
   2844 
   2845  return callOp;
   2846 }
   2847 
   2848 bool BytecodeEmitter::emitIteratorNext(
   2849    const Maybe<uint32_t>& callSourceCoordOffset, IteratorKind iterKind,
   2850    SelfHostedIter selfHostedIter) {
   2851  MOZ_ASSERT(selfHostedIter != SelfHostedIter::Deny ||
   2852                 emitterMode != BytecodeEmitter::SelfHosting,
   2853             ".next() iteration is prohibited in self-hosted code because it"
   2854             "can run user-modifiable iteration code");
   2855 
   2856  //                [stack] ... NEXT ITER
   2857  MOZ_ASSERT(bytecodeSection().stackDepth() >= 2);
   2858 
   2859  if (!emitCall(getIterCallOp(JSOp::Call, selfHostedIter), 0,
   2860                callSourceCoordOffset)) {
   2861    //              [stack] ... RESULT
   2862    return false;
   2863  }
   2864 
   2865  if (iterKind == IteratorKind::Async) {
   2866    if (!emitAwaitInInnermostScope()) {
   2867      //            [stack] ... RESULT
   2868      return false;
   2869    }
   2870  }
   2871 
   2872  if (!emitCheckIsObj(CheckIsObjectKind::IteratorNext)) {
   2873    //              [stack] ... RESULT
   2874    return false;
   2875  }
   2876  return true;
   2877 }
   2878 
   2879 bool BytecodeEmitter::emitIteratorCloseInScope(EmitterScope& currentScope,
   2880                                               IteratorKind iterKind,
   2881                                               CompletionKind completionKind,
   2882                                               SelfHostedIter selfHostedIter) {
   2883  MOZ_ASSERT(selfHostedIter != SelfHostedIter::Deny ||
   2884                 emitterMode != BytecodeEmitter::SelfHosting,
   2885             ".close() on iterators is prohibited in self-hosted code because "
   2886             "it can run user-modifiable iteration code");
   2887 
   2888  if (iterKind == IteratorKind::Sync) {
   2889    return emit2(JSOp::CloseIter, uint8_t(completionKind));
   2890  }
   2891 
   2892  // Generate inline logic corresponding to IteratorClose (ES2021 7.4.6) and
   2893  // AsyncIteratorClose (ES2021 7.4.7). Steps numbers apply to both operations.
   2894  //
   2895  // Callers need to ensure that the iterator object is at the top of the
   2896  // stack.
   2897 
   2898  // For non-Throw completions, we emit the equivalent of:
   2899  //
   2900  // var returnMethod = GetMethod(iterator, "return");
   2901  // if (returnMethod !== undefined) {
   2902  //   var innerResult = [Await] Call(returnMethod, iterator);
   2903  //   CheckIsObj(innerResult);
   2904  // }
   2905  //
   2906  // Whereas for Throw completions, we emit:
   2907  //
   2908  // try {
   2909  //   var returnMethod = GetMethod(iterator, "return");
   2910  //   if (returnMethod !== undefined) {
   2911  //     [Await] Call(returnMethod, iterator);
   2912  //   }
   2913  // } catch {}
   2914 
   2915  Maybe<TryEmitter> tryCatch;
   2916 
   2917  if (completionKind == CompletionKind::Throw) {
   2918    tryCatch.emplace(this, TryEmitter::Kind::TryCatch,
   2919                     TryEmitter::ControlKind::NonSyntactic);
   2920 
   2921    if (!tryCatch->emitTry()) {
   2922      //            [stack] ... ITER
   2923      return false;
   2924    }
   2925  }
   2926 
   2927  if (!emit1(JSOp::Dup)) {
   2928    //              [stack] ... ITER ITER
   2929    return false;
   2930  }
   2931 
   2932  // Steps 1-2 are assertions, step 3 is implicit.
   2933 
   2934  // Step 4.
   2935  //
   2936  // Get the "return" method.
   2937  if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::return_())) {
   2938    //              [stack] ... ITER RET
   2939    return false;
   2940  }
   2941 
   2942  // Step 5.
   2943  //
   2944  // Do nothing if "return" is undefined or null.
   2945  InternalIfEmitter ifReturnMethodIsDefined(this);
   2946  if (!emit1(JSOp::IsNullOrUndefined)) {
   2947    //              [stack] ... ITER RET NULL-OR-UNDEF
   2948    return false;
   2949  }
   2950 
   2951  if (!ifReturnMethodIsDefined.emitThenElse(
   2952          IfEmitter::ConditionKind::Negative)) {
   2953    //              [stack] ... ITER RET
   2954    return false;
   2955  }
   2956 
   2957  // Steps 5.c, 7.
   2958  //
   2959  // Call the "return" method.
   2960  if (!emit1(JSOp::Swap)) {
   2961    //              [stack] ... RET ITER
   2962    return false;
   2963  }
   2964 
   2965  if (!emitCall(getIterCallOp(JSOp::Call, selfHostedIter), 0)) {
   2966    //              [stack] ... RESULT
   2967    return false;
   2968  }
   2969 
   2970  // 7.4.7 AsyncIteratorClose, step 5.d.
   2971  if (iterKind == IteratorKind::Async) {
   2972    if (completionKind != CompletionKind::Throw) {
   2973      // Await clobbers rval, so save the current rval.
   2974      if (!emit1(JSOp::GetRval)) {
   2975        //          [stack] ... RESULT RVAL
   2976        return false;
   2977      }
   2978      if (!emit1(JSOp::Swap)) {
   2979        //          [stack] ... RVAL RESULT
   2980        return false;
   2981      }
   2982    }
   2983 
   2984    if (!emitAwaitInScope(currentScope)) {
   2985      //            [stack] ... RVAL? RESULT
   2986      return false;
   2987    }
   2988 
   2989    if (completionKind != CompletionKind::Throw) {
   2990      if (!emit1(JSOp::Swap)) {
   2991        //          [stack] ... RESULT RVAL
   2992        return false;
   2993      }
   2994      if (!emit1(JSOp::SetRval)) {
   2995        //          [stack] ... RESULT
   2996        return false;
   2997      }
   2998    }
   2999  }
   3000 
   3001  // Step 6 (Handled in caller).
   3002 
   3003  // Step 8.
   3004  if (completionKind != CompletionKind::Throw) {
   3005    // Check that the "return" result is an object.
   3006    if (!emitCheckIsObj(CheckIsObjectKind::IteratorReturn)) {
   3007      //            [stack] ... RESULT
   3008      return false;
   3009    }
   3010  }
   3011 
   3012  if (!ifReturnMethodIsDefined.emitElse()) {
   3013    //              [stack] ... ITER RET
   3014    return false;
   3015  }
   3016 
   3017  if (!emit1(JSOp::Pop)) {
   3018    //              [stack] ... ITER
   3019    return false;
   3020  }
   3021 
   3022  if (!ifReturnMethodIsDefined.emitEnd()) {
   3023    return false;
   3024  }
   3025 
   3026  if (completionKind == CompletionKind::Throw) {
   3027    if (!tryCatch->emitCatch()) {
   3028      //            [stack] ... ITER EXC
   3029      return false;
   3030    }
   3031 
   3032    // Just ignore the exception thrown by call and await.
   3033    if (!emit1(JSOp::Pop)) {
   3034      //            [stack] ... ITER
   3035      return false;
   3036    }
   3037 
   3038    if (!tryCatch->emitEnd()) {
   3039      //            [stack] ... ITER
   3040      return false;
   3041    }
   3042  }
   3043 
   3044  // Step 9 (Handled in caller).
   3045 
   3046  return emit1(JSOp::Pop);
   3047  //                [stack] ...
   3048 }
   3049 
   3050 template <typename InnerEmitter>
   3051 bool BytecodeEmitter::wrapWithDestructuringTryNote(int32_t iterDepth,
   3052                                                   InnerEmitter emitter) {
   3053  MOZ_ASSERT(bytecodeSection().stackDepth() >= iterDepth);
   3054 
   3055  // Pad a nop at the beginning of the bytecode covered by the trynote so
   3056  // that when unwinding environments, we may unwind to the scope
   3057  // corresponding to the pc *before* the start, in case the first bytecode
   3058  // emitted by |emitter| is the start of an inner scope. See comment above
   3059  // UnwindEnvironmentToTryPc.
   3060  if (!emit1(JSOp::TryDestructuring)) {
   3061    return false;
   3062  }
   3063 
   3064  BytecodeOffset start = bytecodeSection().offset();
   3065  if (!emitter(this)) {
   3066    return false;
   3067  }
   3068  BytecodeOffset end = bytecodeSection().offset();
   3069  if (start != end) {
   3070    return addTryNote(TryNoteKind::Destructuring, iterDepth, start, end);
   3071  }
   3072  return true;
   3073 }
   3074 
   3075 bool BytecodeEmitter::emitDefault(ParseNode* defaultExpr, ParseNode* pattern) {
   3076  //                [stack] VALUE
   3077 
   3078  DefaultEmitter de(this);
   3079  if (!de.prepareForDefault()) {
   3080    //              [stack]
   3081    return false;
   3082  }
   3083  if (!emitInitializer(defaultExpr, pattern)) {
   3084    //              [stack] DEFAULTVALUE
   3085    return false;
   3086  }
   3087  if (!de.emitEnd()) {
   3088    //              [stack] VALUE/DEFAULTVALUE
   3089    return false;
   3090  }
   3091  return true;
   3092 }
   3093 
   3094 bool BytecodeEmitter::emitAnonymousFunctionWithName(
   3095    ParseNode* node, TaggedParserAtomIndex name) {
   3096  MOZ_ASSERT(node->isDirectRHSAnonFunction());
   3097 
   3098  if (node->is<FunctionNode>()) {
   3099    // Function doesn't have 'name' property at this point.
   3100    // Set function's name at compile time.
   3101    setFunName(node->as<FunctionNode>().funbox(), name);
   3102 
   3103    return emitTree(node);
   3104  }
   3105 
   3106  MOZ_ASSERT(node->is<ClassNode>());
   3107 
   3108  return emitClass(&node->as<ClassNode>(), ClassNameKind::InferredName, name);
   3109 }
   3110 
   3111 bool BytecodeEmitter::emitAnonymousFunctionWithComputedName(
   3112    ParseNode* node, FunctionPrefixKind prefixKind) {
   3113  MOZ_ASSERT(node->isDirectRHSAnonFunction());
   3114 
   3115  if (node->is<FunctionNode>()) {
   3116    if (!emitTree(node)) {
   3117      //            [stack] NAME FUN
   3118      return false;
   3119    }
   3120    if (!emitDupAt(1)) {
   3121      //            [stack] NAME FUN NAME
   3122      return false;
   3123    }
   3124    if (!emit2(JSOp::SetFunName, uint8_t(prefixKind))) {
   3125      //            [stack] NAME FUN
   3126      return false;
   3127    }
   3128    return true;
   3129  }
   3130 
   3131  MOZ_ASSERT(node->is<ClassNode>());
   3132  MOZ_ASSERT(prefixKind == FunctionPrefixKind::None);
   3133 
   3134  return emitClass(&node->as<ClassNode>(), ClassNameKind::ComputedName);
   3135 }
   3136 
   3137 void BytecodeEmitter::setFunName(FunctionBox* funbox,
   3138                                 TaggedParserAtomIndex name) const {
   3139  // The inferred name may already be set if this function is an interpreted
   3140  // lazy function and we OOM'ed after we set the inferred name the first
   3141  // time.
   3142  if (funbox->hasInferredName()) {
   3143    MOZ_ASSERT(!funbox->emitBytecode);
   3144    MOZ_ASSERT(funbox->displayAtom() == name);
   3145  } else {
   3146    funbox->setInferredName(name);
   3147  }
   3148 }
   3149 
   3150 bool BytecodeEmitter::emitInitializer(ParseNode* initializer,
   3151                                      ParseNode* pattern) {
   3152  if (initializer->isDirectRHSAnonFunction()) {
   3153    MOZ_ASSERT(!pattern->isInParens());
   3154    auto name = pattern->as<NameNode>().name();
   3155    if (!emitAnonymousFunctionWithName(initializer, name)) {
   3156      return false;
   3157    }
   3158  } else {
   3159    if (!emitTree(initializer)) {
   3160      return false;
   3161    }
   3162  }
   3163 
   3164  return true;
   3165 }
   3166 
   3167 bool BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern,
   3168                                                DestructuringFlavor flav,
   3169                                                SelfHostedIter selfHostedIter) {
   3170  MOZ_ASSERT(pattern->isKind(ParseNodeKind::ArrayExpr));
   3171  MOZ_ASSERT(bytecodeSection().stackDepth() != 0);
   3172 
   3173  // Here's pseudo code for |let [a, b, , c=y, ...d] = x;|
   3174  //
   3175  // Lines that are annotated "covered by trynote" mean that upon throwing
   3176  // an exception, IteratorClose is called on iter only if done is false.
   3177  //
   3178  //   let x, y;
   3179  //   let a, b, c, d;
   3180  //   let iter, next, lref, result, done, value; // stack values
   3181  //
   3182  //   // NOTE: the fast path for this example is not applicable, because of
   3183  //   // the spread and the assignment |c=y|, but it is documented here for a
   3184  //   // simpler example, |let [a,b] = x;|
   3185  //   //
   3186  //   // if (IsOptimizableArray(x)) {
   3187  //   //   a = x[0];
   3188  //   //   b = x[1];
   3189  //   //   goto end: // (skip everything below)
   3190  //   // }
   3191  //
   3192  //   iter = x[Symbol.iterator]();
   3193  //   next = iter.next;
   3194  //
   3195  //   // ==== emitted by loop for a ====
   3196  //   lref = GetReference(a);              // covered by trynote
   3197  //
   3198  //   result = Call(next, iter);
   3199  //   done = result.done;
   3200  //
   3201  //   if (done)
   3202  //     value = undefined;
   3203  //   else
   3204  //     value = result.value;
   3205  //
   3206  //   SetOrInitialize(lref, value);        // covered by trynote
   3207  //
   3208  //   // ==== emitted by loop for b ====
   3209  //   lref = GetReference(b);              // covered by trynote
   3210  //
   3211  //   if (done) {
   3212  //     value = undefined;
   3213  //   } else {
   3214  //     result = Call(next, iter);
   3215  //     done = result.done;
   3216  //     if (done)
   3217  //       value = undefined;
   3218  //     else
   3219  //       value = result.value;
   3220  //   }
   3221  //
   3222  //   SetOrInitialize(lref, value);        // covered by trynote
   3223  //
   3224  //   // ==== emitted by loop for elision ====
   3225  //   if (done) {
   3226  //     value = undefined;
   3227  //   } else {
   3228  //     result = Call(next, iter);
   3229  //     done = result.done;
   3230  //     if (done)
   3231  //       value = undefined;
   3232  //     else
   3233  //       value = result.value;
   3234  //   }
   3235  //
   3236  //   // ==== emitted by loop for c ====
   3237  //   lref = GetReference(c);              // covered by trynote
   3238  //
   3239  //   if (done) {
   3240  //     value = undefined;
   3241  //   } else {
   3242  //     result = Call(next, iter);
   3243  //     done = result.done;
   3244  //     if (done)
   3245  //       value = undefined;
   3246  //     else
   3247  //       value = result.value;
   3248  //   }
   3249  //
   3250  //   if (value === undefined)
   3251  //     value = y;                         // covered by trynote
   3252  //
   3253  //   SetOrInitialize(lref, value);        // covered by trynote
   3254  //
   3255  //   // ==== emitted by loop for d ====
   3256  //   lref = GetReference(d);              // covered by trynote
   3257  //
   3258  //   if (done)
   3259  //     value = [];
   3260  //   else
   3261  //     value = [...iter];
   3262  //
   3263  //   SetOrInitialize(lref, value);        // covered by trynote
   3264  //
   3265  //   // === emitted after loop ===
   3266  //   if (!done)
   3267  //      IteratorClose(iter);
   3268  //
   3269  //   end:
   3270 
   3271  bool isEligibleForArrayOptimizations = true;
   3272  for (ParseNode* member : pattern->contents()) {
   3273    switch (member->getKind()) {
   3274      case ParseNodeKind::Elision:
   3275        break;
   3276      case ParseNodeKind::Name: {
   3277        auto name = member->as<NameNode>().name();
   3278        NameLocation loc = lookupName(name);
   3279        if (loc.kind() != NameLocation::Kind::ArgumentSlot &&
   3280            loc.kind() != NameLocation::Kind::FrameSlot &&
   3281            loc.kind() != NameLocation::Kind::EnvironmentCoordinate) {
   3282          isEligibleForArrayOptimizations = false;
   3283        }
   3284        break;
   3285      }
   3286      default:
   3287        // Unfortunately we can't handle any recursive destructuring,
   3288        // because we can't guarantee that the recursed-into parts
   3289        // won't run code which invalidates our constraints. We also
   3290        // cannot handle ParseNodeKind::AssignExpr for similar reasons.
   3291        isEligibleForArrayOptimizations = false;
   3292        break;
   3293    }
   3294    if (!isEligibleForArrayOptimizations) {
   3295      break;
   3296    }
   3297  }
   3298 
   3299  // Use an iterator to destructure the RHS, instead of index lookup. We
   3300  // must leave the *original* value on the stack.
   3301  if (!emit1(JSOp::Dup)) {
   3302    //              [stack] ... OBJ OBJ
   3303    return false;
   3304  }
   3305 
   3306  Maybe<InternalIfEmitter> ifArrayOptimizable;
   3307 
   3308  if (isEligibleForArrayOptimizations) {
   3309    ifArrayOptimizable.emplace(
   3310        this, BranchEmitterBase::LexicalKind::MayContainLexicalAccessInBranch);
   3311 
   3312    if (!emit1(JSOp::Dup)) {
   3313      //            [stack] OBJ OBJ
   3314      return false;
   3315    }
   3316 
   3317    if (!emit1(JSOp::OptimizeGetIterator)) {
   3318      //            [stack] OBJ OBJ IS_OPTIMIZABLE
   3319      return false;
   3320    }
   3321 
   3322    if (!ifArrayOptimizable->emitThenElse()) {
   3323      //            [stack] OBJ OBJ
   3324      return false;
   3325    }
   3326 
   3327    if (!emitAtomOp(JSOp::GetProp,
   3328                    TaggedParserAtomIndex::WellKnown::length())) {
   3329      //            [stack] OBJ LENGTH
   3330      return false;
   3331    }
   3332 
   3333    if (!emit1(JSOp::Swap)) {
   3334      //            [stack] LENGTH OBJ
   3335      return false;
   3336    }
   3337 
   3338    uint32_t idx = 0;
   3339    for (ParseNode* member : pattern->contents()) {
   3340      if (member->isKind(ParseNodeKind::Elision)) {
   3341        idx += 1;
   3342        continue;
   3343      }
   3344      MOZ_ASSERT(member->isKind(ParseNodeKind::Name));
   3345 
   3346      if (!emit1(JSOp::Dup)) {
   3347        //          [stack] LENGTH OBJ OBJ
   3348        return false;
   3349      }
   3350 
   3351      if (!emitNumberOp(idx)) {
   3352        //          [stack] LENGTH OBJ OBJ IDX
   3353        return false;
   3354      }
   3355 
   3356      if (!emit1(JSOp::Dup)) {
   3357        //          [stack] LENGTH OBJ OBJ IDX IDX
   3358        return false;
   3359      }
   3360 
   3361      if (!emitDupAt(4)) {
   3362        //          [stack] LENGTH OBJ OBJ IDX IDX LENGTH
   3363        return false;
   3364      }
   3365 
   3366      if (!emit1(JSOp::Lt)) {
   3367        //          [stack] LENGTH OBJ OBJ IDX IS_IN_DENSE_BOUNDS
   3368        return false;
   3369      }
   3370 
   3371      InternalIfEmitter isInDenseBounds(this);
   3372      if (!isInDenseBounds.emitThenElse()) {
   3373        //          [stack] LENGTH OBJ OBJ IDX
   3374        return false;
   3375      }
   3376 
   3377      if (!emit1(JSOp::GetElem)) {
   3378        //          [stack] LENGTH OBJ VALUE
   3379        return false;
   3380      }
   3381 
   3382      if (!isInDenseBounds.emitElse()) {
   3383        //          [stack] LENGTH OBJ OBJ IDX
   3384        return false;
   3385      }
   3386 
   3387      if (!emitPopN(2)) {
   3388        //          [stack] LENGTH OBJ
   3389        return false;
   3390      }
   3391 
   3392      if (!emit1(JSOp::Undefined)) {
   3393        //          [stack] LENGTH OBJ UNDEFINED
   3394        return false;
   3395      }
   3396 
   3397      if (!isInDenseBounds.emitEnd()) {
   3398        //          [stack] LENGTH OBJ VALUE|UNDEFINED
   3399        return false;
   3400      }
   3401 
   3402      DestructuringLHSRef lref;
   3403      if (!emitDestructuringLHSRef(member, flav, lref)) {
   3404        //          [stack] LENGTH OBJ
   3405        return false;
   3406      }
   3407 
   3408      if (!emitSetOrInitializeDestructuring(member, flav, lref)) {
   3409        //          [stack] LENGTH OBJ
   3410        return false;
   3411      }
   3412 
   3413      idx += 1;
   3414    }
   3415 
   3416    if (!emit1(JSOp::Swap)) {
   3417      //            [stack] OBJ LENGTH
   3418      return false;
   3419    }
   3420 
   3421    if (!emit1(JSOp::Pop)) {
   3422      //            [stack] OBJ
   3423      return false;
   3424    }
   3425 
   3426    if (!ifArrayOptimizable->emitElse()) {
   3427      //            [stack] OBJ OBJ
   3428      return false;
   3429    }
   3430  }
   3431 
   3432  if (!emitIterator(selfHostedIter)) {
   3433    //              [stack] ... OBJ NEXT ITER
   3434    return false;
   3435  }
   3436 
   3437  // For an empty pattern [], call IteratorClose unconditionally. Nothing
   3438  // else needs to be done.
   3439  if (!pattern->head()) {
   3440    if (!emit1(JSOp::Swap)) {
   3441      //            [stack] ... OBJ ITER NEXT
   3442      return false;
   3443    }
   3444    if (!emit1(JSOp::Pop)) {
   3445      //            [stack] ... OBJ ITER
   3446      return false;
   3447    }
   3448 
   3449    if (!emitIteratorCloseInInnermostScope(
   3450            IteratorKind::Sync, CompletionKind::Normal, selfHostedIter)) {
   3451      //            [stack] ... OBJ
   3452      return false;
   3453    }
   3454 
   3455    if (ifArrayOptimizable.isSome()) {
   3456      if (!ifArrayOptimizable->emitEnd()) {
   3457        //          [stack] OBJ
   3458        return false;
   3459      }
   3460    }
   3461 
   3462    return true;
   3463  }
   3464 
   3465  // Push an initial FALSE value for DONE.
   3466  if (!emit1(JSOp::False)) {
   3467    //              [stack] ... OBJ NEXT ITER FALSE
   3468    return false;
   3469  }
   3470 
   3471  // TryNoteKind::Destructuring expects the iterator and the done value
   3472  // to be the second to top and the top of the stack, respectively.
   3473  // IteratorClose is called upon exception only if done is false.
   3474  int32_t tryNoteDepth = bytecodeSection().stackDepth();
   3475 
   3476  for (ParseNode* member : pattern->contents()) {
   3477    bool isFirst = member == pattern->head();
   3478    DebugOnly<bool> hasNext = !!member->pn_next;
   3479 
   3480    ParseNode* subpattern;
   3481    if (member->isKind(ParseNodeKind::Spread)) {
   3482      subpattern = member->as<UnaryNode>().kid();
   3483 
   3484      MOZ_ASSERT(!subpattern->isKind(ParseNodeKind::AssignExpr));
   3485    } else {
   3486      subpattern = member;
   3487    }
   3488 
   3489    ParseNode* lhsPattern = subpattern;
   3490    ParseNode* pndefault = nullptr;
   3491    if (subpattern->isKind(ParseNodeKind::AssignExpr)) {
   3492      lhsPattern = subpattern->as<AssignmentNode>().left();
   3493      pndefault = subpattern->as<AssignmentNode>().right();
   3494    }
   3495 
   3496    // Spec requires LHS reference to be evaluated first.
   3497    DestructuringLHSRef lref;
   3498    bool isElision = lhsPattern->isKind(ParseNodeKind::Elision);
   3499    if (!isElision) {
   3500      auto emitLHSRef = [lhsPattern, flav, &lref](BytecodeEmitter* bce) {
   3501        return bce->emitDestructuringLHSRef(lhsPattern, flav, lref);
   3502        //          [stack] ... OBJ NEXT ITER DONE LREF*
   3503      };
   3504      if (!wrapWithDestructuringTryNote(tryNoteDepth, emitLHSRef)) {
   3505        return false;
   3506      }
   3507    }
   3508 
   3509    // Number of stack slots emitted for the LHS reference.
   3510    size_t emitted = lref.numReferenceSlots();
   3511 
   3512    // Pick the DONE value to the top of the stack.
   3513    if (emitted) {
   3514      if (!emitPickN(emitted)) {
   3515        //          [stack] ... OBJ NEXT ITER LREF* DONE
   3516        return false;
   3517      }
   3518    }
   3519 
   3520    if (isFirst) {
   3521      // If this element is the first, DONE is always FALSE, so pop it.
   3522      //
   3523      // Non-first elements should emit if-else depending on the
   3524      // member pattern, below.
   3525      if (!emit1(JSOp::Pop)) {
   3526        //          [stack] ... OBJ NEXT ITER LREF*
   3527        return false;
   3528      }
   3529    }
   3530 
   3531    if (member->isKind(ParseNodeKind::Spread)) {
   3532      InternalIfEmitter ifThenElse(this);
   3533      if (!isFirst) {
   3534        // If spread is not the first element of the pattern,
   3535        // iterator can already be completed.
   3536        //          [stack] ... OBJ NEXT ITER LREF* DONE
   3537 
   3538        if (!ifThenElse.emitThenElse()) {
   3539          //        [stack] ... OBJ NEXT ITER LREF*
   3540          return false;
   3541        }
   3542 
   3543        if (!emitUint32Operand(JSOp::NewArray, 0)) {
   3544          //        [stack] ... OBJ NEXT ITER LREF* ARRAY
   3545          return false;
   3546        }
   3547        if (!ifThenElse.emitElse()) {
   3548          //        [stack] ... OBJ NEXT ITER LREF*
   3549          return false;
   3550        }
   3551      }
   3552 
   3553      // If iterator is not completed, create a new array with the rest
   3554      // of the iterator.
   3555      if (!emitDupAt(emitted + 1, 2)) {
   3556        //          [stack] ... OBJ NEXT ITER LREF* NEXT ITER
   3557        return false;
   3558      }
   3559      if (!emitUint32Operand(JSOp::NewArray, 0)) {
   3560        //          [stack] ... OBJ NEXT ITER LREF* NEXT ITER ARRAY
   3561        return false;
   3562      }
   3563      if (!emitNumberOp(0)) {
   3564        //          [stack] ... OBJ NEXT ITER LREF* NEXT ITER ARRAY INDEX
   3565        return false;
   3566      }
   3567      if (!emitSpread(SelfHostedIter::Deny)) {
   3568        //          [stack] ... OBJ NEXT ITER LREF* ARRAY INDEX
   3569        return false;
   3570      }
   3571      if (!emit1(JSOp::Pop)) {
   3572        //          [stack] ... OBJ NEXT ITER LREF* ARRAY
   3573        return false;
   3574      }
   3575 
   3576      if (!isFirst) {
   3577        if (!ifThenElse.emitEnd()) {
   3578          return false;
   3579        }
   3580        MOZ_ASSERT(ifThenElse.pushed() == 1);
   3581      }
   3582 
   3583      // At this point the iterator is done. Unpick a TRUE value for DONE above
   3584      // ITER.
   3585      if (!emit1(JSOp::True)) {
   3586        //          [stack] ... OBJ NEXT ITER LREF* ARRAY TRUE
   3587        return false;
   3588      }
   3589      if (!emitUnpickN(emitted + 1)) {
   3590        //          [stack] ... OBJ NEXT ITER TRUE LREF* ARRAY
   3591        return false;
   3592      }
   3593 
   3594      auto emitAssignment = [lhsPattern, flav, &lref](BytecodeEmitter* bce) {
   3595        return bce->emitSetOrInitializeDestructuring(lhsPattern, flav, lref);
   3596        //          [stack] ... OBJ NEXT ITER TRUE
   3597      };
   3598      if (!wrapWithDestructuringTryNote(tryNoteDepth, emitAssignment)) {
   3599        return false;
   3600      }
   3601 
   3602      MOZ_ASSERT(!hasNext);
   3603      break;
   3604    }
   3605 
   3606    InternalIfEmitter ifAlreadyDone(this);
   3607    if (!isFirst) {
   3608      //            [stack] ... OBJ NEXT ITER LREF* DONE
   3609 
   3610      if (!ifAlreadyDone.emitThenElse()) {
   3611        //          [stack] ... OBJ NEXT ITER LREF*
   3612        return false;
   3613      }
   3614 
   3615      if (!emit1(JSOp::Undefined)) {
   3616        //          [stack] ... OBJ NEXT ITER LREF* UNDEF
   3617        return false;
   3618      }
   3619      if (!emit1(JSOp::NopDestructuring)) {
   3620        //          [stack] ... OBJ NEXT ITER LREF* UNDEF
   3621        return false;
   3622      }
   3623 
   3624      // The iterator is done. Unpick a TRUE value for DONE above ITER.
   3625      if (!emit1(JSOp::True)) {
   3626        //          [stack] ... OBJ NEXT ITER LREF* UNDEF TRUE
   3627        return false;
   3628      }
   3629      if (!emitUnpickN(emitted + 1)) {
   3630        //          [stack] ... OBJ NEXT ITER TRUE LREF* UNDEF
   3631        return false;
   3632      }
   3633 
   3634      if (!ifAlreadyDone.emitElse()) {
   3635        //          [stack] ... OBJ NEXT ITER LREF*
   3636        return false;
   3637      }
   3638    }
   3639 
   3640    if (!emitDupAt(emitted + 1, 2)) {
   3641      //            [stack] ... OBJ NEXT ITER LREF* NEXT
   3642      return false;
   3643    }
   3644    if (!emitIteratorNext(Some(pattern->pn_pos.begin), IteratorKind::Sync,
   3645                          selfHostedIter)) {
   3646      //            [stack] ... OBJ NEXT ITER LREF* RESULT
   3647      return false;
   3648    }
   3649    if (!emit1(JSOp::Dup)) {
   3650      //            [stack] ... OBJ NEXT ITER LREF* RESULT RESULT
   3651      return false;
   3652    }
   3653    if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::done())) {
   3654      //            [stack] ... OBJ NEXT ITER LREF* RESULT DONE
   3655      return false;
   3656    }
   3657 
   3658    if (!emit1(JSOp::Dup)) {
   3659      //            [stack] ... OBJ NEXT ITER LREF* RESULT DONE DONE
   3660      return false;
   3661    }
   3662    if (!emitUnpickN(emitted + 2)) {
   3663      //            [stack] ... OBJ NEXT ITER DONE LREF* RESULT DONE
   3664      return false;
   3665    }
   3666 
   3667    InternalIfEmitter ifDone(this);
   3668    if (!ifDone.emitThenElse()) {
   3669      //            [stack] ... OBJ NEXT ITER DONE LREF* RESULT
   3670      return false;
   3671    }
   3672 
   3673    if (!emit1(JSOp::Pop)) {
   3674      //            [stack] ... OBJ NEXT ITER DONE LREF*
   3675      return false;
   3676    }
   3677    if (!emit1(JSOp::Undefined)) {
   3678      //            [stack] ... OBJ NEXT ITER DONE LREF* UNDEF
   3679      return false;
   3680    }
   3681    if (!emit1(JSOp::NopDestructuring)) {
   3682      //            [stack] ... OBJ NEXT ITER DONE LREF* UNDEF
   3683      return false;
   3684    }
   3685 
   3686    if (!ifDone.emitElse()) {
   3687      //            [stack] ... OBJ NEXT ITER DONE LREF* RESULT
   3688      return false;
   3689    }
   3690 
   3691    if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::value())) {
   3692      //            [stack] ... OBJ NEXT ITER DONE LREF* VALUE
   3693      return false;
   3694    }
   3695 
   3696    if (!ifDone.emitEnd()) {
   3697      return false;
   3698    }
   3699    MOZ_ASSERT(ifDone.pushed() == 0);
   3700 
   3701    if (!isFirst) {
   3702      if (!ifAlreadyDone.emitEnd()) {
   3703        return false;
   3704      }
   3705      MOZ_ASSERT(ifAlreadyDone.pushed() == 2);
   3706    }
   3707 
   3708    if (pndefault) {
   3709      auto emitDefault = [pndefault, lhsPattern](BytecodeEmitter* bce) {
   3710        return bce->emitDefault(pndefault, lhsPattern);
   3711        //          [stack] ... OBJ NEXT ITER DONE LREF* VALUE
   3712      };
   3713 
   3714      if (!wrapWithDestructuringTryNote(tryNoteDepth, emitDefault)) {
   3715        return false;
   3716      }
   3717    }
   3718 
   3719    if (!isElision) {
   3720      auto emitAssignment = [lhsPattern, flav, &lref](BytecodeEmitter* bce) {
   3721        return bce->emitSetOrInitializeDestructuring(lhsPattern, flav, lref);
   3722        //          [stack] ... OBJ NEXT ITER DONE
   3723      };
   3724 
   3725      if (!wrapWithDestructuringTryNote(tryNoteDepth, emitAssignment)) {
   3726        return false;
   3727      }
   3728    } else {
   3729      if (!emit1(JSOp::Pop)) {
   3730        //          [stack] ... OBJ NEXT ITER DONE
   3731        return false;
   3732      }
   3733    }
   3734  }
   3735 
   3736  // The last DONE value is on top of the stack. If not DONE, call
   3737  // IteratorClose.
   3738  //                [stack] ... OBJ NEXT ITER DONE
   3739 
   3740  InternalIfEmitter ifDone(this);
   3741  if (!ifDone.emitThenElse()) {
   3742    //              [stack] ... OBJ NEXT ITER
   3743    return false;
   3744  }
   3745  if (!emitPopN(2)) {
   3746    //              [stack] ... OBJ
   3747    return false;
   3748  }
   3749  if (!ifDone.emitElse()) {
   3750    //              [stack] ... OBJ NEXT ITER
   3751    return false;
   3752  }
   3753  if (!emit1(JSOp::Swap)) {
   3754    //              [stack] ... OBJ ITER NEXT
   3755    return false;
   3756  }
   3757  if (!emit1(JSOp::Pop)) {
   3758    //              [stack] ... OBJ ITER
   3759    return false;
   3760  }
   3761  if (!emitIteratorCloseInInnermostScope(
   3762          IteratorKind::Sync, CompletionKind::Normal, selfHostedIter)) {
   3763    //              [stack] ... OBJ
   3764    return false;
   3765  }
   3766  if (!ifDone.emitEnd()) {
   3767    return false;
   3768  }
   3769 
   3770  if (ifArrayOptimizable.isSome()) {
   3771    if (!ifArrayOptimizable->emitEnd()) {
   3772      //            [stack] OBJ
   3773      return false;
   3774    }
   3775  }
   3776 
   3777  return true;
   3778 }
   3779 
   3780 bool BytecodeEmitter::emitComputedPropertyName(UnaryNode* computedPropName) {
   3781  MOZ_ASSERT(computedPropName->isKind(ParseNodeKind::ComputedName));
   3782  return emitTree(computedPropName->kid()) && emit1(JSOp::ToPropertyKey);
   3783 }
   3784 
   3785 bool BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern,
   3786                                                 DestructuringFlavor flav) {
   3787  MOZ_ASSERT(pattern->isKind(ParseNodeKind::ObjectExpr));
   3788 
   3789  //                [stack] ... RHS
   3790  MOZ_ASSERT(bytecodeSection().stackDepth() > 0);
   3791 
   3792  if (!emit1(JSOp::CheckObjCoercible)) {
   3793    //              [stack] ... RHS
   3794    return false;
   3795  }
   3796 
   3797  // To understand why we chose '4', please see the discussion on Bug 1948959.
   3798  const uint8_t estimatedRestSize = 4;
   3799 
   3800  bool needsRestPropertyExcludedSet =
   3801      pattern->count() > 1 && pattern->last()->isKind(ParseNodeKind::Spread);
   3802  if (needsRestPropertyExcludedSet) {
   3803    if (!emitDestructuringObjRestExclusionSet(pattern, estimatedRestSize)) {
   3804      //            [stack] ... RHS SET
   3805      return false;
   3806    }
   3807 
   3808    if (!emit1(JSOp::Swap)) {
   3809      //            [stack] ... SET RHS
   3810      return false;
   3811    }
   3812  }
   3813 
   3814  for (ParseNode* member : pattern->contents()) {
   3815    ParseNode* subpattern;
   3816    bool hasKeyOnStack = false;
   3817    if (member->isKind(ParseNodeKind::MutateProto) ||
   3818        member->isKind(ParseNodeKind::Spread)) {
   3819      subpattern = member->as<UnaryNode>().kid();
   3820 
   3821      MOZ_ASSERT_IF(member->isKind(ParseNodeKind::Spread),
   3822                    !subpattern->isKind(ParseNodeKind::AssignExpr));
   3823    } else {
   3824      MOZ_ASSERT(member->isKind(ParseNodeKind::PropertyDefinition) ||
   3825                 member->isKind(ParseNodeKind::Shorthand));
   3826      subpattern = member->as<BinaryNode>().right();
   3827 
   3828      // Computed property names are evaluated before the subpattern.
   3829      ParseNode* key = member->as<BinaryNode>().left();
   3830      if (key->isKind(ParseNodeKind::ComputedName)) {
   3831        if (!emitComputedPropertyName(&key->as<UnaryNode>())) {
   3832          //        [stack] ... SET? RHS KEY
   3833          return false;
   3834        }
   3835        hasKeyOnStack = true;
   3836      }
   3837    }
   3838 
   3839    ParseNode* lhs = subpattern;
   3840    ParseNode* pndefault = nullptr;
   3841    if (subpattern->isKind(ParseNodeKind::AssignExpr)) {
   3842      lhs = subpattern->as<AssignmentNode>().left();
   3843      pndefault = subpattern->as<AssignmentNode>().right();
   3844    }
   3845 
   3846    // Spec requires LHS reference to be evaluated first.
   3847    DestructuringLHSRef lref;
   3848    if (!emitDestructuringLHSRef(lhs, flav, lref)) {
   3849      //            [stack] ... SET? RHS KEY? LREF*
   3850      return false;
   3851    }
   3852 
   3853    // Number of stack slots emitted for the LHS reference.
   3854    size_t emitted = lref.numReferenceSlots();
   3855 
   3856    // Duplicate the value being destructured to use as a reference base.
   3857    if (!emitDupAt(emitted + hasKeyOnStack)) {
   3858      //            [stack] ... SET? RHS KEY? LREF* RHS
   3859      return false;
   3860    }
   3861 
   3862    if (member->isKind(ParseNodeKind::Spread)) {
   3863      if (!updateSourceCoordNotes(member->pn_pos.begin)) {
   3864        return false;
   3865      }
   3866 
   3867      if (!emit2(JSOp::NewInit, estimatedRestSize)) {
   3868        //          [stack] ... SET? RHS LREF* RHS TARGET
   3869        return false;
   3870      }
   3871      if (!emit1(JSOp::Dup)) {
   3872        //          [stack] ... SET? RHS LREF* RHS TARGET TARGET
   3873        return false;
   3874      }
   3875      if (!emit2(JSOp::Pick, 2)) {
   3876        //          [stack] ... SET? RHS LREF* TARGET TARGET RHS
   3877        return false;
   3878      }
   3879 
   3880      if (needsRestPropertyExcludedSet) {
   3881        if (!emit2(JSOp::Pick, emitted + 4)) {
   3882          //        [stack] ... RHS LREF* TARGET TARGET RHS SET
   3883          return false;
   3884        }
   3885      }
   3886 
   3887      CopyOption option = needsRestPropertyExcludedSet ? CopyOption::Filtered
   3888                                                       : CopyOption::Unfiltered;
   3889      if (!emitCopyDataProperties(option)) {
   3890        //          [stack] ... RHS LREF* TARGET
   3891        return false;
   3892      }
   3893 
   3894      // Destructure TARGET per this member's lhs.
   3895      if (!emitSetOrInitializeDestructuring(lhs, flav, lref)) {
   3896        //          [stack] ... RHS
   3897        return false;
   3898      }
   3899 
   3900      MOZ_ASSERT(member == pattern->last(), "Rest property is always last");
   3901      break;
   3902    }
   3903 
   3904    // Now push the property value currently being matched, which is the value
   3905    // of the current property name "label" on the left of a colon in the object
   3906    // initialiser.
   3907    if (member->isKind(ParseNodeKind::MutateProto)) {
   3908      if (!emitAtomOp(JSOp::GetProp,
   3909                      TaggedParserAtomIndex::WellKnown::proto_())) {
   3910        //          [stack] ... SET? RHS LREF* PROP
   3911        return false;
   3912      }
   3913    } else {
   3914      MOZ_ASSERT(member->isKind(ParseNodeKind::PropertyDefinition) ||
   3915                 member->isKind(ParseNodeKind::Shorthand));
   3916 
   3917      ParseNode* key = member->as<BinaryNode>().left();
   3918      if (key->isKind(ParseNodeKind::ObjectPropertyName) ||
   3919          key->isKind(ParseNodeKind::StringExpr)) {
   3920        if (!emitAtomOp(JSOp::GetProp, key->as<NameNode>().atom())) {
   3921          //        [stack] ... SET? RHS LREF* PROP
   3922          return false;
   3923        }
   3924      } else {
   3925        if (key->isKind(ParseNodeKind::NumberExpr)) {
   3926          if (!emitNumberOp(key->as<NumericLiteral>().value())) {
   3927            //      [stack]... SET? RHS LREF* RHS KEY
   3928            return false;
   3929          }
   3930        } else {
   3931          // Otherwise this is a computed property name. BigInt keys are parsed
   3932          // as (synthetic) computed property names, too.
   3933          MOZ_ASSERT(key->isKind(ParseNodeKind::ComputedName));
   3934          MOZ_ASSERT(hasKeyOnStack);
   3935 
   3936          if (!emit2(JSOp::Pick, emitted + 1)) {
   3937            //      [stack] ... SET? RHS LREF* RHS KEY
   3938            return false;
   3939          }
   3940 
   3941          // Add the computed property key to the exclusion set.
   3942          if (needsRestPropertyExcludedSet) {
   3943            if (!emitDupAt(emitted + 3)) {
   3944              //    [stack] ... SET RHS LREF* RHS KEY SET
   3945              return false;
   3946            }
   3947            if (!emitDupAt(1)) {
   3948              //    [stack] ... SET RHS LREF* RHS KEY SET KEY
   3949              return false;
   3950            }
   3951            if (!emit1(JSOp::Undefined)) {
   3952              //    [stack] ... SET RHS LREF* RHS KEY SET KEY UNDEFINED
   3953              return false;
   3954            }
   3955            if (!emit1(JSOp::InitElem)) {
   3956              //    [stack] ... SET RHS LREF* RHS KEY SET
   3957              return false;
   3958            }
   3959            if (!emit1(JSOp::Pop)) {
   3960              //    [stack] ... SET RHS LREF* RHS KEY
   3961              return false;
   3962            }
   3963          }
   3964        }
   3965 
   3966        // Get the property value.
   3967        if (!emitElemOpBase(JSOp::GetElem)) {
   3968          //        [stack] ... SET? RHS LREF* PROP
   3969          return false;
   3970        }
   3971      }
   3972    }
   3973 
   3974    if (pndefault) {
   3975      if (!emitDefault(pndefault, lhs)) {
   3976        //          [stack] ... SET? RHS LREF* VALUE
   3977        return false;
   3978      }
   3979    }
   3980 
   3981    // Destructure PROP per this member's lhs.
   3982    if (!emitSetOrInitializeDestructuring(lhs, flav, lref)) {
   3983      //            [stack] ... SET? RHS
   3984      return false;
   3985    }
   3986  }
   3987 
   3988  return true;
   3989 }
   3990 
   3991 static bool IsDestructuringRestExclusionSetObjLiteralCompatible(
   3992    ListNode* pattern) {
   3993  uint32_t propCount = 0;
   3994  for (ParseNode* member : pattern->contents()) {
   3995    if (member->isKind(ParseNodeKind::Spread)) {
   3996      MOZ_ASSERT(!member->pn_next, "unexpected trailing element after spread");
   3997      break;
   3998    }
   3999 
   4000    propCount++;
   4001 
   4002    if (member->isKind(ParseNodeKind::MutateProto)) {
   4003      continue;
   4004    }
   4005 
   4006    ParseNode* key = member->as<BinaryNode>().left();
   4007    if (key->isKind(ParseNodeKind::ObjectPropertyName) ||
   4008        key->isKind(ParseNodeKind::StringExpr)) {
   4009      continue;
   4010    }
   4011 
   4012    // Number and BigInt keys aren't yet supported. Computed property names need
   4013    // to be added dynamically.
   4014    MOZ_ASSERT(key->isKind(ParseNodeKind::NumberExpr) ||
   4015               key->isKind(ParseNodeKind::BigIntExpr) ||
   4016               key->isKind(ParseNodeKind::ComputedName));
   4017    return false;
   4018  }
   4019 
   4020  if (propCount > SharedPropMap::MaxPropsForNonDictionary) {
   4021    // JSOp::NewObject cannot accept dictionary-mode objects.
   4022    return false;
   4023  }
   4024 
   4025  return true;
   4026 }
   4027 
   4028 bool BytecodeEmitter::emitDestructuringObjRestExclusionSet(
   4029    ListNode* pattern, uint8_t estimatedRestSize) {
   4030  MOZ_ASSERT(pattern->isKind(ParseNodeKind::ObjectExpr));
   4031  MOZ_ASSERT(pattern->last()->isKind(ParseNodeKind::Spread));
   4032 
   4033  // See if we can use ObjLiteral to construct the exclusion set object.
   4034  if (IsDestructuringRestExclusionSetObjLiteralCompatible(pattern)) {
   4035    if (!emitDestructuringRestExclusionSetObjLiteral(pattern)) {
   4036      //            [stack] OBJ
   4037      return false;
   4038    }
   4039  } else {
   4040    // Take the slow but sure way and start off with a blank object.
   4041    if (!emit2(JSOp::NewInit, estimatedRestSize)) {
   4042      //            [stack] OBJ
   4043      return false;
   4044    }
   4045  }
   4046 
   4047  for (ParseNode* member : pattern->contents()) {
   4048    if (member->isKind(ParseNodeKind::Spread)) {
   4049      MOZ_ASSERT(!member->pn_next, "unexpected trailing element after spread");
   4050      break;
   4051    }
   4052 
   4053    TaggedParserAtomIndex pnatom;
   4054    if (member->isKind(ParseNodeKind::MutateProto)) {
   4055      pnatom = TaggedParserAtomIndex::WellKnown::proto_();
   4056    } else {
   4057      ParseNode* key = member->as<BinaryNode>().left();
   4058      if (key->isKind(ParseNodeKind::ObjectPropertyName) ||
   4059          key->isKind(ParseNodeKind::StringExpr)) {
   4060        pnatom = key->as<NameNode>().atom();
   4061      } else if (key->isKind(ParseNodeKind::NumberExpr)) {
   4062        if (!emitNumberOp(key->as<NumericLiteral>().value())) {
   4063          return false;
   4064        }
   4065      } else {
   4066        // Otherwise this is a computed property name which needs to be added
   4067        // dynamically. BigInt keys are parsed as (synthetic) computed property
   4068        // names, too.
   4069        MOZ_ASSERT(key->isKind(ParseNodeKind::ComputedName));
   4070        continue;
   4071      }
   4072    }
   4073 
   4074    // Initialize elements with |undefined|.
   4075    if (!emit1(JSOp::Undefined)) {
   4076      return false;
   4077    }
   4078 
   4079    if (!pnatom) {
   4080      if (!emit1(JSOp::InitElem)) {
   4081        return false;
   4082      }
   4083    } else {
   4084      if (!emitAtomOp(JSOp::InitProp, pnatom)) {
   4085        return false;
   4086      }
   4087    }
   4088  }
   4089 
   4090  return true;
   4091 }
   4092 
   4093 bool BytecodeEmitter::emitDestructuringOps(ListNode* pattern,
   4094                                           DestructuringFlavor flav,
   4095                                           SelfHostedIter selfHostedIter) {
   4096  if (pattern->isKind(ParseNodeKind::ArrayExpr)) {
   4097    return emitDestructuringOpsArray(pattern, flav, selfHostedIter);
   4098  }
   4099  return emitDestructuringOpsObject(pattern, flav);
   4100 }
   4101 
   4102 bool BytecodeEmitter::emitTemplateString(ListNode* templateString) {
   4103  bool pushedString = false;
   4104 
   4105  for (ParseNode* item : templateString->contents()) {
   4106    bool isString = (item->getKind() == ParseNodeKind::StringExpr ||
   4107                     item->getKind() == ParseNodeKind::TemplateStringExpr);
   4108 
   4109    // Skip empty strings. These are very common: a template string like
   4110    // `${a}${b}` has three empty strings and without this optimization
   4111    // we'd emit four JSOp::Add operations instead of just one.
   4112    if (isString && item->as<NameNode>().atom() ==
   4113                        TaggedParserAtomIndex::WellKnown::empty()) {
   4114      continue;
   4115    }
   4116 
   4117    if (!isString) {
   4118      // We update source notes before emitting the expression
   4119      if (!updateSourceCoordNotes(item->pn_pos.begin)) {
   4120        return false;
   4121      }
   4122    }
   4123 
   4124    if (!emitTree(item)) {
   4125      return false;
   4126    }
   4127 
   4128    if (!isString) {
   4129      // We need to convert the expression to a string
   4130      if (!emit1(JSOp::ToString)) {
   4131        return false;
   4132      }
   4133    }
   4134 
   4135    if (pushedString) {
   4136      // We've pushed two strings onto the stack. Add them together, leaving
   4137      // just one.
   4138      if (!emit1(JSOp::Add)) {
   4139        return false;
   4140      }
   4141    } else {
   4142      pushedString = true;
   4143    }
   4144  }
   4145 
   4146  if (!pushedString) {
   4147    // All strings were empty, this can happen for something like `${""}`.
   4148    // Just push an empty string.
   4149    if (!emitStringOp(JSOp::String,
   4150                      TaggedParserAtomIndex::WellKnown::empty())) {
   4151      return false;
   4152    }
   4153  }
   4154 
   4155  return true;
   4156 }
   4157 
   4158 bool BytecodeEmitter::emitDeclarationList(ListNode* declList) {
   4159  for (ParseNode* decl : declList->contents()) {
   4160    ParseNode* pattern;
   4161    ParseNode* initializer;
   4162    if (decl->isKind(ParseNodeKind::Name)) {
   4163      pattern = decl;
   4164      initializer = nullptr;
   4165    } else {
   4166      AssignmentNode* assignNode = &decl->as<AssignmentNode>();
   4167      pattern = assignNode->left();
   4168      initializer = assignNode->right();
   4169    }
   4170 
   4171    if (pattern->isKind(ParseNodeKind::Name)) {
   4172      // initializer can be null here.
   4173      if (!emitSingleDeclaration(declList, &pattern->as<NameNode>(),
   4174                                 initializer)) {
   4175        return false;
   4176      }
   4177    } else {
   4178      MOZ_ASSERT(pattern->isKind(ParseNodeKind::ArrayExpr) ||
   4179                 pattern->isKind(ParseNodeKind::ObjectExpr));
   4180      MOZ_ASSERT(initializer != nullptr);
   4181 
   4182      if (!updateSourceCoordNotes(initializer->pn_pos.begin)) {
   4183        return false;
   4184      }
   4185      if (!markStepBreakpoint()) {
   4186        return false;
   4187      }
   4188      if (!emitTree(initializer)) {
   4189        return false;
   4190      }
   4191 
   4192      if (!emitDestructuringOps(&pattern->as<ListNode>(),
   4193                                DestructuringFlavor::Declaration,
   4194                                getSelfHostedIterFor(initializer))) {
   4195        return false;
   4196      }
   4197 
   4198      if (!emit1(JSOp::Pop)) {
   4199        return false;
   4200      }
   4201    }
   4202  }
   4203  return true;
   4204 }
   4205 
   4206 bool BytecodeEmitter::emitSingleDeclaration(ListNode* declList, NameNode* decl,
   4207                                            ParseNode* initializer) {
   4208  MOZ_ASSERT(decl->isKind(ParseNodeKind::Name));
   4209 
   4210  // Nothing to do for initializer-less 'var' declarations, as there's no TDZ.
   4211  if (!initializer && declList->isKind(ParseNodeKind::VarStmt)) {
   4212    return true;
   4213  }
   4214 
   4215  auto nameAtom = decl->name();
   4216  NameOpEmitter noe(this, nameAtom, NameOpEmitter::Kind::Initialize);
   4217  if (!noe.prepareForRhs()) {
   4218    //              [stack] ENV?
   4219    return false;
   4220  }
   4221  if (!initializer) {
   4222    // Lexical declarations are initialized to undefined without an
   4223    // initializer.
   4224    MOZ_ASSERT(declList->isKind(ParseNodeKind::LetDecl),
   4225               "var declarations without initializers handled above, "
   4226               "and const declarations must have initializers");
   4227    if (!emit1(JSOp::Undefined)) {
   4228      //            [stack] ENV? UNDEF
   4229      return false;
   4230    }
   4231  } else {
   4232    MOZ_ASSERT(initializer);
   4233 
   4234    if (!updateSourceCoordNotes(initializer->pn_pos.begin)) {
   4235      return false;
   4236    }
   4237    if (!markStepBreakpoint()) {
   4238      return false;
   4239    }
   4240    if (!emitInitializer(initializer, decl)) {
   4241      //            [stack] ENV? V
   4242      return false;
   4243    }
   4244  }
   4245 
   4246 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   4247  if (declList->isKind(ParseNodeKind::UsingDecl)) {
   4248    if (!innermostEmitterScope()->prepareForDisposableAssignment(
   4249            UsingHint::Sync)) {
   4250      //            [stack] ENV? V
   4251      return false;
   4252    }
   4253  } else if (declList->isKind(ParseNodeKind::AwaitUsingDecl)) {
   4254    if (!innermostEmitterScope()->prepareForDisposableAssignment(
   4255            UsingHint::Async)) {
   4256      //            [stack] ENV? V
   4257      return false;
   4258    }
   4259  }
   4260 #endif
   4261 
   4262  if (!noe.emitAssignment()) {
   4263    //              [stack] V
   4264    return false;
   4265  }
   4266 
   4267  if (!emit1(JSOp::Pop)) {
   4268    //              [stack]
   4269    return false;
   4270  }
   4271 
   4272  return true;
   4273 }
   4274 
   4275 bool BytecodeEmitter::emitAssignmentRhs(
   4276    ParseNode* rhs, TaggedParserAtomIndex anonFunctionName) {
   4277  if (rhs->isDirectRHSAnonFunction()) {
   4278    if (anonFunctionName) {
   4279      return emitAnonymousFunctionWithName(rhs, anonFunctionName);
   4280    }
   4281    return emitAnonymousFunctionWithComputedName(rhs, FunctionPrefixKind::None);
   4282  }
   4283  return emitTree(rhs);
   4284 }
   4285 
   4286 // The RHS value to assign is already on the stack, i.e., the next enumeration
   4287 // value in a for-in or for-of loop. Offset is the location in the stack of the
   4288 // already-emitted rhs. If we emitted a JSOp::BindUnqualifiedName or
   4289 // JSOp::BindUnqualifiedGName, then the scope is on the top of the stack and we
   4290 // need to dig one deeper to get the right RHS value.
   4291 bool BytecodeEmitter::emitAssignmentRhs(uint8_t offset) {
   4292  if (offset != 1) {
   4293    return emitPickN(offset - 1);
   4294  }
   4295 
   4296  return true;
   4297 }
   4298 
   4299 static inline JSOp CompoundAssignmentParseNodeKindToJSOp(ParseNodeKind pnk) {
   4300  switch (pnk) {
   4301    case ParseNodeKind::InitExpr:
   4302      return JSOp::Nop;
   4303    case ParseNodeKind::AssignExpr:
   4304      return JSOp::Nop;
   4305    case ParseNodeKind::AddAssignExpr:
   4306      return JSOp::Add;
   4307    case ParseNodeKind::SubAssignExpr:
   4308      return JSOp::Sub;
   4309    case ParseNodeKind::BitOrAssignExpr:
   4310      return JSOp::BitOr;
   4311    case ParseNodeKind::BitXorAssignExpr:
   4312      return JSOp::BitXor;
   4313    case ParseNodeKind::BitAndAssignExpr:
   4314      return JSOp::BitAnd;
   4315    case ParseNodeKind::LshAssignExpr:
   4316      return JSOp::Lsh;
   4317    case ParseNodeKind::RshAssignExpr:
   4318      return JSOp::Rsh;
   4319    case ParseNodeKind::UrshAssignExpr:
   4320      return JSOp::Ursh;
   4321    case ParseNodeKind::MulAssignExpr:
   4322      return JSOp::Mul;
   4323    case ParseNodeKind::DivAssignExpr:
   4324      return JSOp::Div;
   4325    case ParseNodeKind::ModAssignExpr:
   4326      return JSOp::Mod;
   4327    case ParseNodeKind::PowAssignExpr:
   4328      return JSOp::Pow;
   4329    case ParseNodeKind::CoalesceAssignExpr:
   4330    case ParseNodeKind::OrAssignExpr:
   4331    case ParseNodeKind::AndAssignExpr:
   4332      // Short-circuit assignment operators are handled elsewhere.
   4333      [[fallthrough]];
   4334    default:
   4335      MOZ_CRASH("unexpected compound assignment op");
   4336  }
   4337 }
   4338 
   4339 bool BytecodeEmitter::emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs,
   4340                                           ParseNode* rhs) {
   4341  JSOp compoundOp = CompoundAssignmentParseNodeKindToJSOp(kind);
   4342  bool isCompound = compoundOp != JSOp::Nop;
   4343  bool isInit = kind == ParseNodeKind::InitExpr;
   4344 
   4345  // We estimate the number of properties this could create
   4346  // if used as constructor merely by counting this.foo = assignment
   4347  // or init expressions;
   4348  //
   4349  // This currently doesn't handle this[x] = foo;
   4350  if (isInit || kind == ParseNodeKind::AssignExpr) {
   4351    if (lhs->isKind(ParseNodeKind::DotExpr)) {
   4352      if (lhs->as<PropertyAccess>().expression().isKind(
   4353              ParseNodeKind::ThisExpr)) {
   4354        propertyAdditionEstimate++;
   4355      }
   4356    }
   4357  }
   4358 
   4359  MOZ_ASSERT_IF(isInit, lhs->isKind(ParseNodeKind::DotExpr) ||
   4360                            lhs->isKind(ParseNodeKind::ElemExpr) ||
   4361                            lhs->isKind(ParseNodeKind::PrivateMemberExpr));
   4362 
   4363  // |name| is used within NameOpEmitter, so its lifetime must surpass |noe|.
   4364  TaggedParserAtomIndex name;
   4365 
   4366  Maybe<NameOpEmitter> noe;
   4367  Maybe<PropOpEmitter> poe;
   4368  Maybe<ElemOpEmitter> eoe;
   4369  Maybe<PrivateOpEmitter> xoe;
   4370 
   4371  // Deal with non-name assignments.
   4372  uint8_t offset = 1;
   4373 
   4374  // Purpose of anonFunctionName:
   4375  //
   4376  // In normal name assignments (`f = function(){}`), an anonymous function gets
   4377  // an inferred name based on the left-hand side name node.
   4378  //
   4379  // In normal property assignments (`obj.x = function(){}`), the anonymous
   4380  // function does not have a computed name, and rhs->isDirectRHSAnonFunction()
   4381  // will be false (and anonFunctionName will not be used). However, in field
   4382  // initializers (`class C { x = function(){} }`), field initialization is
   4383  // implemented via a property or elem assignment (where we are now), and
   4384  // rhs->isDirectRHSAnonFunction() is set - so we'll assign the name of the
   4385  // function.
   4386  TaggedParserAtomIndex anonFunctionName;
   4387 
   4388  switch (lhs->getKind()) {
   4389    case ParseNodeKind::Name: {
   4390      name = lhs->as<NameNode>().name();
   4391      anonFunctionName = name;
   4392      noe.emplace(this, name,
   4393                  isCompound ? NameOpEmitter::Kind::CompoundAssignment
   4394                             : NameOpEmitter::Kind::SimpleAssignment);
   4395      break;
   4396    }
   4397    case ParseNodeKind::ArgumentsLength:
   4398    case ParseNodeKind::DotExpr: {
   4399      PropertyAccess* prop = &lhs->as<PropertyAccess>();
   4400      bool isSuper = prop->isSuper();
   4401      poe.emplace(this,
   4402                  isCompound ? PropOpEmitter::Kind::CompoundAssignment
   4403                  : isInit   ? PropOpEmitter::Kind::PropInit
   4404                             : PropOpEmitter::Kind::SimpleAssignment,
   4405                  isSuper ? PropOpEmitter::ObjKind::Super
   4406                          : PropOpEmitter::ObjKind::Other);
   4407      if (!poe->prepareForObj()) {
   4408        return false;
   4409      }
   4410      anonFunctionName = prop->name();
   4411      if (isSuper) {
   4412        UnaryNode* base = &prop->expression().as<UnaryNode>();
   4413        if (!emitGetThisForSuperBase(base)) {
   4414          //        [stack] THIS SUPERBASE
   4415          return false;
   4416        }
   4417        // SUPERBASE is pushed onto THIS later in poe->emitGet below.
   4418        offset += 2;
   4419      } else {
   4420        if (!emitTree(&prop->expression())) {
   4421          //        [stack] OBJ
   4422          return false;
   4423        }
   4424        offset += 1;
   4425      }
   4426      break;
   4427    }
   4428    case ParseNodeKind::ElemExpr: {
   4429      PropertyByValue* elem = &lhs->as<PropertyByValue>();
   4430      bool isSuper = elem->isSuper();
   4431      MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
   4432      eoe.emplace(this,
   4433                  isCompound ? ElemOpEmitter::Kind::CompoundAssignment
   4434                  : isInit   ? ElemOpEmitter::Kind::PropInit
   4435                             : ElemOpEmitter::Kind::SimpleAssignment,
   4436                  isSuper ? ElemOpEmitter::ObjKind::Super
   4437                          : ElemOpEmitter::ObjKind::Other);
   4438      if (!emitElemObjAndKey(elem, *eoe)) {
   4439        //          [stack] # if Super
   4440        //          [stack] THIS KEY
   4441        //          [stack] # otherwise
   4442        //          [stack] OBJ KEY
   4443        return false;
   4444      }
   4445      if (isSuper) {
   4446        // SUPERBASE is pushed onto KEY in eoe->emitGet below.
   4447        offset += 3;
   4448      } else {
   4449        offset += 2;
   4450      }
   4451      break;
   4452    }
   4453    case ParseNodeKind::PrivateMemberExpr: {
   4454      PrivateMemberAccess* privateExpr = &lhs->as<PrivateMemberAccess>();
   4455      xoe.emplace(this,
   4456                  isCompound ? PrivateOpEmitter::Kind::CompoundAssignment
   4457                  : isInit   ? PrivateOpEmitter::Kind::PropInit
   4458                             : PrivateOpEmitter::Kind::SimpleAssignment,
   4459                  privateExpr->privateName().name());
   4460      if (!emitTree(&privateExpr->expression())) {
   4461        //          [stack] OBJ
   4462        return false;
   4463      }
   4464      if (!xoe->emitReference()) {
   4465        //          [stack] OBJ KEY
   4466        return false;
   4467      }
   4468      offset += xoe->numReferenceSlots();
   4469      break;
   4470    }
   4471    case ParseNodeKind::ArrayExpr:
   4472    case ParseNodeKind::ObjectExpr:
   4473      break;
   4474    case ParseNodeKind::CallExpr:
   4475      if (!emitTree(lhs)) {
   4476        return false;
   4477      }
   4478 
   4479      // Assignment to function calls is forbidden, but we have to make the
   4480      // call first.  Now we can throw.
   4481      if (!emit2(JSOp::ThrowMsg, uint8_t(ThrowMsgKind::AssignToCall))) {
   4482        return false;
   4483      }
   4484 
   4485      // Rebalance the stack to placate stack-depth assertions.
   4486      if (!emit1(JSOp::Pop)) {
   4487        return false;
   4488      }
   4489      break;
   4490    default:
   4491      MOZ_ASSERT(0);
   4492  }
   4493 
   4494  if (isCompound) {
   4495    MOZ_ASSERT(rhs);
   4496    switch (lhs->getKind()) {
   4497      case ParseNodeKind::ArgumentsLength:
   4498      case ParseNodeKind::DotExpr: {
   4499        PropertyAccess* prop = &lhs->as<PropertyAccess>();
   4500        if (!poe->emitGet(prop->key().atom())) {
   4501          //        [stack] # if Super
   4502          //        [stack] THIS SUPERBASE PROP
   4503          //        [stack] # otherwise
   4504          //        [stack] OBJ PROP
   4505          return false;
   4506        }
   4507        break;
   4508      }
   4509      case ParseNodeKind::ElemExpr: {
   4510        if (!eoe->emitGet()) {
   4511          //        [stack] KEY THIS OBJ ELEM
   4512          return false;
   4513        }
   4514        break;
   4515      }
   4516      case ParseNodeKind::PrivateMemberExpr: {
   4517        if (!xoe->emitGet()) {
   4518          //        [stack] OBJ KEY VALUE
   4519          return false;
   4520        }
   4521        break;
   4522      }
   4523      case ParseNodeKind::CallExpr:
   4524        // We just emitted a JSOp::ThrowMsg and popped the call's return
   4525        // value.  Push a random value to make sure the stack depth is
   4526        // correct.
   4527        if (!emit1(JSOp::Null)) {
   4528          //        [stack] NULL
   4529          return false;
   4530        }
   4531        break;
   4532      default:;
   4533    }
   4534  }
   4535 
   4536  switch (lhs->getKind()) {
   4537    case ParseNodeKind::Name:
   4538      if (!noe->prepareForRhs()) {
   4539        //          [stack] ENV? VAL?
   4540        return false;
   4541      }
   4542      offset += noe->emittedBindOp();
   4543      break;
   4544    case ParseNodeKind::ArgumentsLength:
   4545    case ParseNodeKind::DotExpr:
   4546      if (!poe->prepareForRhs()) {
   4547        //          [stack] # if Simple Assignment with Super
   4548        //          [stack] THIS SUPERBASE
   4549        //          [stack] # if Simple Assignment with other
   4550        //          [stack] OBJ
   4551        //          [stack] # if Compound Assignment with Super
   4552        //          [stack] THIS SUPERBASE PROP
   4553        //          [stack] # if Compound Assignment with other
   4554        //          [stack] OBJ PROP
   4555        return false;
   4556      }
   4557      break;
   4558    case ParseNodeKind::ElemExpr:
   4559      if (!eoe->prepareForRhs()) {
   4560        //          [stack] # if Simple Assignment with Super
   4561        //          [stack] THIS KEY SUPERBASE
   4562        //          [stack] # if Simple Assignment with other
   4563        //          [stack] OBJ KEY
   4564        //          [stack] # if Compound Assignment with Super
   4565        //          [stack] THIS KEY SUPERBASE ELEM
   4566        //          [stack] # if Compound Assignment with other
   4567        //          [stack] OBJ KEY ELEM
   4568        return false;
   4569      }
   4570      break;
   4571    case ParseNodeKind::PrivateMemberExpr:
   4572      // no stack adjustment needed
   4573      break;
   4574    default:
   4575      break;
   4576  }
   4577 
   4578  if (rhs) {
   4579    if (!emitAssignmentRhs(rhs, anonFunctionName)) {
   4580      //            [stack] ... VAL? RHS
   4581      return false;
   4582    }
   4583  } else {
   4584    // Assumption: Things with pre-emitted RHS values never need to be named.
   4585    if (!emitAssignmentRhs(offset)) {
   4586      //            [stack] ... VAL? RHS
   4587      return false;
   4588    }
   4589  }
   4590 
   4591  /* If += etc., emit the binary operator with a hint for the decompiler. */
   4592  if (isCompound) {
   4593    if (!emit1(compoundOp)) {
   4594      //            [stack] ... VAL
   4595      return false;
   4596    }
   4597    if (!emit1(JSOp::NopIsAssignOp)) {
   4598      //            [stack] ... VAL
   4599      return false;
   4600    }
   4601  }
   4602 
   4603  /* Finally, emit the specialized assignment bytecode. */
   4604  switch (lhs->getKind()) {
   4605    case ParseNodeKind::Name: {
   4606      if (!noe->emitAssignment()) {
   4607        //          [stack] VAL
   4608        return false;
   4609      }
   4610      break;
   4611    }
   4612    case ParseNodeKind::ArgumentsLength:
   4613    case ParseNodeKind::DotExpr: {
   4614      PropertyAccess* prop = &lhs->as<PropertyAccess>();
   4615      if (!poe->emitAssignment(prop->key().atom())) {
   4616        //          [stack] VAL
   4617        return false;
   4618      }
   4619      break;
   4620    }
   4621    case ParseNodeKind::CallExpr:
   4622      // We threw above, so nothing to do here.
   4623      break;
   4624    case ParseNodeKind::ElemExpr: {
   4625      if (!eoe->emitAssignment()) {
   4626        //          [stack] VAL
   4627        return false;
   4628      }
   4629      break;
   4630    }
   4631    case ParseNodeKind::PrivateMemberExpr:
   4632      if (!xoe->emitAssignment()) {
   4633        //          [stack] VAL
   4634        return false;
   4635      }
   4636      break;
   4637    case ParseNodeKind::ArrayExpr:
   4638    case ParseNodeKind::ObjectExpr: {
   4639      auto selfHostedIter =
   4640          rhs ? getSelfHostedIterFor(rhs) : SelfHostedIter::Deny;
   4641      if (!emitDestructuringOps(&lhs->as<ListNode>(),
   4642                                DestructuringFlavor::Assignment,
   4643                                selfHostedIter)) {
   4644        return false;
   4645      }
   4646      break;
   4647    }
   4648    default:
   4649      MOZ_ASSERT(0);
   4650  }
   4651  return true;
   4652 }
   4653 
   4654 bool BytecodeEmitter::emitShortCircuitAssignment(AssignmentNode* node) {
   4655  TDZCheckCache tdzCache(this);
   4656 
   4657  JSOp op;
   4658  switch (node->getKind()) {
   4659    case ParseNodeKind::CoalesceAssignExpr:
   4660      op = JSOp::Coalesce;
   4661      break;
   4662    case ParseNodeKind::OrAssignExpr:
   4663      op = JSOp::Or;
   4664      break;
   4665    case ParseNodeKind::AndAssignExpr:
   4666      op = JSOp::And;
   4667      break;
   4668    default:
   4669      MOZ_CRASH("Unexpected ParseNodeKind");
   4670  }
   4671 
   4672  ParseNode* lhs = node->left();
   4673  ParseNode* rhs = node->right();
   4674 
   4675  // |name| is used within NameOpEmitter, so its lifetime must surpass |noe|.
   4676  TaggedParserAtomIndex name;
   4677 
   4678  // Select the appropriate emitter based on the left-hand side.
   4679  Maybe<NameOpEmitter> noe;
   4680  Maybe<PropOpEmitter> poe;
   4681  Maybe<ElemOpEmitter> eoe;
   4682  Maybe<PrivateOpEmitter> xoe;
   4683 
   4684  int32_t depth = bytecodeSection().stackDepth();
   4685 
   4686  // Number of values pushed onto the stack in addition to the lhs value.
   4687  int32_t numPushed;
   4688 
   4689  // Evaluate the left-hand side expression and compute any stack values needed
   4690  // for the assignment.
   4691  switch (lhs->getKind()) {
   4692    case ParseNodeKind::Name: {
   4693      name = lhs->as<NameNode>().name();
   4694      noe.emplace(this, name, NameOpEmitter::Kind::CompoundAssignment);
   4695 
   4696      if (!noe->prepareForRhs()) {
   4697        //          [stack] ENV? LHS
   4698        return false;
   4699      }
   4700 
   4701      numPushed = noe->emittedBindOp();
   4702      break;
   4703    }
   4704    case ParseNodeKind::ArgumentsLength:
   4705    case ParseNodeKind::DotExpr: {
   4706      PropertyAccess* prop = &lhs->as<PropertyAccess>();
   4707      bool isSuper = prop->isSuper();
   4708 
   4709      poe.emplace(this, PropOpEmitter::Kind::CompoundAssignment,
   4710                  isSuper ? PropOpEmitter::ObjKind::Super
   4711                          : PropOpEmitter::ObjKind::Other);
   4712 
   4713      if (!poe->prepareForObj()) {
   4714        return false;
   4715      }
   4716 
   4717      if (isSuper) {
   4718        UnaryNode* base = &prop->expression().as<UnaryNode>();
   4719        if (!emitGetThisForSuperBase(base)) {
   4720          //        [stack] THIS SUPERBASE
   4721          return false;
   4722        }
   4723      } else {
   4724        if (!emitTree(&prop->expression())) {
   4725          //        [stack] OBJ
   4726          return false;
   4727        }
   4728      }
   4729 
   4730      if (!poe->emitGet(prop->key().atom())) {
   4731        //          [stack] # if Super
   4732        //          [stack] THIS SUPERBASE LHS
   4733        //          [stack] # otherwise
   4734        //          [stack] OBJ LHS
   4735        return false;
   4736      }
   4737 
   4738      if (!poe->prepareForRhs()) {
   4739        //          [stack] # if Super
   4740        //          [stack] THIS SUPERBASE LHS
   4741        //          [stack] # otherwise
   4742        //          [stack] OBJ LHS
   4743        return false;
   4744      }
   4745 
   4746      numPushed = 1 + isSuper;
   4747      break;
   4748    }
   4749 
   4750    case ParseNodeKind::ElemExpr: {
   4751      PropertyByValue* elem = &lhs->as<PropertyByValue>();
   4752      bool isSuper = elem->isSuper();
   4753      MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
   4754      eoe.emplace(this, ElemOpEmitter::Kind::CompoundAssignment,
   4755                  isSuper ? ElemOpEmitter::ObjKind::Super
   4756                          : ElemOpEmitter::ObjKind::Other);
   4757 
   4758      if (!emitElemObjAndKey(elem, *eoe)) {
   4759        //          [stack] # if Super
   4760        //          [stack] THIS KEY
   4761        //          [stack] # otherwise
   4762        //          [stack] OBJ KEY
   4763        return false;
   4764      }
   4765 
   4766      if (!eoe->emitGet()) {
   4767        //          [stack] # if Super
   4768        //          [stack] THIS KEY SUPERBASE LHS
   4769        //          [stack] # otherwise
   4770        //          [stack] OBJ KEY LHS
   4771        return false;
   4772      }
   4773 
   4774      if (!eoe->prepareForRhs()) {
   4775        //          [stack] # if Super
   4776        //          [stack] THIS KEY SUPERBASE LHS
   4777        //          [stack] # otherwise
   4778        //          [stack] OBJ KEY LHS
   4779        return false;
   4780      }
   4781 
   4782      numPushed = 2 + isSuper;
   4783      break;
   4784    }
   4785 
   4786    case ParseNodeKind::PrivateMemberExpr: {
   4787      PrivateMemberAccess* privateExpr = &lhs->as<PrivateMemberAccess>();
   4788      xoe.emplace(this, PrivateOpEmitter::Kind::CompoundAssignment,
   4789                  privateExpr->privateName().name());
   4790      if (!emitTree(&privateExpr->expression())) {
   4791        //          [stack] OBJ
   4792        return false;
   4793      }
   4794      if (!xoe->emitReference()) {
   4795        //          [stack] OBJ NAME
   4796        return false;
   4797      }
   4798      if (!xoe->emitGet()) {
   4799        //          [stack] OBJ NAME LHS
   4800        return false;
   4801      }
   4802      numPushed = xoe->numReferenceSlots();
   4803      break;
   4804    }
   4805 
   4806    default:
   4807      MOZ_CRASH();
   4808  }
   4809 
   4810  MOZ_ASSERT(bytecodeSection().stackDepth() == depth + numPushed + 1);
   4811 
   4812  // Test for the short-circuit condition.
   4813  JumpList jump;
   4814  if (!emitJump(op, &jump)) {
   4815    //              [stack] ... LHS
   4816    return false;
   4817  }
   4818 
   4819  // The short-circuit condition wasn't fulfilled, pop the left-hand side value
   4820  // which was kept on the stack.
   4821  if (!emit1(JSOp::Pop)) {
   4822    //              [stack] ...
   4823    return false;
   4824  }
   4825 
   4826  if (!emitAssignmentRhs(rhs, name)) {
   4827    //              [stack] ... RHS
   4828    return false;
   4829  }
   4830 
   4831  // Perform the actual assignment.
   4832  switch (lhs->getKind()) {
   4833    case ParseNodeKind::Name: {
   4834      if (!noe->emitAssignment()) {
   4835        //          [stack] RHS
   4836        return false;
   4837      }
   4838      break;
   4839    }
   4840    case ParseNodeKind::ArgumentsLength:
   4841    case ParseNodeKind::DotExpr: {
   4842      PropertyAccess* prop = &lhs->as<PropertyAccess>();
   4843 
   4844      if (!poe->emitAssignment(prop->key().atom())) {
   4845        //          [stack] RHS
   4846        return false;
   4847      }
   4848      break;
   4849    }
   4850 
   4851    case ParseNodeKind::ElemExpr: {
   4852      if (!eoe->emitAssignment()) {
   4853        //          [stack] RHS
   4854        return false;
   4855      }
   4856      break;
   4857    }
   4858 
   4859    case ParseNodeKind::PrivateMemberExpr:
   4860      if (!xoe->emitAssignment()) {
   4861        //          [stack] RHS
   4862        return false;
   4863      }
   4864      break;
   4865 
   4866    default:
   4867      MOZ_CRASH();
   4868  }
   4869 
   4870  MOZ_ASSERT(bytecodeSection().stackDepth() == depth + 1);
   4871 
   4872  // Join with the short-circuit jump and pop anything left on the stack.
   4873  if (numPushed > 0) {
   4874    JumpList jumpAroundPop;
   4875    if (!emitJump(JSOp::Goto, &jumpAroundPop)) {
   4876      //            [stack] RHS
   4877      return false;
   4878    }
   4879 
   4880    if (!emitJumpTargetAndPatch(jump)) {
   4881      //            [stack] ... LHS
   4882      return false;
   4883    }
   4884 
   4885    // Reconstruct the stack depth after the jump.
   4886    bytecodeSection().setStackDepth(depth + 1 + numPushed);
   4887 
   4888    // Move the left-hand side value to the bottom and pop the rest.
   4889    if (!emitUnpickN(numPushed)) {
   4890      //            [stack] LHS ...
   4891      return false;
   4892    }
   4893    if (!emitPopN(numPushed)) {
   4894      //            [stack] LHS
   4895      return false;
   4896    }
   4897 
   4898    if (!emitJumpTargetAndPatch(jumpAroundPop)) {
   4899      //            [stack] LHS | RHS
   4900      return false;
   4901    }
   4902  } else {
   4903    if (!emitJumpTargetAndPatch(jump)) {
   4904      //            [stack] LHS | RHS
   4905      return false;
   4906    }
   4907  }
   4908 
   4909  MOZ_ASSERT(bytecodeSection().stackDepth() == depth + 1);
   4910 
   4911  return true;
   4912 }
   4913 
   4914 bool BytecodeEmitter::emitCallSiteObjectArray(ObjLiteralWriter& writer,
   4915                                              ListNode* cookedOrRaw,
   4916                                              ParseNode* head, uint32_t count) {
   4917  DebugOnly<size_t> idx = 0;
   4918  for (ParseNode* pn : cookedOrRaw->contentsFrom(head)) {
   4919    MOZ_ASSERT(pn->isKind(ParseNodeKind::TemplateStringExpr) ||
   4920               pn->isKind(ParseNodeKind::RawUndefinedExpr));
   4921 
   4922    if (!emitObjLiteralValue(writer, pn)) {
   4923      return false;
   4924    }
   4925    idx++;
   4926  }
   4927  MOZ_ASSERT(idx == count);
   4928 
   4929  return true;
   4930 }
   4931 
   4932 bool BytecodeEmitter::emitCallSiteObject(CallSiteNode* callSiteObj) {
   4933  constexpr JSOp op = JSOp::CallSiteObj;
   4934 
   4935  // The first element of a call-site node is the raw-values list. Skip over it.
   4936  ListNode* raw = callSiteObj->rawNodes();
   4937  MOZ_ASSERT(raw->isKind(ParseNodeKind::ArrayExpr));
   4938  ParseNode* head = callSiteObj->head()->pn_next;
   4939 
   4940  uint32_t count = callSiteObj->count() - 1;
   4941  MOZ_ASSERT(count == raw->count());
   4942 
   4943  ObjLiteralWriter writer;
   4944  writer.beginCallSiteObj(op);
   4945  writer.beginDenseArrayElements();
   4946 
   4947  // Write elements of the two arrays: the 'cooked' values followed by the
   4948  // 'raw' values.
   4949  MOZ_RELEASE_ASSERT(count < UINT32_MAX / 2,
   4950                     "Number of elements for both arrays must fit in uint32_t");
   4951  if (!emitCallSiteObjectArray(writer, callSiteObj, head, count)) {
   4952    return false;
   4953  }
   4954  if (!emitCallSiteObjectArray(writer, raw, raw->head(), count)) {
   4955    return false;
   4956  }
   4957 
   4958  GCThingIndex cookedIndex;
   4959  if (!addObjLiteralData(writer, &cookedIndex)) {
   4960    return false;
   4961  }
   4962 
   4963  MOZ_ASSERT(sc->hasCallSiteObj());
   4964 
   4965  return emitInternedObjectOp(cookedIndex, op);
   4966 }
   4967 
   4968 bool BytecodeEmitter::emitCatch(BinaryNode* catchClause) {
   4969  // We must be nested under a try-finally statement.
   4970  MOZ_ASSERT(innermostNestableControl->is<TryFinallyControl>());
   4971 
   4972  ParseNode* param = catchClause->left();
   4973  if (!param) {
   4974    // Catch parameter was omitted; just discard the exception.
   4975    if (!emit1(JSOp::Pop)) {
   4976      return false;
   4977    }
   4978  } else {
   4979    switch (param->getKind()) {
   4980      case ParseNodeKind::ArrayExpr:
   4981      case ParseNodeKind::ObjectExpr:
   4982        if (!emitDestructuringOps(&param->as<ListNode>(),
   4983                                  DestructuringFlavor::Declaration,
   4984                                  SelfHostedIter::Deny)) {
   4985          return false;
   4986        }
   4987        if (!emit1(JSOp::Pop)) {
   4988          return false;
   4989        }
   4990        break;
   4991 
   4992      case ParseNodeKind::Name:
   4993        if (!emitLexicalInitialization(&param->as<NameNode>())) {
   4994          return false;
   4995        }
   4996        if (!emit1(JSOp::Pop)) {
   4997          return false;
   4998        }
   4999        break;
   5000 
   5001      default:
   5002        MOZ_ASSERT(0);
   5003    }
   5004  }
   5005 
   5006  /* Emit the catch body. */
   5007  return emitTree(catchClause->right());
   5008 }
   5009 
   5010 // Using MOZ_NEVER_INLINE in here is a workaround for llvm.org/pr14047. See the
   5011 // comment on EmitSwitch.
   5012 MOZ_NEVER_INLINE bool BytecodeEmitter::emitTry(TryNode* tryNode) {
   5013  LexicalScopeNode* catchScope = tryNode->catchScope();
   5014  ParseNode* finallyNode = tryNode->finallyBlock();
   5015 
   5016  TryEmitter::Kind kind;
   5017  if (catchScope) {
   5018    if (finallyNode) {
   5019      kind = TryEmitter::Kind::TryCatchFinally;
   5020    } else {
   5021      kind = TryEmitter::Kind::TryCatch;
   5022    }
   5023  } else {
   5024    MOZ_ASSERT(finallyNode);
   5025    kind = TryEmitter::Kind::TryFinally;
   5026  }
   5027  TryEmitter tryCatch(this, kind, TryEmitter::ControlKind::Syntactic);
   5028 
   5029  if (!tryCatch.emitTry()) {
   5030    return false;
   5031  }
   5032 
   5033  if (!emitTree(tryNode->body())) {
   5034    return false;
   5035  }
   5036 
   5037  // If this try has a catch block, emit it.
   5038  if (catchScope) {
   5039    // The emitted code for a catch block looks like:
   5040    //
   5041    // [pushlexicalenv]             only if any local aliased
   5042    // exception
   5043    // setlocal 0; pop              assign or possibly destructure exception
   5044    // < catch block contents >
   5045    // debugleaveblock
   5046    // [poplexicalenv]              only if any local aliased
   5047    // if there is a finally block:
   5048    //   goto <finally>
   5049    //   [jump target for returning from finally]
   5050    //   goto <after finally>
   5051    if (!tryCatch.emitCatch()) {
   5052      return false;
   5053    }
   5054 
   5055    // Emit the lexical scope and catch body.
   5056    if (!emitTree(catchScope)) {
   5057      return false;
   5058    }
   5059  }
   5060 
   5061  // Emit the finally handler, if there is one.
   5062  if (finallyNode) {
   5063    if (!tryCatch.emitFinally(Some(finallyNode->pn_pos.begin))) {
   5064      return false;
   5065    }
   5066 
   5067    if (!emitTree(finallyNode)) {
   5068      return false;
   5069    }
   5070  }
   5071 
   5072  if (!tryCatch.emitEnd()) {
   5073    return false;
   5074  }
   5075 
   5076  return true;
   5077 }
   5078 
   5079 [[nodiscard]] bool BytecodeEmitter::emitJumpToFinally(JumpList* jump,
   5080                                                      uint32_t idx) {
   5081  // Push the continuation index.
   5082  if (!emitNumberOp(idx)) {
   5083    return false;
   5084  }
   5085 
   5086  // Push |exception_stack|.
   5087  if (!emit1(JSOp::Null)) {
   5088    return false;
   5089  }
   5090 
   5091  // Push |throwing|.
   5092  if (!emit1(JSOp::False)) {
   5093    return false;
   5094  }
   5095 
   5096  // Jump to the finally block.
   5097  if (!emitJumpNoFallthrough(JSOp::Goto, jump)) {
   5098    return false;
   5099  }
   5100 
   5101  return true;
   5102 }
   5103 
   5104 bool BytecodeEmitter::emitIf(TernaryNode* ifNode) {
   5105  IfEmitter ifThenElse(this);
   5106 
   5107  if (!ifThenElse.emitIf(Some(ifNode->kid1()->pn_pos.begin))) {
   5108    return false;
   5109  }
   5110 
   5111 if_again:
   5112  ParseNode* testNode = ifNode->kid1();
   5113  auto conditionKind = IfEmitter::ConditionKind::Positive;
   5114  if (testNode->isKind(ParseNodeKind::NotExpr)) {
   5115    testNode = testNode->as<UnaryNode>().kid();
   5116    conditionKind = IfEmitter::ConditionKind::Negative;
   5117  }
   5118 
   5119  if (!markStepBreakpoint()) {
   5120    return false;
   5121  }
   5122 
   5123  // Emit code for the condition before pushing stmtInfo.
   5124  // NOTE: NotExpr of testNode may be unwrapped, and in that case the negation
   5125  //       is handled by conditionKind.
   5126  if (!emitTree(testNode)) {
   5127    return false;
   5128  }
   5129 
   5130  ParseNode* elseNode = ifNode->kid3();
   5131  if (elseNode) {
   5132    if (!ifThenElse.emitThenElse(conditionKind)) {
   5133      return false;
   5134    }
   5135  } else {
   5136    if (!ifThenElse.emitThen(conditionKind)) {
   5137      return false;
   5138    }
   5139  }
   5140 
   5141  /* Emit code for the then part. */
   5142  if (!emitTree(ifNode->kid2())) {
   5143    return false;
   5144  }
   5145 
   5146  if (elseNode) {
   5147    if (elseNode->isKind(ParseNodeKind::IfStmt)) {
   5148      ifNode = &elseNode->as<TernaryNode>();
   5149 
   5150      if (!ifThenElse.emitElseIf(Some(ifNode->kid1()->pn_pos.begin))) {
   5151        return false;
   5152      }
   5153 
   5154      goto if_again;
   5155    }
   5156 
   5157    if (!ifThenElse.emitElse()) {
   5158      return false;
   5159    }
   5160 
   5161    /* Emit code for the else part. */
   5162    if (!emitTree(elseNode)) {
   5163      return false;
   5164    }
   5165  }
   5166 
   5167  if (!ifThenElse.emitEnd()) {
   5168    return false;
   5169  }
   5170 
   5171  return true;
   5172 }
   5173 
   5174 bool BytecodeEmitter::emitHoistedFunctionsInList(ListNode* stmtList) {
   5175  MOZ_ASSERT(stmtList->hasTopLevelFunctionDeclarations());
   5176 
   5177  // We can call this multiple times for sloppy eval scopes.
   5178  if (stmtList->emittedTopLevelFunctionDeclarations()) {
   5179    return true;
   5180  }
   5181 
   5182  stmtList->setEmittedTopLevelFunctionDeclarations();
   5183 
   5184  for (ParseNode* stmt : stmtList->contents()) {
   5185    ParseNode* maybeFun = stmt;
   5186 
   5187    if (!sc->strict()) {
   5188      while (maybeFun->isKind(ParseNodeKind::LabelStmt)) {
   5189        maybeFun = maybeFun->as<LabeledStatement>().statement();
   5190      }
   5191    }
   5192 
   5193    if (maybeFun->is<FunctionNode>() &&
   5194        maybeFun->as<FunctionNode>().functionIsHoisted()) {
   5195      if (!emitTree(maybeFun)) {
   5196        return false;
   5197      }
   5198    }
   5199  }
   5200 
   5201  return true;
   5202 }
   5203 
   5204 bool BytecodeEmitter::emitLexicalScopeBody(
   5205    ParseNode* body, EmitLineNumberNote emitLineNote /* = EMIT_LINENOTE */) {
   5206  if (body->isKind(ParseNodeKind::StatementList) &&
   5207      body->as<ListNode>().hasTopLevelFunctionDeclarations()) {
   5208    // This block contains function statements whose definitions are
   5209    // hoisted to the top of the block. Emit these as a separate pass
   5210    // before the rest of the block.
   5211    if (!emitHoistedFunctionsInList(&body->as<ListNode>())) {
   5212      return false;
   5213    }
   5214  }
   5215 
   5216  // Line notes were updated by emitLexicalScope or emitScript.
   5217  return emitTree(body, ValueUsage::WantValue, emitLineNote);
   5218 }
   5219 
   5220 // Using MOZ_NEVER_INLINE in here is a workaround for llvm.org/pr14047. See
   5221 // the comment on emitSwitch.
   5222 MOZ_NEVER_INLINE bool BytecodeEmitter::emitLexicalScope(
   5223    LexicalScopeNode* lexicalScope) {
   5224  LexicalScopeEmitter lse(this);
   5225 
   5226  ParseNode* body = lexicalScope->scopeBody();
   5227  if (lexicalScope->isEmptyScope()) {
   5228    if (!lse.emitEmptyScope()) {
   5229      return false;
   5230    }
   5231 
   5232    if (!emitLexicalScopeBody(body)) {
   5233      return false;
   5234    }
   5235 
   5236    if (!lse.emitEnd()) {
   5237      return false;
   5238    }
   5239 
   5240    return true;
   5241  }
   5242 
   5243  // We are about to emit some bytecode for what the spec calls "declaration
   5244  // instantiation". Assign these instructions to the opening `{` of the
   5245  // block. (Using the location of each declaration we're instantiating is
   5246  // too weird when stepping in the debugger.)
   5247  if (!ParseNodeRequiresSpecialLineNumberNotes(body)) {
   5248    if (!updateSourceCoordNotes(lexicalScope->pn_pos.begin)) {
   5249      return false;
   5250    }
   5251  }
   5252 
   5253  ScopeKind kind;
   5254  if (body->isKind(ParseNodeKind::Catch)) {
   5255    BinaryNode* catchNode = &body->as<BinaryNode>();
   5256    kind =
   5257        (!catchNode->left() || catchNode->left()->isKind(ParseNodeKind::Name))
   5258            ? ScopeKind::SimpleCatch
   5259            : ScopeKind::Catch;
   5260  } else {
   5261    kind = lexicalScope->kind();
   5262  }
   5263 
   5264 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   5265  BlockKind blockKind = BlockKind::Other;
   5266  if (body->isKind(ParseNodeKind::ForStmt) &&
   5267      body->as<ForNode>().head()->isKind(ParseNodeKind::ForOf)) {
   5268    MOZ_ASSERT(kind == ScopeKind::Lexical);
   5269    blockKind = BlockKind::ForOf;
   5270  }
   5271 #endif
   5272 
   5273  if (!lse.emitScope(kind, lexicalScope->scopeBindings()
   5274 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   5275                               ,
   5276                     blockKind
   5277 #endif
   5278                     )) {
   5279    return false;
   5280  }
   5281 
   5282  if (body->isKind(ParseNodeKind::ForStmt)) {
   5283    // for loops need to emit JSOp::FreshenLexicalEnv/JSOp::RecreateLexicalEnv
   5284    // if there are lexical declarations in the head. Signal this by passing a
   5285    // non-nullptr lexical scope.
   5286    if (!emitFor(&body->as<ForNode>(), &lse.emitterScope())) {
   5287      return false;
   5288    }
   5289  } else {
   5290    if (!emitLexicalScopeBody(body, SUPPRESS_LINENOTE)) {
   5291      return false;
   5292    }
   5293  }
   5294 
   5295  if (!lse.emitEnd()) {
   5296    return false;
   5297  }
   5298  return true;
   5299 }
   5300 
   5301 bool BytecodeEmitter::emitWith(BinaryNode* withNode) {
   5302  // Ensure that the column of the 'with' is set properly.
   5303  if (!updateSourceCoordNotes(withNode->left()->pn_pos.begin)) {
   5304    return false;
   5305  }
   5306 
   5307  if (!markStepBreakpoint()) {
   5308    return false;
   5309  }
   5310 
   5311  if (!emitTree(withNode->left())) {
   5312    return false;
   5313  }
   5314 
   5315  EmitterScope emitterScope(this);
   5316  if (!emitterScope.enterWith(this)) {
   5317    return false;
   5318  }
   5319 
   5320  if (!emitTree(withNode->right())) {
   5321    return false;
   5322  }
   5323 
   5324  return emitterScope.leave(this);
   5325 }
   5326 
   5327 bool BytecodeEmitter::emitCopyDataProperties(CopyOption option) {
   5328  DebugOnly<int32_t> depth = bytecodeSection().stackDepth();
   5329 
   5330  uint32_t argc;
   5331  if (option == CopyOption::Filtered) {
   5332    MOZ_ASSERT(depth > 2);
   5333    //              [stack] TARGET SOURCE SET
   5334    argc = 3;
   5335 
   5336    if (!emitAtomOp(JSOp::GetIntrinsic,
   5337                    TaggedParserAtomIndex::WellKnown::CopyDataProperties())) {
   5338      //            [stack] TARGET SOURCE SET COPYDATAPROPERTIES
   5339      return false;
   5340    }
   5341  } else {
   5342    MOZ_ASSERT(depth > 1);
   5343    //              [stack] TARGET SOURCE
   5344    argc = 2;
   5345 
   5346    if (!emitAtomOp(
   5347            JSOp::GetIntrinsic,
   5348            TaggedParserAtomIndex::WellKnown::CopyDataPropertiesUnfiltered())) {
   5349      //            [stack] TARGET SOURCE COPYDATAPROPERTIES
   5350      return false;
   5351    }
   5352  }
   5353 
   5354  if (!emit1(JSOp::Undefined)) {
   5355    //              [stack] TARGET SOURCE SET? COPYDATAPROPERTIES
   5356    //                    UNDEFINED
   5357    return false;
   5358  }
   5359  if (!emit2(JSOp::Pick, argc + 1)) {
   5360    //              [stack] SOURCE SET? COPYDATAPROPERTIES UNDEFINED
   5361    //                    TARGET
   5362    return false;
   5363  }
   5364  if (!emit2(JSOp::Pick, argc + 1)) {
   5365    //              [stack] SET? COPYDATAPROPERTIES UNDEFINED TARGET
   5366    //                    SOURCE
   5367    return false;
   5368  }
   5369  if (option == CopyOption::Filtered) {
   5370    if (!emit2(JSOp::Pick, argc + 1)) {
   5371      //            [stack] COPYDATAPROPERTIES UNDEFINED TARGET SOURCE SET
   5372      return false;
   5373    }
   5374  }
   5375  // Callee is always self-hosted instrinsic, and cannot be content function.
   5376  if (!emitCall(JSOp::CallIgnoresRv, argc)) {
   5377    //              [stack] IGNORED
   5378    return false;
   5379  }
   5380 
   5381  if (!emit1(JSOp::Pop)) {
   5382    //              [stack]
   5383    return false;
   5384  }
   5385 
   5386  MOZ_ASSERT(depth - int(argc) == bytecodeSection().stackDepth());
   5387  return true;
   5388 }
   5389 
   5390 bool BytecodeEmitter::emitBigIntOp(BigIntLiteral* bigint) {
   5391  GCThingIndex index;
   5392  if (!perScriptData().gcThingList().append(bigint, &index)) {
   5393    return false;
   5394  }
   5395  return emitGCIndexOp(JSOp::BigInt, index);
   5396 }
   5397 
   5398 bool BytecodeEmitter::emitIterable(ParseNode* value,
   5399                                   SelfHostedIter selfHostedIter,
   5400                                   IteratorKind iterKind) {
   5401  MOZ_ASSERT(getSelfHostedIterFor(value) == selfHostedIter);
   5402 
   5403  if (!emitTree(value)) {
   5404    //              [stack] ITERABLE
   5405    return false;
   5406  }
   5407 
   5408  switch (selfHostedIter) {
   5409    case SelfHostedIter::Deny:
   5410    case SelfHostedIter::AllowContent:
   5411      //            [stack] ITERABLE
   5412      return true;
   5413 
   5414    case SelfHostedIter::AllowContentWith: {
   5415      // This is the following case:
   5416      //
   5417      //   for (const nextValue of allowContentIterWith(items, usingIterator)) {
   5418      //
   5419      // `items` is emitted by `emitTree(value)` above, and the result is on the
   5420      // stack as ITERABLE.
   5421      // `usingIterator` is the value of `items[Symbol.iterator]`, that's
   5422      // already retrieved.
   5423      ListNode* argsList = value->as<CallNode>().args();
   5424      MOZ_ASSERT_IF(iterKind == IteratorKind::Sync, argsList->count() == 2);
   5425      MOZ_ASSERT_IF(iterKind == IteratorKind::Async, argsList->count() == 3);
   5426 
   5427      if (!emitTree(argsList->head()->pn_next)) {
   5428        //          [stack] ITERABLE ITERFN
   5429        return false;
   5430      }
   5431 
   5432      // Async iterator has two possible iterators: An async iterator and a sync
   5433      // iterator.
   5434      if (iterKind == IteratorKind::Async) {
   5435        if (!emitTree(argsList->head()->pn_next->pn_next)) {
   5436          //        [stack] ITERABLE ASYNC_ITERFN SYNC_ITERFN
   5437          return false;
   5438        }
   5439      }
   5440 
   5441      //            [stack] ITERABLE ASYNC_ITERFN? SYNC_ITERFN
   5442      return true;
   5443    }
   5444 
   5445    case SelfHostedIter::AllowContentWithNext: {
   5446      // This is the following case:
   5447      //
   5448      //   for (const nextValue of allowContentIterWithNext(iterator, next)) {
   5449      //
   5450      // `iterator` is emitted by `emitTree(value)` above, and the result is on
   5451      // the stack as ITER.
   5452      // `next` is the value of `iterator.next`, that's already retrieved.
   5453      ListNode* argsList = value->as<CallNode>().args();
   5454      MOZ_ASSERT(argsList->count() == 2);
   5455 
   5456      if (!emitTree(argsList->head()->pn_next)) {
   5457        //          [stack] ITER NEXT
   5458        return false;
   5459      }
   5460 
   5461      if (!emit1(JSOp::Swap)) {
   5462        //          [stack] NEXT ITER
   5463        return false;
   5464      }
   5465 
   5466      //            [stack] NEXT ITER
   5467      return true;
   5468    }
   5469  }
   5470 
   5471  MOZ_CRASH("invalid self-hosted iteration kind");
   5472 }
   5473 
   5474 bool BytecodeEmitter::emitIterator(SelfHostedIter selfHostedIter) {
   5475  MOZ_ASSERT(selfHostedIter != SelfHostedIter::Deny ||
   5476                 emitterMode != BytecodeEmitter::SelfHosting,
   5477             "[Symbol.iterator]() call is prohibited in self-hosted code "
   5478             "because it can run user-modifiable iteration code");
   5479 
   5480  if (selfHostedIter == SelfHostedIter::AllowContentWithNext) {
   5481    //              [stack] NEXT ITER
   5482 
   5483    // Nothing to do, stack already contains the iterator and its `next` method.
   5484    return true;
   5485  }
   5486 
   5487  if (selfHostedIter != SelfHostedIter::AllowContentWith) {
   5488    //              [stack] OBJ
   5489 
   5490    // Convert iterable to iterator.
   5491    if (!emit1(JSOp::Dup)) {
   5492      //            [stack] OBJ OBJ
   5493      return false;
   5494    }
   5495    if (!emit2(JSOp::Symbol, uint8_t(JS::SymbolCode::iterator))) {
   5496      //            [stack] OBJ OBJ @@ITERATOR
   5497      return false;
   5498    }
   5499    if (!emitElemOpBase(JSOp::GetElem)) {
   5500      //            [stack] OBJ ITERFN
   5501      return false;
   5502    }
   5503  }
   5504 
   5505  if (!emit1(JSOp::Swap)) {
   5506    //              [stack] ITERFN OBJ
   5507    return false;
   5508  }
   5509  if (!emitCall(getIterCallOp(JSOp::CallIter, selfHostedIter), 0)) {
   5510    //              [stack] ITER
   5511    return false;
   5512  }
   5513  if (!emitCheckIsObj(CheckIsObjectKind::GetIterator)) {
   5514    //              [stack] ITER
   5515    return false;
   5516  }
   5517  if (!emit1(JSOp::Dup)) {
   5518    //              [stack] ITER ITER
   5519    return false;
   5520  }
   5521  if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::next())) {
   5522    //              [stack] ITER NEXT
   5523    return false;
   5524  }
   5525  if (!emit1(JSOp::Swap)) {
   5526    //              [stack] NEXT ITER
   5527    return false;
   5528  }
   5529  return true;
   5530 }
   5531 
   5532 bool BytecodeEmitter::emitAsyncIterator(SelfHostedIter selfHostedIter) {
   5533  MOZ_ASSERT(selfHostedIter != SelfHostedIter::AllowContentWithNext);
   5534  MOZ_ASSERT(selfHostedIter != SelfHostedIter::Deny ||
   5535                 emitterMode != BytecodeEmitter::SelfHosting,
   5536             "[Symbol.asyncIterator]() call is prohibited in self-hosted code "
   5537             "because it can run user-modifiable iteration code");
   5538 
   5539  if (selfHostedIter != SelfHostedIter::AllowContentWith) {
   5540    //              [stack] OBJ
   5541 
   5542    // Convert iterable to iterator.
   5543    if (!emit1(JSOp::Dup)) {
   5544      //            [stack] OBJ OBJ
   5545      return false;
   5546    }
   5547    if (!emit2(JSOp::Symbol, uint8_t(JS::SymbolCode::asyncIterator))) {
   5548      //            [stack] OBJ OBJ @@ASYNCITERATOR
   5549      return false;
   5550    }
   5551    if (!emitElemOpBase(JSOp::GetElem)) {
   5552      //            [stack] OBJ ASYNC_ITERFN
   5553      return false;
   5554    }
   5555  } else {
   5556    //              [stack] OBJ ASYNC_ITERFN SYNC_ITERFN
   5557 
   5558    if (!emitElemOpBase(JSOp::Swap)) {
   5559      //            [stack] OBJ SYNC_ITERFN ASYNC_ITERFN
   5560      return false;
   5561    }
   5562  }
   5563 
   5564  InternalIfEmitter ifAsyncIterIsUndefined(this);
   5565  if (!emit1(JSOp::IsNullOrUndefined)) {
   5566    //              [stack] OBJ SYNC_ITERFN? ASYNC_ITERFN NULL-OR-UNDEF
   5567    return false;
   5568  }
   5569  if (!ifAsyncIterIsUndefined.emitThenElse()) {
   5570    //              [stack] OBJ SYNC_ITERFN? ASYNC_ITERFN
   5571    return false;
   5572  }
   5573 
   5574  if (!emit1(JSOp::Pop)) {
   5575    //              [stack] OBJ SYNC_ITERFN?
   5576    return false;
   5577  }
   5578 
   5579  if (selfHostedIter != SelfHostedIter::AllowContentWith) {
   5580    if (!emit1(JSOp::Dup)) {
   5581      //            [stack] OBJ OBJ
   5582      return false;
   5583    }
   5584    if (!emit2(JSOp::Symbol, uint8_t(JS::SymbolCode::iterator))) {
   5585      //            [stack] OBJ OBJ @@ITERATOR
   5586      return false;
   5587    }
   5588    if (!emitElemOpBase(JSOp::GetElem)) {
   5589      //            [stack] OBJ SYNC_ITERFN
   5590      return false;
   5591    }
   5592  } else {
   5593    //              [stack] OBJ SYNC_ITERFN
   5594  }
   5595 
   5596  if (!emit1(JSOp::Swap)) {
   5597    //              [stack] SYNC_ITERFN OBJ
   5598    return false;
   5599  }
   5600  if (!emitCall(getIterCallOp(JSOp::CallIter, selfHostedIter), 0)) {
   5601    //              [stack] ITER
   5602    return false;
   5603  }
   5604  if (!emitCheckIsObj(CheckIsObjectKind::GetIterator)) {
   5605    //              [stack] ITER
   5606    return false;
   5607  }
   5608 
   5609  if (!emit1(JSOp::Dup)) {
   5610    //              [stack] ITER ITER
   5611    return false;
   5612  }
   5613  if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::next())) {
   5614    //              [stack] ITER SYNCNEXT
   5615    return false;
   5616  }
   5617 
   5618  if (!emit1(JSOp::ToAsyncIter)) {
   5619    //              [stack] ITER
   5620    return false;
   5621  }
   5622 
   5623  if (!ifAsyncIterIsUndefined.emitElse()) {
   5624    //              [stack] OBJ SYNC_ITERFN? ASYNC_ITERFN
   5625    return false;
   5626  }
   5627 
   5628  if (selfHostedIter == SelfHostedIter::AllowContentWith) {
   5629    if (!emit1(JSOp::Swap)) {
   5630      //            [stack] OBJ ASYNC_ITERFN SYNC_ITERFN
   5631      return false;
   5632    }
   5633    if (!emit1(JSOp::Pop)) {
   5634      //            [stack] OBJ ASYNC_ITERFN
   5635      return false;
   5636    }
   5637  }
   5638 
   5639  if (!emit1(JSOp::Swap)) {
   5640    //              [stack] ASYNC_ITERFN OBJ
   5641    return false;
   5642  }
   5643  if (!emitCall(getIterCallOp(JSOp::CallIter, selfHostedIter), 0)) {
   5644    //              [stack] ITER
   5645    return false;
   5646  }
   5647  if (!emitCheckIsObj(CheckIsObjectKind::GetAsyncIterator)) {
   5648    //              [stack] ITER
   5649    return false;
   5650  }
   5651 
   5652  if (!ifAsyncIterIsUndefined.emitEnd()) {
   5653    //              [stack] ITER
   5654    return false;
   5655  }
   5656 
   5657  if (!emit1(JSOp::Dup)) {
   5658    //              [stack] ITER ITER
   5659    return false;
   5660  }
   5661  if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::next())) {
   5662    //              [stack] ITER NEXT
   5663    return false;
   5664  }
   5665  if (!emit1(JSOp::Swap)) {
   5666    //              [stack] NEXT ITER
   5667    return false;
   5668  }
   5669 
   5670  return true;
   5671 }
   5672 
   5673 bool BytecodeEmitter::emitSpread(SelfHostedIter selfHostedIter) {
   5674  LoopControl loopInfo(this, StatementKind::Spread);
   5675 
   5676  if (!loopInfo.emitLoopHead(this, Nothing())) {
   5677    //              [stack] NEXT ITER ARR I
   5678    return false;
   5679  }
   5680 
   5681  {
   5682 #ifdef DEBUG
   5683    auto loopDepth = bytecodeSection().stackDepth();
   5684 #endif
   5685 
   5686    // Spread operations can't contain |continue|, so don't bother setting loop
   5687    // and enclosing "update" offsets, as we do with for-loops.
   5688 
   5689    if (!emitDupAt(3, 2)) {
   5690      //            [stack] NEXT ITER ARR I NEXT ITER
   5691      return false;
   5692    }
   5693    if (!emitIteratorNext(Nothing(), IteratorKind::Sync, selfHostedIter)) {
   5694      //            [stack] NEXT ITER ARR I RESULT
   5695      return false;
   5696    }
   5697    if (!emit1(JSOp::Dup)) {
   5698      //            [stack] NEXT ITER ARR I RESULT RESULT
   5699      return false;
   5700    }
   5701    if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::done())) {
   5702      //            [stack] NEXT ITER ARR I RESULT DONE
   5703      return false;
   5704    }
   5705    if (!emitJump(JSOp::JumpIfTrue, &loopInfo.breaks)) {
   5706      //            [stack] NEXT ITER ARR I RESULT
   5707      return false;
   5708    }
   5709 
   5710    // Emit code to assign result.value to the iteration variable.
   5711    if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::value())) {
   5712      //            [stack] NEXT ITER ARR I VALUE
   5713      return false;
   5714    }
   5715    if (!emit1(JSOp::InitElemInc)) {
   5716      //            [stack] NEXT ITER ARR I
   5717      return false;
   5718    }
   5719 
   5720    if (!loopInfo.emitLoopEnd(this, JSOp::Goto, TryNoteKind::ForOf)) {
   5721      //            [stack] NEXT ITER ARR I
   5722      return false;
   5723    }
   5724 
   5725    MOZ_ASSERT(bytecodeSection().stackDepth() == loopDepth);
   5726  }
   5727 
   5728  // When we leave the loop body and jump to this point, the result value is
   5729  // still on the stack. Account for that by updating the stack depth
   5730  // manually.
   5731  bytecodeSection().setStackDepth(bytecodeSection().stackDepth() + 1);
   5732 
   5733  // No continues should occur in spreads.
   5734  MOZ_ASSERT(!loopInfo.continues.offset.valid());
   5735 
   5736  if (!emit2(JSOp::Pick, 4)) {
   5737    //              [stack] ITER ARR I RESULT NEXT
   5738    return false;
   5739  }
   5740  if (!emit2(JSOp::Pick, 4)) {
   5741    //              [stack] ARR I RESULT NEXT ITER
   5742    return false;
   5743  }
   5744 
   5745  return emitPopN(3);
   5746  //                [stack] ARR I
   5747 }
   5748 
   5749 bool BytecodeEmitter::emitInitializeForInOrOfTarget(TernaryNode* forHead) {
   5750  MOZ_ASSERT(forHead->isKind(ParseNodeKind::ForIn) ||
   5751             forHead->isKind(ParseNodeKind::ForOf));
   5752 
   5753  MOZ_ASSERT(bytecodeSection().stackDepth() >= 1,
   5754             "must have a per-iteration value for initializing");
   5755 
   5756  ParseNode* target = forHead->kid1();
   5757  MOZ_ASSERT(!forHead->kid2());
   5758 
   5759  // If the for-in/of loop didn't have a variable declaration, per-loop
   5760  // initialization is just assigning the iteration value to a target
   5761  // expression.
   5762  if (!target->is<DeclarationListNode>()) {
   5763    return emitAssignmentOrInit(ParseNodeKind::AssignExpr, target, nullptr);
   5764    //              [stack] ... ITERVAL
   5765  }
   5766 
   5767  // Otherwise, per-loop initialization is (possibly) declaration
   5768  // initialization.  If the declaration is a lexical declaration, it must be
   5769  // initialized.  If the declaration is a variable declaration, an
   5770  // assignment to that name (which does *not* necessarily assign to the
   5771  // variable!) must be generated.
   5772 
   5773  auto* declarationList = &target->as<DeclarationListNode>();
   5774  if (!updateSourceCoordNotes(declarationList->pn_pos.begin)) {
   5775    return false;
   5776  }
   5777 
   5778  target = declarationList->singleBinding();
   5779 
   5780  NameNode* nameNode = nullptr;
   5781  if (target->isKind(ParseNodeKind::Name)) {
   5782    nameNode = &target->as<NameNode>();
   5783  } else if (target->isKind(ParseNodeKind::AssignExpr)) {
   5784    BinaryNode* assignNode = &target->as<BinaryNode>();
   5785    if (assignNode->left()->is<NameNode>()) {
   5786      nameNode = &assignNode->left()->as<NameNode>();
   5787    }
   5788  }
   5789 
   5790  if (nameNode) {
   5791    auto nameAtom = nameNode->name();
   5792    NameOpEmitter noe(this, nameAtom, NameOpEmitter::Kind::Initialize);
   5793    if (!noe.prepareForRhs()) {
   5794      return false;
   5795    }
   5796    if (noe.emittedBindOp()) {
   5797      // Per-iteration initialization in for-in/of loops computes the
   5798      // iteration value *before* initializing.  Thus the initializing
   5799      // value may be buried under a bind-specific value on the stack.
   5800      // Swap it to the top of the stack.
   5801      MOZ_ASSERT(bytecodeSection().stackDepth() >= 2);
   5802      if (!emit1(JSOp::Swap)) {
   5803        return false;
   5804      }
   5805    } else {
   5806      // In cases of emitting a frame slot or environment slot,
   5807      // nothing needs be done.
   5808      MOZ_ASSERT(bytecodeSection().stackDepth() >= 1);
   5809    }
   5810 
   5811 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   5812    if (declarationList->isKind(ParseNodeKind::UsingDecl)) {
   5813      if (!innermostEmitterScope()->prepareForDisposableAssignment(
   5814              UsingHint::Sync)) {
   5815        //            [stack] ENV? V
   5816        return false;
   5817      }
   5818    } else if (declarationList->isKind(ParseNodeKind::AwaitUsingDecl)) {
   5819      if (!innermostEmitterScope()->prepareForDisposableAssignment(
   5820              UsingHint::Async)) {
   5821        //            [stack] ENV? V
   5822        return false;
   5823      }
   5824    }
   5825 #endif
   5826 
   5827    if (!noe.emitAssignment()) {
   5828      return false;
   5829    }
   5830 
   5831    // The caller handles removing the iteration value from the stack.
   5832    return true;
   5833  }
   5834 
   5835  MOZ_ASSERT(
   5836      !target->isKind(ParseNodeKind::AssignExpr),
   5837      "for-in/of loop destructuring declarations can't have initializers");
   5838 
   5839  MOZ_ASSERT(target->isKind(ParseNodeKind::ArrayExpr) ||
   5840             target->isKind(ParseNodeKind::ObjectExpr));
   5841  return emitDestructuringOps(&target->as<ListNode>(),
   5842                              DestructuringFlavor::Declaration,
   5843                              SelfHostedIter::Deny);
   5844 }
   5845 
   5846 bool BytecodeEmitter::emitForOf(ForNode* forOfLoop,
   5847                                const EmitterScope* headLexicalEmitterScope) {
   5848  MOZ_ASSERT(forOfLoop->isKind(ParseNodeKind::ForStmt));
   5849 
   5850  TernaryNode* forOfHead = forOfLoop->head();
   5851  MOZ_ASSERT(forOfHead->isKind(ParseNodeKind::ForOf));
   5852 
   5853  unsigned iflags = forOfLoop->iflags();
   5854  IteratorKind iterKind =
   5855      (iflags & JSITER_FORAWAITOF) ? IteratorKind::Async : IteratorKind::Sync;
   5856  MOZ_ASSERT_IF(iterKind == IteratorKind::Async, sc->isSuspendableContext());
   5857  MOZ_ASSERT_IF(iterKind == IteratorKind::Async,
   5858                sc->asSuspendableContext()->isAsync());
   5859 
   5860  ParseNode* forHeadExpr = forOfHead->kid3();
   5861 
   5862  // Certain builtins (e.g. Array.from) are implemented in self-hosting
   5863  // as for-of loops.
   5864  auto selfHostedIter = getSelfHostedIterFor(forHeadExpr);
   5865 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   5866  ForOfEmitter::HeadUsingDeclarationKind headUsingDeclKind =
   5867      ForOfEmitter::HeadUsingDeclarationKind::None;
   5868  if (forOfHead->kid1()->isKind(ParseNodeKind::UsingDecl)) {
   5869    headUsingDeclKind = ForOfEmitter::HeadUsingDeclarationKind::Sync;
   5870  } else if (forOfHead->kid1()->isKind(ParseNodeKind::AwaitUsingDecl)) {
   5871    headUsingDeclKind = ForOfEmitter::HeadUsingDeclarationKind::Async;
   5872  }
   5873 #endif
   5874 
   5875  ForOfEmitter forOf(this, headLexicalEmitterScope, selfHostedIter, iterKind
   5876 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   5877                     ,
   5878                     headUsingDeclKind
   5879 #endif
   5880  );
   5881 
   5882  if (!forOf.emitIterated()) {
   5883    //              [stack]
   5884    return false;
   5885  }
   5886 
   5887  if (!updateSourceCoordNotes(forHeadExpr->pn_pos.begin)) {
   5888    return false;
   5889  }
   5890  if (!markStepBreakpoint()) {
   5891    return false;
   5892  }
   5893  if (!emitIterable(forHeadExpr, selfHostedIter, iterKind)) {
   5894    //              [stack] ITERABLE
   5895    return false;
   5896  }
   5897 
   5898  if (headLexicalEmitterScope) {
   5899    DebugOnly<ParseNode*> forOfTarget = forOfHead->kid1();
   5900    MOZ_ASSERT(forOfTarget->isKind(ParseNodeKind::LetDecl) ||
   5901               forOfTarget->isKind(ParseNodeKind::ConstDecl)
   5902 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   5903               || forOfTarget->isKind(ParseNodeKind::UsingDecl) ||
   5904               forOfTarget->isKind(ParseNodeKind::AwaitUsingDecl)
   5905 #endif
   5906    );
   5907  }
   5908 
   5909  if (!forOf.emitInitialize(forOfHead->pn_pos.begin)) {
   5910    //              [stack] NEXT ITER VALUE
   5911    return false;
   5912  }
   5913 
   5914  if (!emitInitializeForInOrOfTarget(forOfHead)) {
   5915    //              [stack] NEXT ITER VALUE
   5916    return false;
   5917  }
   5918 
   5919  if (!forOf.emitBody()) {
   5920    //              [stack] NEXT ITER UNDEF
   5921    return false;
   5922  }
   5923 
   5924  // Perform the loop body.
   5925  ParseNode* forBody = forOfLoop->body();
   5926  if (!emitTree(forBody)) {
   5927    //              [stack] NEXT ITER UNDEF
   5928    return false;
   5929  }
   5930 
   5931  if (!forOf.emitEnd(forHeadExpr->pn_pos.begin)) {
   5932    //              [stack]
   5933    return false;
   5934  }
   5935 
   5936  return true;
   5937 }
   5938 
   5939 bool BytecodeEmitter::emitForIn(ForNode* forInLoop,
   5940                                const EmitterScope* headLexicalEmitterScope) {
   5941  TernaryNode* forInHead = forInLoop->head();
   5942  MOZ_ASSERT(forInHead->isKind(ParseNodeKind::ForIn));
   5943 
   5944  ForInEmitter forIn(this, headLexicalEmitterScope);
   5945 
   5946  // Annex B: Evaluate the var-initializer expression if present.
   5947  // |for (var i = initializer in expr) { ... }|
   5948  ParseNode* forInTarget = forInHead->kid1();
   5949  if (forInTarget->is<DeclarationListNode>()) {
   5950    auto* declarationList = &forInTarget->as<DeclarationListNode>();
   5951 
   5952    ParseNode* decl = declarationList->singleBinding();
   5953    if (decl->isKind(ParseNodeKind::AssignExpr)) {
   5954      BinaryNode* assignNode = &decl->as<BinaryNode>();
   5955      if (assignNode->left()->is<NameNode>()) {
   5956        NameNode* nameNode = &assignNode->left()->as<NameNode>();
   5957        ParseNode* initializer = assignNode->right();
   5958        MOZ_ASSERT(
   5959            forInTarget->isKind(ParseNodeKind::VarStmt),
   5960            "for-in initializers are only permitted for |var| declarations");
   5961 
   5962        if (!updateSourceCoordNotes(decl->pn_pos.begin)) {
   5963          return false;
   5964        }
   5965 
   5966        auto nameAtom = nameNode->name();
   5967        NameOpEmitter noe(this, nameAtom, NameOpEmitter::Kind::Initialize);
   5968        if (!noe.prepareForRhs()) {
   5969          return false;
   5970        }
   5971        if (!emitInitializer(initializer, nameNode)) {
   5972          return false;
   5973        }
   5974        if (!noe.emitAssignment()) {
   5975          return false;
   5976        }
   5977 
   5978        // Pop the initializer.
   5979        if (!emit1(JSOp::Pop)) {
   5980          return false;
   5981        }
   5982      }
   5983    }
   5984  }
   5985 
   5986  if (!forIn.emitIterated()) {
   5987    //              [stack]
   5988    return false;
   5989  }
   5990 
   5991  // Evaluate the expression being iterated.
   5992  ParseNode* expr = forInHead->kid3();
   5993 
   5994  if (!updateSourceCoordNotes(expr->pn_pos.begin)) {
   5995    return false;
   5996  }
   5997  if (!markStepBreakpoint()) {
   5998    return false;
   5999  }
   6000  if (!emitTree(expr)) {
   6001    //              [stack] EXPR
   6002    return false;
   6003  }
   6004 
   6005  MOZ_ASSERT(forInLoop->iflags() == 0);
   6006 
   6007  MOZ_ASSERT_IF(headLexicalEmitterScope,
   6008                forInTarget->isKind(ParseNodeKind::LetDecl) ||
   6009                    forInTarget->isKind(ParseNodeKind::ConstDecl));
   6010 
   6011  if (!forIn.emitInitialize()) {
   6012    //              [stack] ITER ITERVAL
   6013    return false;
   6014  }
   6015 
   6016  if (!emitInitializeForInOrOfTarget(forInHead)) {
   6017    //              [stack] ITER ITERVAL
   6018    return false;
   6019  }
   6020 
   6021  if (!forIn.emitBody()) {
   6022    //              [stack] ITER ITERVAL
   6023    return false;
   6024  }
   6025 
   6026  // Perform the loop body.
   6027  ParseNode* forBody = forInLoop->body();
   6028  if (!emitTree(forBody)) {
   6029    //              [stack] ITER ITERVAL
   6030    return false;
   6031  }
   6032 
   6033  if (!forIn.emitEnd(forInHead->pn_pos.begin)) {
   6034    //              [stack]
   6035    return false;
   6036  }
   6037 
   6038  return true;
   6039 }
   6040 
   6041 /* C-style `for (init; cond; update) ...` loop. */
   6042 bool BytecodeEmitter::emitCStyleFor(
   6043    ForNode* forNode, const EmitterScope* headLexicalEmitterScope) {
   6044  TernaryNode* forHead = forNode->head();
   6045  ParseNode* forBody = forNode->body();
   6046  ParseNode* init = forHead->kid1();
   6047  ParseNode* cond = forHead->kid2();
   6048  ParseNode* update = forHead->kid3();
   6049  bool isLet = init && init->isKind(ParseNodeKind::LetDecl);
   6050 
   6051  CForEmitter cfor(this, isLet ? headLexicalEmitterScope : nullptr);
   6052 
   6053  if (!cfor.emitInit(init ? Some(init->pn_pos.begin) : Nothing())) {
   6054    //              [stack]
   6055    return false;
   6056  }
   6057 
   6058  // If the head of this for-loop declared any lexical variables, the parser
   6059  // wrapped this ParseNodeKind::For node in a ParseNodeKind::LexicalScope
   6060  // representing the implicit scope of those variables. By the time we get
   6061  // here, we have already entered that scope. So far, so good.
   6062  if (init) {
   6063    // Emit the `init` clause, whether it's an expression or a variable
   6064    // declaration. (The loop variables were hoisted into an enclosing
   6065    // scope, but we still need to emit code for the initializers.)
   6066    if (init->is<DeclarationListNode>()) {
   6067      MOZ_ASSERT(!init->as<DeclarationListNode>().empty());
   6068 
   6069      if (!emitTree(init)) {
   6070        //          [stack]
   6071        return false;
   6072      }
   6073    } else {
   6074      if (!updateSourceCoordNotes(init->pn_pos.begin)) {
   6075        return false;
   6076      }
   6077      if (!markStepBreakpoint()) {
   6078        return false;
   6079      }
   6080 
   6081      // 'init' is an expression, not a declaration. emitTree left its
   6082      // value on the stack.
   6083      if (!emitTree(init, ValueUsage::IgnoreValue)) {
   6084        //          [stack] VAL
   6085        return false;
   6086      }
   6087      if (!emit1(JSOp::Pop)) {
   6088        //          [stack]
   6089        return false;
   6090      }
   6091    }
   6092  }
   6093 
   6094  if (!cfor.emitCond(cond ? Some(cond->pn_pos.begin) : Nothing())) {
   6095    //              [stack]
   6096    return false;
   6097  }
   6098 
   6099  if (cond) {
   6100    if (!updateSourceCoordNotes(cond->pn_pos.begin)) {
   6101      return false;
   6102    }
   6103    if (!markStepBreakpoint()) {
   6104      return false;
   6105    }
   6106    if (!emitTree(cond)) {
   6107      //            [stack] VAL
   6108      return false;
   6109    }
   6110  }
   6111 
   6112  if (!cfor.emitBody(cond ? CForEmitter::Cond::Present
   6113                          : CForEmitter::Cond::Missing)) {
   6114    //              [stack]
   6115    return false;
   6116  }
   6117 
   6118  if (!emitTree(forBody)) {
   6119    //              [stack]
   6120    return false;
   6121  }
   6122 
   6123  if (!cfor.emitUpdate(
   6124          update ? CForEmitter::Update::Present : CForEmitter::Update::Missing,
   6125          update ? Some(update->pn_pos.begin) : Nothing())) {
   6126    //              [stack]
   6127    return false;
   6128  }
   6129 
   6130  // Check for update code to do before the condition (if any).
   6131  if (update) {
   6132    if (!updateSourceCoordNotes(update->pn_pos.begin)) {
   6133      return false;
   6134    }
   6135    if (!markStepBreakpoint()) {
   6136      return false;
   6137    }
   6138    if (!emitTree(update, ValueUsage::IgnoreValue)) {
   6139      //            [stack] VAL
   6140      return false;
   6141    }
   6142  }
   6143 
   6144  if (!cfor.emitEnd(forNode->pn_pos.begin)) {
   6145    //              [stack]
   6146    return false;
   6147  }
   6148 
   6149  return true;
   6150 }
   6151 
   6152 bool BytecodeEmitter::emitFor(ForNode* forNode,
   6153                              const EmitterScope* headLexicalEmitterScope) {
   6154  if (forNode->head()->isKind(ParseNodeKind::ForHead)) {
   6155    return emitCStyleFor(forNode, headLexicalEmitterScope);
   6156  }
   6157 
   6158  if (!updateLineNumberNotes(forNode->pn_pos.begin)) {
   6159    return false;
   6160  }
   6161 
   6162  if (forNode->head()->isKind(ParseNodeKind::ForIn)) {
   6163    return emitForIn(forNode, headLexicalEmitterScope);
   6164  }
   6165 
   6166  MOZ_ASSERT(forNode->head()->isKind(ParseNodeKind::ForOf));
   6167  return emitForOf(forNode, headLexicalEmitterScope);
   6168 }
   6169 
   6170 MOZ_NEVER_INLINE bool BytecodeEmitter::emitFunction(
   6171    FunctionNode* funNode, bool needsProto /* = false */) {
   6172  FunctionBox* funbox = funNode->funbox();
   6173 
   6174  //                [stack]
   6175 
   6176  FunctionEmitter fe(this, funbox, funNode->syntaxKind(),
   6177                     funNode->functionIsHoisted()
   6178                         ? FunctionEmitter::IsHoisted::Yes
   6179                         : FunctionEmitter::IsHoisted::No);
   6180 
   6181  // |wasEmittedByEnclosingScript| flag is set to true once the function has
   6182  // been emitted. Function definitions that need hoisting to the top of the
   6183  // function will be seen by emitFunction in two places.
   6184  if (funbox->wasEmittedByEnclosingScript()) {
   6185    if (!fe.emitAgain()) {
   6186      //            [stack]
   6187      return false;
   6188    }
   6189    MOZ_ASSERT(funNode->functionIsHoisted());
   6190  } else if (funbox->isInterpreted()) {
   6191    if (!funbox->emitBytecode) {
   6192      return fe.emitLazy();
   6193      //            [stack] FUN?
   6194    }
   6195 
   6196    if (!fe.prepareForNonLazy()) {
   6197      //            [stack]
   6198      return false;
   6199    }
   6200 
   6201    BytecodeEmitter bce2(this, funbox);
   6202    if (!bce2.init(funNode->pn_pos)) {
   6203      return false;
   6204    }
   6205 
   6206    /* We measured the max scope depth when we parsed the function. */
   6207    if (!bce2.emitFunctionScript(funNode)) {
   6208      return false;
   6209    }
   6210 
   6211    if (!fe.emitNonLazyEnd()) {
   6212      //            [stack] FUN?
   6213      return false;
   6214    }
   6215  } else {
   6216    if (!fe.emitAsmJSModule()) {
   6217      //            [stack]
   6218      return false;
   6219    }
   6220  }
   6221 
   6222  // Track the last emitted top-level self-hosted function, so that intrinsics
   6223  // can adjust attributes at parse time.
   6224  //
   6225  // NOTE: We also disallow lambda functions in the top-level body. This is done
   6226  // to simplify handling of the self-hosted stencil. Within normal function
   6227  // declarations there are no such restrictions.
   6228  if (emitterMode == EmitterMode::SelfHosting) {
   6229    if (sc->isTopLevelContext()) {
   6230      MOZ_ASSERT(!funbox->isLambda());
   6231      MOZ_ASSERT(funbox->explicitName());
   6232      prevSelfHostedTopLevelFunction = funbox;
   6233    }
   6234  }
   6235 
   6236  return true;
   6237 }
   6238 
   6239 bool BytecodeEmitter::emitDo(BinaryNode* doNode) {
   6240  ParseNode* bodyNode = doNode->left();
   6241 
   6242  DoWhileEmitter doWhile(this);
   6243  if (!doWhile.emitBody(doNode->pn_pos.begin, getOffsetForLoop(bodyNode))) {
   6244    return false;
   6245  }
   6246 
   6247  if (!emitTree(bodyNode)) {
   6248    return false;
   6249  }
   6250 
   6251  if (!doWhile.emitCond()) {
   6252    return false;
   6253  }
   6254 
   6255  ParseNode* condNode = doNode->right();
   6256  if (!updateSourceCoordNotes(condNode->pn_pos.begin)) {
   6257    return false;
   6258  }
   6259  if (!markStepBreakpoint()) {
   6260    return false;
   6261  }
   6262  if (!emitTree(condNode)) {
   6263    return false;
   6264  }
   6265 
   6266  if (!doWhile.emitEnd()) {
   6267    return false;
   6268  }
   6269 
   6270  return true;
   6271 }
   6272 
   6273 bool BytecodeEmitter::emitWhile(BinaryNode* whileNode) {
   6274  ParseNode* bodyNode = whileNode->right();
   6275 
   6276  WhileEmitter wh(this);
   6277 
   6278  ParseNode* condNode = whileNode->left();
   6279  if (!wh.emitCond(whileNode->pn_pos.begin, getOffsetForLoop(condNode),
   6280                   whileNode->pn_pos.end)) {
   6281    return false;
   6282  }
   6283 
   6284  if (!updateSourceCoordNotes(condNode->pn_pos.begin)) {
   6285    return false;
   6286  }
   6287  if (!markStepBreakpoint()) {
   6288    return false;
   6289  }
   6290  if (!emitTree(condNode)) {
   6291    return false;
   6292  }
   6293 
   6294  if (!wh.emitBody()) {
   6295    return false;
   6296  }
   6297  if (!emitTree(bodyNode)) {
   6298    return false;
   6299  }
   6300 
   6301  if (!wh.emitEnd()) {
   6302    return false;
   6303  }
   6304 
   6305  return true;
   6306 }
   6307 
   6308 bool BytecodeEmitter::emitBreak(TaggedParserAtomIndex label) {
   6309  BreakableControl* target;
   6310  if (label) {
   6311    // Any statement with the matching label may be the break target.
   6312    auto hasSameLabel = [label](LabelControl* labelControl) {
   6313      return labelControl->label() == label;
   6314    };
   6315    target = findInnermostNestableControl<LabelControl>(hasSameLabel);
   6316  } else {
   6317    auto isNotLabel = [](BreakableControl* control) {
   6318      return !control->is<LabelControl>();
   6319    };
   6320    target = findInnermostNestableControl<BreakableControl>(isNotLabel);
   6321  }
   6322 
   6323  return emitGoto(target, GotoKind::Break);
   6324 }
   6325 
   6326 bool BytecodeEmitter::emitContinue(TaggedParserAtomIndex label) {
   6327  LoopControl* target = nullptr;
   6328  if (label) {
   6329    // Find the loop statement enclosed by the matching label.
   6330    NestableControl* control = innermostNestableControl;
   6331    while (!control->is<LabelControl>() ||
   6332           control->as<LabelControl>().label() != label) {
   6333      if (control->is<LoopControl>()) {
   6334        target = &control->as<LoopControl>();
   6335      }
   6336      control = control->enclosing();
   6337    }
   6338  } else {
   6339    target = findInnermostNestableControl<LoopControl>();
   6340  }
   6341  return emitGoto(target, GotoKind::Continue);
   6342 }
   6343 
   6344 bool BytecodeEmitter::emitGetFunctionThis(NameNode* thisName) {
   6345  MOZ_ASSERT(sc->hasFunctionThisBinding());
   6346  MOZ_ASSERT(thisName->isName(TaggedParserAtomIndex::WellKnown::dot_this_()));
   6347 
   6348  if (!updateLineNumberNotes(thisName->pn_pos.begin)) {
   6349    return false;
   6350  }
   6351 
   6352  if (!emitGetName(TaggedParserAtomIndex::WellKnown::dot_this_())) {
   6353    //              [stack] THIS
   6354    return false;
   6355  }
   6356  if (sc->needsThisTDZChecks()) {
   6357    if (!emit1(JSOp::CheckThis)) {
   6358      //            [stack] THIS
   6359      return false;
   6360    }
   6361  }
   6362 
   6363  return true;
   6364 }
   6365 
   6366 bool BytecodeEmitter::emitGetThisForSuperBase(UnaryNode* superBase) {
   6367  MOZ_ASSERT(superBase->isKind(ParseNodeKind::SuperBase));
   6368  NameNode* nameNode = &superBase->kid()->as<NameNode>();
   6369  return emitGetFunctionThis(nameNode);
   6370  //                [stack] THIS
   6371 }
   6372 
   6373 bool BytecodeEmitter::emitThisLiteral(ThisLiteral* pn) {
   6374  if (ParseNode* kid = pn->kid()) {
   6375    NameNode* thisName = &kid->as<NameNode>();
   6376    return emitGetFunctionThis(thisName);
   6377    //              [stack] THIS
   6378  }
   6379 
   6380  if (sc->thisBinding() == ThisBinding::Module) {
   6381    return emit1(JSOp::Undefined);
   6382    //              [stack] UNDEF
   6383  }
   6384 
   6385  MOZ_ASSERT(sc->thisBinding() == ThisBinding::Global);
   6386 
   6387  MOZ_ASSERT(outermostScope().hasNonSyntacticScopeOnChain() ==
   6388             sc->hasNonSyntacticScope());
   6389  if (sc->hasNonSyntacticScope()) {
   6390    return emit1(JSOp::NonSyntacticGlobalThis);
   6391    //                [stack] THIS
   6392  }
   6393 
   6394  return emit1(JSOp::GlobalThis);
   6395  //                [stack] THIS
   6396 }
   6397 
   6398 bool BytecodeEmitter::emitCheckDerivedClassConstructorReturn() {
   6399  MOZ_ASSERT(
   6400      lookupName(TaggedParserAtomIndex::WellKnown::dot_this_()).hasKnownSlot());
   6401  if (!emitGetName(TaggedParserAtomIndex::WellKnown::dot_this_())) {
   6402    return false;
   6403  }
   6404  if (!emit1(JSOp::CheckReturn)) {
   6405    return false;
   6406  }
   6407  if (!emit1(JSOp::SetRval)) {
   6408    return false;
   6409  }
   6410  return true;
   6411 }
   6412 
   6413 bool BytecodeEmitter::emitNewTarget() {
   6414  MOZ_ASSERT(sc->allowNewTarget());
   6415 
   6416  if (!emitGetName(TaggedParserAtomIndex::WellKnown::dot_newTarget_())) {
   6417    //              [stack] NEW.TARGET
   6418    return false;
   6419  }
   6420  return true;
   6421 }
   6422 
   6423 bool BytecodeEmitter::emitNewTarget(NewTargetNode* pn) {
   6424  MOZ_ASSERT(pn->newTargetName()->isName(
   6425      TaggedParserAtomIndex::WellKnown::dot_newTarget_()));
   6426 
   6427  return emitNewTarget();
   6428 }
   6429 
   6430 bool BytecodeEmitter::emitNewTarget(CallNode* pn) {
   6431  MOZ_ASSERT(pn->callOp() == JSOp::SuperCall ||
   6432             pn->callOp() == JSOp::SpreadSuperCall);
   6433 
   6434  // The parser is responsible for marking the "new.target" binding as being
   6435  // implicitly used in super() calls.
   6436  return emitNewTarget();
   6437 }
   6438 
   6439 bool BytecodeEmitter::emitReturn(UnaryNode* returnNode) {
   6440  if (!updateSourceCoordNotes(returnNode->pn_pos.begin)) {
   6441    return false;
   6442  }
   6443 
   6444  if (!markStepBreakpoint()) {
   6445    return false;
   6446  }
   6447 
   6448  /* Push a return value */
   6449  if (ParseNode* expr = returnNode->kid()) {
   6450    if (!emitTree(expr)) {
   6451      return false;
   6452    }
   6453 
   6454    if (sc->asSuspendableContext()->isAsync() &&
   6455        sc->asSuspendableContext()->isGenerator()) {
   6456      if (!emitAwaitInInnermostScope()) {
   6457        return false;
   6458      }
   6459    }
   6460  } else {
   6461    /* No explicit return value provided */
   6462    if (!emit1(JSOp::Undefined)) {
   6463      return false;
   6464    }
   6465  }
   6466 
   6467  // We know functionBodyEndPos is set because "return" is only
   6468  // valid in a function, and so we've passed through
   6469  // emitFunctionScript.
   6470  if (!updateSourceCoordNotes(*functionBodyEndPos)) {
   6471    return false;
   6472  }
   6473 
   6474  /*
   6475   * The return value is currently on the stack. We would like to
   6476   * generate JSOp::Return, but if we have work to do before returning,
   6477   * we will instead generate JSOp::SetRval / JSOp::RetRval.
   6478   *
   6479   * We don't know whether we will need fixup code until after calling
   6480   * prepareForNonLocalJumpToOutermost, so we start by generating
   6481   * JSOp::SetRval, then mutate it to JSOp::Return in finishReturn if it
   6482   * wasn't needed.
   6483   */
   6484  BytecodeOffset setRvalOffset = bytecodeSection().offset();
   6485  if (!emit1(JSOp::SetRval)) {
   6486    return false;
   6487  }
   6488 
   6489  NonLocalExitControl nle(this, NonLocalExitKind::Return);
   6490  return nle.emitReturn(setRvalOffset);
   6491 }
   6492 
   6493 bool BytecodeEmitter::finishReturn(BytecodeOffset setRvalOffset) {
   6494  // The return value is currently in rval. Depending on the current function,
   6495  // we may have to do additional work before returning:
   6496  // - Derived class constructors must check if the return value is an object.
   6497  // - Generators and async functions must do a final yield.
   6498  // - Non-async generators must return the value as an iterator result:
   6499  //   { value: <rval>, done: true }
   6500  // - Non-generator async functions must resolve the function's result promise
   6501  //   with the value.
   6502  //
   6503  // If we have not generated any code since the SetRval that stored the return
   6504  // value, we can also optimize the bytecode by rewriting that SetRval as a
   6505  // JSOp::Return. See |emitReturn| above.
   6506 
   6507  bool isDerivedClassConstructor =
   6508      sc->isFunctionBox() && sc->asFunctionBox()->isDerivedClassConstructor();
   6509  bool needsFinalYield =
   6510      sc->isFunctionBox() && sc->asFunctionBox()->needsFinalYield();
   6511  bool isSimpleReturn =
   6512      setRvalOffset.valid() &&
   6513      setRvalOffset + BytecodeOffsetDiff(JSOpLength_SetRval) ==
   6514          bytecodeSection().offset();
   6515 
   6516  if (isDerivedClassConstructor) {
   6517    MOZ_ASSERT(!needsFinalYield);
   6518    if (!emitJump(JSOp::Goto, &endOfDerivedClassConstructorBody)) {
   6519      return false;
   6520    }
   6521    return true;
   6522  }
   6523 
   6524  if (needsFinalYield) {
   6525    if (!emitJump(JSOp::Goto, &finalYields)) {
   6526      return false;
   6527    }
   6528    return true;
   6529  }
   6530 
   6531  if (isSimpleReturn) {
   6532    MOZ_ASSERT(JSOp(bytecodeSection().code()[setRvalOffset.value()]) ==
   6533               JSOp::SetRval);
   6534    bytecodeSection().code()[setRvalOffset.value()] = jsbytecode(JSOp::Return);
   6535    return true;
   6536  }
   6537 
   6538  // Nothing special needs to be done.
   6539  return emitReturnRval();
   6540 }
   6541 
   6542 bool BytecodeEmitter::emitGetDotGeneratorInScope(EmitterScope& currentScope) {
   6543  if (!sc->isFunction() && sc->isModuleContext() &&
   6544      sc->asModuleContext()->isAsync()) {
   6545    NameLocation loc = *locationOfNameBoundInScopeType<ModuleScope>(
   6546        TaggedParserAtomIndex::WellKnown::dot_generator_(), &currentScope);
   6547    return emitGetNameAtLocation(
   6548        TaggedParserAtomIndex::WellKnown::dot_generator_(), loc);
   6549  }
   6550  NameLocation loc = *locationOfNameBoundInScopeType<FunctionScope>(
   6551      TaggedParserAtomIndex::WellKnown::dot_generator_(), &currentScope);
   6552  return emitGetNameAtLocation(
   6553      TaggedParserAtomIndex::WellKnown::dot_generator_(), loc);
   6554 }
   6555 
   6556 bool BytecodeEmitter::emitInitialYield(UnaryNode* yieldNode) {
   6557  if (!emitTree(yieldNode->kid())) {
   6558    return false;
   6559  }
   6560 
   6561  if (!emitYieldOp(JSOp::InitialYield)) {
   6562    //              [stack] RVAL GENERATOR RESUMEKIND
   6563    return false;
   6564  }
   6565  if (!emit1(JSOp::CheckResumeKind)) {
   6566    //              [stack] RVAL
   6567    return false;
   6568  }
   6569  if (!emit1(JSOp::Pop)) {
   6570    //              [stack]
   6571    return false;
   6572  }
   6573 
   6574  return true;
   6575 }
   6576 
   6577 bool BytecodeEmitter::emitYield(UnaryNode* yieldNode) {
   6578  MOZ_ASSERT(sc->isFunctionBox());
   6579  MOZ_ASSERT(sc->asFunctionBox()->isGenerator());
   6580  MOZ_ASSERT(yieldNode->isKind(ParseNodeKind::YieldExpr));
   6581 
   6582  bool needsIteratorResult = sc->asFunctionBox()->needsIteratorResult();
   6583  if (needsIteratorResult) {
   6584    if (!emitPrepareIteratorResult()) {
   6585      //            [stack] ITEROBJ
   6586      return false;
   6587    }
   6588  }
   6589  if (ParseNode* expr = yieldNode->kid()) {
   6590    if (!emitTree(expr)) {
   6591      //            [stack] ITEROBJ? VAL
   6592      return false;
   6593    }
   6594  } else {
   6595    if (!emit1(JSOp::Undefined)) {
   6596      //            [stack] ITEROBJ? UNDEFINED
   6597      return false;
   6598    }
   6599  }
   6600 
   6601  if (sc->asSuspendableContext()->isAsync()) {
   6602    MOZ_ASSERT(!needsIteratorResult);
   6603    if (!emitAwaitInInnermostScope()) {
   6604      //            [stack] RESULT
   6605      return false;
   6606    }
   6607  }
   6608 
   6609  if (needsIteratorResult) {
   6610    if (!emitFinishIteratorResult(false)) {
   6611      //            [stack] ITEROBJ
   6612      return false;
   6613    }
   6614  }
   6615 
   6616  if (!emitGetDotGeneratorInInnermostScope()) {
   6617    //              [stack] # if needsIteratorResult
   6618    //              [stack] ITEROBJ .GENERATOR
   6619    //              [stack] # else
   6620    //              [stack] RESULT .GENERATOR
   6621    return false;
   6622  }
   6623 
   6624  if (!emitYieldOp(JSOp::Yield)) {
   6625    //              [stack] YIELDRESULT GENERATOR RESUMEKIND
   6626    return false;
   6627  }
   6628 
   6629  if (!emit1(JSOp::CheckResumeKind)) {
   6630    //              [stack] YIELDRESULT
   6631    return false;
   6632  }
   6633 
   6634  return true;
   6635 }
   6636 
   6637 bool BytecodeEmitter::emitAwaitInInnermostScope(UnaryNode* awaitNode) {
   6638  MOZ_ASSERT(sc->isSuspendableContext());
   6639  MOZ_ASSERT(awaitNode->isKind(ParseNodeKind::AwaitExpr));
   6640 
   6641  if (!emitTree(awaitNode->kid())) {
   6642    return false;
   6643  }
   6644  return emitAwaitInInnermostScope();
   6645 }
   6646 
   6647 bool BytecodeEmitter::emitAwaitInScope(EmitterScope& currentScope) {
   6648  if (!emit1(JSOp::CanSkipAwait)) {
   6649    //              [stack] VALUE CANSKIP
   6650    return false;
   6651  }
   6652 
   6653  if (!emit1(JSOp::MaybeExtractAwaitValue)) {
   6654    //              [stack] VALUE_OR_RESOLVED CANSKIP
   6655    return false;
   6656  }
   6657 
   6658  InternalIfEmitter ifCanSkip(this);
   6659  if (!ifCanSkip.emitThen(IfEmitter::ConditionKind::Negative)) {
   6660    //              [stack] VALUE_OR_RESOLVED
   6661    return false;
   6662  }
   6663 
   6664  if (sc->asSuspendableContext()->needsPromiseResult()) {
   6665    if (!emitGetDotGeneratorInScope(currentScope)) {
   6666      //            [stack] VALUE GENERATOR
   6667      return false;
   6668    }
   6669    if (!emit1(JSOp::AsyncAwait)) {
   6670      //            [stack] PROMISE
   6671      return false;
   6672    }
   6673  }
   6674 
   6675  if (!emitGetDotGeneratorInScope(currentScope)) {
   6676    //              [stack] VALUE|PROMISE GENERATOR
   6677    return false;
   6678  }
   6679  if (!emitYieldOp(JSOp::Await)) {
   6680    //              [stack] RESOLVED GENERATOR RESUMEKIND
   6681    return false;
   6682  }
   6683  if (!emit1(JSOp::CheckResumeKind)) {
   6684    //              [stack] RESOLVED
   6685    return false;
   6686  }
   6687 
   6688  if (!ifCanSkip.emitEnd()) {
   6689    return false;
   6690  }
   6691 
   6692  MOZ_ASSERT(ifCanSkip.popped() == 0);
   6693 
   6694  return true;
   6695 }
   6696 
   6697 // ES2019 draft rev 49b781ec80117b60f73327ef3054703a3111e40c
   6698 // 14.4.14 Runtime Semantics: Evaluation
   6699 // YieldExpression : yield* AssignmentExpression
   6700 bool BytecodeEmitter::emitYieldStar(ParseNode* iter) {
   6701  MOZ_ASSERT(getSelfHostedIterFor(iter) == SelfHostedIter::Deny,
   6702             "yield* is prohibited in self-hosted code because it can run "
   6703             "user-modifiable iteration code");
   6704 
   6705  MOZ_ASSERT(sc->isSuspendableContext());
   6706  MOZ_ASSERT(sc->asSuspendableContext()->isGenerator());
   6707 
   6708  // Step 1.
   6709  IteratorKind iterKind = sc->asSuspendableContext()->isAsync()
   6710                              ? IteratorKind::Async
   6711                              : IteratorKind::Sync;
   6712  bool needsIteratorResult = sc->asSuspendableContext()->needsIteratorResult();
   6713 
   6714  // Steps 2-5.
   6715  if (!emitTree(iter)) {
   6716    //              [stack] ITERABLE
   6717    return false;
   6718  }
   6719  if (iterKind == IteratorKind::Async) {
   6720    if (!emitAsyncIterator(SelfHostedIter::Deny)) {
   6721      //            [stack] NEXT ITER
   6722      return false;
   6723    }
   6724  } else {
   6725    if (!emitIterator(SelfHostedIter::Deny)) {
   6726      //            [stack] NEXT ITER
   6727      return false;
   6728    }
   6729  }
   6730 
   6731  // Step 6.
   6732  // Start with NormalCompletion(undefined).
   6733  if (!emit1(JSOp::Undefined)) {
   6734    //              [stack] NEXT ITER RECEIVED
   6735    return false;
   6736  }
   6737  if (!emitPushResumeKind(GeneratorResumeKind::Next)) {
   6738    //              [stack] NEXT ITER RECEIVED RESUMEKIND
   6739    return false;
   6740  }
   6741 
   6742  const int32_t startDepth = bytecodeSection().stackDepth();
   6743  MOZ_ASSERT(startDepth >= 4);
   6744 
   6745  // Step 7 is a loop.
   6746  LoopControl loopInfo(this, StatementKind::YieldStar);
   6747  if (!loopInfo.emitLoopHead(this, Nothing())) {
   6748    //              [stack] NEXT ITER RECEIVED RESUMEKIND
   6749    return false;
   6750  }
   6751 
   6752  // Step 7.a. Check for Normal completion.
   6753  if (!emit1(JSOp::Dup)) {
   6754    //              [stack] NEXT ITER RECEIVED RESUMEKIND RESUMEKIND
   6755    return false;
   6756  }
   6757  if (!emitPushResumeKind(GeneratorResumeKind::Next)) {
   6758    //              [stack] NEXT ITER RECEIVED RESUMEKIND RESUMEKIND NORMAL
   6759    return false;
   6760  }
   6761  if (!emit1(JSOp::StrictEq)) {
   6762    //              [stack] NEXT ITER RECEIVED RESUMEKIND IS_NORMAL
   6763    return false;
   6764  }
   6765 
   6766  InternalIfEmitter ifKind(this);
   6767  if (!ifKind.emitThenElse()) {
   6768    //              [stack] NEXT ITER RECEIVED RESUMEKIND
   6769    return false;
   6770  }
   6771  {
   6772    if (!emit1(JSOp::Pop)) {
   6773      //            [stack] NEXT ITER RECEIVED
   6774      return false;
   6775    }
   6776 
   6777    // Step 7.a.i.
   6778    // result = iter.next(received)
   6779    if (!emit2(JSOp::Unpick, 2)) {
   6780      //            [stack] RECEIVED NEXT ITER
   6781      return false;
   6782    }
   6783    if (!emit1(JSOp::Dup2)) {
   6784      //            [stack] RECEIVED NEXT ITER NEXT ITER
   6785      return false;
   6786    }
   6787    if (!emit2(JSOp::Pick, 4)) {
   6788      //            [stack] NEXT ITER NEXT ITER RECEIVED
   6789      return false;
   6790    }
   6791    if (!emitCall(JSOp::Call, 1, iter)) {
   6792      //            [stack] NEXT ITER RESULT
   6793      return false;
   6794    }
   6795 
   6796    // Step 7.a.ii.
   6797    if (iterKind == IteratorKind::Async) {
   6798      if (!emitAwaitInInnermostScope()) {
   6799        //          [stack] NEXT ITER RESULT
   6800        return false;
   6801      }
   6802    }
   6803 
   6804    // Step 7.a.iii.
   6805    if (!emitCheckIsObj(CheckIsObjectKind::IteratorNext)) {
   6806      //            [stack] NEXT ITER RESULT
   6807      return false;
   6808    }
   6809 
   6810    // Bytecode for steps 7.a.iv-vii is emitted after the ifKind if-else because
   6811    // it's shared with other branches.
   6812  }
   6813 
   6814  // Step 7.b. Check for Throw completion.
   6815  if (!ifKind.emitElseIf(Nothing())) {
   6816    //              [stack] NEXT ITER RECEIVED RESUMEKIND
   6817    return false;
   6818  }
   6819  if (!emit1(JSOp::Dup)) {
   6820    //              [stack] NEXT ITER RECEIVED RESUMEKIND RESUMEKIND
   6821    return false;
   6822  }
   6823  if (!emitPushResumeKind(GeneratorResumeKind::Throw)) {
   6824    //              [stack] NEXT ITER RECEIVED RESUMEKIND RESUMEKIND THROW
   6825    return false;
   6826  }
   6827  if (!emit1(JSOp::StrictEq)) {
   6828    //              [stack] NEXT ITER RECEIVED RESUMEKIND IS_THROW
   6829    return false;
   6830  }
   6831  if (!ifKind.emitThenElse()) {
   6832    //              [stack] NEXT ITER RECEIVED RESUMEKIND
   6833    return false;
   6834  }
   6835  {
   6836    if (!emit1(JSOp::Pop)) {
   6837      //            [stack] NEXT ITER RECEIVED
   6838      return false;
   6839    }
   6840    // Step 7.b.i.
   6841    if (!emitDupAt(1)) {
   6842      //            [stack] NEXT ITER RECEIVED ITER
   6843      return false;
   6844    }
   6845    if (!emit1(JSOp::Dup)) {
   6846      //            [stack] NEXT ITER RECEIVED ITER ITER
   6847      return false;
   6848    }
   6849    if (!emitAtomOp(JSOp::GetProp,
   6850                    TaggedParserAtomIndex::WellKnown::throw_())) {
   6851      //            [stack] NEXT ITER RECEIVED ITER THROW
   6852      return false;
   6853    }
   6854 
   6855    // Step 7.b.ii.
   6856    InternalIfEmitter ifThrowMethodIsNotDefined(this);
   6857    if (!emit1(JSOp::IsNullOrUndefined)) {
   6858      //            [stack] NEXT ITER RECEIVED ITER THROW NULL-OR-UNDEF
   6859      return false;
   6860    }
   6861 
   6862    if (!ifThrowMethodIsNotDefined.emitThenElse(
   6863            IfEmitter::ConditionKind::Negative)) {
   6864      //            [stack] NEXT ITER RECEIVED ITER THROW
   6865      return false;
   6866    }
   6867 
   6868    // Step 7.b.ii.1.
   6869    // RESULT = ITER.throw(EXCEPTION)
   6870    if (!emit1(JSOp::Swap)) {
   6871      //            [stack] NEXT ITER RECEIVED THROW ITER
   6872      return false;
   6873    }
   6874    if (!emit2(JSOp::Pick, 2)) {
   6875      //            [stack] NEXT ITER THROW ITER RECEIVED
   6876      return false;
   6877    }
   6878    if (!emitCall(JSOp::Call, 1, iter)) {
   6879      //            [stack] NEXT ITER RESULT
   6880      return false;
   6881    }
   6882 
   6883    // Step 7.b.ii.2.
   6884    if (iterKind == IteratorKind::Async) {
   6885      if (!emitAwaitInInnermostScope()) {
   6886        //          [stack] NEXT ITER RESULT
   6887        return false;
   6888      }
   6889    }
   6890 
   6891    // Step 7.b.ii.4.
   6892    if (!emitCheckIsObj(CheckIsObjectKind::IteratorThrow)) {
   6893      //            [stack] NEXT ITER RESULT
   6894      return false;
   6895    }
   6896 
   6897    // Bytecode for steps 7.b.ii.5-8 is emitted after the ifKind if-else because
   6898    // it's shared with other branches.
   6899 
   6900    // Step 7.b.iii.
   6901    if (!ifThrowMethodIsNotDefined.emitElse()) {
   6902      //            [stack] NEXT ITER RECEIVED ITER THROW
   6903      return false;
   6904    }
   6905    if (!emit1(JSOp::Pop)) {
   6906      //            [stack] NEXT ITER RECEIVED ITER
   6907      return false;
   6908    }
   6909 
   6910    // Steps 7.b.iii.1-4.
   6911    //
   6912    // If the iterator does not have a "throw" method, it calls IteratorClose
   6913    // and then throws a TypeError.
   6914    if (!emitIteratorCloseInInnermostScope(iterKind, CompletionKind::Normal,
   6915                                           SelfHostedIter::Deny)) {
   6916      //            [stack] NEXT ITER RECEIVED ITER
   6917      return false;
   6918    }
   6919    // Steps 7.b.iii.5-6.
   6920    if (!emit2(JSOp::ThrowMsg, uint8_t(ThrowMsgKind::IteratorNoThrow))) {
   6921      //            [stack] NEXT ITER RECEIVED ITER
   6922      //            [stack] # throw
   6923      return false;
   6924    }
   6925 
   6926    if (!ifThrowMethodIsNotDefined.emitEnd()) {
   6927      return false;
   6928    }
   6929  }
   6930 
   6931  // Step 7.c. It must be a Return completion.
   6932  if (!ifKind.emitElse()) {
   6933    //              [stack] NEXT ITER RECEIVED RESUMEKIND
   6934    return false;
   6935  }
   6936  {
   6937    if (!emit1(JSOp::Pop)) {
   6938      //            [stack] NEXT ITER RECEIVED
   6939      return false;
   6940    }
   6941 
   6942    // Step 7.c.i.
   6943    //
   6944    // Call iterator.return() for receiving a "forced return" completion from
   6945    // the generator.
   6946 
   6947    // Step 7.c.ii.
   6948    //
   6949    // Get the "return" method.
   6950    if (!emitDupAt(1)) {
   6951      //            [stack] NEXT ITER RECEIVED ITER
   6952      return false;
   6953    }
   6954    if (!emit1(JSOp::Dup)) {
   6955      //            [stack] NEXT ITER RECEIVED ITER ITER
   6956      return false;
   6957    }
   6958    if (!emitAtomOp(JSOp::GetProp,
   6959                    TaggedParserAtomIndex::WellKnown::return_())) {
   6960      //            [stack] NEXT ITER RECEIVED ITER RET
   6961      return false;
   6962    }
   6963 
   6964    // Step 7.c.iii.
   6965    //
   6966    // Do nothing if "return" is undefined or null.
   6967    InternalIfEmitter ifReturnMethodIsDefined(this);
   6968    if (!emit1(JSOp::IsNullOrUndefined)) {
   6969      //            [stack] NEXT ITER RECEIVED ITER RET NULL-OR-UNDEF
   6970      return false;
   6971    }
   6972 
   6973    // Step 7.c.iv.
   6974    //
   6975    // Call "return" with the argument passed to Generator.prototype.return.
   6976    if (!ifReturnMethodIsDefined.emitThenElse(
   6977            IfEmitter::ConditionKind::Negative)) {
   6978      //            [stack] NEXT ITER RECEIVED ITER RET
   6979      return false;
   6980    }
   6981    if (!emit1(JSOp::Swap)) {
   6982      //            [stack] NEXT ITER RECEIVED RET ITER
   6983      return false;
   6984    }
   6985    if (!emit2(JSOp::Pick, 2)) {
   6986      //            [stack] NEXT ITER RET ITER RECEIVED
   6987      return false;
   6988    }
   6989    if (needsIteratorResult) {
   6990      if (!emitAtomOp(JSOp::GetProp,
   6991                      TaggedParserAtomIndex::WellKnown::value())) {
   6992        //          [stack] NEXT ITER RET ITER VAL
   6993        return false;
   6994      }
   6995    }
   6996    if (!emitCall(JSOp::Call, 1)) {
   6997      //            [stack] NEXT ITER RESULT
   6998      return false;
   6999    }
   7000 
   7001    // Step 7.c.v.
   7002    if (iterKind == IteratorKind::Async) {
   7003      if (!emitAwaitInInnermostScope()) {
   7004        //          [stack] NEXT ITER RESULT
   7005        return false;
   7006      }
   7007    }
   7008 
   7009    // Step 7.c.vi.
   7010    if (!emitCheckIsObj(CheckIsObjectKind::IteratorReturn)) {
   7011      //            [stack] NEXT ITER RESULT
   7012      return false;
   7013    }
   7014 
   7015    // Check if the returned object from iterator.return() is done. If not,
   7016    // continue yielding.
   7017 
   7018    // Steps 7.c.vii-viii.
   7019    InternalIfEmitter ifReturnDone(this);
   7020    if (!emit1(JSOp::Dup)) {
   7021      //            [stack] NEXT ITER RESULT RESULT
   7022      return false;
   7023    }
   7024    if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::done())) {
   7025      //            [stack] NEXT ITER RESULT DONE
   7026      return false;
   7027    }
   7028    if (!ifReturnDone.emitThenElse()) {
   7029      //            [stack] NEXT ITER RESULT
   7030      return false;
   7031    }
   7032 
   7033    // Step 7.c.viii.1.
   7034    if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::value())) {
   7035      //            [stack] NEXT ITER VALUE
   7036      return false;
   7037    }
   7038    if (needsIteratorResult) {
   7039      if (!emitPrepareIteratorResult()) {
   7040        //          [stack] NEXT ITER VALUE RESULT
   7041        return false;
   7042      }
   7043      if (!emit1(JSOp::Swap)) {
   7044        //          [stack] NEXT ITER RESULT VALUE
   7045        return false;
   7046      }
   7047      if (!emitFinishIteratorResult(true)) {
   7048        //          [stack] NEXT ITER RESULT
   7049        return false;
   7050      }
   7051    }
   7052 
   7053    if (!ifReturnDone.emitElse()) {
   7054      //            [stack] NEXT ITER RESULT
   7055      return false;
   7056    }
   7057 
   7058    // Jump to continue label for steps 7.c.ix-x.
   7059    if (!emitJump(JSOp::Goto, &loopInfo.continues)) {
   7060      //            [stack] NEXT ITER RESULT
   7061      return false;
   7062    }
   7063 
   7064    if (!ifReturnDone.emitEnd()) {
   7065      //            [stack] NEXT ITER RESULT
   7066      return false;
   7067    }
   7068 
   7069    // Step 7.c.iii.
   7070    if (!ifReturnMethodIsDefined.emitElse()) {
   7071      //            [stack] NEXT ITER RECEIVED ITER RET
   7072      return false;
   7073    }
   7074    if (!emitPopN(2)) {
   7075      //            [stack] NEXT ITER RECEIVED
   7076      return false;
   7077    }
   7078    if (iterKind == IteratorKind::Async) {
   7079      // Step 7.c.iii.1.
   7080      if (!emitAwaitInInnermostScope()) {
   7081        //          [stack] NEXT ITER RECEIVED
   7082        return false;
   7083      }
   7084    }
   7085    if (!ifReturnMethodIsDefined.emitEnd()) {
   7086      //            [stack] NEXT ITER RECEIVED
   7087      return false;
   7088    }
   7089 
   7090    // Perform a "forced generator return".
   7091    //
   7092    // Step 7.c.iii.2.
   7093    // Step 7.c.viii.2.
   7094    if (!emitGetDotGeneratorInInnermostScope()) {
   7095      //            [stack] NEXT ITER RESULT GENOBJ
   7096      return false;
   7097    }
   7098    if (!emitPushResumeKind(GeneratorResumeKind::Return)) {
   7099      //            [stack] NEXT ITER RESULT GENOBJ RESUMEKIND
   7100      return false;
   7101    }
   7102    if (!emit1(JSOp::CheckResumeKind)) {
   7103      //            [stack] NEXT ITER RESULT GENOBJ RESUMEKIND
   7104      return false;
   7105    }
   7106  }
   7107 
   7108  if (!ifKind.emitEnd()) {
   7109    //              [stack] NEXT ITER RESULT
   7110    return false;
   7111  }
   7112 
   7113  // Shared tail for Normal/Throw completions.
   7114  //
   7115  // Steps 7.a.iv-v.
   7116  // Steps 7.b.ii.5-6.
   7117  //
   7118  //                [stack] NEXT ITER RESULT
   7119 
   7120  // if (result.done) break;
   7121  if (!emit1(JSOp::Dup)) {
   7122    //              [stack] NEXT ITER RESULT RESULT
   7123    return false;
   7124  }
   7125  if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::done())) {
   7126    //              [stack] NEXT ITER RESULT DONE
   7127    return false;
   7128  }
   7129  if (!emitJump(JSOp::JumpIfTrue, &loopInfo.breaks)) {
   7130    //              [stack] NEXT ITER RESULT
   7131    return false;
   7132  }
   7133 
   7134  // Steps 7.a.vi-vii.
   7135  // Steps 7.b.ii.7-8.
   7136  // Steps 7.c.ix-x.
   7137  if (!loopInfo.emitContinueTarget(this)) {
   7138    //              [stack] NEXT ITER RESULT
   7139    return false;
   7140  }
   7141  if (iterKind == IteratorKind::Async) {
   7142    if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::value())) {
   7143      //            [stack] NEXT ITER RESULT
   7144      return false;
   7145    }
   7146  }
   7147  if (!emitGetDotGeneratorInInnermostScope()) {
   7148    //              [stack] NEXT ITER RESULT GENOBJ
   7149    return false;
   7150  }
   7151  if (!emitYieldOp(JSOp::Yield)) {
   7152    //              [stack] NEXT ITER RVAL GENOBJ RESUMEKIND
   7153    return false;
   7154  }
   7155  if (!emit1(JSOp::Swap)) {
   7156    //              [stack] NEXT ITER RVAL RESUMEKIND GENOBJ
   7157    return false;
   7158  }
   7159  if (!emit1(JSOp::Pop)) {
   7160    //              [stack] NEXT ITER RVAL RESUMEKIND
   7161    return false;
   7162  }
   7163  if (!loopInfo.emitLoopEnd(this, JSOp::Goto, TryNoteKind::Loop)) {
   7164    //              [stack] NEXT ITER RVAL RESUMEKIND
   7165    return false;
   7166  }
   7167 
   7168  // Jumps to this point have 3 (instead of 4) values on the stack.
   7169  MOZ_ASSERT(bytecodeSection().stackDepth() == startDepth);
   7170  bytecodeSection().setStackDepth(startDepth - 1);
   7171 
   7172  //                [stack] NEXT ITER RESULT
   7173 
   7174  // Step 7.a.v.1.
   7175  // Step 7.b.ii.6.a.
   7176  //
   7177  // result.value
   7178  if (!emit2(JSOp::Unpick, 2)) {
   7179    //              [stack] RESULT NEXT ITER
   7180    return false;
   7181  }
   7182  if (!emitPopN(2)) {
   7183    //              [stack] RESULT
   7184    return false;
   7185  }
   7186  if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::value())) {
   7187    //              [stack] VALUE
   7188    return false;
   7189  }
   7190 
   7191  MOZ_ASSERT(bytecodeSection().stackDepth() == startDepth - 3);
   7192 
   7193  return true;
   7194 }
   7195 
   7196 bool BytecodeEmitter::emitStatementList(ListNode* stmtList) {
   7197  for (ParseNode* stmt : stmtList->contents()) {
   7198    if (!emitTree(stmt)) {
   7199      return false;
   7200    }
   7201  }
   7202  return true;
   7203 }
   7204 
   7205 bool BytecodeEmitter::emitExpressionStatement(UnaryNode* exprStmt) {
   7206  MOZ_ASSERT(exprStmt->isKind(ParseNodeKind::ExpressionStmt));
   7207 
   7208  /*
   7209   * Top-level or called-from-a-native JS_Execute/EvaluateScript,
   7210   * debugger, and eval frames may need the value of the ultimate
   7211   * expression statement as the script's result, despite the fact
   7212   * that it appears useless to the compiler.
   7213   *
   7214   * API users may also set the ReadOnlyCompileOptions::noScriptRval option when
   7215   * calling JS_Compile* to suppress JSOp::SetRval.
   7216   */
   7217  bool wantval = false;
   7218  bool useful = false;
   7219  if (sc->isTopLevelContext()) {
   7220    useful = wantval = !sc->noScriptRval();
   7221  }
   7222 
   7223  /* Don't eliminate expressions with side effects. */
   7224  ParseNode* expr = exprStmt->kid();
   7225  if (!useful) {
   7226    if (!checkSideEffects(expr, &useful)) {
   7227      return false;
   7228    }
   7229 
   7230    /*
   7231     * Don't eliminate apparently useless expressions if they are labeled
   7232     * expression statements. The startOffset() test catches the case
   7233     * where we are nesting in emitTree for a labeled compound statement.
   7234     */
   7235    if (innermostNestableControl &&
   7236        innermostNestableControl->is<LabelControl>() &&
   7237        innermostNestableControl->as<LabelControl>().startOffset() >=
   7238            bytecodeSection().offset()) {
   7239      useful = true;
   7240    }
   7241  }
   7242 
   7243  if (useful) {
   7244    ValueUsage valueUsage =
   7245        wantval ? ValueUsage::WantValue : ValueUsage::IgnoreValue;
   7246    ExpressionStatementEmitter ese(this, valueUsage);
   7247    if (!ese.prepareForExpr(exprStmt->pn_pos.begin)) {
   7248      return false;
   7249    }
   7250    if (!markStepBreakpoint()) {
   7251      return false;
   7252    }
   7253    if (!emitTree(expr, valueUsage)) {
   7254      return false;
   7255    }
   7256    if (!ese.emitEnd()) {
   7257      return false;
   7258    }
   7259  }
   7260 
   7261  return true;
   7262 }
   7263 
   7264 bool BytecodeEmitter::emitDeleteName(UnaryNode* deleteNode) {
   7265  MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteNameExpr));
   7266 
   7267  NameNode* nameExpr = &deleteNode->kid()->as<NameNode>();
   7268  MOZ_ASSERT(nameExpr->isKind(ParseNodeKind::Name));
   7269 
   7270  return emitAtomOp(JSOp::DelName, nameExpr->atom());
   7271 }
   7272 
   7273 bool BytecodeEmitter::emitDeleteProperty(UnaryNode* deleteNode) {
   7274  MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeletePropExpr));
   7275 
   7276  PropertyAccess* propExpr = &deleteNode->kid()->as<PropertyAccess>();
   7277  PropOpEmitter poe(this, PropOpEmitter::Kind::Delete,
   7278                    propExpr->as<PropertyAccess>().isSuper()
   7279                        ? PropOpEmitter::ObjKind::Super
   7280                        : PropOpEmitter::ObjKind::Other);
   7281 
   7282  if (!poe.prepareForObj()) {
   7283    return false;
   7284  }
   7285 
   7286  if (propExpr->isSuper()) {
   7287    // The expression |delete super.foo;| has to evaluate |super.foo|, which
   7288    // could throw if |this| hasn't yet been set by a |super(...)| call.
   7289    auto* base = &propExpr->expression().as<UnaryNode>();
   7290    if (!emitGetThisForSuperBase(base)) {
   7291      //            [stack] THIS
   7292      return false;
   7293    }
   7294  } else {
   7295    if (!emitPropLHS(propExpr)) {
   7296      //            [stack] OBJ
   7297      return false;
   7298    }
   7299  }
   7300 
   7301  if (!poe.emitDelete(propExpr->key().atom())) {
   7302    //              [stack] # if Super
   7303    //              [stack] THIS
   7304    //              [stack] # otherwise
   7305    //              [stack] SUCCEEDED
   7306    return false;
   7307  }
   7308 
   7309  return true;
   7310 }
   7311 
   7312 bool BytecodeEmitter::emitDeleteElement(UnaryNode* deleteNode) {
   7313  MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteElemExpr));
   7314 
   7315  auto* elemExpr = &deleteNode->kid()->as<PropertyByValue>();
   7316  bool isSuper = elemExpr->isSuper();
   7317  MOZ_ASSERT(!elemExpr->key().isKind(ParseNodeKind::PrivateName));
   7318  ElemOpEmitter eoe(
   7319      this, ElemOpEmitter::Kind::Delete,
   7320      isSuper ? ElemOpEmitter::ObjKind::Super : ElemOpEmitter::ObjKind::Other);
   7321 
   7322  if (!emitElemObjAndKey(elemExpr, eoe)) {
   7323    //              [stack] # if Super
   7324    //              [stack] THIS KEY
   7325    //              [stack] # otherwise
   7326    //              [stack] OBJ KEY
   7327    return false;
   7328  }
   7329 
   7330  if (!eoe.emitDelete()) {
   7331    //              [stack] # if Super
   7332    //              [stack] THIS
   7333    //              [stack] # otherwise
   7334    //              [stack] SUCCEEDED
   7335    return false;
   7336  }
   7337 
   7338  return true;
   7339 }
   7340 
   7341 bool BytecodeEmitter::emitDeleteExpression(UnaryNode* deleteNode) {
   7342  MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteExpr));
   7343 
   7344  ParseNode* expression = deleteNode->kid();
   7345 
   7346  // If useless, just emit JSOp::True; otherwise convert |delete <expr>| to
   7347  // effectively |<expr>, true|.
   7348  bool useful = false;
   7349  if (!checkSideEffects(expression, &useful)) {
   7350    return false;
   7351  }
   7352 
   7353  if (useful) {
   7354    if (!emitTree(expression)) {
   7355      return false;
   7356    }
   7357    if (!emit1(JSOp::Pop)) {
   7358      return false;
   7359    }
   7360  }
   7361 
   7362  return emit1(JSOp::True);
   7363 }
   7364 
   7365 bool BytecodeEmitter::emitDeleteOptionalChain(UnaryNode* deleteNode) {
   7366  MOZ_ASSERT(deleteNode->isKind(ParseNodeKind::DeleteOptionalChainExpr));
   7367 
   7368  OptionalEmitter oe(this, bytecodeSection().stackDepth());
   7369 
   7370  ParseNode* kid = deleteNode->kid();
   7371  switch (kid->getKind()) {
   7372    case ParseNodeKind::ElemExpr:
   7373    case ParseNodeKind::OptionalElemExpr: {
   7374      auto* elemExpr = &kid->as<PropertyByValueBase>();
   7375      if (!emitDeleteElementInOptChain(elemExpr, oe)) {
   7376        //          [stack] # If shortcircuit
   7377        //          [stack] UNDEFINED-OR-NULL
   7378        //          [stack] # otherwise
   7379        //          [stack] SUCCEEDED
   7380        return false;
   7381      }
   7382 
   7383      break;
   7384    }
   7385    case ParseNodeKind::ArgumentsLength:
   7386    case ParseNodeKind::DotExpr:
   7387    case ParseNodeKind::OptionalDotExpr: {
   7388      auto* propExpr = &kid->as<PropertyAccessBase>();
   7389      if (!emitDeletePropertyInOptChain(propExpr, oe)) {
   7390        //          [stack] # If shortcircuit
   7391        //          [stack] UNDEFINED-OR-NULL
   7392        //          [stack] # otherwise
   7393        //          [stack] SUCCEEDED
   7394        return false;
   7395      }
   7396      break;
   7397    }
   7398    default:
   7399      MOZ_ASSERT_UNREACHABLE("Unrecognized optional delete ParseNodeKind");
   7400  }
   7401 
   7402  if (!oe.emitOptionalJumpTarget(JSOp::True)) {
   7403    //              [stack] # If shortcircuit
   7404    //              [stack] TRUE
   7405    //              [stack] # otherwise
   7406    //              [stack] SUCCEEDED
   7407    return false;
   7408  }
   7409 
   7410  return true;
   7411 }
   7412 
   7413 bool BytecodeEmitter::emitDeletePropertyInOptChain(PropertyAccessBase* propExpr,
   7414                                                   OptionalEmitter& oe) {
   7415  MOZ_ASSERT_IF(propExpr->is<PropertyAccess>(),
   7416                !propExpr->as<PropertyAccess>().isSuper());
   7417  PropOpEmitter poe(this, PropOpEmitter::Kind::Delete,
   7418                    PropOpEmitter::ObjKind::Other);
   7419 
   7420  if (!poe.prepareForObj()) {
   7421    //              [stack]
   7422    return false;
   7423  }
   7424  if (!emitOptionalTree(&propExpr->expression(), oe)) {
   7425    //              [stack] OBJ
   7426    return false;
   7427  }
   7428  if (propExpr->isKind(ParseNodeKind::OptionalDotExpr)) {
   7429    if (!oe.emitJumpShortCircuit()) {
   7430      //            [stack] # if Jump
   7431      //            [stack] UNDEFINED-OR-NULL
   7432      //            [stack] # otherwise
   7433      //            [stack] OBJ
   7434      return false;
   7435    }
   7436  }
   7437 
   7438  if (!poe.emitDelete(propExpr->key().atom())) {
   7439    //              [stack] SUCCEEDED
   7440    return false;
   7441  }
   7442 
   7443  return true;
   7444 }
   7445 
   7446 bool BytecodeEmitter::emitDeleteElementInOptChain(PropertyByValueBase* elemExpr,
   7447                                                  OptionalEmitter& oe) {
   7448  MOZ_ASSERT_IF(elemExpr->is<PropertyByValue>(),
   7449                !elemExpr->as<PropertyByValue>().isSuper());
   7450  ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Delete,
   7451                    ElemOpEmitter::ObjKind::Other);
   7452 
   7453  if (!eoe.prepareForObj()) {
   7454    //              [stack]
   7455    return false;
   7456  }
   7457 
   7458  if (!emitOptionalTree(&elemExpr->expression(), oe)) {
   7459    //              [stack] OBJ
   7460    return false;
   7461  }
   7462 
   7463  if (elemExpr->isKind(ParseNodeKind::OptionalElemExpr)) {
   7464    if (!oe.emitJumpShortCircuit()) {
   7465      //            [stack] # if Jump
   7466      //            [stack] UNDEFINED-OR-NULL
   7467      //            [stack] # otherwise
   7468      //            [stack] OBJ
   7469      return false;
   7470    }
   7471  }
   7472 
   7473  if (!eoe.prepareForKey()) {
   7474    //              [stack] OBJ
   7475    return false;
   7476  }
   7477 
   7478  if (!emitTree(&elemExpr->key())) {
   7479    //              [stack] OBJ KEY
   7480    return false;
   7481  }
   7482 
   7483  if (!eoe.emitDelete()) {
   7484    //              [stack] SUCCEEDED
   7485    return false;
   7486  }
   7487 
   7488  return true;
   7489 }
   7490 
   7491 bool BytecodeEmitter::emitDebugCheckSelfHosted() {
   7492  //                [stack] CALLEE
   7493 
   7494 #ifdef DEBUG
   7495  if (!emit1(JSOp::DebugCheckSelfHosted)) {
   7496    //              [stack] CALLEE
   7497    return false;
   7498  }
   7499 #endif
   7500 
   7501  return true;
   7502 }
   7503 
   7504 bool BytecodeEmitter::emitSelfHostedCallFunction(CallNode* callNode, JSOp op) {
   7505  // Special-casing of callFunction to emit bytecode that directly
   7506  // invokes the callee with the correct |this| object and arguments.
   7507  // callFunction(fun, thisArg, arg0, arg1) thus becomes:
   7508  // - emit lookup for fun
   7509  // - emit lookup for thisArg
   7510  // - emit lookups for arg0, arg1
   7511  //
   7512  // argc is set to the amount of actually emitted args and the
   7513  // emitting of args below is disabled by setting emitArgs to false.
   7514  NameNode* calleeNode = &callNode->callee()->as<NameNode>();
   7515  ListNode* argsList = callNode->args();
   7516 
   7517  MOZ_ASSERT(argsList->count() >= 2);
   7518 
   7519  MOZ_ASSERT(callNode->callOp() == JSOp::Call);
   7520 
   7521  bool constructing =
   7522      calleeNode->name() ==
   7523      TaggedParserAtomIndex::WellKnown::constructContentFunction();
   7524  ParseNode* funNode = argsList->head();
   7525 
   7526  if (!emitTree(funNode)) {
   7527    //              [stack] CALLEE
   7528    return false;
   7529  }
   7530 
   7531 #ifdef DEBUG
   7532  MOZ_ASSERT(op == JSOp::Call || op == JSOp::CallContent ||
   7533             op == JSOp::NewContent);
   7534  if (op == JSOp::Call) {
   7535    if (!emitDebugCheckSelfHosted()) {
   7536      //            [stack] CALLEE
   7537      return false;
   7538    }
   7539  }
   7540 #endif
   7541 
   7542  ParseNode* thisOrNewTarget = funNode->pn_next;
   7543  if (constructing) {
   7544    // Save off the new.target value, but here emit a proper |this| for a
   7545    // constructing call.
   7546    if (!emit1(JSOp::IsConstructing)) {
   7547      //            [stack] CALLEE IS_CONSTRUCTING
   7548      return false;
   7549    }
   7550  } else {
   7551    // It's |this|, emit it.
   7552    if (!emitTree(thisOrNewTarget)) {
   7553      //            [stack] CALLEE THIS
   7554      return false;
   7555    }
   7556  }
   7557 
   7558  for (ParseNode* argpn : argsList->contentsFrom(thisOrNewTarget->pn_next)) {
   7559    if (!emitTree(argpn)) {
   7560      //            [stack] CALLEE ... ARGS...
   7561      return false;
   7562    }
   7563  }
   7564 
   7565  if (constructing) {
   7566    if (!emitTree(thisOrNewTarget)) {
   7567      //            [stack] CALLEE IS_CONSTRUCTING ARGS... NEW.TARGET
   7568      return false;
   7569    }
   7570  }
   7571 
   7572  uint32_t argc = argsList->count() - 2;
   7573  if (!emitCall(op, argc)) {
   7574    //              [stack] RVAL
   7575    return false;
   7576  }
   7577 
   7578  return true;
   7579 }
   7580 
   7581 bool BytecodeEmitter::emitSelfHostedResumeGenerator(CallNode* callNode) {
   7582  ListNode* argsList = callNode->args();
   7583 
   7584  // Syntax: resumeGenerator(gen, value, 'next'|'throw'|'return')
   7585  MOZ_ASSERT(argsList->count() == 3);
   7586 
   7587  ParseNode* genNode = argsList->head();
   7588  if (!emitTree(genNode)) {
   7589    //              [stack] GENERATOR
   7590    return false;
   7591  }
   7592 
   7593  ParseNode* valNode = genNode->pn_next;
   7594  if (!emitTree(valNode)) {
   7595    //              [stack] GENERATOR VALUE
   7596    return false;
   7597  }
   7598 
   7599  ParseNode* kindNode = valNode->pn_next;
   7600  MOZ_ASSERT(kindNode->isKind(ParseNodeKind::StringExpr));
   7601  GeneratorResumeKind kind =
   7602      ParserAtomToResumeKind(kindNode->as<NameNode>().atom());
   7603  MOZ_ASSERT(!kindNode->pn_next);
   7604 
   7605  if (!emitPushResumeKind(kind)) {
   7606    //              [stack] GENERATOR VALUE RESUMEKIND
   7607    return false;
   7608  }
   7609 
   7610  if (!emit1(JSOp::Resume)) {
   7611    //              [stack] RVAL
   7612    return false;
   7613  }
   7614 
   7615  return true;
   7616 }
   7617 
   7618 bool BytecodeEmitter::emitSelfHostedForceInterpreter() {
   7619  // JSScript::hasForceInterpreterOp() relies on JSOp::ForceInterpreter being
   7620  // the first bytecode op in the script.
   7621  MOZ_ASSERT(bytecodeSection().code().empty());
   7622 
   7623  if (!emit1(JSOp::ForceInterpreter)) {
   7624    return false;
   7625  }
   7626  if (!emit1(JSOp::Undefined)) {
   7627    return false;
   7628  }
   7629 
   7630  return true;
   7631 }
   7632 
   7633 bool BytecodeEmitter::emitSelfHostedAllowContentIter(CallNode* callNode) {
   7634  ListNode* argsList = callNode->args();
   7635 
   7636  MOZ_ASSERT(argsList->count() == 1);
   7637 
   7638  // We're just here as a sentinel. Pass the value through directly.
   7639  return emitTree(argsList->head());
   7640 }
   7641 
   7642 bool BytecodeEmitter::emitSelfHostedAllowContentIterWith(CallNode* callNode) {
   7643  ListNode* argsList = callNode->args();
   7644 
   7645  MOZ_ASSERT(argsList->count() == 2 || argsList->count() == 3);
   7646 
   7647  // We're just here as a sentinel. Pass the value through directly.
   7648  return emitTree(argsList->head());
   7649 }
   7650 
   7651 bool BytecodeEmitter::emitSelfHostedAllowContentIterWithNext(
   7652    CallNode* callNode) {
   7653  ListNode* argsList = callNode->args();
   7654 
   7655  MOZ_ASSERT(argsList->count() == 2);
   7656 
   7657  // We're just here as a sentinel. Pass the value through directly.
   7658  return emitTree(argsList->head());
   7659 }
   7660 
   7661 bool BytecodeEmitter::emitSelfHostedDefineDataProperty(CallNode* callNode) {
   7662  ListNode* argsList = callNode->args();
   7663 
   7664  // Only optimize when 3 arguments are passed.
   7665  MOZ_ASSERT(argsList->count() == 3);
   7666 
   7667  ParseNode* objNode = argsList->head();
   7668  if (!emitTree(objNode)) {
   7669    return false;
   7670  }
   7671 
   7672  ParseNode* idNode = objNode->pn_next;
   7673  if (!emitTree(idNode)) {
   7674    return false;
   7675  }
   7676 
   7677  ParseNode* valNode = idNode->pn_next;
   7678  if (!emitTree(valNode)) {
   7679    return false;
   7680  }
   7681 
   7682  // This will leave the object on the stack instead of pushing |undefined|,
   7683  // but that's fine because the self-hosted code doesn't use the return
   7684  // value.
   7685  return emit1(JSOp::InitElem);
   7686 }
   7687 
   7688 bool BytecodeEmitter::emitSelfHostedHasOwn(CallNode* callNode) {
   7689  ListNode* argsList = callNode->args();
   7690 
   7691  MOZ_ASSERT(argsList->count() == 2);
   7692 
   7693  ParseNode* idNode = argsList->head();
   7694  if (!emitTree(idNode)) {
   7695    return false;
   7696  }
   7697 
   7698  ParseNode* objNode = idNode->pn_next;
   7699  if (!emitTree(objNode)) {
   7700    return false;
   7701  }
   7702 
   7703  return emit1(JSOp::HasOwn);
   7704 }
   7705 
   7706 bool BytecodeEmitter::emitSelfHostedGetPropertySuper(CallNode* callNode) {
   7707  ListNode* argsList = callNode->args();
   7708 
   7709  MOZ_ASSERT(argsList->count() == 3);
   7710 
   7711  ParseNode* objNode = argsList->head();
   7712  ParseNode* idNode = objNode->pn_next;
   7713  ParseNode* receiverNode = idNode->pn_next;
   7714 
   7715  if (!emitTree(receiverNode)) {
   7716    return false;
   7717  }
   7718 
   7719  if (!emitTree(idNode)) {
   7720    return false;
   7721  }
   7722 
   7723  if (!emitTree(objNode)) {
   7724    return false;
   7725  }
   7726 
   7727  return emitElemOpBase(JSOp::GetElemSuper);
   7728 }
   7729 
   7730 bool BytecodeEmitter::emitSelfHostedToNumeric(CallNode* callNode) {
   7731  ListNode* argsList = callNode->args();
   7732 
   7733  MOZ_ASSERT(argsList->count() == 1);
   7734 
   7735  ParseNode* argNode = argsList->head();
   7736 
   7737  if (!emitTree(argNode)) {
   7738    return false;
   7739  }
   7740 
   7741  return emit1(JSOp::ToNumeric);
   7742 }
   7743 
   7744 bool BytecodeEmitter::emitSelfHostedToString(CallNode* callNode) {
   7745  ListNode* argsList = callNode->args();
   7746 
   7747  MOZ_ASSERT(argsList->count() == 1);
   7748 
   7749  ParseNode* argNode = argsList->head();
   7750 
   7751  if (!emitTree(argNode)) {
   7752    return false;
   7753  }
   7754 
   7755  return emit1(JSOp::ToString);
   7756 }
   7757 
   7758 bool BytecodeEmitter::emitSelfHostedIsNullOrUndefined(CallNode* callNode) {
   7759  ListNode* argsList = callNode->args();
   7760 
   7761  MOZ_ASSERT(argsList->count() == 1);
   7762 
   7763  ParseNode* argNode = argsList->head();
   7764 
   7765  if (!emitTree(argNode)) {
   7766    //              [stack] ARG
   7767    return false;
   7768  }
   7769  if (!emit1(JSOp::IsNullOrUndefined)) {
   7770    //              [stack] ARG IS_NULL_OR_UNDEF
   7771    return false;
   7772  }
   7773  if (!emit1(JSOp::Swap)) {
   7774    //              [stack] IS_NULL_OR_UNDEF ARG
   7775    return false;
   7776  }
   7777  if (!emit1(JSOp::Pop)) {
   7778    //              [stack] IS_NULL_OR_UNDEF
   7779    return false;
   7780  }
   7781  return true;
   7782 }
   7783 
   7784 bool BytecodeEmitter::emitSelfHostedIteratorClose(CallNode* callNode) {
   7785  ListNode* argsList = callNode->args();
   7786  MOZ_ASSERT(argsList->count() == 1);
   7787 
   7788  ParseNode* argNode = argsList->head();
   7789  if (!emitTree(argNode)) {
   7790    //              [stack] ARG
   7791    return false;
   7792  }
   7793 
   7794  if (!emit2(JSOp::CloseIter, uint8_t(CompletionKind::Normal))) {
   7795    //              [stack]
   7796    return false;
   7797  }
   7798 
   7799  // This is still a call node, so we must generate a stack value.
   7800  if (!emit1(JSOp::Undefined)) {
   7801    //              [stack] RVAL
   7802    return false;
   7803  }
   7804 
   7805  return true;
   7806 }
   7807 
   7808 bool BytecodeEmitter::emitSelfHostedGetBuiltinConstructorOrPrototype(
   7809    CallNode* callNode, bool isConstructor) {
   7810  ListNode* argsList = callNode->args();
   7811 
   7812  MOZ_ASSERT(argsList->count() == 1);
   7813 
   7814  ParseNode* argNode = argsList->head();
   7815 
   7816  if (!argNode->isKind(ParseNodeKind::StringExpr)) {
   7817    reportError(callNode, JSMSG_UNEXPECTED_TYPE, "built-in name",
   7818                "not a string constant");
   7819    return false;
   7820  }
   7821 
   7822  auto name = argNode->as<NameNode>().atom();
   7823 
   7824  BuiltinObjectKind kind;
   7825  if (isConstructor) {
   7826    kind = BuiltinConstructorForName(name);
   7827  } else {
   7828    kind = BuiltinPrototypeForName(name);
   7829  }
   7830 
   7831  if (kind == BuiltinObjectKind::None) {
   7832    reportError(callNode, JSMSG_UNEXPECTED_TYPE, "built-in name",
   7833                "not a valid built-in");
   7834    return false;
   7835  }
   7836 
   7837  return emitBuiltinObject(kind);
   7838 }
   7839 
   7840 bool BytecodeEmitter::emitSelfHostedGetBuiltinConstructor(CallNode* callNode) {
   7841  return emitSelfHostedGetBuiltinConstructorOrPrototype(
   7842      callNode, /* isConstructor = */ true);
   7843 }
   7844 
   7845 bool BytecodeEmitter::emitSelfHostedGetBuiltinPrototype(CallNode* callNode) {
   7846  return emitSelfHostedGetBuiltinConstructorOrPrototype(
   7847      callNode, /* isConstructor = */ false);
   7848 }
   7849 
   7850 JS::SymbolCode ParserAtomToSymbolCode(TaggedParserAtomIndex atom) {
   7851  // NOTE: This is a linear search, but the set of entries is quite small and
   7852  // this is only used for initial self-hosted parse.
   7853 #define MATCH_WELL_KNOWN_SYMBOL(NAME)                     \
   7854  if (atom == TaggedParserAtomIndex::WellKnown::NAME()) { \
   7855    return JS::SymbolCode::NAME;                          \
   7856  }
   7857  JS_FOR_EACH_WELL_KNOWN_SYMBOL(MATCH_WELL_KNOWN_SYMBOL)
   7858 #undef MATCH_WELL_KNOWN_SYMBOL
   7859 
   7860  return JS::SymbolCode::Limit;
   7861 }
   7862 
   7863 bool BytecodeEmitter::emitSelfHostedGetBuiltinSymbol(CallNode* callNode) {
   7864  ListNode* argsList = callNode->args();
   7865 
   7866  MOZ_ASSERT(argsList->count() == 1);
   7867 
   7868  ParseNode* argNode = argsList->head();
   7869 
   7870  if (!argNode->isKind(ParseNodeKind::StringExpr)) {
   7871    reportError(callNode, JSMSG_UNEXPECTED_TYPE, "built-in name",
   7872                "not a string constant");
   7873    return false;
   7874  }
   7875 
   7876  auto name = argNode->as<NameNode>().atom();
   7877 
   7878  JS::SymbolCode code = ParserAtomToSymbolCode(name);
   7879  if (code == JS::SymbolCode::Limit) {
   7880    reportError(callNode, JSMSG_UNEXPECTED_TYPE, "built-in name",
   7881                "not a valid built-in");
   7882    return false;
   7883  }
   7884 
   7885  return emit2(JSOp::Symbol, uint8_t(code));
   7886 }
   7887 
   7888 bool BytecodeEmitter::emitSelfHostedArgumentsLength(CallNode* callNode) {
   7889  MOZ_ASSERT(!sc->asFunctionBox()->needsArgsObj());
   7890  sc->asFunctionBox()->setUsesArgumentsIntrinsics();
   7891 
   7892  MOZ_ASSERT(callNode->args()->count() == 0);
   7893 
   7894  return emit1(JSOp::ArgumentsLength);
   7895 }
   7896 
   7897 bool BytecodeEmitter::emitSelfHostedGetArgument(CallNode* callNode) {
   7898  MOZ_ASSERT(!sc->asFunctionBox()->needsArgsObj());
   7899  sc->asFunctionBox()->setUsesArgumentsIntrinsics();
   7900 
   7901  ListNode* argsList = callNode->args();
   7902  MOZ_ASSERT(argsList->count() == 1);
   7903 
   7904  ParseNode* argNode = argsList->head();
   7905  if (!emitTree(argNode)) {
   7906    return false;
   7907  }
   7908 
   7909  return emit1(JSOp::GetActualArg);
   7910 }
   7911 
   7912 #ifdef DEBUG
   7913 void BytecodeEmitter::assertSelfHostedExpectedTopLevel(ParseNode* node) {
   7914  // The function argument is expected to be a simple binding/function name.
   7915  // Eg. `function foo() { }; SpecialIntrinsic(foo)`
   7916  MOZ_ASSERT(node->isKind(ParseNodeKind::Name),
   7917             "argument must be a function name");
   7918  TaggedParserAtomIndex targetName = node->as<NameNode>().name();
   7919 
   7920  // The special intrinsics must follow the target functions definition. A
   7921  // simple assert is fine here since any hoisted function will cause a non-null
   7922  // value to be set here.
   7923  MOZ_ASSERT(prevSelfHostedTopLevelFunction);
   7924 
   7925  // The target function must match the most recently defined top-level
   7926  // self-hosted function.
   7927  MOZ_ASSERT(prevSelfHostedTopLevelFunction->explicitName() == targetName,
   7928             "selfhost decorator must immediately follow target function");
   7929 }
   7930 #endif
   7931 
   7932 bool BytecodeEmitter::emitSelfHostedSetIsInlinableLargeFunction(
   7933    CallNode* callNode) {
   7934 #ifdef DEBUG
   7935  ListNode* argsList = callNode->args();
   7936 
   7937  MOZ_ASSERT(argsList->count() == 1);
   7938 
   7939  assertSelfHostedExpectedTopLevel(argsList->head());
   7940 #endif
   7941 
   7942  MOZ_ASSERT(prevSelfHostedTopLevelFunction->isInitialCompilation);
   7943  prevSelfHostedTopLevelFunction->setIsInlinableLargeFunction();
   7944 
   7945  // This is still a call node, so we must generate a stack value.
   7946  return emit1(JSOp::Undefined);
   7947 }
   7948 
   7949 bool BytecodeEmitter::emitSelfHostedSetCanonicalName(CallNode* callNode) {
   7950  ListNode* argsList = callNode->args();
   7951 
   7952  MOZ_ASSERT(argsList->count() == 2);
   7953 
   7954 #ifdef DEBUG
   7955  assertSelfHostedExpectedTopLevel(argsList->head());
   7956 #endif
   7957 
   7958  ParseNode* nameNode = argsList->last();
   7959  MOZ_ASSERT(nameNode->isKind(ParseNodeKind::StringExpr));
   7960  TaggedParserAtomIndex specName = nameNode->as<NameNode>().atom();
   7961  // Canonical name must be atomized.
   7962  compilationState.parserAtoms.markUsedByStencil(specName,
   7963                                                 ParserAtom::Atomize::Yes);
   7964 
   7965  // Store the canonical name for instantiation.
   7966  prevSelfHostedTopLevelFunction->functionStencil().setSelfHostedCanonicalName(
   7967      specName);
   7968 
   7969  return emit1(JSOp::Undefined);
   7970 }
   7971 
   7972 #ifdef DEBUG
   7973 void BytecodeEmitter::assertSelfHostedUnsafeGetReservedSlot(
   7974    ListNode* argsList) {
   7975  MOZ_ASSERT(argsList->count() == 2);
   7976 
   7977  ParseNode* objNode = argsList->head();
   7978  ParseNode* slotNode = objNode->pn_next;
   7979 
   7980  // Ensure that the slot argument is fixed, this is required by the JITs.
   7981  MOZ_ASSERT(slotNode->isKind(ParseNodeKind::NumberExpr),
   7982             "slot argument must be a constant");
   7983 }
   7984 
   7985 void BytecodeEmitter::assertSelfHostedUnsafeSetReservedSlot(
   7986    ListNode* argsList) {
   7987  MOZ_ASSERT(argsList->count() == 3);
   7988 
   7989  ParseNode* objNode = argsList->head();
   7990  ParseNode* slotNode = objNode->pn_next;
   7991 
   7992  // Ensure that the slot argument is fixed, this is required by the JITs.
   7993  MOZ_ASSERT(slotNode->isKind(ParseNodeKind::NumberExpr),
   7994             "slot argument must be a constant");
   7995 }
   7996 #endif
   7997 
   7998 /* A version of emitCalleeAndThis for the optional cases:
   7999 *   * a?.()
   8000 *   * a?.b()
   8001 *   * a?.["b"]()
   8002 *   * (a?.b)()
   8003 *   * a?.#b()
   8004 *
   8005 * See emitCallOrNew and emitOptionalCall for more context.
   8006 */
   8007 bool BytecodeEmitter::emitOptionalCalleeAndThis(ParseNode* callee,
   8008                                                CallNode* call,
   8009                                                CallOrNewEmitter& cone,
   8010                                                OptionalEmitter& oe) {
   8011  AutoCheckRecursionLimit recursion(fc);
   8012  if (!recursion.check(fc)) {
   8013    return false;
   8014  }
   8015 
   8016  switch (ParseNodeKind kind = callee->getKind()) {
   8017    case ParseNodeKind::Name: {
   8018      auto name = callee->as<NameNode>().name();
   8019      if (!cone.emitNameCallee(name)) {
   8020        //          [stack] CALLEE THIS
   8021        return false;
   8022      }
   8023      break;
   8024    }
   8025 
   8026    case ParseNodeKind::OptionalDotExpr: {
   8027      MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting);
   8028      OptionalPropertyAccess* prop = &callee->as<OptionalPropertyAccess>();
   8029      bool isSuper = false;
   8030 
   8031      PropOpEmitter& poe = cone.prepareForPropCallee(isSuper);
   8032      if (!emitOptionalDotExpression(prop, poe, isSuper, oe)) {
   8033        //          [stack] CALLEE THIS
   8034        return false;
   8035      }
   8036      break;
   8037    }
   8038    case ParseNodeKind::ArgumentsLength:
   8039    case ParseNodeKind::DotExpr: {
   8040      MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting);
   8041      PropertyAccess* prop = &callee->as<PropertyAccess>();
   8042      bool isSuper = prop->isSuper();
   8043 
   8044      PropOpEmitter& poe = cone.prepareForPropCallee(isSuper);
   8045      if (!emitOptionalDotExpression(prop, poe, isSuper, oe)) {
   8046        //          [stack] CALLEE THIS
   8047        return false;
   8048      }
   8049      break;
   8050    }
   8051 
   8052    case ParseNodeKind::OptionalElemExpr: {
   8053      OptionalPropertyByValue* elem = &callee->as<OptionalPropertyByValue>();
   8054      bool isSuper = false;
   8055      MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
   8056      ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper);
   8057      if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) {
   8058        //          [stack] CALLEE THIS
   8059        return false;
   8060      }
   8061      break;
   8062    }
   8063    case ParseNodeKind::ElemExpr: {
   8064      PropertyByValue* elem = &callee->as<PropertyByValue>();
   8065      bool isSuper = elem->isSuper();
   8066      MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
   8067      ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper);
   8068      if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) {
   8069        //          [stack] CALLEE THIS
   8070        return false;
   8071      }
   8072      break;
   8073    }
   8074 
   8075    case ParseNodeKind::PrivateMemberExpr:
   8076    case ParseNodeKind::OptionalPrivateMemberExpr: {
   8077      PrivateMemberAccessBase* privateExpr =
   8078          &callee->as<PrivateMemberAccessBase>();
   8079      PrivateOpEmitter& xoe =
   8080          cone.prepareForPrivateCallee(privateExpr->privateName().name());
   8081      if (!emitOptionalPrivateExpression(privateExpr, xoe, oe)) {
   8082        //          [stack] CALLEE THIS
   8083        return false;
   8084      }
   8085      break;
   8086    }
   8087 
   8088    case ParseNodeKind::Function:
   8089      if (!cone.prepareForFunctionCallee()) {
   8090        return false;
   8091      }
   8092      if (!emitOptionalTree(callee, oe)) {
   8093        //          [stack] CALLEE
   8094        return false;
   8095      }
   8096      break;
   8097 
   8098    case ParseNodeKind::OptionalChain: {
   8099      return emitCalleeAndThisForOptionalChain(&callee->as<UnaryNode>(), call,
   8100                                               cone);
   8101    }
   8102 
   8103    default:
   8104      MOZ_RELEASE_ASSERT(kind != ParseNodeKind::SuperBase);
   8105 
   8106      if (!cone.prepareForOtherCallee()) {
   8107        return false;
   8108      }
   8109      if (!emitOptionalTree(callee, oe)) {
   8110        //          [stack] CALLEE
   8111        return false;
   8112      }
   8113      break;
   8114  }
   8115 
   8116  if (!cone.emitThis()) {
   8117    //              [stack] CALLEE THIS
   8118    return false;
   8119  }
   8120 
   8121  return true;
   8122 }
   8123 
   8124 bool BytecodeEmitter::emitCalleeAndThis(ParseNode* callee, CallNode* maybeCall,
   8125                                        CallOrNewEmitter& cone) {
   8126  MOZ_ASSERT_IF(maybeCall, maybeCall->callee() == callee);
   8127 
   8128  switch (callee->getKind()) {
   8129    case ParseNodeKind::Name: {
   8130      auto name = callee->as<NameNode>().name();
   8131      if (!cone.emitNameCallee(name)) {
   8132        //          [stack] CALLEE THIS?
   8133        return false;
   8134      }
   8135      break;
   8136    }
   8137    case ParseNodeKind::ArgumentsLength:
   8138    case ParseNodeKind::DotExpr: {
   8139      MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting);
   8140      PropertyAccess* prop = &callee->as<PropertyAccess>();
   8141      bool isSuper = prop->isSuper();
   8142 
   8143      PropOpEmitter& poe = cone.prepareForPropCallee(isSuper);
   8144      if (!poe.prepareForObj()) {
   8145        return false;
   8146      }
   8147      if (isSuper) {
   8148        UnaryNode* base = &prop->expression().as<UnaryNode>();
   8149        if (!emitGetThisForSuperBase(base)) {
   8150          //        [stack] THIS
   8151          return false;
   8152        }
   8153      } else {
   8154        if (!emitPropLHS(prop)) {
   8155          //        [stack] OBJ
   8156          return false;
   8157        }
   8158      }
   8159      if (!poe.emitGet(prop->key().atom())) {
   8160        //          [stack] CALLEE THIS?
   8161        return false;
   8162      }
   8163 
   8164      break;
   8165    }
   8166    case ParseNodeKind::ElemExpr: {
   8167      MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting);
   8168      PropertyByValue* elem = &callee->as<PropertyByValue>();
   8169      bool isSuper = elem->isSuper();
   8170      MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
   8171      ElemOpEmitter& eoe = cone.prepareForElemCallee(isSuper);
   8172      if (!emitElemObjAndKey(elem, eoe)) {
   8173        //          [stack] # if Super
   8174        //          [stack] THIS? THIS KEY
   8175        //          [stack] # otherwise
   8176        //          [stack] OBJ? OBJ KEY
   8177        return false;
   8178      }
   8179      if (!eoe.emitGet()) {
   8180        //          [stack] CALLEE THIS?
   8181        return false;
   8182      }
   8183 
   8184      break;
   8185    }
   8186    case ParseNodeKind::PrivateMemberExpr: {
   8187      MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting);
   8188      PrivateMemberAccessBase* privateExpr =
   8189          &callee->as<PrivateMemberAccessBase>();
   8190      PrivateOpEmitter& xoe =
   8191          cone.prepareForPrivateCallee(privateExpr->privateName().name());
   8192      if (!emitTree(&privateExpr->expression())) {
   8193        //          [stack] OBJ
   8194        return false;
   8195      }
   8196      if (!xoe.emitReference()) {
   8197        //          [stack] OBJ NAME
   8198        return false;
   8199      }
   8200      if (!xoe.emitGetForCallOrNew()) {
   8201        //          [stack] CALLEE THIS
   8202        return false;
   8203      }
   8204 
   8205      break;
   8206    }
   8207    case ParseNodeKind::Function:
   8208      if (!cone.prepareForFunctionCallee()) {
   8209        return false;
   8210      }
   8211      if (!emitTree(callee)) {
   8212        //          [stack] CALLEE
   8213        return false;
   8214      }
   8215      break;
   8216    case ParseNodeKind::SuperBase:
   8217      MOZ_ASSERT(maybeCall);
   8218      MOZ_ASSERT(maybeCall->isKind(ParseNodeKind::SuperCallExpr));
   8219      MOZ_ASSERT(callee->isKind(ParseNodeKind::SuperBase));
   8220      if (!cone.emitSuperCallee()) {
   8221        //          [stack] CALLEE IsConstructing
   8222        return false;
   8223      }
   8224      break;
   8225    case ParseNodeKind::OptionalChain: {
   8226      MOZ_ASSERT(maybeCall);
   8227      return emitCalleeAndThisForOptionalChain(&callee->as<UnaryNode>(),
   8228                                               maybeCall, cone);
   8229    }
   8230    default:
   8231      if (!cone.prepareForOtherCallee()) {
   8232        return false;
   8233      }
   8234      if (!emitTree(callee)) {
   8235        return false;
   8236      }
   8237      break;
   8238  }
   8239 
   8240  if (!cone.emitThis()) {
   8241    //              [stack] CALLEE THIS
   8242    return false;
   8243  }
   8244 
   8245  return true;
   8246 }
   8247 
   8248 ParseNode* BytecodeEmitter::getCoordNode(ParseNode* callNode,
   8249                                         ParseNode* calleeNode, JSOp op,
   8250                                         ListNode* argsList) const {
   8251  ParseNode* coordNode = callNode;
   8252  if (op == JSOp::Call || op == JSOp::SpreadCall) {
   8253    // Default to using the location of the `(` itself.
   8254    // obj[expr]() // expression
   8255    //          ^  // column coord
   8256    coordNode = argsList;
   8257 
   8258    switch (calleeNode->getKind()) {
   8259      case ParseNodeKind::ArgumentsLength:
   8260      case ParseNodeKind::DotExpr:
   8261        // Use the position of a property access identifier.
   8262        //
   8263        // obj().aprop() // expression
   8264        //       ^       // column coord
   8265        //
   8266        // Note: Because of the constant folding logic in FoldElement,
   8267        // this case also applies for constant string properties.
   8268        //
   8269        // obj()['aprop']() // expression
   8270        //       ^          // column coord
   8271        coordNode = &calleeNode->as<PropertyAccess>().key();
   8272        break;
   8273      case ParseNodeKind::Name: {
   8274        // Use the start of callee name unless it is at a separator
   8275        // or has no args.
   8276        //
   8277        // 2 + obj()   // expression
   8278        //     ^       // column coord
   8279        //
   8280        if (argsList->empty() ||
   8281            !bytecodeSection().atSeparator(calleeNode->pn_pos.begin)) {
   8282          // Use the start of callee names.
   8283          coordNode = calleeNode;
   8284        }
   8285        break;
   8286      }
   8287 
   8288      default:
   8289        break;
   8290    }
   8291  }
   8292  return coordNode;
   8293 }
   8294 
   8295 bool BytecodeEmitter::emitArguments(ListNode* argsList, bool isCall,
   8296                                    bool isSpread, CallOrNewEmitter& cone) {
   8297  uint32_t argc = argsList->count();
   8298  if (argc >= ARGC_LIMIT) {
   8299    reportError(argsList,
   8300                isCall ? JSMSG_TOO_MANY_FUN_ARGS : JSMSG_TOO_MANY_CON_ARGS);
   8301    return false;
   8302  }
   8303  if (!isSpread) {
   8304    if (!cone.prepareForNonSpreadArguments()) {
   8305      //            [stack] CALLEE THIS
   8306      return false;
   8307    }
   8308    for (ParseNode* arg : argsList->contents()) {
   8309      if (!updateSourceCoordNotesIfNonLiteral(arg)) {
   8310        return false;
   8311      }
   8312      if (!emitTree(arg)) {
   8313        //          [stack] CALLEE THIS ARG*
   8314        return false;
   8315      }
   8316    }
   8317  } else if (cone.wantSpreadOperand()) {
   8318    auto* spreadNode = &argsList->head()->as<UnaryNode>();
   8319    if (!updateSourceCoordNotesIfNonLiteral(spreadNode->kid())) {
   8320      return false;
   8321    }
   8322    if (!emitTree(spreadNode->kid())) {
   8323      //            [stack] CALLEE THIS ARG0
   8324      return false;
   8325    }
   8326 
   8327    if (!cone.emitSpreadArgumentsTest()) {
   8328      //            [stack] CALLEE THIS ARG0
   8329      return false;
   8330    }
   8331 
   8332    if (cone.wantSpreadIteration()) {
   8333      if (!emitSpreadIntoArray(spreadNode)) {
   8334        //          [stack] CALLEE THIS ARR
   8335        return false;
   8336      }
   8337    }
   8338 
   8339    if (!cone.emitSpreadArgumentsTestEnd()) {
   8340      //            [stack] CALLEE THIS ARR
   8341      return false;
   8342    }
   8343  } else {
   8344    if (!cone.prepareForSpreadArguments()) {
   8345      //            [stack] CALLEE THIS
   8346      return false;
   8347    }
   8348    if (!emitArray(argsList)) {
   8349      //            [stack] CALLEE THIS ARR
   8350      return false;
   8351    }
   8352  }
   8353 
   8354  return true;
   8355 }
   8356 
   8357 bool BytecodeEmitter::emitOptionalCall(CallNode* callNode, OptionalEmitter& oe,
   8358                                       ValueUsage valueUsage) {
   8359  /*
   8360   * A modified version of emitCallOrNew that handles optional calls.
   8361   *
   8362   * These include the following:
   8363   *    a?.()
   8364   *    a.b?.()
   8365   *    a.["b"]?.()
   8366   *    (a?.b)?.()
   8367   *
   8368   * See CallOrNewEmitter for more context.
   8369   */
   8370  ParseNode* calleeNode = callNode->callee();
   8371  ListNode* argsList = callNode->args();
   8372  bool isSpread = IsSpreadOp(callNode->callOp());
   8373  JSOp op = callNode->callOp();
   8374  uint32_t argc = argsList->count();
   8375  bool isOptimizableSpread = isSpread && argc == 1;
   8376 
   8377  CallOrNewEmitter cone(this, op,
   8378                        isOptimizableSpread
   8379                            ? CallOrNewEmitter::ArgumentsKind::SingleSpread
   8380                            : CallOrNewEmitter::ArgumentsKind::Other,
   8381                        valueUsage);
   8382 
   8383  ParseNode* coordNode = getCoordNode(callNode, calleeNode, op, argsList);
   8384 
   8385  if (!emitOptionalCalleeAndThis(calleeNode, callNode, cone, oe)) {
   8386    //              [stack] CALLEE THIS
   8387    return false;
   8388  }
   8389 
   8390  if (callNode->isKind(ParseNodeKind::OptionalCallExpr)) {
   8391    if (!oe.emitJumpShortCircuitForCall()) {
   8392      //            [stack] CALLEE THIS
   8393      return false;
   8394    }
   8395  }
   8396 
   8397  if (!emitArguments(argsList, /* isCall = */ true, isSpread, cone)) {
   8398    //              [stack] CALLEE THIS ARGS...
   8399    return false;
   8400  }
   8401 
   8402  if (!cone.emitEnd(argc, coordNode->pn_pos.begin)) {
   8403    //              [stack] RVAL
   8404    return false;
   8405  }
   8406 
   8407  return true;
   8408 }
   8409 
   8410 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   8411 bool BytecodeEmitter::emitSelfHostedDisposeResources(CallNode* callNode,
   8412                                                     DisposalKind kind) {
   8413  ListNode* argsList = callNode->args();
   8414  MOZ_ASSERT(argsList->count() == 2);
   8415 
   8416  ParseNode* resourcesNode = argsList->head();
   8417  ParseNode* countNode = resourcesNode->pn_next;
   8418 
   8419  DisposalEmitter de(this, bool(kind));
   8420 
   8421  if (!emit1(JSOp::False)) {
   8422    // [stack] THROWING
   8423    return false;
   8424  }
   8425 
   8426  if (!emit1(JSOp::Undefined)) {
   8427    // [stack] THROWING UNDEF
   8428    return false;
   8429  }
   8430 
   8431  if (!de.prepareForDisposeCapability()) {
   8432    // [stack] RVAL? NEEDS-AWAIT? HAS-AWAITED? THROWING UNDEF
   8433    return false;
   8434  }
   8435 
   8436  if (!emitTree(resourcesNode)) {
   8437    // [stack] RVAL? NEEDS-AWAIT? HAS-AWAITED? THROWING UNDEF RESOURCES
   8438    return false;
   8439  }
   8440 
   8441  if (!emitTree(countNode)) {
   8442    // [stack] RVAL? NEEDS-AWAIT? HAS-AWAITED? THROWING UNDEF RESOURCES COUNT
   8443    return false;
   8444  }
   8445 
   8446  if (!de.emitEnd(*innermostEmitterScope())) {
   8447    // [stack] EXC THROWING
   8448    return false;
   8449  }
   8450 
   8451  // [stack] EXC THROWING
   8452 
   8453  InternalIfEmitter ifThrow(this);
   8454 
   8455  if (!ifThrow.emitThenElse()) {
   8456    // [stack] EXC
   8457    return false;
   8458  }
   8459 
   8460  if (!emit1(JSOp::Throw)) {
   8461    // [stack]
   8462    return false;
   8463  }
   8464 
   8465  if (!ifThrow.emitElse()) {
   8466    // [stack] EXC
   8467    return false;
   8468  }
   8469 
   8470  if (!emit1(JSOp::Pop)) {
   8471    // [stack]
   8472    return false;
   8473  }
   8474 
   8475  if (!ifThrow.emitEnd()) {
   8476    // [stack]
   8477    return false;
   8478  }
   8479 
   8480  if (!emit1(JSOp::Undefined)) {
   8481    // [stack] RVAL
   8482    return false;
   8483  }
   8484 
   8485  return true;
   8486 }
   8487 #endif
   8488 
   8489 bool BytecodeEmitter::emitCallOrNew(CallNode* callNode, ValueUsage valueUsage) {
   8490  /*
   8491   * Emit callable invocation or operator new (constructor call) code.
   8492   * First, emit code for the left operand to evaluate the callable or
   8493   * constructable object expression.
   8494   *
   8495   * Then (or in a call case that has no explicit reference-base
   8496   * object) we emit JSOp::Undefined to produce the undefined |this|
   8497   * value required for calls (which non-strict mode functions
   8498   * will box into the global object).
   8499   */
   8500  bool isCall = callNode->isKind(ParseNodeKind::CallExpr) ||
   8501                callNode->isKind(ParseNodeKind::TaggedTemplateExpr);
   8502  ParseNode* calleeNode = callNode->callee();
   8503  ListNode* argsList = callNode->args();
   8504  JSOp op = callNode->callOp();
   8505 
   8506  if (calleeNode->isKind(ParseNodeKind::Name) &&
   8507      emitterMode == BytecodeEmitter::SelfHosting && op == JSOp::Call) {
   8508    // Calls to "forceInterpreter", "callFunction",
   8509    // "callContentFunction", or "resumeGenerator" in self-hosted
   8510    // code generate inline bytecode.
   8511    //
   8512    // NOTE: The list of special instruction names has to be kept in sync with
   8513    // "js/src/builtin/.eslintrc.js".
   8514    auto calleeName = calleeNode->as<NameNode>().name();
   8515    if (calleeName == TaggedParserAtomIndex::WellKnown::callFunction()) {
   8516      return emitSelfHostedCallFunction(callNode, JSOp::Call);
   8517    }
   8518    if (calleeName == TaggedParserAtomIndex::WellKnown::callContentFunction()) {
   8519      return emitSelfHostedCallFunction(callNode, JSOp::CallContent);
   8520    }
   8521    if (calleeName ==
   8522        TaggedParserAtomIndex::WellKnown::constructContentFunction()) {
   8523      return emitSelfHostedCallFunction(callNode, JSOp::NewContent);
   8524    }
   8525    if (calleeName == TaggedParserAtomIndex::WellKnown::resumeGenerator()) {
   8526      return emitSelfHostedResumeGenerator(callNode);
   8527    }
   8528    if (calleeName == TaggedParserAtomIndex::WellKnown::forceInterpreter()) {
   8529      return emitSelfHostedForceInterpreter();
   8530    }
   8531    if (calleeName == TaggedParserAtomIndex::WellKnown::allowContentIter()) {
   8532      return emitSelfHostedAllowContentIter(callNode);
   8533    }
   8534    if (calleeName ==
   8535        TaggedParserAtomIndex::WellKnown::allowContentIterWith()) {
   8536      return emitSelfHostedAllowContentIterWith(callNode);
   8537    }
   8538    if (calleeName ==
   8539        TaggedParserAtomIndex::WellKnown::allowContentIterWithNext()) {
   8540      return emitSelfHostedAllowContentIterWithNext(callNode);
   8541    }
   8542    if (calleeName == TaggedParserAtomIndex::WellKnown::DefineDataProperty() &&
   8543        argsList->count() == 3) {
   8544      return emitSelfHostedDefineDataProperty(callNode);
   8545    }
   8546    if (calleeName == TaggedParserAtomIndex::WellKnown::hasOwn()) {
   8547      return emitSelfHostedHasOwn(callNode);
   8548    }
   8549    if (calleeName == TaggedParserAtomIndex::WellKnown::getPropertySuper()) {
   8550      return emitSelfHostedGetPropertySuper(callNode);
   8551    }
   8552    if (calleeName == TaggedParserAtomIndex::WellKnown::ToNumeric()) {
   8553      return emitSelfHostedToNumeric(callNode);
   8554    }
   8555    if (calleeName == TaggedParserAtomIndex::WellKnown::ToString()) {
   8556      return emitSelfHostedToString(callNode);
   8557    }
   8558    if (calleeName ==
   8559        TaggedParserAtomIndex::WellKnown::GetBuiltinConstructor()) {
   8560      return emitSelfHostedGetBuiltinConstructor(callNode);
   8561    }
   8562    if (calleeName == TaggedParserAtomIndex::WellKnown::GetBuiltinPrototype()) {
   8563      return emitSelfHostedGetBuiltinPrototype(callNode);
   8564    }
   8565    if (calleeName == TaggedParserAtomIndex::WellKnown::GetBuiltinSymbol()) {
   8566      return emitSelfHostedGetBuiltinSymbol(callNode);
   8567    }
   8568    if (calleeName == TaggedParserAtomIndex::WellKnown::ArgumentsLength()) {
   8569      return emitSelfHostedArgumentsLength(callNode);
   8570    }
   8571    if (calleeName == TaggedParserAtomIndex::WellKnown::GetArgument()) {
   8572      return emitSelfHostedGetArgument(callNode);
   8573    }
   8574    if (calleeName ==
   8575        TaggedParserAtomIndex::WellKnown::SetIsInlinableLargeFunction()) {
   8576      return emitSelfHostedSetIsInlinableLargeFunction(callNode);
   8577    }
   8578    if (calleeName == TaggedParserAtomIndex::WellKnown::SetCanonicalName()) {
   8579      return emitSelfHostedSetCanonicalName(callNode);
   8580    }
   8581    if (calleeName == TaggedParserAtomIndex::WellKnown::IsNullOrUndefined()) {
   8582      return emitSelfHostedIsNullOrUndefined(callNode);
   8583    }
   8584    if (calleeName == TaggedParserAtomIndex::WellKnown::IteratorClose()) {
   8585      return emitSelfHostedIteratorClose(callNode);
   8586    }
   8587 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
   8588    if (calleeName ==
   8589        TaggedParserAtomIndex::WellKnown::DisposeResourcesAsync()) {
   8590      return emitSelfHostedDisposeResources(callNode, DisposalKind::Async);
   8591    }
   8592    if (calleeName ==
   8593        TaggedParserAtomIndex::WellKnown::DisposeResourcesSync()) {
   8594      return emitSelfHostedDisposeResources(callNode, DisposalKind::Sync);
   8595    }
   8596 #endif
   8597 #ifdef DEBUG
   8598    if (calleeName ==
   8599            TaggedParserAtomIndex::WellKnown::UnsafeGetReservedSlot() ||
   8600        calleeName == TaggedParserAtomIndex::WellKnown::
   8601                          UnsafeGetObjectFromReservedSlot() ||
   8602        calleeName == TaggedParserAtomIndex::WellKnown::
   8603                          UnsafeGetInt32FromReservedSlot() ||
   8604        calleeName == TaggedParserAtomIndex::WellKnown::
   8605                          UnsafeGetStringFromReservedSlot()) {
   8606      // Make sure that this call is correct, but don't emit any special code.
   8607      assertSelfHostedUnsafeGetReservedSlot(argsList);
   8608    }
   8609    if (calleeName ==
   8610        TaggedParserAtomIndex::WellKnown::UnsafeSetReservedSlot()) {
   8611      // Make sure that this call is correct, but don't emit any special code.
   8612      assertSelfHostedUnsafeSetReservedSlot(argsList);
   8613    }
   8614 #endif
   8615    // Fall through
   8616  }
   8617 
   8618  uint32_t argc = argsList->count();
   8619  bool isSpread = IsSpreadOp(op);
   8620  bool isOptimizableSpread = isSpread && argc == 1;
   8621  bool isDefaultDerivedClassConstructor =
   8622      sc->isFunctionBox() && sc->asFunctionBox()->isDerivedClassConstructor() &&
   8623      sc->asFunctionBox()->isSyntheticFunction();
   8624  MOZ_ASSERT_IF(isDefaultDerivedClassConstructor, isOptimizableSpread);
   8625  CallOrNewEmitter cone(
   8626      this, op,
   8627      isOptimizableSpread
   8628          ? isDefaultDerivedClassConstructor
   8629                ? CallOrNewEmitter::ArgumentsKind::PassthroughRest
   8630                : CallOrNewEmitter::ArgumentsKind::SingleSpread
   8631          : CallOrNewEmitter::ArgumentsKind::Other,
   8632      valueUsage);
   8633 
   8634  if (!emitCalleeAndThis(calleeNode, callNode, cone)) {
   8635    //              [stack] CALLEE THIS
   8636    return false;
   8637  }
   8638  if (!emitArguments(argsList, isCall, isSpread, cone)) {
   8639    //              [stack] CALLEE THIS ARGS...
   8640    return false;
   8641  }
   8642 
   8643  // Push new.target for construct calls.
   8644  if (IsConstructOp(op)) {
   8645    if (op == JSOp::SuperCall || op == JSOp::SpreadSuperCall) {
   8646      if (!emitNewTarget(callNode)) {
   8647        //          [stack] CALLEE THIS ARGS.. NEW.TARGET
   8648        return false;
   8649      }
   8650    } else {
   8651      // Repush the callee as new.target
   8652      uint32_t effectiveArgc = isSpread ? 1 : argc;
   8653      if (!emitDupAt(effectiveArgc + 1)) {
   8654        //          [stack] CALLEE THIS ARGS.. CALLEE
   8655        return false;
   8656      }
   8657    }
   8658  }
   8659 
   8660  ParseNode* coordNode = getCoordNode(callNode, calleeNode, op, argsList);
   8661 
   8662  if (!cone.emitEnd(argc, coordNode->pn_pos.begin)) {
   8663    //              [stack] RVAL
   8664    return false;
   8665  }
   8666 
   8667  return true;
   8668 }
   8669 
   8670 // This list must be kept in the same order in several places:
   8671 //   - The binary operators in ParseNode.h ,
   8672 //   - the binary operators in TokenKind.h
   8673 //   - the precedence list in Parser.cpp
   8674 static const JSOp ParseNodeKindToJSOp[] = {
   8675    // Some binary ops require special code generation (PrivateIn);
   8676    // these should not use BinaryOpParseNodeKindToJSOp. This table fills those
   8677    // slots with Nops to make the rest of the table lookup work.
   8678    JSOp::Coalesce, JSOp::Or,       JSOp::And, JSOp::BitOr,    JSOp::BitXor,
   8679    JSOp::BitAnd,   JSOp::StrictEq, JSOp::Eq,  JSOp::StrictNe, JSOp::Ne,
   8680    JSOp::Lt,       JSOp::Le,       JSOp::Gt,  JSOp::Ge,       JSOp::Instanceof,
   8681    JSOp::In,       JSOp::Nop,      JSOp::Lsh, JSOp::Rsh,      JSOp::Ursh,
   8682    JSOp::Add,      JSOp::Sub,      JSOp::Mul, JSOp::Div,      JSOp::Mod,
   8683    JSOp::Pow};
   8684 
   8685 static inline JSOp BinaryOpParseNodeKindToJSOp(ParseNodeKind pnk) {
   8686  MOZ_ASSERT(pnk >= ParseNodeKind::BinOpFirst);
   8687  MOZ_ASSERT(pnk <= ParseNodeKind::BinOpLast);
   8688  int parseNodeFirst = size_t(ParseNodeKind::BinOpFirst);
   8689 #ifdef DEBUG
   8690  int jsopArraySize = std::size(ParseNodeKindToJSOp);
   8691  int parseNodeKindListSize =
   8692      size_t(ParseNodeKind::BinOpLast) - parseNodeFirst + 1;
   8693  MOZ_ASSERT(jsopArraySize == parseNodeKindListSize);
   8694  // Ensure we don't use this to find an op for a parse node
   8695  // requiring special emission rules.
   8696  MOZ_ASSERT(ParseNodeKindToJSOp[size_t(pnk) - parseNodeFirst] != JSOp::Nop);
   8697 #endif
   8698  return ParseNodeKindToJSOp[size_t(pnk) - parseNodeFirst];
   8699 }
   8700 
   8701 bool BytecodeEmitter::emitRightAssociative(ListNode* node) {
   8702  // ** is the only right-associative operator.
   8703  MOZ_ASSERT(node->isKind(ParseNodeKind::PowExpr));
   8704 
   8705  // Right-associative operator chain.
   8706  for (ParseNode* subexpr : node->contents()) {
   8707    if (!updateSourceCoordNotesIfNonLiteral(subexpr)) {
   8708      return false;
   8709    }
   8710    if (!emitTree(subexpr)) {
   8711      return false;
   8712    }
   8713  }
   8714  for (uint32_t i = 0; i < node->count() - 1; i++) {
   8715    if (!emit1(JSOp::Pow)) {
   8716      return false;
   8717    }
   8718  }
   8719  return true;
   8720 }
   8721 
   8722 Maybe<ConstantCompareOperand>
   8723 BytecodeEmitter::parseNodeToConstantCompareOperand(ParseNode* constant) {
   8724  switch (constant->getKind()) {
   8725    case ParseNodeKind::NumberExpr: {
   8726      double d = constant->as<NumericLiteral>().value();
   8727      int32_t ival;
   8728      if (NumberEqualsInt32(d, &ival)) {
   8729        if (ConstantCompareOperand::CanEncodeInt32ValueAsOperand(ival)) {
   8730          return Some(ConstantCompareOperand(int8_t(ival)));
   8731        }
   8732      }
   8733      return Nothing();
   8734    }
   8735    case ParseNodeKind::TrueExpr:
   8736    case ParseNodeKind::FalseExpr:
   8737      return Some(
   8738          ConstantCompareOperand(constant->isKind(ParseNodeKind::TrueExpr)));
   8739    case ParseNodeKind::NullExpr:
   8740      return Some(
   8741          ConstantCompareOperand(ConstantCompareOperand::EncodedType::Null));
   8742    case ParseNodeKind::RawUndefinedExpr:
   8743      return Some(ConstantCompareOperand(
   8744          ConstantCompareOperand::EncodedType::Undefined));
   8745    case ParseNodeKind::Name: {
   8746      MOZ_ASSERT(constant->as<NameNode>().name() ==
   8747                 TaggedParserAtomIndex::WellKnown::undefined());
   8748      NameLocation loc = lookupName(constant->as<NameNode>().name());
   8749      switch (loc.kind()) {
   8750        case NameLocation::Kind::Global:
   8751          if (!sc->hasNonSyntacticScope()) {
   8752            return Some(ConstantCompareOperand(
   8753                ConstantCompareOperand::EncodedType::Undefined));
   8754          }
   8755          return Nothing();
   8756        case NameLocation::Kind::Intrinsic:
   8757          return Some(ConstantCompareOperand(
   8758              ConstantCompareOperand::EncodedType::Undefined));
   8759        default:
   8760          return Nothing();
   8761      }
   8762    }
   8763    default:
   8764      return Nothing();
   8765  }
   8766 }
   8767 
   8768 bool BytecodeEmitter::tryEmitConstantEq(ListNode* node, JSOp op,
   8769                                        bool* emitted) {
   8770  // We ignore long chains of === or !==, we
   8771  // only optimise cases a === b or a !== b
   8772  if (node->count() != 2) {
   8773    *emitted = false;
   8774    return true;
   8775  }
   8776 
   8777  JSOp constantOp;
   8778  switch (op) {
   8779    case JSOp::StrictEq:
   8780      constantOp = JSOp::StrictConstantEq;
   8781      break;
   8782    case JSOp::StrictNe:
   8783      constantOp = JSOp::StrictConstantNe;
   8784      break;
   8785    default:
   8786      *emitted = false;
   8787      return true;
   8788  }
   8789 
   8790  ParseNode* left = node->head();
   8791  ParseNode* right = node->head()->pn_next;
   8792 
   8793  ParseNode* expressionNode;
   8794  ParseNode* constantNode;
   8795  if (left->isConstant() || left->isUndefinedLiteral()) {
   8796    expressionNode = right;
   8797    constantNode = left;
   8798  } else if (right->isConstant() || right->isUndefinedLiteral()) {
   8799    expressionNode = left;
   8800    constantNode = right;
   8801  } else {
   8802    *emitted = false;
   8803    return true;
   8804  }
   8805 
   8806  Maybe<ConstantCompareOperand> operand =
   8807      parseNodeToConstantCompareOperand(constantNode);
   8808  if (operand.isNothing()) {
   8809    *emitted = false;
   8810    return true;
   8811  }
   8812 
   8813  if (!emitTree(expressionNode)) {
   8814    return false;
   8815  }
   8816 
   8817  if (!emitUint16Operand(constantOp, operand->rawValue())) {
   8818    return false;
   8819  }
   8820 
   8821  *emitted = true;
   8822  return true;
   8823 }
   8824 
   8825 bool BytecodeEmitter::emitLeftAssociative(ListNode* node) {
   8826  JSOp op = BinaryOpParseNodeKindToJSOp(node->getKind());
   8827  bool constantEqEmitted = false;
   8828  if (!tryEmitConstantEq(node, op, &constantEqEmitted)) {
   8829    return false;
   8830  }
   8831  if (constantEqEmitted) {
   8832    return true;
   8833  }
   8834  // Left-associative operator chain.
   8835  if (!emitTree(node->head())) {
   8836    return false;
   8837  }
   8838  ParseNode* nextExpr = node->head()->pn_next;
   8839  do {
   8840    if (!updateSourceCoordNotesIfNonLiteral(nextExpr)) {
   8841      return false;
   8842    }
   8843    if (!emitTree(nextExpr)) {
   8844      return false;
   8845    }
   8846    if (!emit1(op)) {
   8847      return false;
   8848    }
   8849  } while ((nextExpr = nextExpr->pn_next));
   8850  return true;
   8851 }
   8852 
   8853 bool BytecodeEmitter::emitPrivateInExpr(ListNode* node) {
   8854  MOZ_ASSERT(node->head()->isKind(ParseNodeKind::PrivateName));
   8855 
   8856  NameNode& privateNameNode = node->head()->as<NameNode>();
   8857  TaggedParserAtomIndex privateName = privateNameNode.name();
   8858 
   8859  PrivateOpEmitter xoe(this, PrivateOpEmitter::Kind::ErgonomicBrandCheck,
   8860                       privateName);
   8861 
   8862  ParseNode* valueNode = node->head()->pn_next;
   8863  MOZ_ASSERT(valueNode->pn_next == nullptr);
   8864 
   8865  if (!emitTree(valueNode)) {
   8866    //              [stack] OBJ
   8867    return false;
   8868  }
   8869 
   8870  if (!xoe.emitReference()) {
   8871    //              [stack] OBJ BRAND  if private method
   8872    //              [stack] OBJ NAME   if private field or accessor.
   8873    return false;
   8874  }
   8875 
   8876  if (!xoe.emitBrandCheck()) {
   8877    //              [stack] OBJ BRAND BOOL if private method
   8878    //              [stack] OBJ NAME  BOOL if private field or accessor.
   8879    return false;
   8880  }
   8881 
   8882  if (!emitUnpickN(2)) {
   8883    //              [stack] BOOL OBJ BRAND if private method
   8884    //              [stack] BOOL OBJ NAME   if private field or accessor.
   8885    return false;
   8886  }
   8887 
   8888  if (!emitPopN(2)) {
   8889    //              [stack] BOOL
   8890    return false;
   8891  }
   8892 
   8893  return true;
   8894 }
   8895 
   8896 /*
   8897 * Special `emitTree` for Optional Chaining case.
   8898 * Examples of this are `emitOptionalChain`, `emitDeleteOptionalChain` and
   8899 * `emitCalleeAndThisForOptionalChain`.
   8900 */
   8901 bool BytecodeEmitter::emitOptionalTree(
   8902    ParseNode* pn, OptionalEmitter& oe,
   8903    ValueUsage valueUsage /* = ValueUsage::WantValue */) {
   8904  AutoCheckRecursionLimit recursion(fc);
   8905  if (!recursion.check(fc)) {
   8906    return false;
   8907  }
   8908  ParseNodeKind kind = pn->getKind();
   8909  switch (kind) {
   8910    case ParseNodeKind::OptionalDotExpr: {
   8911      OptionalPropertyAccess* prop = &pn->as<OptionalPropertyAccess>();
   8912      bool isSuper = false;
   8913      PropOpEmitter poe(this, PropOpEmitter::Kind::Get,
   8914                        PropOpEmitter::ObjKind::Other);
   8915      if (!emitOptionalDotExpression(prop, poe, isSuper, oe)) {
   8916        return false;
   8917      }
   8918      break;
   8919    }
   8920    case ParseNodeKind::ArgumentsLength:
   8921    case ParseNodeKind::DotExpr: {
   8922      PropertyAccess* prop = &pn->as<PropertyAccess>();
   8923      bool isSuper = prop->isSuper();
   8924      PropOpEmitter poe(this, PropOpEmitter::Kind::Get,
   8925                        isSuper ? PropOpEmitter::ObjKind::Super
   8926                                : PropOpEmitter::ObjKind::Other);
   8927      if (!emitOptionalDotExpression(prop, poe, isSuper, oe)) {
   8928        return false;
   8929      }
   8930      break;
   8931    }
   8932 
   8933    case ParseNodeKind::OptionalElemExpr: {
   8934      OptionalPropertyByValue* elem = &pn->as<OptionalPropertyByValue>();
   8935      bool isSuper = false;
   8936      MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
   8937      ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get,
   8938                        ElemOpEmitter::ObjKind::Other);
   8939 
   8940      if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) {
   8941        return false;
   8942      }
   8943      break;
   8944    }
   8945    case ParseNodeKind::ElemExpr: {
   8946      PropertyByValue* elem = &pn->as<PropertyByValue>();
   8947      bool isSuper = elem->isSuper();
   8948      MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
   8949      ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get,
   8950                        isSuper ? ElemOpEmitter::ObjKind::Super
   8951                                : ElemOpEmitter::ObjKind::Other);
   8952 
   8953      if (!emitOptionalElemExpression(elem, eoe, isSuper, oe)) {
   8954        return false;
   8955      }
   8956      break;
   8957    }
   8958    case ParseNodeKind::PrivateMemberExpr:
   8959    case ParseNodeKind::OptionalPrivateMemberExpr: {
   8960      PrivateMemberAccessBase* privateExpr = &pn->as<PrivateMemberAccessBase>();
   8961      PrivateOpEmitter xoe(this, PrivateOpEmitter::Kind::Get,
   8962                           privateExpr->privateName().name());
   8963      if (!emitOptionalPrivateExpression(privateExpr, xoe, oe)) {
   8964        return false;
   8965      }
   8966      break;
   8967    }
   8968    case ParseNodeKind::CallExpr:
   8969    case ParseNodeKind::OptionalCallExpr:
   8970      if (!emitOptionalCall(&pn->as<CallNode>(), oe, valueUsage)) {
   8971        return false;
   8972      }
   8973      break;
   8974    // List of accepted ParseNodeKinds that might appear only at the beginning
   8975    // of an Optional Chain.
   8976    // For example, a taggedTemplateExpr node might occur if we have
   8977    // `test`?.b, with `test` as the taggedTemplateExpr ParseNode.
   8978    default:
   8979 #ifdef DEBUG
   8980      // https://tc39.es/ecma262/#sec-primary-expression
   8981      bool isPrimaryExpression =
   8982          kind == ParseNodeKind::ThisExpr || kind == ParseNodeKind::Name ||
   8983          kind == ParseNodeKind::PrivateName ||
   8984          kind == ParseNodeKind::NullExpr || kind == ParseNodeKind::TrueExpr ||
   8985          kind == ParseNodeKind::FalseExpr ||
   8986          kind == ParseNodeKind::NumberExpr ||
   8987          kind == ParseNodeKind::BigIntExpr ||
   8988          kind == ParseNodeKind::StringExpr ||
   8989          kind == ParseNodeKind::ArrayExpr ||
   8990          kind == ParseNodeKind::ObjectExpr ||
   8991          kind == ParseNodeKind::Function || kind == ParseNodeKind::ClassDecl ||
   8992          kind == ParseNodeKind::RegExpExpr ||
   8993          kind == ParseNodeKind::TemplateStringExpr ||
   8994          kind == ParseNodeKind::TemplateStringListExpr ||
   8995          kind == ParseNodeKind::RawUndefinedExpr || pn->isInParens();
   8996 
   8997      // https://tc39.es/ecma262/#sec-left-hand-side-expressions
   8998      bool isMemberExpression = isPrimaryExpression ||
   8999                                kind == ParseNodeKind::TaggedTemplateExpr ||
   9000                                kind == ParseNodeKind::NewExpr ||
   9001                                kind == ParseNodeKind::NewTargetExpr ||
   9002                                kind == ParseNodeKind::ImportMetaExpr;
   9003 
   9004      bool isCallExpression = kind == ParseNodeKind::SetThis ||
   9005                              kind == ParseNodeKind::CallImportExpr;
   9006 
   9007      MOZ_ASSERT(isMemberExpression || isCallExpression,
   9008                 "Unknown ParseNodeKind for OptionalChain");
   9009 #endif
   9010      return emitTree(pn);
   9011  }
   9012  return true;
   9013 }
   9014 
   9015 // Handle the case of a call made on a OptionalChainParseNode.
   9016 // For example `(a?.b)()` and `(a?.b)?.()`.
   9017 bool BytecodeEmitter::emitCalleeAndThisForOptionalChain(
   9018    UnaryNode* optionalChain, CallNode* callNode, CallOrNewEmitter& cone) {
   9019  ParseNode* calleeNode = optionalChain->kid();
   9020 
   9021  // Create a new OptionalEmitter, in order to emit the right bytecode
   9022  // in isolation.
   9023  OptionalEmitter oe(this, bytecodeSection().stackDepth());
   9024 
   9025  if (!emitOptionalCalleeAndThis(calleeNode, callNode, cone, oe)) {
   9026    //              [stack] CALLEE THIS
   9027    return false;
   9028  }
   9029 
   9030  // complete the jump if necessary. This will set both the "this" value
   9031  // and the "callee" value to undefined, if the callee is undefined. It
   9032  // does not matter much what the this value is, the function call will
   9033  // fail if it is not optional, and be set to undefined otherwise.
   9034  if (!oe.emitOptionalJumpTarget(JSOp::Undefined,
   9035                                 OptionalEmitter::Kind::Reference)) {
   9036    //              [stack] # If shortcircuit
   9037    //              [stack] UNDEFINED UNDEFINED
   9038    //              [stack] # otherwise
   9039    //              [stack] CALLEE THIS
   9040    return false;
   9041  }
   9042  return true;
   9043 }
   9044 
   9045 bool BytecodeEmitter::emitOptionalChain(UnaryNode* optionalChain,
   9046                                        ValueUsage valueUsage) {
   9047  ParseNode* expr = optionalChain->kid();
   9048 
   9049  OptionalEmitter oe(this, bytecodeSection().stackDepth());
   9050 
   9051  if (!emitOptionalTree(expr, oe, valueUsage)) {
   9052    //              [stack] VAL
   9053    return false;
   9054  }
   9055 
   9056  if (!oe.emitOptionalJumpTarget(JSOp::Undefined)) {
   9057    //              [stack] # If shortcircuit
   9058    //              [stack] UNDEFINED
   9059    //              [stack] # otherwise
   9060    //              [stack] VAL
   9061    return false;
   9062  }
   9063 
   9064  return true;
   9065 }
   9066 
   9067 bool BytecodeEmitter::emitOptionalDotExpression(PropertyAccessBase* prop,
   9068                                                PropOpEmitter& poe,
   9069                                                bool isSuper,
   9070                                                OptionalEmitter& oe) {
   9071  if (!poe.prepareForObj()) {
   9072    //              [stack]
   9073    return false;
   9074  }
   9075 
   9076  if (isSuper) {
   9077    UnaryNode* base = &prop->expression().as<UnaryNode>();
   9078    if (!emitGetThisForSuperBase(base)) {
   9079      //            [stack] OBJ
   9080      return false;
   9081    }
   9082  } else {
   9083    if (!emitOptionalTree(&prop->expression(), oe)) {
   9084      //            [stack] OBJ
   9085      return false;
   9086    }
   9087  }
   9088 
   9089  if (prop->isKind(ParseNodeKind::OptionalDotExpr)) {
   9090    MOZ_ASSERT(!isSuper);
   9091    if (!oe.emitJumpShortCircuit()) {
   9092      //            [stack] # if Jump
   9093      //            [stack] UNDEFINED-OR-NULL
   9094      //            [stack] # otherwise
   9095      //            [stack] OBJ
   9096      return false;
   9097    }
   9098  }
   9099 
   9100  if (!poe.emitGet(prop->key().atom())) {
   9101    //              [stack] PROP
   9102    return false;
   9103  }
   9104 
   9105  return true;
   9106 }
   9107 
   9108 bool BytecodeEmitter::emitOptionalElemExpression(PropertyByValueBase* elem,
   9109                                                 ElemOpEmitter& eoe,
   9110                                                 bool isSuper,
   9111                                                 OptionalEmitter& oe) {
   9112  if (!eoe.prepareForObj()) {
   9113    //              [stack]
   9114    return false;
   9115  }
   9116 
   9117  if (isSuper) {
   9118    UnaryNode* base = &elem->expression().as<UnaryNode>();
   9119    if (!emitGetThisForSuperBase(base)) {
   9120      //            [stack] OBJ
   9121      return false;
   9122    }
   9123  } else {
   9124    if (!emitOptionalTree(&elem->expression(), oe)) {
   9125      //            [stack] OBJ
   9126      return false;
   9127    }
   9128  }
   9129 
   9130  if (elem->isKind(ParseNodeKind::OptionalElemExpr)) {
   9131    MOZ_ASSERT(!isSuper);
   9132    if (!oe.emitJumpShortCircuit()) {
   9133      //            [stack] # if Jump
   9134      //            [stack] UNDEFINED-OR-NULL
   9135      //            [stack] # otherwise
   9136      //            [stack] OBJ
   9137      return false;
   9138    }
   9139  }
   9140 
   9141  if (!eoe.prepareForKey()) {
   9142    //              [stack] OBJ? OBJ
   9143    return false;
   9144  }
   9145 
   9146  if (!emitTree(&elem->key())) {
   9147    //              [stack] OBJ? OBJ KEY
   9148    return false;
   9149  }
   9150 
   9151  if (!eoe.emitGet()) {
   9152    //              [stack] ELEM
   9153    return false;
   9154  }
   9155 
   9156  return true;
   9157 }
   9158 
   9159 bool BytecodeEmitter::emitOptionalPrivateExpression(
   9160    PrivateMemberAccessBase* privateExpr, PrivateOpEmitter& xoe,
   9161    OptionalEmitter& oe) {
   9162  if (!emitOptionalTree(&privateExpr->expression(), oe)) {
   9163    //              [stack] OBJ
   9164    return false;
   9165  }
   9166 
   9167  if (privateExpr->isKind(ParseNodeKind::OptionalPrivateMemberExpr)) {
   9168    if (!oe.emitJumpShortCircuit()) {
   9169      //            [stack] # if Jump
   9170      //            [stack] UNDEFINED-OR-NULL
   9171      //            [stack] # otherwise
   9172      //            [stack] OBJ
   9173      return false;
   9174    }
   9175  }
   9176 
   9177  if (!xoe.emitReference()) {
   9178    //              [stack] OBJ NAME
   9179    return false;
   9180  }
   9181  if (!xoe.emitGet()) {
   9182    //              [stack] CALLEE THIS  # if call
   9183    //              [stack] VALUE        # otherwise
   9184    return false;
   9185  }
   9186 
   9187  return true;
   9188 }
   9189 
   9190 bool BytecodeEmitter::emitShortCircuit(ListNode* node, ValueUsage valueUsage) {
   9191  MOZ_ASSERT(node->isKind(ParseNodeKind::OrExpr) ||
   9192             node->isKind(ParseNodeKind::CoalesceExpr) ||
   9193             node->isKind(ParseNodeKind::AndExpr));
   9194 
   9195  /*
   9196   * JSOp::Or converts the operand on the stack to boolean, leaves the original
   9197   * value on the stack and jumps if true; otherwise it falls into the next
   9198   * bytecode, which pops the left operand and then evaluates the right operand.
   9199   * The jump goes around the right operand evaluation.
   9200   *
   9201   * JSOp::And converts the operand on the stack to boolean and jumps if false;
   9202   * otherwise it falls into the right operand's bytecode.
   9203   */
   9204 
   9205  TDZCheckCache tdzCache(this);
   9206 
   9207  JSOp op;
   9208  switch (node->getKind()) {
   9209    case ParseNodeKind::OrExpr:
   9210      op = JSOp::Or;
   9211      break;
   9212    case ParseNodeKind::CoalesceExpr:
   9213      op = JSOp::Coalesce;
   9214      break;
   9215    case ParseNodeKind::AndExpr:
   9216      op = JSOp::And;
   9217      break;
   9218    default:
   9219      MOZ_CRASH("Unexpected ParseNodeKind");
   9220  }
   9221 
   9222  JumpList jump;
   9223 
   9224  // Left-associative operator chain: avoid too much recursion.
   9225  //
   9226  // Emit all nodes but the last.
   9227  for (ParseNode* expr : node->contentsTo(node->last())) {
   9228    if (!emitTree(expr)) {
   9229      return false;
   9230    }
   9231    if (!emitJump(op, &jump)) {
   9232      return false;
   9233    }
   9234    if (!emit1(JSOp::Pop)) {
   9235      return false;
   9236    }
   9237  }
   9238 
   9239  // Emit the last node
   9240  if (!emitTree(node->last(), valueUsage)) {
   9241    return false;
   9242  }
   9243 
   9244  if (!emitJumpTargetAndPatch(jump)) {
   9245    return false;
   9246  }
   9247  return true;
   9248 }
   9249 
   9250 bool BytecodeEmitter::emitSequenceExpr(ListNode* node, ValueUsage valueUsage) {
   9251  for (ParseNode* child : node->contentsTo(node->last())) {
   9252    if (!updateSourceCoordNotes(child->pn_pos.begin)) {
   9253      return false;
   9254    }
   9255    if (!emitTree(child, ValueUsage::IgnoreValue)) {
   9256      return false;
   9257    }
   9258    if (!emit1(JSOp::Pop)) {
   9259      return false;
   9260    }
   9261  }
   9262 
   9263  ParseNode* child = node->last();
   9264  if (!updateSourceCoordNotes(child->pn_pos.begin)) {
   9265    return false;
   9266  }
   9267  if (!emitTree(child, valueUsage)) {
   9268    return false;
   9269  }
   9270  return true;
   9271 }
   9272 
   9273 // Using MOZ_NEVER_INLINE in here is a workaround for llvm.org/pr14047. See
   9274 // the comment on emitSwitch.
   9275 MOZ_NEVER_INLINE bool BytecodeEmitter::emitIncOrDec(UnaryNode* incDec,
   9276                                                    ValueUsage valueUsage) {
   9277  switch (incDec->kid()->getKind()) {
   9278    case ParseNodeKind::ArgumentsLength:
   9279    case ParseNodeKind::DotExpr:
   9280      return emitPropIncDec(incDec, valueUsage);
   9281    case ParseNodeKind::ElemExpr:
   9282      return emitElemIncDec(incDec, valueUsage);
   9283    case ParseNodeKind::PrivateMemberExpr:
   9284      return emitPrivateIncDec(incDec, valueUsage);
   9285    case ParseNodeKind::CallExpr:
   9286      return emitCallIncDec(incDec);
   9287    default:
   9288      return emitNameIncDec(incDec, valueUsage);
   9289  }
   9290 }
   9291 
   9292 // Using MOZ_NEVER_INLINE in here is a workaround for llvm.org/pr14047. See
   9293 // the comment on emitSwitch.
   9294 MOZ_NEVER_INLINE bool BytecodeEmitter::emitLabeledStatement(
   9295    const LabeledStatement* labeledStmt) {
   9296  auto name = labeledStmt->label();
   9297  LabelEmitter label(this);
   9298 
   9299  label.emitLabel(name);
   9300 
   9301  if (!emitTree(labeledStmt->statement())) {
   9302    return false;
   9303  }
   9304  if (!label.emitEnd()) {
   9305    return false;
   9306  }
   9307 
   9308  return true;
   9309 }
   9310 
   9311 bool BytecodeEmitter::emitConditionalExpression(
   9312    ConditionalExpression& conditional, ValueUsage valueUsage) {
   9313  CondEmitter cond(this);
   9314  if (!cond.emitCond()) {
   9315    return false;
   9316  }
   9317 
   9318  ParseNode* conditionNode = &conditional.condition();
   9319  auto conditionKind = IfEmitter::ConditionKind::Positive;
   9320  if (conditionNode->isKind(ParseNodeKind::NotExpr)) {
   9321    conditionNode = conditionNode->as<UnaryNode>().kid();
   9322    conditionKind = IfEmitter::ConditionKind::Negative;
   9323  }
   9324 
   9325  // NOTE: NotExpr of conditionNode may be unwrapped, and in that case the
   9326  //       negation is handled by conditionKind.
   9327  if (!emitTree(conditionNode)) {
   9328    return false;
   9329  }
   9330 
   9331  if (!cond.emitThenElse(conditionKind)) {
   9332    return false;
   9333  }
   9334 
   9335  if (!emitTree(&conditional.thenExpression(), valueUsage)) {
   9336    return false;
   9337  }
   9338 
   9339  if (!cond.emitElse()) {
   9340    return false;
   9341  }
   9342 
   9343  if (!emitTree(&conditional.elseExpression(), valueUsage)) {
   9344    return false;
   9345  }
   9346 
   9347  if (!cond.emitEnd()) {
   9348    return false;
   9349  }
   9350  MOZ_ASSERT(cond.pushed() == 1);
   9351 
   9352  return true;
   9353 }
   9354 
   9355 // Check for an object-literal property list that can be handled by the
   9356 // ObjLiteral writer. We ensure that for each `prop: value` pair, the key is a
   9357 // constant name or numeric index, there is no accessor specified, and the value
   9358 // can be encoded by an ObjLiteral instruction (constant number, string,
   9359 // boolean, null/undefined).
   9360 void BytecodeEmitter::isPropertyListObjLiteralCompatible(
   9361    ListNode* obj, bool* withValues, bool* withoutValues) const {
   9362  bool keysOK = true;
   9363  bool valuesOK = true;
   9364  uint32_t propCount = 0;
   9365 
   9366  for (ParseNode* propdef : obj->contents()) {
   9367    if (!propdef->is<BinaryNode>()) {
   9368      keysOK = false;
   9369      break;
   9370    }
   9371    propCount++;
   9372 
   9373    BinaryNode* prop = &propdef->as<BinaryNode>();
   9374    ParseNode* key = prop->left();
   9375    ParseNode* value = prop->right();
   9376 
   9377    // Computed keys not OK (ObjLiteral data stores constant keys).
   9378    if (key->isKind(ParseNodeKind::ComputedName)) {
   9379      keysOK = false;
   9380      break;
   9381    }
   9382 
   9383    // BigIntExprs should have been lowered to computed names at parse
   9384    // time, and so should be excluded above.
   9385    MOZ_ASSERT(!key->isKind(ParseNodeKind::BigIntExpr));
   9386 
   9387    // Numeric keys OK as long as they are integers and in range.
   9388    if (key->isKind(ParseNodeKind::NumberExpr)) {
   9389      double numValue = key->as<NumericLiteral>().value();
   9390      int32_t i = 0;
   9391      if (!NumberIsInt32(numValue, &i)) {
   9392        keysOK = false;
   9393        break;
   9394      }
   9395      if (!ObjLiteralWriter::arrayIndexInRange(i)) {
   9396        keysOK = false;
   9397        break;
   9398      }
   9399    }
   9400 
   9401    MOZ_ASSERT(key->isKind(ParseNodeKind::ObjectPropertyName) ||
   9402               key->isKind(ParseNodeKind::StringExpr) ||
   9403               key->isKind(ParseNodeKind::NumberExpr));
   9404 
   9405    AccessorType accessorType =
   9406        prop->is<PropertyDefinition>()
   9407            ? prop->as<PropertyDefinition>().accessorType()
   9408            : AccessorType::None;
   9409    if (accessorType != AccessorType::None) {
   9410      keysOK = false;
   9411      break;
   9412    }
   9413 
   9414    if (!isRHSObjLiteralCompatible(value)) {
   9415      valuesOK = false;
   9416    }
   9417  }
   9418 
   9419  if (propCount > SharedPropMap::MaxPropsForNonDictionary) {
   9420    // JSOp::NewObject cannot accept dictionary-mode objects.
   9421    keysOK = false;
   9422  }
   9423 
   9424  *withValues = keysOK && valuesOK;
   9425  *withoutValues = keysOK;
   9426 }
   9427 
   9428 bool BytecodeEmitter::isArrayObjLiteralCompatible(ListNode* array) const {
   9429  for (ParseNode* elem : array->contents()) {
   9430    if (elem->isKind(ParseNodeKind::Spread)) {
   9431      return false;
   9432    }
   9433    if (!isRHSObjLiteralCompatible(elem)) {
   9434      return false;
   9435    }
   9436  }
   9437  return true;
   9438 }
   9439 
   9440 bool BytecodeEmitter::emitPropertyList(ListNode* obj, PropertyEmitter& pe,
   9441                                       PropListType type) {
   9442  //                [stack] CTOR? OBJ
   9443 
   9444  size_t curFieldKeyIndex = 0;
   9445  size_t curStaticFieldKeyIndex = 0;
   9446  for (ParseNode* propdef : obj->contents()) {
   9447    if (propdef->is<ClassField>()) {
   9448      MOZ_ASSERT(type == ClassBody);
   9449      // Only handle computing field keys here: the .initializers lambda array
   9450      // is created elsewhere.
   9451      ClassField* field = &propdef->as<ClassField>();
   9452      if (field->name().getKind() == ParseNodeKind::ComputedName) {
   9453        auto fieldKeys =
   9454            field->isStatic()
   9455                ? TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_()
   9456                : TaggedParserAtomIndex::WellKnown::dot_fieldKeys_();
   9457        if (!emitGetName(fieldKeys)) {
   9458          //        [stack] CTOR OBJ ARRAY
   9459          return false;
   9460        }
   9461 
   9462        ParseNode* nameExpr = field->name().as<UnaryNode>().kid();
   9463 
   9464        if (!emitTree(nameExpr, ValueUsage::WantValue)) {
   9465          //        [stack] CTOR OBJ ARRAY KEY
   9466          return false;
   9467        }
   9468 
   9469        if (!emit1(JSOp::ToPropertyKey)) {
   9470          //        [stack] CTOR OBJ ARRAY KEY
   9471          return false;
   9472        }
   9473 
   9474        size_t fieldKeysIndex;
   9475        if (field->isStatic()) {
   9476          fieldKeysIndex = curStaticFieldKeyIndex++;
   9477        } else {
   9478          fieldKeysIndex = curFieldKeyIndex++;
   9479        }
   9480 
   9481        if (!emitUint32Operand(JSOp::InitElemArray, fieldKeysIndex)) {
   9482          //        [stack] CTOR OBJ ARRAY
   9483          return false;
   9484        }
   9485 
   9486        if (!emit1(JSOp::Pop)) {
   9487          //        [stack] CTOR OBJ
   9488          return false;
   9489        }
   9490      }
   9491      continue;
   9492    }
   9493 
   9494    if (propdef->isKind(ParseNodeKind::StaticClassBlock)) {
   9495      // Static class blocks are emitted as part of
   9496      // emitCreateMemberInitializers.
   9497      continue;
   9498    }
   9499 
   9500    if (propdef->is<LexicalScopeNode>()) {
   9501      // Constructors are sometimes wrapped in LexicalScopeNodes. As we
   9502      // already handled emitting the constructor, skip it.
   9503      MOZ_ASSERT(
   9504          propdef->as<LexicalScopeNode>().scopeBody()->is<ClassMethod>());
   9505      continue;
   9506    }
   9507 
   9508    // Handle __proto__: v specially because *only* this form, and no other
   9509    // involving "__proto__", performs [[Prototype]] mutation.
   9510    if (propdef->isKind(ParseNodeKind::MutateProto)) {
   9511      //            [stack] OBJ
   9512      MOZ_ASSERT(type == ObjectLiteral);
   9513      if (!pe.prepareForProtoValue(propdef->pn_pos.begin)) {
   9514        //          [stack] OBJ
   9515        return false;
   9516      }
   9517      if (!emitTree(propdef->as<UnaryNode>().kid())) {
   9518        //          [stack] OBJ PROTO
   9519        return false;
   9520      }
   9521      if (!pe.emitMutateProto()) {
   9522        //          [stack] OBJ
   9523        return false;
   9524      }
   9525      continue;
   9526    }
   9527 
   9528    if (propdef->isKind(ParseNodeKind::Spread)) {
   9529      MOZ_ASSERT(type == ObjectLiteral);
   9530      //            [stack] OBJ
   9531      if (!pe.prepareForSpreadOperand(propdef->pn_pos.begin)) {
   9532        //          [stack] OBJ OBJ
   9533        return false;
   9534      }
   9535      if (!emitTree(propdef->as<UnaryNode>().kid())) {
   9536        //          [stack] OBJ OBJ VAL
   9537        return false;
   9538      }
   9539      if (!pe.emitSpread()) {
   9540        //          [stack] OBJ
   9541        return false;
   9542      }
   9543      continue;
   9544    }
   9545 
   9546    BinaryNode* prop = &propdef->as<BinaryNode>();
   9547 
   9548    ParseNode* key = prop->left();
   9549    AccessorType accessorType;
   9550    if (prop->is<ClassMethod>()) {
   9551      ClassMethod& method = prop->as<ClassMethod>();
   9552      accessorType = method.accessorType();
   9553 
   9554      if (!method.isStatic() && key->isKind(ParseNodeKind::PrivateName) &&
   9555          accessorType != AccessorType::None) {
   9556        // Private non-static accessors are stamped onto instances from
   9557        // initializers; see emitCreateMemberInitializers.
   9558        continue;
   9559      }
   9560    } else if (prop->is<PropertyDefinition>()) {
   9561      accessorType = prop->as<PropertyDefinition>().accessorType();
   9562    } else {
   9563      accessorType = AccessorType::None;
   9564    }
   9565 
   9566    auto emitValue = [this, &key, &prop, accessorType, &pe]() {
   9567      //            [stack] CTOR? OBJ CTOR? KEY?
   9568 
   9569      ParseNode* propVal = prop->right();
   9570      if (propVal->isDirectRHSAnonFunction()) {
   9571        // The following branches except for the last `else` clause emit the
   9572        // cases handled in NameResolver::resolveFun (see NameFunctions.cpp)
   9573        if (key->isKind(ParseNodeKind::ObjectPropertyName) ||
   9574            key->isKind(ParseNodeKind::PrivateName) ||
   9575            key->isKind(ParseNodeKind::StringExpr)) {
   9576          auto keyAtom = key->as<NameNode>().atom();
   9577          if (!emitAnonymousFunctionWithName(propVal, keyAtom)) {
   9578            //      [stack] CTOR? OBJ CTOR? VAL
   9579            return false;
   9580          }
   9581        } else if (key->isKind(ParseNodeKind::NumberExpr)) {
   9582          MOZ_ASSERT(accessorType == AccessorType::None);
   9583 
   9584          auto keyAtom = key->as<NumericLiteral>().toAtom(fc, parserAtoms());
   9585          if (!keyAtom) {
   9586            return false;
   9587          }
   9588          if (!emitAnonymousFunctionWithName(propVal, keyAtom)) {
   9589            //      [stack] CTOR? OBJ CTOR? KEY VAL
   9590            return false;
   9591          }
   9592        } else if (key->isKind(ParseNodeKind::ComputedName) &&
   9593                   (key->as<UnaryNode>().kid()->isKind(
   9594                        ParseNodeKind::NumberExpr) ||
   9595                    key->as<UnaryNode>().kid()->isKind(
   9596                        ParseNodeKind::StringExpr)) &&
   9597                   accessorType == AccessorType::None) {
   9598          ParseNode* keyKid = key->as<UnaryNode>().kid();
   9599          if (keyKid->isKind(ParseNodeKind::NumberExpr)) {
   9600            auto keyAtom =
   9601                keyKid->as<NumericLiteral>().toAtom(fc, parserAtoms());
   9602            if (!keyAtom) {
   9603              return false;
   9604            }
   9605            if (!emitAnonymousFunctionWithName(propVal, keyAtom)) {
   9606              //    [stack] CTOR? OBJ CTOR? KEY VAL
   9607              return false;
   9608            }
   9609          } else {
   9610            MOZ_ASSERT(keyKid->isKind(ParseNodeKind::StringExpr));
   9611            auto keyAtom = keyKid->as<NameNode>().atom();
   9612            if (!emitAnonymousFunctionWithName(propVal, keyAtom)) {
   9613              //    [stack] CTOR? OBJ CTOR? KEY VAL
   9614              return false;
   9615            }
   9616          }
   9617        } else {
   9618          // Either a proper computed property name or a synthetic computed
   9619          // property name for BigInt keys.
   9620          MOZ_ASSERT(key->isKind(ParseNodeKind::ComputedName));
   9621 
   9622          FunctionPrefixKind prefix =
   9623              accessorType == AccessorType::None     ? FunctionPrefixKind::None
   9624              : accessorType == AccessorType::Getter ? FunctionPrefixKind::Get
   9625                                                     : FunctionPrefixKind::Set;
   9626 
   9627          if (!emitAnonymousFunctionWithComputedName(propVal, prefix)) {
   9628            //      [stack] CTOR? OBJ CTOR? KEY VAL
   9629            return false;
   9630          }
   9631        }
   9632      } else {
   9633        if (!emitTree(propVal)) {
   9634          //        [stack] CTOR? OBJ CTOR? KEY? VAL
   9635          return false;
   9636        }
   9637      }
   9638 
   9639      if (propVal->is<FunctionNode>() &&
   9640          propVal->as<FunctionNode>().funbox()->needsHomeObject()) {
   9641        if (!pe.emitInitHomeObject()) {
   9642          //        [stack] CTOR? OBJ CTOR? KEY? FUN
   9643          return false;
   9644        }
   9645      }
   9646 
   9647 #ifdef ENABLE_DECORATORS
   9648      if (prop->is<ClassMethod>()) {
   9649        ClassMethod& method = prop->as<ClassMethod>();
   9650        if (method.decorators() && !method.decorators()->empty()) {
   9651          DecoratorEmitter::Kind kind;
   9652          switch (method.accessorType()) {
   9653            case AccessorType::Getter:
   9654              kind = DecoratorEmitter::Getter;
   9655              break;
   9656            case AccessorType::Setter:
   9657              kind = DecoratorEmitter::Setter;
   9658              break;
   9659            case AccessorType::None:
   9660              kind = DecoratorEmitter::Method;
   9661              break;
   9662          }
   9663 
   9664          if (!method.isStatic()) {
   9665            bool hasKeyOnStack = key->isKind(ParseNodeKind::NumberExpr) ||
   9666                                 key->isKind(ParseNodeKind::ComputedName);
   9667            if (!emitDupAt(hasKeyOnStack ? 4 : 3)) {
   9668              //        [stack] ADDINIT OBJ KEY? VAL ADDINIT
   9669              return false;
   9670            }
   9671          } else {
   9672            // TODO: See bug 1868220 for support for static methods.
   9673            // Note: Key will be present if this has a private name.
   9674            if (!emit1(JSOp::Undefined)) {
   9675              //        [stack] CTOR OBJ CTOR KEY? VAL ADDINIT
   9676              return false;
   9677            }
   9678          }
   9679 
   9680          if (!emit1(JSOp::Swap)) {
   9681            //        [stack] ADDINIT CTOR? OBJ CTOR? KEY? ADDINIT VAL
   9682            return false;
   9683          }
   9684 
   9685          // The decorators are applied to the current value on the stack,
   9686          // possibly replacing it.
   9687          DecoratorEmitter de(this);
   9688          if (!de.emitApplyDecoratorsToElementDefinition(
   9689                  kind, key, method.decorators(), method.isStatic())) {
   9690            //        [stack] ADDINIT CTOR? OBJ CTOR? KEY? ADDINIT VAL
   9691            return false;
   9692          }
   9693 
   9694          if (!emit1(JSOp::Swap)) {
   9695            //        [stack] ADDINIT CTOR? OBJ CTOR? KEY? VAL ADDINIT
   9696            return false;
   9697          }
   9698 
   9699          if (!emitPopN(1)) {
   9700            //        [stack] ADDINIT CTOR? OBJ CTOR? KEY? VAL
   9701            return false;
   9702          }
   9703        }
   9704      }
   9705 #endif
   9706 
   9707      return true;
   9708    };
   9709 
   9710    PropertyEmitter::Kind kind =
   9711        (type == ClassBody && propdef->as<ClassMethod>().isStatic())
   9712            ? PropertyEmitter::Kind::Static
   9713            : PropertyEmitter::Kind::Prototype;
   9714    if (key->isKind(ParseNodeKind::ObjectPropertyName) ||
   9715        key->isKind(ParseNodeKind::StringExpr)) {
   9716      //            [stack] CTOR? OBJ
   9717 
   9718      auto keyAtom = key->as<NameNode>().atom();
   9719 
   9720      // emitClass took care of constructor already.
   9721      if (type == ClassBody &&
   9722          keyAtom == TaggedParserAtomIndex::WellKnown::constructor() &&
   9723          !propdef->as<ClassMethod>().isStatic()) {
   9724        continue;
   9725      }
   9726 
   9727      if (!pe.prepareForPropValue(propdef->pn_pos.begin, kind)) {
   9728        //          [stack] CTOR? OBJ CTOR?
   9729        return false;
   9730      }
   9731 
   9732      if (!emitValue()) {
   9733        //          [stack] CTOR? OBJ CTOR? VAL
   9734        return false;
   9735      }
   9736 
   9737      if (!pe.emitInit(accessorType, keyAtom)) {
   9738        //          [stack] CTOR? OBJ
   9739        return false;
   9740      }
   9741 
   9742      continue;
   9743    }
   9744 
   9745    if (key->isKind(ParseNodeKind::NumberExpr)) {
   9746      //            [stack] CTOR? OBJ
   9747      if (!pe.prepareForIndexPropKey(propdef->pn_pos.begin, kind)) {
   9748        //          [stack] CTOR? OBJ CTOR?
   9749        return false;
   9750      }
   9751      if (!emitNumberOp(key->as<NumericLiteral>().value())) {
   9752        //        [stack] CTOR? OBJ CTOR? KEY
   9753        return false;
   9754      }
   9755      if (!pe.prepareForIndexPropValue()) {
   9756        //          [stack] CTOR? OBJ CTOR? KEY
   9757        return false;
   9758      }
   9759      if (!emitValue()) {
   9760        //          [stack] CTOR? OBJ CTOR? KEY VAL
   9761        return false;
   9762      }
   9763 
   9764      if (!pe.emitInitIndexOrComputed(accessorType)) {
   9765        //          [stack] CTOR? OBJ
   9766        return false;
   9767      }
   9768 
   9769      continue;
   9770    }
   9771 
   9772    if (key->isKind(ParseNodeKind::ComputedName)) {
   9773      // Either a proper computed property name or a synthetic computed property
   9774      // name for BigInt keys.
   9775 
   9776      //            [stack] CTOR? OBJ
   9777 
   9778      if (!pe.prepareForComputedPropKey(propdef->pn_pos.begin, kind)) {
   9779        //          [stack] CTOR? OBJ CTOR?
   9780        return false;
   9781      }
   9782      if (!emitTree(key->as<UnaryNode>().kid())) {
   9783        //          [stack] CTOR? OBJ CTOR? KEY
   9784        return false;
   9785      }
   9786      if (!pe.prepareForComputedPropValue()) {
   9787        //          [stack] CTOR? OBJ CTOR? KEY
   9788        return false;
   9789      }
   9790      if (!emitValue()) {
   9791        //          [stack] CTOR? OBJ CTOR? KEY VAL
   9792        return false;
   9793      }
   9794 
   9795      if (!pe.emitInitIndexOrComputed(accessorType)) {
   9796        //          [stack] CTOR? OBJ
   9797        return false;
   9798      }
   9799 
   9800      continue;
   9801    }
   9802 
   9803    MOZ_ASSERT(key->isKind(ParseNodeKind::PrivateName));
   9804    MOZ_ASSERT(type == ClassBody);
   9805 
   9806    auto* privateName = &key->as<NameNode>();
   9807 
   9808    if (kind == PropertyEmitter::Kind::Prototype) {
   9809      MOZ_ASSERT(accessorType == AccessorType::None);
   9810      if (!pe.prepareForPrivateMethod()) {
   9811        //          [stack] CTOR OBJ
   9812        return false;
   9813      }
   9814      NameOpEmitter noe(this, privateName->atom(),
   9815                        NameOpEmitter::Kind::SimpleAssignment);
   9816 
   9817      // Ensure the NameOp emitter doesn't push an environment onto the stack,
   9818      // because that would change the stack location of the home object.
   9819      MOZ_ASSERT(noe.loc().kind() == NameLocation::Kind::FrameSlot ||
   9820                 noe.loc().kind() == NameLocation::Kind::EnvironmentCoordinate);
   9821 
   9822      if (!noe.prepareForRhs()) {
   9823        //          [stack] CTOR OBJ
   9824        return false;
   9825      }
   9826      if (!emitValue()) {
   9827        //          [stack] CTOR OBJ METHOD
   9828        return false;
   9829      }
   9830      if (!noe.emitAssignment()) {
   9831        //          [stack] CTOR OBJ METHOD
   9832        return false;
   9833      }
   9834      if (!emit1(JSOp::Pop)) {
   9835        //          [stack] CTOR OBJ
   9836        return false;
   9837      }
   9838      if (!pe.skipInit()) {
   9839        //          [stack] CTOR OBJ
   9840        return false;
   9841      }
   9842      continue;
   9843    }
   9844 
   9845    MOZ_ASSERT(kind == PropertyEmitter::Kind::Static);
   9846 
   9847    //              [stack] CTOR OBJ
   9848 
   9849    if (!pe.prepareForPrivateStaticMethod(propdef->pn_pos.begin)) {
   9850      //            [stack] CTOR OBJ CTOR
   9851      return false;
   9852    }
   9853    if (!emitGetPrivateName(privateName)) {
   9854      //            [stack] CTOR OBJ CTOR KEY
   9855      return false;
   9856    }
   9857    if (!emitValue()) {
   9858      //            [stack] CTOR OBJ CTOR KEY VAL
   9859      return false;
   9860    }
   9861 
   9862    if (!pe.emitPrivateStaticMethod(accessorType)) {
   9863      //            [stack] CTOR OBJ
   9864      return false;
   9865    }
   9866 
   9867    if (privateName->privateNameKind() == PrivateNameKind::Setter) {
   9868      if (!emitDupAt(1)) {
   9869        //          [stack] CTOR OBJ CTOR
   9870        return false;
   9871      }
   9872      if (!emitGetPrivateName(privateName)) {
   9873        //          [stack] CTOR OBJ CTOR NAME
   9874        return false;
   9875      }
   9876      if (!emitAtomOp(JSOp::GetIntrinsic,
   9877                      TaggedParserAtomIndex::WellKnown::NoPrivateGetter())) {
   9878        //          [stack] CTOR OBJ CTOR NAME FUN
   9879        return false;
   9880      }
   9881      if (!emit1(JSOp::InitHiddenElemGetter)) {
   9882        //          [stack] CTOR OBJ CTOR
   9883        return false;
   9884      }
   9885      if (!emit1(JSOp::Pop)) {
   9886        //          [stack] CTOR OBJ
   9887        return false;
   9888      }
   9889    }
   9890  }
   9891 
   9892  return true;
   9893 }
   9894 
   9895 bool BytecodeEmitter::emitPropertyListObjLiteral(ListNode* obj, JSOp op,
   9896                                                 bool useObjLiteralValues) {
   9897  ObjLiteralWriter writer;
   9898 
   9899 #ifdef DEBUG
   9900  // In self-hosted JS, we check duplication only on debug build.
   9901  mozilla::Maybe<mozilla::HashSet<frontend::TaggedParserAtomIndex,
   9902                                  frontend::TaggedParserAtomIndexHasher>>
   9903      selfHostedPropNames;
   9904  if (emitterMode == BytecodeEmitter::SelfHosting) {
   9905    selfHostedPropNames.emplace();
   9906  }
   9907 #endif
   9908 
   9909  if (op == JSOp::Object) {
   9910    writer.beginObject(op);
   9911  } else {
   9912    MOZ_ASSERT(op == JSOp::NewObject);
   9913    writer.beginShape(op);
   9914  }
   9915 
   9916  for (ParseNode* propdef : obj->contents()) {
   9917    BinaryNode* prop = &propdef->as<BinaryNode>();
   9918    ParseNode* key = prop->left();
   9919 
   9920    if (key->is<NameNode>()) {
   9921      if (emitterMode == BytecodeEmitter::SelfHosting) {
   9922        auto propName = key->as<NameNode>().atom();
   9923 #ifdef DEBUG
   9924        // Self-hosted JS shouldn't contain duplicate properties.
   9925        auto p = selfHostedPropNames->lookupForAdd(propName);
   9926        MOZ_ASSERT(!p);
   9927        if (!selfHostedPropNames->add(p, propName)) {
   9928          js::ReportOutOfMemory(fc);
   9929          return false;
   9930        }
   9931 #endif
   9932        writer.setPropNameNoDuplicateCheck(parserAtoms(), propName);
   9933      } else {
   9934        if (!writer.setPropName(parserAtoms(), key->as<NameNode>().atom())) {
   9935          return false;
   9936        }
   9937      }
   9938    } else {
   9939      double numValue = key->as<NumericLiteral>().value();
   9940      int32_t i = 0;
   9941      DebugOnly<bool> numIsInt =
   9942          NumberIsInt32(numValue, &i);  // checked previously.
   9943      MOZ_ASSERT(numIsInt);
   9944      MOZ_ASSERT(
   9945          ObjLiteralWriter::arrayIndexInRange(i));  // checked previously.
   9946 
   9947      // Ignore indexed properties if we're not storing property values, and
   9948      // rely on InitElem ops to define those. These properties will be either
   9949      // dense elements (not possible to represent in the literal's shape) or
   9950      // sparse elements (enumerated separately, so this doesn't affect property
   9951      // iteration order).
   9952      if (!useObjLiteralValues) {
   9953        continue;
   9954      }
   9955 
   9956      writer.setPropIndex(i);
   9957    }
   9958 
   9959    if (useObjLiteralValues) {
   9960      MOZ_ASSERT(op == JSOp::Object);
   9961      ParseNode* value = prop->right();
   9962      if (!emitObjLiteralValue(writer, value)) {
   9963        return false;
   9964      }
   9965    } else {
   9966      if (!writer.propWithUndefinedValue(fc)) {
   9967        return false;
   9968      }
   9969    }
   9970  }
   9971 
   9972  GCThingIndex index;
   9973  if (!addObjLiteralData(writer, &index)) {
   9974    return false;
   9975  }
   9976 
   9977  // JSOp::Object may only be used by (top-level) run-once scripts.
   9978  MOZ_ASSERT_IF(op == JSOp::Object,
   9979                sc->isTopLevelContext() && sc->treatAsRunOnce());
   9980 
   9981  if (!emitGCIndexOp(op, index)) {
   9982    //              [stack] OBJ
   9983    return false;
   9984  }
   9985 
   9986  return true;
   9987 }
   9988 
   9989 bool BytecodeEmitter::emitDestructuringRestExclusionSetObjLiteral(
   9990    ListNode* pattern) {
   9991  // Note: if we want to squeeze out a little more performance, we could switch
   9992  // to the `JSOp::Object` opcode, because the exclusion set object is never
   9993  // exposed to the user, so it's safe to bake the object into the bytecode.
   9994  constexpr JSOp op = JSOp::NewObject;
   9995 
   9996  ObjLiteralWriter writer;
   9997  writer.beginShape(op);
   9998 
   9999  for (ParseNode* member : pattern->contents()) {
  10000    if (member->isKind(ParseNodeKind::Spread)) {
  10001      MOZ_ASSERT(!member->pn_next, "unexpected trailing element after spread");
  10002      break;
  10003    }
  10004 
  10005    TaggedParserAtomIndex atom;
  10006    if (member->isKind(ParseNodeKind::MutateProto)) {
  10007      atom = TaggedParserAtomIndex::WellKnown::proto_();
  10008    } else {
  10009      ParseNode* key = member->as<BinaryNode>().left();
  10010      atom = key->as<NameNode>().atom();
  10011    }
  10012 
  10013    if (!writer.setPropName(parserAtoms(), atom)) {
  10014      return false;
  10015    }
  10016 
  10017    if (!writer.propWithUndefinedValue(fc)) {
  10018      return false;
  10019    }
  10020  }
  10021 
  10022  GCThingIndex index;
  10023  if (!addObjLiteralData(writer, &index)) {
  10024    return false;
  10025  }
  10026 
  10027  if (!emitGCIndexOp(op, index)) {
  10028    //              [stack] OBJ
  10029    return false;
  10030  }
  10031 
  10032  return true;
  10033 }
  10034 
  10035 bool BytecodeEmitter::emitObjLiteralArray(ListNode* array) {
  10036  MOZ_ASSERT(checkSingletonContext());
  10037 
  10038  constexpr JSOp op = JSOp::Object;
  10039 
  10040  ObjLiteralWriter writer;
  10041  writer.beginArray(op);
  10042 
  10043  writer.beginDenseArrayElements();
  10044  for (ParseNode* elem : array->contents()) {
  10045    if (!emitObjLiteralValue(writer, elem)) {
  10046      return false;
  10047    }
  10048  }
  10049 
  10050  GCThingIndex index;
  10051  if (!addObjLiteralData(writer, &index)) {
  10052    return false;
  10053  }
  10054 
  10055  if (!emitGCIndexOp(op, index)) {
  10056    //              [stack] OBJ
  10057    return false;
  10058  }
  10059 
  10060  return true;
  10061 }
  10062 
  10063 bool BytecodeEmitter::isRHSObjLiteralCompatible(ParseNode* value) const {
  10064  return value->isKind(ParseNodeKind::NumberExpr) ||
  10065         value->isKind(ParseNodeKind::TrueExpr) ||
  10066         value->isKind(ParseNodeKind::FalseExpr) ||
  10067         value->isKind(ParseNodeKind::NullExpr) ||
  10068         value->isKind(ParseNodeKind::RawUndefinedExpr) ||
  10069         value->isKind(ParseNodeKind::StringExpr) ||
  10070         value->isKind(ParseNodeKind::TemplateStringExpr);
  10071 }
  10072 
  10073 bool BytecodeEmitter::emitObjLiteralValue(ObjLiteralWriter& writer,
  10074                                          ParseNode* value) {
  10075  MOZ_ASSERT(isRHSObjLiteralCompatible(value));
  10076  if (value->isKind(ParseNodeKind::NumberExpr)) {
  10077    double numValue = value->as<NumericLiteral>().value();
  10078    int32_t i = 0;
  10079    js::Value v;
  10080    if (NumberIsInt32(numValue, &i)) {
  10081      v.setInt32(i);
  10082    } else {
  10083      v.setDouble(numValue);
  10084    }
  10085    if (!writer.propWithConstNumericValue(fc, v)) {
  10086      return false;
  10087    }
  10088  } else if (value->isKind(ParseNodeKind::TrueExpr)) {
  10089    if (!writer.propWithTrueValue(fc)) {
  10090      return false;
  10091    }
  10092  } else if (value->isKind(ParseNodeKind::FalseExpr)) {
  10093    if (!writer.propWithFalseValue(fc)) {
  10094      return false;
  10095    }
  10096  } else if (value->isKind(ParseNodeKind::NullExpr)) {
  10097    if (!writer.propWithNullValue(fc)) {
  10098      return false;
  10099    }
  10100  } else if (value->isKind(ParseNodeKind::RawUndefinedExpr)) {
  10101    if (!writer.propWithUndefinedValue(fc)) {
  10102      return false;
  10103    }
  10104  } else if (value->isKind(ParseNodeKind::StringExpr) ||
  10105             value->isKind(ParseNodeKind::TemplateStringExpr)) {
  10106    if (!writer.propWithAtomValue(fc, parserAtoms(),
  10107                                  value->as<NameNode>().atom())) {
  10108      return false;
  10109    }
  10110  } else {
  10111    MOZ_CRASH("Unexpected parse node");
  10112  }
  10113  return true;
  10114 }
  10115 
  10116 static bool NeedsPrivateBrand(ParseNode* member) {
  10117  return member->is<ClassMethod>() &&
  10118         member->as<ClassMethod>().name().isKind(ParseNodeKind::PrivateName) &&
  10119         !member->as<ClassMethod>().isStatic();
  10120 }
  10121 
  10122 #ifdef ENABLE_DECORATORS
  10123 static bool HasDecorators(ParseNode* member) {
  10124  return member->is<ClassMethod>() && member->as<ClassMethod>().decorators();
  10125 }
  10126 #endif
  10127 
  10128 mozilla::Maybe<MemberInitializers> BytecodeEmitter::setupMemberInitializers(
  10129    ListNode* classMembers, FieldPlacement placement) const {
  10130  bool isStatic = placement == FieldPlacement::Static;
  10131 
  10132  size_t numFields = 0;
  10133  size_t numPrivateInitializers = 0;
  10134  bool hasPrivateBrand = false;
  10135 #ifdef ENABLE_DECORATORS
  10136  bool hasDecorators = false;
  10137 #endif
  10138  for (ParseNode* member : classMembers->contents()) {
  10139    if (NeedsFieldInitializer(member, isStatic)) {
  10140      numFields++;
  10141    } else if (NeedsAccessorInitializer(member, isStatic)) {
  10142      numPrivateInitializers++;
  10143      hasPrivateBrand = true;
  10144    } else if (NeedsPrivateBrand(member)) {
  10145      hasPrivateBrand = true;
  10146    }
  10147 #ifdef ENABLE_DECORATORS
  10148    if (!hasDecorators && HasDecorators(member)) {
  10149      hasDecorators = true;
  10150    }
  10151 #endif
  10152  }
  10153 
  10154  // If there are more initializers than can be represented, return invalid.
  10155  if (numFields + numPrivateInitializers >
  10156      MemberInitializers::MaxInitializers) {
  10157    return Nothing();
  10158  }
  10159  return Some(MemberInitializers(hasPrivateBrand,
  10160 #ifdef ENABLE_DECORATORS
  10161                                 hasDecorators,
  10162 #endif
  10163                                 numFields + numPrivateInitializers));
  10164 }
  10165 
  10166 // Purpose of .fieldKeys:
  10167 // Computed field names (`["x"] = 2;`) must be ran at class-evaluation time,
  10168 // not object construction time. The transformation to do so is roughly as
  10169 // follows:
  10170 //
  10171 // class C {
  10172 //   [keyExpr] = valueExpr;
  10173 // }
  10174 // -->
  10175 // let .fieldKeys = [keyExpr];
  10176 // let .initializers = [
  10177 //   () => {
  10178 //     this[.fieldKeys[0]] = valueExpr;
  10179 //   }
  10180 // ];
  10181 // class C {
  10182 //   constructor() {
  10183 //     .initializers[0]();
  10184 //   }
  10185 // }
  10186 //
  10187 // BytecodeEmitter::emitCreateFieldKeys does `let .fieldKeys = [...];`
  10188 // BytecodeEmitter::emitPropertyList fills in the elements of the array.
  10189 // See GeneralParser::fieldInitializer for the `this[.fieldKeys[0]]` part.
  10190 bool BytecodeEmitter::emitCreateFieldKeys(ListNode* obj,
  10191                                          FieldPlacement placement) {
  10192  bool isStatic = placement == FieldPlacement::Static;
  10193  auto isFieldWithComputedName = [isStatic](ParseNode* propdef) {
  10194    return propdef->is<ClassField>() &&
  10195           propdef->as<ClassField>().isStatic() == isStatic &&
  10196           propdef->as<ClassField>().name().getKind() ==
  10197               ParseNodeKind::ComputedName;
  10198  };
  10199 
  10200  size_t numFieldKeys = std::count_if(
  10201      obj->contents().begin(), obj->contents().end(), isFieldWithComputedName);
  10202  if (numFieldKeys == 0) {
  10203    return true;
  10204  }
  10205 
  10206  auto fieldKeys =
  10207      isStatic ? TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_()
  10208               : TaggedParserAtomIndex::WellKnown::dot_fieldKeys_();
  10209  NameOpEmitter noe(this, fieldKeys, NameOpEmitter::Kind::Initialize);
  10210  if (!noe.prepareForRhs()) {
  10211    return false;
  10212  }
  10213 
  10214  if (!emitUint32Operand(JSOp::NewArray, numFieldKeys)) {
  10215    //              [stack] ARRAY
  10216    return false;
  10217  }
  10218 
  10219  if (!noe.emitAssignment()) {
  10220    //              [stack] ARRAY
  10221    return false;
  10222  }
  10223 
  10224  if (!emit1(JSOp::Pop)) {
  10225    //              [stack]
  10226    return false;
  10227  }
  10228 
  10229  return true;
  10230 }
  10231 
  10232 static bool HasInitializer(ParseNode* node, bool isStaticContext) {
  10233  return (node->is<ClassField>() &&
  10234          node->as<ClassField>().isStatic() == isStaticContext) ||
  10235         (isStaticContext && node->is<StaticClassBlock>());
  10236 }
  10237 
  10238 static FunctionNode* GetInitializer(ParseNode* node, bool isStaticContext) {
  10239  MOZ_ASSERT(HasInitializer(node, isStaticContext));
  10240  MOZ_ASSERT_IF(!node->is<ClassField>(), isStaticContext);
  10241  return node->is<ClassField>() ? node->as<ClassField>().initializer()
  10242                                : node->as<StaticClassBlock>().function();
  10243 }
  10244 
  10245 static bool IsPrivateInstanceAccessor(const ClassMethod* classMethod) {
  10246  return !classMethod->isStatic() &&
  10247         classMethod->name().isKind(ParseNodeKind::PrivateName) &&
  10248         classMethod->accessorType() != AccessorType::None;
  10249 }
  10250 
  10251 bool BytecodeEmitter::emitCreateMemberInitializers(ClassEmitter& ce,
  10252                                                   ListNode* obj,
  10253                                                   FieldPlacement placement
  10254 #ifdef ENABLE_DECORATORS
  10255                                                   ,
  10256                                                   bool hasHeritage
  10257 #endif
  10258 ) {
  10259  // FieldPlacement::Instance, hasHeritage == false
  10260  //                [stack] HOME
  10261  //
  10262  // FieldPlacement::Instance, hasHeritage == true
  10263  //                [stack] HOME HERIT
  10264  //
  10265  // FieldPlacement::Static
  10266  //                [stack] CTOR HOME
  10267 #ifdef ENABLE_DECORATORS
  10268  MOZ_ASSERT_IF(placement == FieldPlacement::Static, !hasHeritage);
  10269 #endif
  10270  mozilla::Maybe<MemberInitializers> memberInitializers =
  10271      setupMemberInitializers(obj, placement);
  10272  if (!memberInitializers) {
  10273    ReportAllocationOverflow(fc);
  10274    return false;
  10275  }
  10276 
  10277  size_t numInitializers = memberInitializers->numMemberInitializers;
  10278  if (numInitializers == 0) {
  10279    return true;
  10280  }
  10281 
  10282  bool isStatic = placement == FieldPlacement::Static;
  10283  if (!ce.prepareForMemberInitializers(numInitializers, isStatic)) {
  10284    //              [stack] HOME HERIT? ARR
  10285    // or:
  10286    //              [stack] CTOR HOME ARR
  10287    return false;
  10288  }
  10289 
  10290  // Private accessors could be used in the field initializers, so make sure
  10291  // accessor initializers appear earlier in the .initializers array so they
  10292  // run first. Static private methods are not initialized using initializers
  10293  // (emitPropertyList emits bytecode to stamp them onto the constructor), so
  10294  // skip this step if isStatic.
  10295  if (!isStatic) {
  10296    if (!emitPrivateMethodInitializers(ce, obj)) {
  10297      return false;
  10298    }
  10299  }
  10300 
  10301  for (ParseNode* propdef : obj->contents()) {
  10302    if (!HasInitializer(propdef, isStatic)) {
  10303      continue;
  10304    }
  10305 
  10306    FunctionNode* initializer = GetInitializer(propdef, isStatic);
  10307 
  10308    if (!ce.prepareForMemberInitializer()) {
  10309      return false;
  10310    }
  10311    if (!emitTree(initializer)) {
  10312      //            [stack] HOME HERIT? ARR LAMBDA
  10313      // or:
  10314      //            [stack] CTOR HOME ARR LAMBDA
  10315      return false;
  10316    }
  10317    if (initializer->funbox()->needsHomeObject()) {
  10318      MOZ_ASSERT(initializer->funbox()->allowSuperProperty());
  10319      if (!ce.emitMemberInitializerHomeObject(isStatic)) {
  10320        //          [stack] HOME HERIT? ARR LAMBDA
  10321        // or:
  10322        //          [stack] CTOR HOME ARR LAMBDA
  10323        return false;
  10324      }
  10325    }
  10326    if (!ce.emitStoreMemberInitializer()) {
  10327      //            [stack] HOME HERIT? ARR
  10328      // or:
  10329      //            [stack] CTOR HOME ARR
  10330      return false;
  10331    }
  10332  }
  10333 
  10334 #ifdef ENABLE_DECORATORS
  10335  // Index to use to append new initializers returned by decorators to the array
  10336  if (!emitNumberOp(numInitializers)) {
  10337    //            [stack] HOME HERIT? ARR I
  10338    // or:
  10339    //            [stack] CTOR HOME ARR I
  10340    return false;
  10341  }
  10342 
  10343  for (ParseNode* propdef : obj->contents()) {
  10344    if (!propdef->is<ClassField>()) {
  10345      continue;
  10346    }
  10347    ClassField* field = &propdef->as<ClassField>();
  10348    if (field->isStatic() != isStatic) {
  10349      continue;
  10350    }
  10351    if (field->decorators() && !field->decorators()->empty()) {
  10352      DecoratorEmitter de(this);
  10353      if (!field->hasAccessor()) {
  10354        if (!emitDupAt((hasHeritage || isStatic) ? 4 : 3)) {
  10355          //            [stack] ADDINIT HOME HERIT? ARR I ADDINIT
  10356          // or:
  10357          //            [stack] ADDINIT CTOR HOME ARR I ADDINIT
  10358          return false;
  10359        }
  10360        if (!de.emitApplyDecoratorsToFieldDefinition(
  10361                &field->name(), field->decorators(), field->isStatic())) {
  10362          //        [stack] HOME HERIT? ARR I ADDINIT INITS
  10363          // or:
  10364          //        [stack] CTOR HOME ARR I ADDINIT INITS
  10365          return false;
  10366        }
  10367        if (!emit1(JSOp::Swap)) {
  10368          //        [stack] HOME HERIT? ARR I INITS ADDINIT
  10369          // or:
  10370          //        [stack] CTOR HOME ARR I INITS ADDINIT
  10371          return false;
  10372        }
  10373        if (!emitPopN(1)) {
  10374          //            [stack] ADDINIT HOME HERIT? ARR I INITS
  10375          // or:
  10376          //            [stack] ADDINIT CTOR HOME ARR I INITS
  10377          return false;
  10378        }
  10379      } else {
  10380        ClassMethod* accessorGetterNode = field->accessorGetterNode();
  10381        auto accessorGetterKeyAtom =
  10382            accessorGetterNode->left()->as<NameNode>().atom();
  10383        ClassMethod* accessorSetterNode = field->accessorSetterNode();
  10384        auto accessorSetterKeyAtom =
  10385            accessorSetterNode->left()->as<NameNode>().atom();
  10386        if (!IsPrivateInstanceAccessor(accessorGetterNode)) {
  10387          if (!emitTree(&accessorGetterNode->method())) {
  10388            //      [stack] ADDINIT HOME HERIT? ARR I GET
  10389            // or:
  10390            //      [stack] ADDINIT CTOR HOME ARR I GET
  10391            return false;
  10392          }
  10393          if (!emitTree(&accessorSetterNode->method())) {
  10394            //      [stack] ADDINIT HOME HERIT? ARR I GET
  10395            //      SET
  10396            // or:
  10397            //      [stack] ADDINIT CTOR HOME ARR I GET SET
  10398            return false;
  10399          }
  10400        } else {
  10401          MOZ_ASSERT(IsPrivateInstanceAccessor(accessorSetterNode));
  10402          auto getAccessor = [this](
  10403                                 ClassMethod* classMethod,
  10404                                 TaggedParserAtomIndex& updatedAtom) -> bool {
  10405            //      [stack]
  10406 
  10407            // Synthesize a name for the lexical variable that will store the
  10408            // private method body.
  10409            TaggedParserAtomIndex name =
  10410                classMethod->name().as<NameNode>().atom();
  10411            AccessorType accessorType = classMethod->accessorType();
  10412            StringBuilder storedMethodName(fc);
  10413            if (!storedMethodName.append(parserAtoms(), name)) {
  10414              return false;
  10415            }
  10416            if (!storedMethodName.append(accessorType == AccessorType::Getter
  10417                                             ? ".getter"
  10418                                             : ".setter")) {
  10419              return false;
  10420            }
  10421            updatedAtom = storedMethodName.finishParserAtom(parserAtoms(), fc);
  10422            if (!updatedAtom) {
  10423              return false;
  10424            }
  10425 
  10426            return emitGetName(updatedAtom);
  10427            //      [stack] ACCESSOR
  10428          };
  10429 
  10430          if (!getAccessor(accessorGetterNode, accessorGetterKeyAtom)) {
  10431            //      [stack] ADDINIT HOME HERIT? ARR I GET
  10432            // or:
  10433            //      [stack] ADDINIT CTOR HOME ARR I GET
  10434            return false;
  10435          };
  10436 
  10437          if (!getAccessor(accessorSetterNode, accessorSetterKeyAtom)) {
  10438            //      [stack] ADDINIT HOME HERIT? ARR I GET SET
  10439            // or:
  10440            //      [stack] ADDINIT CTOR HOME ARR I GET SET
  10441            return false;
  10442          };
  10443        }
  10444 
  10445        if (!emitDupAt((hasHeritage || isStatic) ? 6 : 5)) {
  10446          //      [stack] ADDINIT HOME HERIT? ARR I GET SET ADDINIT
  10447          // or:
  10448          //      [stack] ADDINIT CTOR HOME ARR I GET SET ADDINIT
  10449          return false;
  10450        }
  10451 
  10452        if (!emitUnpickN(2)) {
  10453          //      [stack] ADDINIT HOME HERIT? ARR I ADDINIT GET SET
  10454          // or:
  10455          //      [stack] ADDINIT CTOR HOME ARR I ADDINIT GET SET
  10456          return false;
  10457        }
  10458 
  10459        if (!de.emitApplyDecoratorsToAccessorDefinition(
  10460                &field->name(), field->decorators(), field->isStatic())) {
  10461          //        [stack] ADDINIT HOME HERIT? ARR I ADDINIT GET SET INITS
  10462          // or:
  10463          //        [stack] ADDINIT CTOR HOME ARR I ADDINIT GET SET INITS
  10464          return false;
  10465        }
  10466 
  10467        if (!emitPickN(3)) {
  10468          //      [stack] HOME HERIT? ARR I GET SET INITS ADDINIT
  10469          // or:
  10470          //      [stack] CTOR HOME ARR I GET SET INITS ADDINIT
  10471          return false;
  10472        }
  10473 
  10474        if (!emitPopN(1)) {
  10475          //      [stack] ADDINIT HOME HERIT? ARR I GET SET INITS
  10476          // or:
  10477          //      [stack] ADDINIT CTOR HOME ARR I GET SET INITS
  10478          return false;
  10479        }
  10480 
  10481        if (!emitUnpickN(2)) {
  10482          //        [stack] ADDINIT HOME HERIT? ARR I INITS GET SET
  10483          // or:
  10484          //        [stack] ADDINIT CTOR HOME ARR I INITS GET SET
  10485          return false;
  10486        }
  10487 
  10488        if (!IsPrivateInstanceAccessor(accessorGetterNode)) {
  10489          if (!isStatic) {
  10490            if (!emitDupAt(hasHeritage ? 6 : 5)) {
  10491              //    [stack] ADDINIT HOME HERIT? ARR I INITS GET SET HOME
  10492              return false;
  10493            }
  10494          } else {
  10495            if (!emitDupAt(6)) {
  10496              //    [stack] ADDINIT CTOR HOME ARR I INITS GET SET CTOR
  10497              return false;
  10498            }
  10499            if (!emitDupAt(6)) {
  10500              //    [stack] ADDINIT CTOR HOME ARR I INITS GET SET CTOR HOME
  10501              return false;
  10502            }
  10503          }
  10504 
  10505          PropertyEmitter::Kind kind = field->isStatic()
  10506                                           ? PropertyEmitter::Kind::Static
  10507                                           : PropertyEmitter::Kind::Prototype;
  10508          if (!accessorGetterNode->name().isKind(ParseNodeKind::PrivateName)) {
  10509            MOZ_ASSERT(
  10510                !accessorSetterNode->name().isKind(ParseNodeKind::PrivateName));
  10511 
  10512            if (!ce.prepareForPropValue(propdef->pn_pos.begin, kind)) {
  10513              //    [stack] ADDINIT HOME HERIT? ARR I INITS GET SET HOME
  10514              // or:
  10515              //    [stack] ADDINIT CTOR HOME ARR I INITS GET SET CTOR HOME CTOR
  10516              return false;
  10517            }
  10518            if (!emitPickN(isStatic ? 3 : 1)) {
  10519              //    [stack] ADDINIT HOME HERIT? ARR I INITS GET HOME SET
  10520              // or:
  10521              //    [stack] ADDINIT CTOR HOME ARR I INITS GET CTOR HOME CTOR SET
  10522              return false;
  10523            }
  10524            if (!ce.emitInit(AccessorType::Setter, accessorSetterKeyAtom)) {
  10525              //    [stack] ADDINIT HOME HERIT? ARR I INITS GET HOME
  10526              // or:
  10527              //    [stack] ADDINIT CTOR HOME ARR I INITS GET CTOR HOME
  10528              return false;
  10529            }
  10530 
  10531            if (!ce.prepareForPropValue(propdef->pn_pos.begin, kind)) {
  10532              //    [stack] ADDINIT HOME HERIT? ARR I INITS GET HOME
  10533              // or:
  10534              //    [stack] ADDINIT CTOR HOME ARR I INITS GET CTOR HOME CTOR
  10535              return false;
  10536            }
  10537            if (!emitPickN(isStatic ? 3 : 1)) {
  10538              //    [stack] ADDINIT HOME HERIT? ARR I INITS HOME GET
  10539              // or:
  10540              //    [stack] ADDINIT CTOR HOME ARR I INITS CTOR HOME CTOR GET
  10541              return false;
  10542            }
  10543            if (!ce.emitInit(AccessorType::Getter, accessorGetterKeyAtom)) {
  10544              //    [stack] ADDINIT HOME HERIT? ARR I INITS HOME
  10545              // or:
  10546              //    [stack] ADDINIT CTOR HOME ARR I INITS CTOR HOME
  10547              return false;
  10548            }
  10549          } else {
  10550            MOZ_ASSERT(isStatic);
  10551            // The getter and setter share the same name.
  10552            if (!emitNewPrivateName(accessorSetterKeyAtom,
  10553                                    accessorSetterKeyAtom)) {
  10554              return false;
  10555            }
  10556            if (!ce.prepareForPrivateStaticMethod(propdef->pn_pos.begin)) {
  10557              //    [stack] ADDINIT CTOR HOME ARR I INITS GET SET CTOR HOME CTOR
  10558              return false;
  10559            }
  10560            if (!emitGetPrivateName(
  10561                    &accessorSetterNode->name().as<NameNode>())) {
  10562              //    [stack] ADDINIT CTOR HOME ARR I INITS GET SET CTOR HOME CTOR
  10563              //    KEY
  10564              return false;
  10565            }
  10566            if (!emitPickN(4)) {
  10567              //    [stack] ADDINIT CTOR HOME ARR I INITS GET CTOR HOME CTOR KEY
  10568              //    SET
  10569              return false;
  10570            }
  10571            if (!ce.emitPrivateStaticMethod(AccessorType::Setter)) {
  10572              //    [stack] ADDINIT CTOR HOME ARR I INITS GET CTOR HOME
  10573              return false;
  10574            }
  10575 
  10576            if (!ce.prepareForPrivateStaticMethod(propdef->pn_pos.begin)) {
  10577              //    [stack] ADDINIT CTOR HOME ARR I INITS GET CTOR HOME CTOR
  10578              return false;
  10579            }
  10580            if (!emitGetPrivateName(
  10581                    &accessorGetterNode->name().as<NameNode>())) {
  10582              //    [stack] ADDINIT CTOR HOME ARR I INITS GET CTOR HOME CTOR KEY
  10583              return false;
  10584            }
  10585            if (!emitPickN(4)) {
  10586              //    [stack] ADDINIT CTOR HOME ARR I INITS CTOR HOME CTOR KEY GET
  10587              return false;
  10588            }
  10589            if (!ce.emitPrivateStaticMethod(AccessorType::Getter)) {
  10590              //    [stack] ADDINIT CTOR HOME ARR I INITS CTOR HOME
  10591              return false;
  10592            }
  10593          }
  10594 
  10595          if (!isStatic) {
  10596            if (!emitPopN(1)) {
  10597              //    [stack] ADDINIT HOME HERIT? ARR I INITS
  10598              return false;
  10599            }
  10600          } else {
  10601            if (!emitPopN(2)) {
  10602              //    [stack] ADDINIT CTOR HOME ARR I INITS
  10603              return false;
  10604            }
  10605          }
  10606        } else {
  10607          MOZ_ASSERT(IsPrivateInstanceAccessor(accessorSetterNode));
  10608 
  10609          if (!emitLexicalInitialization(accessorSetterKeyAtom)) {
  10610            //      [stack] ADDINIT HOME HERIT? ARR I INITS GET SET
  10611            // or:
  10612            //      [stack] ADDINIT CTOR HOME ARR I INITS GET SET
  10613            return false;
  10614          }
  10615 
  10616          if (!emitPopN(1)) {
  10617            //      [stack] ADDINIT HOME HERIT? ARR I INITS GET
  10618            // or:
  10619            //      [stack] ADDINIT CTOR HOME ARR I INITS GET
  10620            return false;
  10621          }
  10622 
  10623          if (!emitLexicalInitialization(accessorGetterKeyAtom)) {
  10624            //      [stack] ADDINIT HOME HERIT? ARR I INITS GET
  10625            // or:
  10626            //      [stack] ADDINIT CTOR HOME ARR I INITS GET
  10627            return false;
  10628          }
  10629 
  10630          if (!emitPopN(1)) {
  10631            //      [stack] ADDINIT HOME HERIT? ARR I INITS
  10632            // or:
  10633            //      [stack] ADDINIT CTOR HOME ARR I INITS
  10634            return false;
  10635          }
  10636        }
  10637      }
  10638      if (!emit1(JSOp::InitElemInc)) {
  10639        //          [stack] ADDINIT HOME HERIT? ARR I
  10640        // or:
  10641        //          [stack] ADDINIT CTOR HOME ARR I
  10642        return false;
  10643      }
  10644    }
  10645  }
  10646 
  10647  // Pop I
  10648  if (!emitPopN(1)) {
  10649    //              [stack] ADDINIT HOME HERIT? ARR
  10650    // or:
  10651    //              [stack] ADDINIT CTOR HOME ARR
  10652    return false;
  10653  }
  10654 #endif
  10655 
  10656  if (!ce.emitMemberInitializersEnd()) {
  10657    //              [stack] ADDINIT HOME HERIT?
  10658    // or:
  10659    //              [stack] ADDINIT CTOR HOME
  10660    return false;
  10661  }
  10662 
  10663  return true;
  10664 }
  10665 
  10666 bool BytecodeEmitter::emitPrivateMethodInitializers(ClassEmitter& ce,
  10667                                                    ListNode* obj) {
  10668  for (ParseNode* propdef : obj->contents()) {
  10669    if (!propdef->is<ClassMethod>()) {
  10670      continue;
  10671    }
  10672    auto* classMethod = &propdef->as<ClassMethod>();
  10673 
  10674    // Skip over anything which isn't a private instance accessor.
  10675    if (!IsPrivateInstanceAccessor(classMethod)) {
  10676      continue;
  10677    }
  10678 
  10679    if (!ce.prepareForMemberInitializer()) {
  10680      //            [stack] HOMEOBJ HERITAGE? ARRAY
  10681      // or:
  10682      //            [stack] CTOR HOMEOBJ ARRAY
  10683      return false;
  10684    }
  10685 
  10686    // Synthesize a name for the lexical variable that will store the
  10687    // private method body.
  10688    TaggedParserAtomIndex name = classMethod->name().as<NameNode>().atom();
  10689    AccessorType accessorType = classMethod->accessorType();
  10690    StringBuilder storedMethodName(fc);
  10691    if (!storedMethodName.append(parserAtoms(), name)) {
  10692      return false;
  10693    }
  10694    if (!storedMethodName.append(
  10695            accessorType == AccessorType::Getter ? ".getter" : ".setter")) {
  10696      return false;
  10697    }
  10698    auto storedMethodAtom =
  10699        storedMethodName.finishParserAtom(parserAtoms(), fc);
  10700 
  10701    // Emit the private method body and store it as a lexical var.
  10702    if (!emitFunction(&classMethod->method())) {
  10703      //            [stack] HOMEOBJ HERITAGE? ARRAY METHOD
  10704      // or:
  10705      //            [stack] CTOR HOMEOBJ ARRAY METHOD
  10706      return false;
  10707    }
  10708    // The private method body needs to access the home object,
  10709    // and the CE knows where that is on the stack.
  10710    if (classMethod->method().funbox()->needsHomeObject()) {
  10711      if (!ce.emitMemberInitializerHomeObject(false)) {
  10712        //          [stack] HOMEOBJ HERITAGE? ARRAY METHOD
  10713        // or:
  10714        //          [stack] CTOR HOMEOBJ ARRAY METHOD
  10715        return false;
  10716      }
  10717    }
  10718    if (!emitLexicalInitialization(storedMethodAtom)) {
  10719      //            [stack] HOMEOBJ HERITAGE? ARRAY METHOD
  10720      // or:
  10721      //            [stack] CTOR HOMEOBJ ARRAY METHOD
  10722      return false;
  10723    }
  10724    if (!emit1(JSOp::Pop)) {
  10725      //            [stack] HOMEOBJ HERITAGE? ARRAY
  10726      // or:
  10727      //            [stack] CTOR HOMEOBJ ARRAY
  10728      return false;
  10729    }
  10730 
  10731    if (!emitPrivateMethodInitializer(classMethod, storedMethodAtom)) {
  10732      //            [stack] HOMEOBJ HERITAGE? ARRAY
  10733      // or:
  10734      //            [stack] CTOR HOMEOBJ ARRAY
  10735      return false;
  10736    }
  10737 
  10738    // Store the emitted initializer function into the .initializers array.
  10739    if (!ce.emitStoreMemberInitializer()) {
  10740      //            [stack] HOMEOBJ HERITAGE? ARRAY
  10741      // or:
  10742      //            [stack] CTOR HOMEOBJ ARRAY
  10743      return false;
  10744    }
  10745  }
  10746 
  10747  return true;
  10748 }
  10749 
  10750 bool BytecodeEmitter::emitPrivateMethodInitializer(
  10751    ClassMethod* classMethod, TaggedParserAtomIndex storedMethodAtom) {
  10752  MOZ_ASSERT(IsPrivateInstanceAccessor(classMethod));
  10753 
  10754  auto* name = &classMethod->name().as<NameNode>();
  10755 
  10756  // Emit the synthesized initializer function.
  10757  FunctionNode* funNode = classMethod->initializerIfPrivate();
  10758  MOZ_ASSERT(funNode);
  10759  FunctionBox* funbox = funNode->funbox();
  10760  FunctionEmitter fe(this, funbox, funNode->syntaxKind(),
  10761                     FunctionEmitter::IsHoisted::No);
  10762  if (!fe.prepareForNonLazy()) {
  10763    //              [stack]
  10764    return false;
  10765  }
  10766 
  10767  BytecodeEmitter bce2(this, funbox);
  10768  if (!bce2.init(funNode->pn_pos)) {
  10769    return false;
  10770  }
  10771  ParamsBodyNode* paramsBody = funNode->body();
  10772  FunctionScriptEmitter fse(&bce2, funbox, Nothing(), Nothing());
  10773  if (!fse.prepareForParameters()) {
  10774    //              [stack]
  10775    return false;
  10776  }
  10777  if (!bce2.emitFunctionFormalParameters(paramsBody)) {
  10778    //              [stack]
  10779    return false;
  10780  }
  10781  if (!fse.prepareForBody()) {
  10782    //              [stack]
  10783    return false;
  10784  }
  10785 
  10786  if (!bce2.emit1(JSOp::FunctionThis)) {
  10787    //              [stack] THIS
  10788    return false;
  10789  }
  10790  if (!bce2.emitGetPrivateName(name)) {
  10791    //              [stack] THIS NAME
  10792    return false;
  10793  }
  10794  if (!bce2.emitGetName(storedMethodAtom)) {
  10795    //              [stack] THIS NAME METHOD
  10796    return false;
  10797  }
  10798 
  10799  switch (name->privateNameKind()) {
  10800    case PrivateNameKind::Setter:
  10801      if (!bce2.emit1(JSOp::InitHiddenElemSetter)) {
  10802        //          [stack] THIS
  10803        return false;
  10804      }
  10805      if (!bce2.emitGetPrivateName(name)) {
  10806        //          [stack] THIS NAME
  10807        return false;
  10808      }
  10809      if (!bce2.emitAtomOp(
  10810              JSOp::GetIntrinsic,
  10811              TaggedParserAtomIndex::WellKnown::NoPrivateGetter())) {
  10812        //          [stack] THIS NAME FUN
  10813        return false;
  10814      }
  10815      if (!bce2.emit1(JSOp::InitHiddenElemGetter)) {
  10816        //          [stack] THIS
  10817        return false;
  10818      }
  10819      break;
  10820    case PrivateNameKind::Getter:
  10821    case PrivateNameKind::GetterSetter:
  10822      if (classMethod->accessorType() == AccessorType::Getter) {
  10823        if (!bce2.emit1(JSOp::InitHiddenElemGetter)) {
  10824          //        [stack] THIS
  10825          return false;
  10826        }
  10827      } else {
  10828        if (!bce2.emit1(JSOp::InitHiddenElemSetter)) {
  10829          //        [stack] THIS
  10830          return false;
  10831        }
  10832      }
  10833      break;
  10834    default:
  10835      MOZ_CRASH("Invalid op");
  10836  }
  10837 
  10838  // Pop remaining THIS.
  10839  if (!bce2.emit1(JSOp::Pop)) {
  10840    //              [stack]
  10841    return false;
  10842  }
  10843 
  10844  if (!fse.emitEndBody()) {
  10845    //              [stack]
  10846    return false;
  10847  }
  10848  if (!fse.intoStencil()) {
  10849    return false;
  10850  }
  10851 
  10852  if (!fe.emitNonLazyEnd()) {
  10853    //              [stack] HOMEOBJ HERITAGE? ARRAY FUN
  10854    // or:
  10855    //              [stack] CTOR HOMEOBJ ARRAY FUN
  10856    return false;
  10857  }
  10858 
  10859  return true;
  10860 }
  10861 
  10862 const MemberInitializers& BytecodeEmitter::findMemberInitializersForCall()
  10863    const {
  10864  for (const auto* current = this; current; current = current->parent) {
  10865    if (current->sc->isFunctionBox()) {
  10866      FunctionBox* funbox = current->sc->asFunctionBox();
  10867 
  10868      if (funbox->isArrow()) {
  10869        continue;
  10870      }
  10871 
  10872      // If we found a non-arrow / non-constructor we were never allowed to
  10873      // expect fields in the first place.
  10874      MOZ_RELEASE_ASSERT(funbox->isClassConstructor());
  10875 
  10876      return funbox->useMemberInitializers() ? funbox->memberInitializers()
  10877                                             : MemberInitializers::Empty();
  10878    }
  10879  }
  10880 
  10881  MOZ_RELEASE_ASSERT(compilationState.scopeContext.memberInitializers);
  10882  return *compilationState.scopeContext.memberInitializers;
  10883 }
  10884 
  10885 bool BytecodeEmitter::emitInitializeInstanceMembers(
  10886    bool isDerivedClassConstructor) {
  10887  const MemberInitializers& memberInitializers =
  10888      findMemberInitializersForCall();
  10889  MOZ_ASSERT(memberInitializers.valid);
  10890 
  10891  if (memberInitializers.hasPrivateBrand) {
  10892    // This is guaranteed to run after super(), so we don't need TDZ checks.
  10893    if (!emitGetName(TaggedParserAtomIndex::WellKnown::dot_this_())) {
  10894      //            [stack] THIS
  10895      return false;
  10896    }
  10897    if (!emitGetName(TaggedParserAtomIndex::WellKnown::dot_privateBrand_())) {
  10898      //            [stack] THIS BRAND
  10899      return false;
  10900    }
  10901    if (isDerivedClassConstructor) {
  10902      if (!emitCheckPrivateField(ThrowCondition::ThrowHas,
  10903                                 ThrowMsgKind::PrivateBrandDoubleInit)) {
  10904        //          [stack] THIS BRAND BOOL
  10905        return false;
  10906      }
  10907      if (!emit1(JSOp::Pop)) {
  10908        //          [stack] THIS BRAND
  10909        return false;
  10910      }
  10911    }
  10912    if (!emit1(JSOp::Null)) {
  10913      //            [stack] THIS BRAND NULL
  10914      return false;
  10915    }
  10916    if (!emit1(JSOp::InitHiddenElem)) {
  10917      //            [stack] THIS
  10918      return false;
  10919    }
  10920    if (!emit1(JSOp::Pop)) {
  10921      //            [stack]
  10922      return false;
  10923    }
  10924  }
  10925 
  10926  size_t numInitializers = memberInitializers.numMemberInitializers;
  10927  if (numInitializers > 0) {
  10928    if (!emitGetName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
  10929      //              [stack] ARRAY
  10930      return false;
  10931    }
  10932 
  10933    for (size_t index = 0; index < numInitializers; index++) {
  10934      if (index < numInitializers - 1) {
  10935        // We Dup to keep the array around (it is consumed in the bytecode
  10936        // below) for next iterations of this loop, except for the last
  10937        // iteration, which avoids an extra Pop at the end of the loop.
  10938        if (!emit1(JSOp::Dup)) {
  10939          //          [stack] ARRAY ARRAY
  10940          return false;
  10941        }
  10942      }
  10943 
  10944      if (!emitNumberOp(index)) {
  10945        //            [stack] ARRAY? ARRAY INDEX
  10946        return false;
  10947      }
  10948 
  10949      if (!emit1(JSOp::GetElem)) {
  10950        //            [stack] ARRAY? FUNC
  10951        return false;
  10952      }
  10953 
  10954      // This is guaranteed to run after super(), so we don't need TDZ checks.
  10955      if (!emitGetName(TaggedParserAtomIndex::WellKnown::dot_this_())) {
  10956        //            [stack] ARRAY? FUNC THIS
  10957        return false;
  10958      }
  10959 
  10960      // Callee is always internal function.
  10961      if (!emitCall(JSOp::CallIgnoresRv, 0)) {
  10962        //            [stack] ARRAY? RVAL
  10963        return false;
  10964      }
  10965 
  10966      if (!emit1(JSOp::Pop)) {
  10967        //            [stack] ARRAY?
  10968        return false;
  10969      }
  10970    }
  10971 #ifdef ENABLE_DECORATORS
  10972    if (memberInitializers.hasDecorators) {
  10973      // Decorators Proposal
  10974      // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-initializeinstanceelements
  10975      // 4. For each element e of elements, do
  10976      //     4.a. If elementRecord.[[Kind]] is field or accessor, then
  10977      //         4.a.i. Perform ? InitializeFieldOrAccessor(O, elementRecord).
  10978      //
  10979 
  10980      // TODO: (See Bug 1817993) At the moment, we're applying the
  10981      // initialization logic in two steps. The pre-decorator initialization
  10982      // code runs, stores the initial value, and then we retrieve it here and
  10983      // apply the initializers added by decorators. We should unify these two
  10984      // steps.
  10985      if (!emitGetName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
  10986        //              [stack] ARRAY
  10987        return false;
  10988      }
  10989 
  10990      if (!emit1(JSOp::Dup)) {
  10991        //          [stack] ARRAY ARRAY
  10992        return false;
  10993      }
  10994 
  10995      if (!emitAtomOp(JSOp::GetProp,
  10996                      TaggedParserAtomIndex::WellKnown::length())) {
  10997        //          [stack] ARRAY LENGTH
  10998        return false;
  10999      }
  11000 
  11001      if (!emitNumberOp(static_cast<double>(numInitializers))) {
  11002        //          [stack] ARRAY LENGTH INDEX
  11003        return false;
  11004      }
  11005 
  11006      InternalWhileEmitter wh(this);
  11007      // At this point, we have no context to determine offsets in the
  11008      // code for this while statement. Ideally, it would correspond to
  11009      // the field we're initializing.
  11010      if (!wh.emitCond()) {
  11011        //          [stack] ARRAY LENGTH INDEX
  11012        return false;
  11013      }
  11014 
  11015      if (!emit1(JSOp::Dup)) {
  11016        //          [stack] ARRAY LENGTH INDEX INDEX
  11017        return false;
  11018      }
  11019 
  11020      if (!emitDupAt(2)) {
  11021        //          [stack] ARRAY LENGTH INDEX INDEX LENGTH
  11022        return false;
  11023      }
  11024 
  11025      if (!emit1(JSOp::Lt)) {
  11026        //          [stack] ARRAY LENGTH INDEX BOOL
  11027        return false;
  11028      }
  11029 
  11030      if (!wh.emitBody()) {
  11031        //          [stack] ARRAY LENGTH INDEX
  11032        return false;
  11033      }
  11034 
  11035      if (!emitDupAt(2)) {
  11036        //          [stack] ARRAY LENGTH INDEX ARRAY
  11037        return false;
  11038      }
  11039 
  11040      if (!emitDupAt(1)) {
  11041        //          [stack] ARRAY LENGTH INDEX ARRAY INDEX
  11042        return false;
  11043      }
  11044 
  11045      // Retrieve initializers for this field
  11046      if (!emit1(JSOp::GetElem)) {
  11047        //            [stack] ARRAY LENGTH INDEX INITIALIZERS
  11048        return false;
  11049      }
  11050 
  11051      // This is guaranteed to run after super(), so we don't need TDZ checks.
  11052      if (!emitGetName(TaggedParserAtomIndex::WellKnown::dot_this_())) {
  11053        //            [stack] ARRAY LENGTH INDEX INITIALIZERS THIS
  11054        return false;
  11055      }
  11056 
  11057      if (!emit1(JSOp::Swap)) {
  11058        //            [stack] ARRAY LENGTH INDEX THIS INITIALIZERS
  11059        return false;
  11060      }
  11061 
  11062      DecoratorEmitter de(this);
  11063      if (!de.emitInitializeFieldOrAccessor()) {
  11064        //            [stack] ARRAY LENGTH INDEX
  11065        return false;
  11066      }
  11067 
  11068      if (!emit1(JSOp::Inc)) {
  11069        //            [stack] ARRAY LENGTH INDEX
  11070        return false;
  11071      }
  11072 
  11073      if (!wh.emitEnd()) {
  11074        //          [stack] ARRAY LENGTH INDEX
  11075        return false;
  11076      }
  11077 
  11078      if (!emitPopN(3)) {
  11079        //            [stack]
  11080        return false;
  11081      }
  11082      // 5. Return unused.
  11083 
  11084      if (!de.emitCallExtraInitializers(TaggedParserAtomIndex::WellKnown::
  11085                                            dot_instanceExtraInitializers_())) {
  11086        return false;
  11087      }
  11088    }
  11089 #endif
  11090  }
  11091  return true;
  11092 }
  11093 
  11094 bool BytecodeEmitter::emitInitializeStaticFields(ListNode* classMembers) {
  11095  auto isStaticField = [](ParseNode* propdef) {
  11096    return HasInitializer(propdef, true);
  11097  };
  11098  size_t numFields =
  11099      std::count_if(classMembers->contents().begin(),
  11100                    classMembers->contents().end(), isStaticField);
  11101 
  11102  if (numFields == 0) {
  11103    return true;
  11104  }
  11105 
  11106  if (!emitGetName(
  11107          TaggedParserAtomIndex::WellKnown::dot_staticInitializers_())) {
  11108    //              [stack] CTOR ARRAY
  11109    return false;
  11110  }
  11111 
  11112  for (size_t fieldIndex = 0; fieldIndex < numFields; fieldIndex++) {
  11113    bool hasNext = fieldIndex < numFields - 1;
  11114    if (hasNext) {
  11115      // We Dup to keep the array around (it is consumed in the bytecode below)
  11116      // for next iterations of this loop, except for the last iteration, which
  11117      // avoids an extra Pop at the end of the loop.
  11118      if (!emit1(JSOp::Dup)) {
  11119        //          [stack] CTOR ARRAY ARRAY
  11120        return false;
  11121      }
  11122    }
  11123 
  11124    if (!emitNumberOp(fieldIndex)) {
  11125      //            [stack] CTOR ARRAY? ARRAY INDEX
  11126      return false;
  11127    }
  11128 
  11129    if (!emit1(JSOp::GetElem)) {
  11130      //            [stack] CTOR ARRAY? FUNC
  11131      return false;
  11132    }
  11133 
  11134    if (!emitDupAt(1 + hasNext)) {
  11135      //            [stack] CTOR ARRAY? FUNC CTOR
  11136      return false;
  11137    }
  11138 
  11139    // Callee is always internal function.
  11140    if (!emitCall(JSOp::CallIgnoresRv, 0)) {
  11141      //            [stack] CTOR ARRAY? RVAL
  11142      return false;
  11143    }
  11144 
  11145    if (!emit1(JSOp::Pop)) {
  11146      //            [stack] CTOR ARRAY?
  11147      return false;
  11148    }
  11149  }
  11150 
  11151 #ifdef ENABLE_DECORATORS
  11152  // Decorators Proposal
  11153  // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-initializeinstanceelements
  11154  // 4. For each element e of elements, do
  11155  //     4.a. If elementRecord.[[Kind]] is field or accessor, then
  11156  //         4.a.i. Perform ? InitializeFieldOrAccessor(O, elementRecord).
  11157  //
  11158 
  11159  // TODO: (See Bug 1817993) At the moment, we're applying the initialization
  11160  // logic in two steps. The pre-decorator initialization code runs, stores
  11161  // the initial value, and then we retrieve it here and apply the
  11162  // initializers added by decorators. We should unify these two steps.
  11163  if (!emitGetName(
  11164          TaggedParserAtomIndex::WellKnown::dot_staticInitializers_())) {
  11165    //          [stack] CTOR ARRAY
  11166    return false;
  11167  }
  11168 
  11169  if (!emit1(JSOp::Dup)) {
  11170    //          [stack] CTOR ARRAY ARRAY
  11171    return false;
  11172  }
  11173 
  11174  if (!emitAtomOp(JSOp::GetProp, TaggedParserAtomIndex::WellKnown::length())) {
  11175    //          [stack] CTOR ARRAY LENGTH
  11176    return false;
  11177  }
  11178 
  11179  if (!emitNumberOp(static_cast<double>(numFields))) {
  11180    //          [stack] CTOR ARRAY LENGTH INDEX
  11181    return false;
  11182  }
  11183 
  11184  InternalWhileEmitter wh(this);
  11185  // At this point, we have no context to determine offsets in the
  11186  // code for this while statement. Ideally, it would correspond to
  11187  // the field we're initializing.
  11188  if (!wh.emitCond()) {
  11189    //          [stack] CTOR ARRAY LENGTH INDEX
  11190    return false;
  11191  }
  11192 
  11193  if (!emit1(JSOp::Dup)) {
  11194    //          [stack] CTOR ARRAY LENGTH INDEX INDEX
  11195    return false;
  11196  }
  11197 
  11198  if (!emitDupAt(2)) {
  11199    //          [stack] CTOR ARRAY LENGTH INDEX INDEX LENGTH
  11200    return false;
  11201  }
  11202 
  11203  if (!emit1(JSOp::Lt)) {
  11204    //          [stack] CTOR ARRAY LENGTH INDEX BOOL
  11205    return false;
  11206  }
  11207 
  11208  if (!wh.emitBody()) {
  11209    //          [stack] CTOR ARRAY LENGTH INDEX
  11210    return false;
  11211  }
  11212 
  11213  if (!emitDupAt(2)) {
  11214    //          [stack] CTOR ARRAY LENGTH INDEX ARRAY
  11215    return false;
  11216  }
  11217 
  11218  if (!emitDupAt(1)) {
  11219    //          [stack] CTOR ARRAY LENGTH INDEX ARRAY INDEX
  11220    return false;
  11221  }
  11222 
  11223  // Retrieve initializers for this field
  11224  if (!emit1(JSOp::GetElem)) {
  11225    //            [stack] CTOR ARRAY LENGTH INDEX INITIALIZERS
  11226    return false;
  11227  }
  11228 
  11229  if (!emitDupAt(4)) {
  11230    //            [stack] CTOR ARRAY LENGTH INDEX INITIALIZERS CTOR
  11231    return false;
  11232  }
  11233 
  11234  if (!emit1(JSOp::Swap)) {
  11235    //            [stack] CTOR ARRAY LENGTH INDEX CTOR INITIALIZERS
  11236    return false;
  11237  }
  11238 
  11239  DecoratorEmitter de(this);
  11240  if (!de.emitInitializeFieldOrAccessor()) {
  11241    //            [stack] CTOR ARRAY LENGTH INDEX
  11242    return false;
  11243  }
  11244 
  11245  if (!emit1(JSOp::Inc)) {
  11246    //            [stack] CTOR ARRAY LENGTH INDEX
  11247    return false;
  11248  }
  11249 
  11250  if (!wh.emitEnd()) {
  11251    //          [stack] CTOR ARRAY LENGTH INDEX
  11252    return false;
  11253  }
  11254 
  11255  if (!emitPopN(3)) {
  11256    //            [stack] CTOR
  11257    return false;
  11258  }
  11259  // 5. Return unused.
  11260 #endif
  11261 
  11262  // Overwrite |.staticInitializers| and |.staticFieldKeys| with undefined to
  11263  // avoid keeping the arrays alive indefinitely.
  11264  auto clearStaticFieldSlot = [&](TaggedParserAtomIndex name) {
  11265    NameOpEmitter noe(this, name, NameOpEmitter::Kind::SimpleAssignment);
  11266    if (!noe.prepareForRhs()) {
  11267      //            [stack] ENV? VAL?
  11268      return false;
  11269    }
  11270 
  11271    if (!emit1(JSOp::Undefined)) {
  11272      //            [stack] ENV? VAL? UNDEFINED
  11273      return false;
  11274    }
  11275 
  11276    if (!noe.emitAssignment()) {
  11277      //            [stack] VAL
  11278      return false;
  11279    }
  11280 
  11281    if (!emit1(JSOp::Pop)) {
  11282      //            [stack]
  11283      return false;
  11284    }
  11285 
  11286    return true;
  11287  };
  11288 
  11289  if (!clearStaticFieldSlot(
  11290          TaggedParserAtomIndex::WellKnown::dot_staticInitializers_())) {
  11291    return false;
  11292  }
  11293 
  11294  auto isStaticFieldWithComputedName = [](ParseNode* propdef) {
  11295    return propdef->is<ClassField>() && propdef->as<ClassField>().isStatic() &&
  11296           propdef->as<ClassField>().name().getKind() ==
  11297               ParseNodeKind::ComputedName;
  11298  };
  11299 
  11300  if (std::any_of(classMembers->contents().begin(),
  11301                  classMembers->contents().end(),
  11302                  isStaticFieldWithComputedName)) {
  11303    if (!clearStaticFieldSlot(
  11304            TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_())) {
  11305      return false;
  11306    }
  11307  }
  11308 
  11309  return true;
  11310 }
  11311 
  11312 // Using MOZ_NEVER_INLINE in here is a workaround for llvm.org/pr14047. See
  11313 // the comment on emitSwitch.
  11314 MOZ_NEVER_INLINE bool BytecodeEmitter::emitObject(ListNode* objNode) {
  11315  // Note: this method uses the ObjLiteralWriter and emits ObjLiteralStencil
  11316  // objects into the GCThingList, which will evaluate them into real GC objects
  11317  // or shapes during JSScript::fullyInitFromEmitter. Eventually we want
  11318  // JSOp::Object to be a real opcode, but for now, performance constraints
  11319  // limit us to evaluating object literals at the end of parse, when we're
  11320  // allowed to allocate GC things.
  11321  //
  11322  // There are four cases here, in descending order of preference:
  11323  //
  11324  // 1. The list of property names is "normal" and constant (no computed
  11325  //    values, no integer indices), the values are all simple constants
  11326  //    (numbers, booleans, strings), *and* this occurs in a run-once
  11327  //    (singleton) context. In this case, we can emit ObjLiteral
  11328  //    instructions to build an object with values, and the object will be
  11329  //    attached to a JSOp::Object opcode, whose semantics are for the backend
  11330  //    to simply steal the object from the script.
  11331  //
  11332  // 2. The list of property names is "normal" and constant as above, *and* this
  11333  //    occurs in a run-once (singleton) context, but some values are complex
  11334  //    (computed expressions, sub-objects, functions, etc.). In this case, we
  11335  //    can still use JSOp::Object (because singleton context), but the object
  11336  //    has |undefined| property values and InitProp ops are emitted to set the
  11337  //    values.
  11338  //
  11339  // 3. The list of property names is "normal" and constant as above, but this
  11340  //    occurs in a non-run-once (non-singleton) context. In this case, we can
  11341  //    use the ObjLiteral functionality to describe an *empty* object (all
  11342  //    values left undefined) with the right fields, which will become a
  11343  //    JSOp::NewObject opcode using the object's shape to speed up the creation
  11344  //    of the object each time it executes. The emitted bytecode still needs
  11345  //    InitProp ops to set the values in this case.
  11346  //
  11347  // 4. Any other case. As a fallback, we use NewInit to create a new, empty
  11348  //    object (i.e., `{}`) and then emit bytecode to initialize its properties
  11349  //    one-by-one.
  11350 
  11351  bool useObjLiteral = false;
  11352  bool useObjLiteralValues = false;
  11353  isPropertyListObjLiteralCompatible(objNode, &useObjLiteralValues,
  11354                                     &useObjLiteral);
  11355 
  11356  //                [stack]
  11357  //
  11358  ObjectEmitter oe(this);
  11359  if (useObjLiteral) {
  11360    bool singleton = checkSingletonContext() &&
  11361                     !objNode->hasNonConstInitializer() && objNode->head();
  11362    JSOp op;
  11363    if (singleton) {
  11364      // Case 1 or 2.
  11365      op = JSOp::Object;
  11366    } else {
  11367      // Case 3.
  11368      useObjLiteralValues = false;
  11369      op = JSOp::NewObject;
  11370    }
  11371 
  11372    // Use an ObjLiteral op. This will record ObjLiteral insns in the
  11373    // objLiteralWriter's buffer and add a fixup to the list of ObjLiteral
  11374    // fixups so that at GC-publish time at the end of parse, the full object
  11375    // (case 1 or 2) or shape (case 3) can be allocated and the bytecode can be
  11376    // patched to refer to it.
  11377    if (!emitPropertyListObjLiteral(objNode, op, useObjLiteralValues)) {
  11378      //            [stack] OBJ
  11379      return false;
  11380    }
  11381    // Put the ObjectEmitter in the right state. This tells it that there will
  11382    // already be an object on the stack as a result of the (eventual)
  11383    // NewObject or Object op, and prepares it to emit values if needed.
  11384    if (!oe.emitObjectWithTemplateOnStack()) {
  11385      //            [stack] OBJ
  11386      return false;
  11387    }
  11388    if (!useObjLiteralValues) {
  11389      // Case 2 or 3 above: we still need to emit bytecode to fill in the
  11390      // object's property values.
  11391      if (!emitPropertyList(objNode, oe, ObjectLiteral)) {
  11392        //          [stack] OBJ
  11393        return false;
  11394      }
  11395    }
  11396  } else {
  11397    // Case 4 above: no ObjLiteral use, just bytecode to build the object from
  11398    // scratch.
  11399    if (!oe.emitObject(objNode->count())) {
  11400      //            [stack] OBJ
  11401      return false;
  11402    }
  11403    if (!emitPropertyList(objNode, oe, ObjectLiteral)) {
  11404      //            [stack] OBJ
  11405      return false;
  11406    }
  11407  }
  11408 
  11409  if (!oe.emitEnd()) {
  11410    //              [stack] OBJ
  11411    return false;
  11412  }
  11413 
  11414  return true;
  11415 }
  11416 
  11417 bool BytecodeEmitter::emitArrayLiteral(ListNode* array) {
  11418  // Emit JSOp::Object if the array consists entirely of primitive values and we
  11419  // are in a singleton context.
  11420  if (checkSingletonContext() && !array->hasNonConstInitializer() &&
  11421      !array->empty() && isArrayObjLiteralCompatible(array)) {
  11422    return emitObjLiteralArray(array);
  11423  }
  11424 
  11425  return emitArray(array);
  11426 }
  11427 
  11428 bool BytecodeEmitter::emitArray(ListNode* array) {
  11429  /*
  11430   * Emit code for [a, b, c] that is equivalent to constructing a new
  11431   * array and in source order evaluating each element value and adding
  11432   * it to the array, without invoking latent setters.  We use the
  11433   * JSOp::NewInit and JSOp::InitElemArray bytecodes to ignore setters and
  11434   * to avoid dup'ing and popping the array as each element is added, as
  11435   * JSOp::SetElem/JSOp::SetProp would do.
  11436   */
  11437 
  11438  uint32_t nspread = 0;
  11439  for (ParseNode* elem : array->contents()) {
  11440    if (elem->isKind(ParseNodeKind::Spread)) {
  11441      nspread++;
  11442    }
  11443  }
  11444 
  11445  // Array literal's length is limited to NELEMENTS_LIMIT in parser.
  11446  static_assert(NativeObject::MAX_DENSE_ELEMENTS_COUNT <= INT32_MAX,
  11447                "array literals' maximum length must not exceed limits "
  11448                "required by BaselineCompiler::emit_NewArray, "
  11449                "BaselineCompiler::emit_InitElemArray, "
  11450                "and DoSetElemFallback's handling of JSOp::InitElemArray");
  11451 
  11452  uint32_t count = array->count();
  11453  MOZ_ASSERT(count >= nspread);
  11454  MOZ_ASSERT(count <= NativeObject::MAX_DENSE_ELEMENTS_COUNT,
  11455             "the parser must throw an error if the array exceeds maximum "
  11456             "length");
  11457 
  11458  // For arrays with spread, this is a very pessimistic allocation, the
  11459  // minimum possible final size.
  11460  if (!emitUint32Operand(JSOp::NewArray, count - nspread)) {
  11461    //              [stack] ARRAY
  11462    return false;
  11463  }
  11464 
  11465  uint32_t index = 0;
  11466  bool afterSpread = false;
  11467  for (ParseNode* elem : array->contents()) {
  11468    if (elem->isKind(ParseNodeKind::Spread)) {
  11469      if (!afterSpread) {
  11470        afterSpread = true;
  11471        if (!emitNumberOp(index)) {
  11472          //        [stack] ARRAY INDEX
  11473          return false;
  11474        }
  11475      }
  11476 
  11477      ParseNode* expr = elem->as<UnaryNode>().kid();
  11478      SelfHostedIter selfHostedIter = getSelfHostedIterFor(expr);
  11479 
  11480      if (!updateSourceCoordNotes(elem->pn_pos.begin)) {
  11481        return false;
  11482      }
  11483      if (!emitIterable(expr, selfHostedIter)) {
  11484        //          [stack] ARRAY INDEX ITERABLE
  11485        return false;
  11486      }
  11487      if (!emitIterator(selfHostedIter)) {
  11488        //          [stack] ARRAY INDEX NEXT ITER
  11489        return false;
  11490      }
  11491      if (!emit2(JSOp::Pick, 3)) {
  11492        //          [stack] INDEX NEXT ITER ARRAY
  11493        return false;
  11494      }
  11495      if (!emit2(JSOp::Pick, 3)) {
  11496        //          [stack] NEXT ITER ARRAY INDEX
  11497        return false;
  11498      }
  11499      if (!emitSpread(selfHostedIter)) {
  11500        //          [stack] ARRAY INDEX
  11501        return false;
  11502      }
  11503    } else {
  11504      if (!updateSourceCoordNotesIfNonLiteral(elem)) {
  11505        return false;
  11506      }
  11507      if (elem->isKind(ParseNodeKind::Elision)) {
  11508        if (!emit1(JSOp::Hole)) {
  11509          return false;
  11510        }
  11511      } else {
  11512        if (!emitTree(elem, ValueUsage::WantValue)) {
  11513          //        [stack] ARRAY INDEX? VALUE
  11514          return false;
  11515        }
  11516      }
  11517 
  11518      if (afterSpread) {
  11519        if (!emit1(JSOp::InitElemInc)) {
  11520          //        [stack] ARRAY (INDEX+1)
  11521          return false;
  11522        }
  11523      } else {
  11524        if (!emitUint32Operand(JSOp::InitElemArray, index)) {
  11525          //        [stack] ARRAY
  11526          return false;
  11527        }
  11528      }
  11529    }
  11530 
  11531    index++;
  11532  }
  11533  MOZ_ASSERT(index == count);
  11534  if (afterSpread) {
  11535    if (!emit1(JSOp::Pop)) {
  11536      //            [stack] ARRAY
  11537      return false;
  11538    }
  11539  }
  11540  return true;
  11541 }
  11542 
  11543 bool BytecodeEmitter::emitSpreadIntoArray(UnaryNode* elem) {
  11544  MOZ_ASSERT(elem->isKind(ParseNodeKind::Spread));
  11545 
  11546  if (!updateSourceCoordNotes(elem->pn_pos.begin)) {
  11547    //              [stack] VALUE
  11548    return false;
  11549  }
  11550 
  11551  SelfHostedIter selfHostedIter = getSelfHostedIterFor(elem->kid());
  11552  MOZ_ASSERT(selfHostedIter == SelfHostedIter::Deny ||
  11553             selfHostedIter == SelfHostedIter::AllowContent);
  11554 
  11555  if (!emitIterator(selfHostedIter)) {
  11556    //              [stack] NEXT ITER
  11557    return false;
  11558  }
  11559 
  11560  if (!emitUint32Operand(JSOp::NewArray, 0)) {
  11561    //              [stack] NEXT ITER ARRAY
  11562    return false;
  11563  }
  11564 
  11565  if (!emitNumberOp(0)) {
  11566    //              [stack] NEXT ITER ARRAY INDEX
  11567    return false;
  11568  }
  11569 
  11570  if (!emitSpread(selfHostedIter)) {
  11571    //              [stack] ARRAY INDEX
  11572    return false;
  11573  }
  11574 
  11575  if (!emit1(JSOp::Pop)) {
  11576    //              [stack] ARRAY
  11577    return false;
  11578  }
  11579  return true;
  11580 }
  11581 
  11582 static inline JSOp UnaryOpParseNodeKindToJSOp(ParseNodeKind pnk) {
  11583  switch (pnk) {
  11584    case ParseNodeKind::ThrowStmt:
  11585      return JSOp::Throw;
  11586    case ParseNodeKind::VoidExpr:
  11587      return JSOp::Void;
  11588    case ParseNodeKind::NotExpr:
  11589      return JSOp::Not;
  11590    case ParseNodeKind::BitNotExpr:
  11591      return JSOp::BitNot;
  11592    case ParseNodeKind::PosExpr:
  11593      return JSOp::Pos;
  11594    case ParseNodeKind::NegExpr:
  11595      return JSOp::Neg;
  11596    default:
  11597      MOZ_CRASH("unexpected unary op");
  11598  }
  11599 }
  11600 
  11601 bool BytecodeEmitter::emitUnary(UnaryNode* unaryNode) {
  11602  if (!updateSourceCoordNotes(unaryNode->pn_pos.begin)) {
  11603    return false;
  11604  }
  11605 
  11606  JSOp op = UnaryOpParseNodeKindToJSOp(unaryNode->getKind());
  11607  ValueUsage valueUsage =
  11608      op == JSOp::Void ? ValueUsage::IgnoreValue : ValueUsage::WantValue;
  11609  if (!emitTree(unaryNode->kid(), valueUsage)) {
  11610    return false;
  11611  }
  11612  return emit1(op);
  11613 }
  11614 
  11615 bool BytecodeEmitter::emitTypeof(UnaryNode* typeofNode, JSOp op) {
  11616  MOZ_ASSERT(op == JSOp::Typeof || op == JSOp::TypeofExpr);
  11617 
  11618  if (!updateSourceCoordNotes(typeofNode->pn_pos.begin)) {
  11619    return false;
  11620  }
  11621 
  11622  if (!emitTree(typeofNode->kid())) {
  11623    return false;
  11624  }
  11625 
  11626  return emit1(op);
  11627 }
  11628 
  11629 bool BytecodeEmitter::tryEmitTypeofEq(ListNode* node, bool* emitted) {
  11630  // Emit specialized opcode for the following if possible:
  11631  //  * typeof val == "type"
  11632  //  * typeof val != "type"
  11633  //  * typeof val > "u"     # minified `typeof val === "undefined"`
  11634  //  * typeof val < "u"     # minified `typeof val !== "undefined"`
  11635  //
  11636  // NOTE: Given the comparison is done for string, `==` and `===` have
  11637  //       no difference. Same for `!=` and `!==`.
  11638  MOZ_ASSERT(node->isKind(ParseNodeKind::StrictEqExpr) ||
  11639             node->isKind(ParseNodeKind::EqExpr) ||
  11640             node->isKind(ParseNodeKind::StrictNeExpr) ||
  11641             node->isKind(ParseNodeKind::NeExpr) ||
  11642             node->isKind(ParseNodeKind::LtExpr) ||
  11643             node->isKind(ParseNodeKind::GtExpr));
  11644 
  11645  if (node->count() != 2) {
  11646    *emitted = false;
  11647    return true;
  11648  }
  11649 
  11650  ParseNode* left = node->head();
  11651  ParseNode* right = left->pn_next;
  11652  MOZ_ASSERT(right);
  11653 
  11654  UnaryNode* typeofNode;
  11655  NameNode* typenameNode;
  11656  JSOp op;
  11657  JSType type;
  11658 
  11659  if (node->isKind(ParseNodeKind::LtExpr) ||
  11660      node->isKind(ParseNodeKind::GtExpr)) {
  11661    if (left->isKind(ParseNodeKind::TypeOfNameExpr) &&
  11662        right->isKind(ParseNodeKind::StringExpr)) {
  11663      typeofNode = &left->as<UnaryNode>();
  11664      typenameNode = &right->as<NameNode>();
  11665 
  11666      if (node->isKind(ParseNodeKind::LtExpr)) {
  11667        op = JSOp::Ne;
  11668      } else {
  11669        op = JSOp::Eq;
  11670      }
  11671    } else if (left->isKind(ParseNodeKind::TypeOfNameExpr) &&
  11672               right->isKind(ParseNodeKind::StringExpr)) {
  11673      typeofNode = &left->as<UnaryNode>();
  11674      typenameNode = &right->as<NameNode>();
  11675 
  11676      if (node->isKind(ParseNodeKind::LtExpr)) {
  11677        op = JSOp::Eq;
  11678      } else {
  11679        op = JSOp::Ne;
  11680      }
  11681    } else {
  11682      *emitted = false;
  11683      return true;
  11684    }
  11685 
  11686    TaggedParserAtomIndex typeName = typenameNode->atom();
  11687    if (typeName.isLength1StaticParserString() &&
  11688        typeName.toLength1StaticParserString() ==
  11689            Length1StaticParserString('u')) {
  11690      type = JSTYPE_UNDEFINED;
  11691    } else {
  11692      *emitted = false;
  11693      return true;
  11694    }
  11695  } else {
  11696    if (node->isKind(ParseNodeKind::StrictEqExpr) ||
  11697        node->isKind(ParseNodeKind::EqExpr)) {
  11698      op = JSOp::Eq;
  11699    } else {
  11700      op = JSOp::Ne;
  11701    }
  11702 
  11703    // NOTE: ParseNodeKind::TypeOfExpr cannot use JSOp::TypeofEq.
  11704    //       See JSOp::GetName document.
  11705    if (left->isKind(ParseNodeKind::TypeOfNameExpr) &&
  11706        right->isKind(ParseNodeKind::StringExpr)) {
  11707      typeofNode = &left->as<UnaryNode>();
  11708      typenameNode = &right->as<NameNode>();
  11709    } else if (right->isKind(ParseNodeKind::TypeOfNameExpr) &&
  11710               left->isKind(ParseNodeKind::StringExpr)) {
  11711      typeofNode = &right->as<UnaryNode>();
  11712      typenameNode = &left->as<NameNode>();
  11713    } else {
  11714      *emitted = false;
  11715      return true;
  11716    }
  11717 
  11718    TaggedParserAtomIndex typeName = typenameNode->atom();
  11719    if (typeName == TaggedParserAtomIndex::WellKnown::undefined()) {
  11720      type = JSTYPE_UNDEFINED;
  11721    } else if (typeName == TaggedParserAtomIndex::WellKnown::object()) {
  11722      type = JSTYPE_OBJECT;
  11723    } else if (typeName == TaggedParserAtomIndex::WellKnown::function()) {
  11724      type = JSTYPE_FUNCTION;
  11725    } else if (typeName == TaggedParserAtomIndex::WellKnown::string()) {
  11726      type = JSTYPE_STRING;
  11727    } else if (typeName == TaggedParserAtomIndex::WellKnown::number()) {
  11728      type = JSTYPE_NUMBER;
  11729    } else if (typeName == TaggedParserAtomIndex::WellKnown::boolean()) {
  11730      type = JSTYPE_BOOLEAN;
  11731    } else if (typeName == TaggedParserAtomIndex::WellKnown::symbol()) {
  11732      type = JSTYPE_SYMBOL;
  11733    } else if (typeName == TaggedParserAtomIndex::WellKnown::bigint()) {
  11734      type = JSTYPE_BIGINT;
  11735    } else {
  11736      *emitted = false;
  11737      return true;
  11738    }
  11739  }
  11740 
  11741  if (!updateSourceCoordNotes(typeofNode->pn_pos.begin)) {
  11742    return false;
  11743  }
  11744 
  11745  if (!emitTree(typeofNode->kid())) {
  11746    //          [stack] VAL
  11747    return false;
  11748  }
  11749 
  11750  if (!emit2(JSOp::TypeofEq, TypeofEqOperand(type, op).rawValue())) {
  11751    //          [stack] CMP
  11752    return false;
  11753  }
  11754 
  11755  *emitted = true;
  11756  return true;
  11757 }
  11758 
  11759 bool BytecodeEmitter::emitFunctionFormalParameters(ParamsBodyNode* paramsBody) {
  11760  FunctionBox* funbox = sc->asFunctionBox();
  11761 
  11762  bool hasRest = funbox->hasRest();
  11763 
  11764  FunctionParamsEmitter fpe(this, funbox);
  11765  for (ParseNode* arg : paramsBody->parameters()) {
  11766    ParseNode* bindingElement = arg;
  11767    ParseNode* initializer = nullptr;
  11768    if (arg->isKind(ParseNodeKind::AssignExpr)) {
  11769      bindingElement = arg->as<BinaryNode>().left();
  11770      initializer = arg->as<BinaryNode>().right();
  11771    }
  11772    bool hasInitializer = !!initializer;
  11773    bool isRest =
  11774        hasRest && arg->pn_next == *std::end(paramsBody->parameters());
  11775    bool isDestructuring = !bindingElement->isKind(ParseNodeKind::Name);
  11776 
  11777    // Left-hand sides are either simple names or destructuring patterns.
  11778    MOZ_ASSERT(bindingElement->isKind(ParseNodeKind::Name) ||
  11779               bindingElement->isKind(ParseNodeKind::ArrayExpr) ||
  11780               bindingElement->isKind(ParseNodeKind::ObjectExpr));
  11781 
  11782    auto emitDefaultInitializer = [this, &initializer, &bindingElement]() {
  11783      //            [stack]
  11784 
  11785      if (!this->emitInitializer(initializer, bindingElement)) {
  11786        //          [stack] DEFAULT
  11787        return false;
  11788      }
  11789      return true;
  11790    };
  11791 
  11792    auto emitDestructuring = [this, &bindingElement]() {
  11793      //            [stack] ARG
  11794 
  11795      if (!this->emitDestructuringOps(&bindingElement->as<ListNode>(),
  11796                                      DestructuringFlavor::Declaration,
  11797                                      SelfHostedIter::Deny)) {
  11798        //          [stack] ARG
  11799        return false;
  11800      }
  11801 
  11802      return true;
  11803    };
  11804 
  11805    if (isRest) {
  11806      if (isDestructuring) {
  11807        if (!fpe.prepareForDestructuringRest()) {
  11808          //        [stack]
  11809          return false;
  11810        }
  11811        if (!emitDestructuring()) {
  11812          //        [stack]
  11813          return false;
  11814        }
  11815        if (!fpe.emitDestructuringRestEnd()) {
  11816          //        [stack]
  11817          return false;
  11818        }
  11819      } else {
  11820        auto paramName = bindingElement->as<NameNode>().name();
  11821        if (!fpe.emitRest(paramName)) {
  11822          //        [stack]
  11823          return false;
  11824        }
  11825      }
  11826 
  11827      continue;
  11828    }
  11829 
  11830    if (isDestructuring) {
  11831      if (hasInitializer) {
  11832        if (!fpe.prepareForDestructuringDefaultInitializer()) {
  11833          //        [stack]
  11834          return false;
  11835        }
  11836        if (!emitDefaultInitializer()) {
  11837          //        [stack]
  11838          return false;
  11839        }
  11840        if (!fpe.prepareForDestructuringDefault()) {
  11841          //        [stack]
  11842          return false;
  11843        }
  11844        if (!emitDestructuring()) {
  11845          //        [stack]
  11846          return false;
  11847        }
  11848        if (!fpe.emitDestructuringDefaultEnd()) {
  11849          //        [stack]
  11850          return false;
  11851        }
  11852      } else {
  11853        if (!fpe.prepareForDestructuring()) {
  11854          //        [stack]
  11855          return false;
  11856        }
  11857        if (!emitDestructuring()) {
  11858          //        [stack]
  11859          return false;
  11860        }
  11861        if (!fpe.emitDestructuringEnd()) {
  11862          //        [stack]
  11863          return false;
  11864        }
  11865      }
  11866 
  11867      continue;
  11868    }
  11869 
  11870    if (hasInitializer) {
  11871      if (!fpe.prepareForDefault()) {
  11872        //          [stack]
  11873        return false;
  11874      }
  11875      if (!emitDefaultInitializer()) {
  11876        //          [stack]
  11877        return false;
  11878      }
  11879      auto paramName = bindingElement->as<NameNode>().name();
  11880      if (!fpe.emitDefaultEnd(paramName)) {
  11881        //          [stack]
  11882        return false;
  11883      }
  11884 
  11885      continue;
  11886    }
  11887 
  11888    auto paramName = bindingElement->as<NameNode>().name();
  11889    if (!fpe.emitSimple(paramName)) {
  11890      //            [stack]
  11891      return false;
  11892    }
  11893  }
  11894 
  11895  return true;
  11896 }
  11897 
  11898 bool BytecodeEmitter::emitInitializeFunctionSpecialNames() {
  11899  FunctionBox* funbox = sc->asFunctionBox();
  11900 
  11901  //                [stack]
  11902 
  11903  auto emitInitializeFunctionSpecialName =
  11904      [](BytecodeEmitter* bce, TaggedParserAtomIndex name, JSOp op) {
  11905        // A special name must be slotful, either on the frame or on the
  11906        // call environment.
  11907        MOZ_ASSERT(bce->lookupName(name).hasKnownSlot());
  11908 
  11909        NameOpEmitter noe(bce, name, NameOpEmitter::Kind::Initialize);
  11910        if (!noe.prepareForRhs()) {
  11911          //        [stack]
  11912          return false;
  11913        }
  11914        if (!bce->emit1(op)) {
  11915          //        [stack] THIS/ARGUMENTS/NEW.TARGET
  11916          return false;
  11917        }
  11918        if (!noe.emitAssignment()) {
  11919          //        [stack] THIS/ARGUMENTS/NEW.TARGET
  11920          return false;
  11921        }
  11922        if (!bce->emit1(JSOp::Pop)) {
  11923          //        [stack]
  11924          return false;
  11925        }
  11926 
  11927        return true;
  11928      };
  11929 
  11930  // Do nothing if the function doesn't have an arguments binding.
  11931  if (funbox->needsArgsObj()) {
  11932    // Self-hosted code should use the more efficient ArgumentsLength and
  11933    // GetArgument intrinsics instead of `arguments`.
  11934    MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting);
  11935    if (!emitInitializeFunctionSpecialName(
  11936            this, TaggedParserAtomIndex::WellKnown::arguments(),
  11937            JSOp::Arguments)) {
  11938      //            [stack]
  11939      return false;
  11940    }
  11941  }
  11942 
  11943  // Do nothing if the function doesn't have a this-binding (this
  11944  // happens for instance if it doesn't use this/eval or if it's an
  11945  // arrow function).
  11946  if (funbox->functionHasThisBinding()) {
  11947    if (!emitInitializeFunctionSpecialName(
  11948            this, TaggedParserAtomIndex::WellKnown::dot_this_(),
  11949            JSOp::FunctionThis)) {
  11950      return false;
  11951    }
  11952  }
  11953 
  11954  // Do nothing if the function doesn't have a new.target-binding (this happens
  11955  // for instance if it doesn't use new.target/eval or if it's an arrow
  11956  // function).
  11957  if (funbox->functionHasNewTargetBinding()) {
  11958    if (!emitInitializeFunctionSpecialName(
  11959            this, TaggedParserAtomIndex::WellKnown::dot_newTarget_(),
  11960            JSOp::NewTarget)) {
  11961      return false;
  11962    }
  11963  }
  11964 
  11965  // Do nothing if the function doesn't implicitly return a promise result.
  11966  if (funbox->needsPromiseResult()) {
  11967    if (!emitInitializeFunctionSpecialName(
  11968            this, TaggedParserAtomIndex::WellKnown::dot_generator_(),
  11969            JSOp::Generator)) {
  11970      //            [stack]
  11971      return false;
  11972    }
  11973  }
  11974  return true;
  11975 }
  11976 
  11977 bool BytecodeEmitter::emitLexicalInitialization(NameNode* name) {
  11978  return emitLexicalInitialization(name->name());
  11979 }
  11980 
  11981 bool BytecodeEmitter::emitLexicalInitialization(TaggedParserAtomIndex name) {
  11982  NameOpEmitter noe(this, name, NameOpEmitter::Kind::Initialize);
  11983  if (!noe.prepareForRhs()) {
  11984    return false;
  11985  }
  11986 
  11987  // The caller has pushed the RHS to the top of the stack. Assert that the
  11988  // binding can be initialized without a binding object on the stack, and that
  11989  // no JSOp::BindUnqualifiedName or JSOp::BindUnqualifiedGName ops were
  11990  // emitted.
  11991  MOZ_ASSERT(noe.loc().isLexical() || noe.loc().isSynthetic() ||
  11992             noe.loc().isPrivateMethod());
  11993  MOZ_ASSERT(!noe.emittedBindOp());
  11994 
  11995  if (!noe.emitAssignment()) {
  11996    return false;
  11997  }
  11998 
  11999  return true;
  12000 }
  12001 
  12002 static MOZ_ALWAYS_INLINE ParseNode* FindConstructor(ListNode* classMethods) {
  12003  for (ParseNode* classElement : classMethods->contents()) {
  12004    ParseNode* unwrappedElement = classElement;
  12005    if (unwrappedElement->is<LexicalScopeNode>()) {
  12006      unwrappedElement = unwrappedElement->as<LexicalScopeNode>().scopeBody();
  12007    }
  12008    if (unwrappedElement->is<ClassMethod>()) {
  12009      ClassMethod& method = unwrappedElement->as<ClassMethod>();
  12010      ParseNode& methodName = method.name();
  12011      if (!method.isStatic() &&
  12012          (methodName.isKind(ParseNodeKind::ObjectPropertyName) ||
  12013           methodName.isKind(ParseNodeKind::StringExpr)) &&
  12014          methodName.as<NameNode>().atom() ==
  12015              TaggedParserAtomIndex::WellKnown::constructor()) {
  12016        return classElement;
  12017      }
  12018    }
  12019  }
  12020  return nullptr;
  12021 }
  12022 
  12023 bool BytecodeEmitter::emitNewPrivateName(TaggedParserAtomIndex bindingName,
  12024                                         TaggedParserAtomIndex symbolName) {
  12025  if (!emitAtomOp(JSOp::NewPrivateName, symbolName)) {
  12026    //              [stack] HERITAGE PRIVATENAME
  12027    return false;
  12028  }
  12029 
  12030  // Add a binding for #name => privatename
  12031  if (!emitLexicalInitialization(bindingName)) {
  12032    //              [stack] HERITAGE PRIVATENAME
  12033    return false;
  12034  }
  12035 
  12036  // Pop Private name off the stack.
  12037  if (!emit1(JSOp::Pop)) {
  12038    //              [stack] HERITAGE
  12039    return false;
  12040  }
  12041 
  12042  return true;
  12043 }
  12044 
  12045 bool BytecodeEmitter::emitNewPrivateNames(
  12046    TaggedParserAtomIndex privateBrandName, ListNode* classMembers) {
  12047  bool hasPrivateBrand = false;
  12048 
  12049  for (ParseNode* classElement : classMembers->contents()) {
  12050    ParseNode* elementName;
  12051    if (classElement->is<ClassMethod>()) {
  12052      elementName = &classElement->as<ClassMethod>().name();
  12053    } else if (classElement->is<ClassField>()) {
  12054      elementName = &classElement->as<ClassField>().name();
  12055    } else {
  12056      continue;
  12057    }
  12058 
  12059    if (!elementName->isKind(ParseNodeKind::PrivateName)) {
  12060      continue;
  12061    }
  12062 
  12063    // Non-static private methods' private names are optimized away.
  12064    bool isOptimized = false;
  12065    if (classElement->is<ClassMethod>() &&
  12066        !classElement->as<ClassMethod>().isStatic()) {
  12067      hasPrivateBrand = true;
  12068      if (classElement->as<ClassMethod>().accessorType() ==
  12069          AccessorType::None) {
  12070        isOptimized = true;
  12071      }
  12072    }
  12073 
  12074    if (!isOptimized) {
  12075      auto privateName = elementName->as<NameNode>().name();
  12076      if (!emitNewPrivateName(privateName, privateName)) {
  12077        return false;
  12078      }
  12079    }
  12080  }
  12081 
  12082  if (hasPrivateBrand) {
  12083    // We don't make a private name for every optimized method, but we need one
  12084    // private name per class, the `.privateBrand`.
  12085    if (!emitNewPrivateName(
  12086            TaggedParserAtomIndex::WellKnown::dot_privateBrand_(),
  12087            privateBrandName)) {
  12088      return false;
  12089    }
  12090  }
  12091  return true;
  12092 }
  12093 
  12094 // This follows ES6 14.5.14 (ClassDefinitionEvaluation) and ES6 14.5.15
  12095 // (BindingClassDeclarationEvaluation).
  12096 bool BytecodeEmitter::emitClass(
  12097    ClassNode* classNode,
  12098    ClassNameKind nameKind /* = ClassNameKind::BindingName */,
  12099    TaggedParserAtomIndex
  12100        nameForAnonymousClass /* = TaggedParserAtomIndex::null() */) {
  12101  MOZ_ASSERT((nameKind == ClassNameKind::InferredName) ==
  12102             bool(nameForAnonymousClass));
  12103 
  12104  ParseNode* heritageExpression = classNode->heritage();
  12105  ListNode* classMembers = classNode->memberList();
  12106  ParseNode* constructor = FindConstructor(classMembers);
  12107 
  12108  // If |nameKind != ClassNameKind::ComputedName|
  12109  //                [stack]
  12110  // Else
  12111  //                [stack] NAME
  12112 
  12113  ClassEmitter ce(this);
  12114  TaggedParserAtomIndex innerName;
  12115  ClassEmitter::Kind kind = ClassEmitter::Kind::Expression;
  12116  if (ClassNames* names = classNode->names()) {
  12117    MOZ_ASSERT(nameKind == ClassNameKind::BindingName);
  12118    innerName = names->innerBinding()->name();
  12119    MOZ_ASSERT(innerName);
  12120 
  12121    if (names->outerBinding()) {
  12122      MOZ_ASSERT(names->outerBinding()->name());
  12123      MOZ_ASSERT(names->outerBinding()->name() == innerName);
  12124      kind = ClassEmitter::Kind::Declaration;
  12125    }
  12126  }
  12127 
  12128  if (LexicalScopeNode* scopeBindings = classNode->scopeBindings()) {
  12129    if (!ce.emitScope(scopeBindings->scopeBindings())) {
  12130      //            [stack]
  12131      return false;
  12132    }
  12133  }
  12134 
  12135  bool isDerived = !!heritageExpression;
  12136  if (isDerived) {
  12137    if (!updateSourceCoordNotes(classNode->pn_pos.begin)) {
  12138      return false;
  12139    }
  12140    if (!markStepBreakpoint()) {
  12141      return false;
  12142    }
  12143    if (!emitTree(heritageExpression)) {
  12144      //            [stack] HERITAGE
  12145      return false;
  12146    }
  12147  }
  12148 
  12149  // The class body scope holds any private names. Those mustn't be visible in
  12150  // the heritage expression and hence the scope must be emitted after the
  12151  // heritage expression.
  12152  if (ClassBodyScopeNode* bodyScopeBindings = classNode->bodyScopeBindings()) {
  12153    if (!ce.emitBodyScope(bodyScopeBindings->scopeBindings())) {
  12154      //            [stack] HERITAGE
  12155      return false;
  12156    }
  12157 
  12158    // The spec does not say anything about private brands being symbols.  It's
  12159    // an implementation detail. So we can give the special private brand
  12160    // symbol any description we want and users won't normally see it. For
  12161    // debugging, use the class name.
  12162    auto privateBrandName = innerName;
  12163    if (!innerName) {
  12164      privateBrandName = nameForAnonymousClass
  12165                             ? nameForAnonymousClass
  12166                             : TaggedParserAtomIndex::WellKnown::anonymous();
  12167    }
  12168    if (!emitNewPrivateNames(privateBrandName, classMembers)) {
  12169      return false;
  12170    }
  12171  }
  12172 
  12173  bool hasNameOnStack = nameKind == ClassNameKind::ComputedName;
  12174  if (isDerived) {
  12175    if (!ce.emitDerivedClass(innerName, nameForAnonymousClass,
  12176                             hasNameOnStack)) {
  12177      //            [stack] HOMEOBJ HERITAGE
  12178      return false;
  12179    }
  12180  } else {
  12181    int membersCount = 0;
  12182    for (ParseNode* node : classMembers->contents()) {
  12183      if (node->getKind() == ParseNodeKind::ClassField) {
  12184        membersCount++;
  12185      }
  12186    }
  12187    membersCount = (membersCount > 255) ? 255 : membersCount;
  12188    if (!ce.emitClass(innerName, nameForAnonymousClass, hasNameOnStack,
  12189                      uint8_t(membersCount))) {
  12190      //            [stack] HOMEOBJ
  12191      return false;
  12192    }
  12193  }
  12194 
  12195  // Stack currently has HOMEOBJ followed by optional HERITAGE. When HERITAGE
  12196  // is not used, an implicit value of %FunctionPrototype% is implied.
  12197 
  12198  // See |Parser::classMember(...)| for the reason why |.initializers| is
  12199  // created within its own scope.
  12200  Maybe<LexicalScopeEmitter> lse;
  12201  FunctionNode* ctor;
  12202 #ifdef ENABLE_DECORATORS
  12203  bool extraInitializersPresent = false;
  12204 #endif
  12205  if (constructor->is<LexicalScopeNode>()) {
  12206    LexicalScopeNode* constructorScope = &constructor->as<LexicalScopeNode>();
  12207 
  12208    MOZ_ASSERT(!constructorScope->isEmptyScope());
  12209 #ifdef ENABLE_DECORATORS
  12210    // With decorators enabled we expect to see |.initializers|,
  12211    // and |.instanceExtraInitializers| in this scope.
  12212    MOZ_ASSERT(constructorScope->scopeBindings()->length == 2);
  12213    MOZ_ASSERT(GetScopeDataTrailingNames(constructorScope->scopeBindings())[0]
  12214                   .name() ==
  12215               TaggedParserAtomIndex::WellKnown::dot_initializers_());
  12216    MOZ_ASSERT(
  12217        GetScopeDataTrailingNames(constructorScope->scopeBindings())[1]
  12218            .name() ==
  12219        TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_());
  12220 
  12221    // We should only call this code if we know decorators are present, see bug
  12222    // 1871147.
  12223    lse.emplace(this);
  12224    if (!lse->emitScope(ScopeKind::Lexical,
  12225                        constructorScope->scopeBindings())) {
  12226      return false;
  12227    }
  12228 
  12229    // TODO: See bug 1868220 for support for static extra initializers.
  12230    if (!ce.prepareForExtraInitializers(TaggedParserAtomIndex::WellKnown::
  12231                                            dot_instanceExtraInitializers_())) {
  12232      return false;
  12233    }
  12234 
  12235    if (classNode->addInitializerFunction()) {
  12236      DecoratorEmitter de(this);
  12237      if (!de.emitCreateAddInitializerFunction(
  12238              classNode->addInitializerFunction(),
  12239              TaggedParserAtomIndex::WellKnown::
  12240                  dot_instanceExtraInitializers_())) {
  12241        //            [stack] HOMEOBJ HERITAGE? ADDINIT
  12242        return false;
  12243      }
  12244 
  12245      if (!emitUnpickN(isDerived ? 2 : 1)) {
  12246        //            [stack] ADDINIT HOMEOBJ HERITAGE?
  12247        return false;
  12248      }
  12249 
  12250      extraInitializersPresent = true;
  12251    }
  12252 #else
  12253    // The constructor scope should only contain the |.initializers| binding.
  12254    MOZ_ASSERT(constructorScope->scopeBindings()->length == 1);
  12255    MOZ_ASSERT(GetScopeDataTrailingNames(constructorScope->scopeBindings())[0]
  12256                   .name() ==
  12257               TaggedParserAtomIndex::WellKnown::dot_initializers_());
  12258 #endif
  12259 
  12260    auto needsInitializer = [](ParseNode* propdef) {
  12261      return NeedsFieldInitializer(propdef, false) ||
  12262             NeedsAccessorInitializer(propdef, false);
  12263    };
  12264 
  12265    // As an optimization omit the |.initializers| binding when no instance
  12266    // fields or private methods are present.
  12267    bool needsInitializers =
  12268        std::any_of(classMembers->contents().begin(),
  12269                    classMembers->contents().end(), needsInitializer);
  12270    if (needsInitializers) {
  12271 #ifndef ENABLE_DECORATORS
  12272      lse.emplace(this);
  12273      if (!lse->emitScope(ScopeKind::Lexical,
  12274                          constructorScope->scopeBindings())) {
  12275        return false;
  12276      }
  12277 #endif
  12278      // Any class with field initializers will have a constructor
  12279      if (!emitCreateMemberInitializers(ce, classMembers,
  12280                                        FieldPlacement::Instance
  12281 #ifdef ENABLE_DECORATORS
  12282                                        ,
  12283                                        isDerived
  12284 #endif
  12285                                        )) {
  12286        return false;
  12287      }
  12288    }
  12289 
  12290    ctor = &constructorScope->scopeBody()->as<ClassMethod>().method();
  12291  } else {
  12292    // The |.initializers| binding is never emitted when in self-hosting mode.
  12293    MOZ_ASSERT(emitterMode == BytecodeEmitter::SelfHosting);
  12294    ctor = &constructor->as<ClassMethod>().method();
  12295  }
  12296 
  12297  bool needsHomeObject = ctor->funbox()->needsHomeObject();
  12298  // HERITAGE is consumed inside emitFunction.
  12299  if (nameKind == ClassNameKind::InferredName) {
  12300    setFunName(ctor->funbox(), nameForAnonymousClass);
  12301  }
  12302  if (!emitFunction(ctor, isDerived)) {
  12303    //              [stack] HOMEOBJ CTOR
  12304    return false;
  12305  }
  12306  if (lse.isSome()) {
  12307    if (!lse->emitEnd()) {
  12308      return false;
  12309    }
  12310    lse.reset();
  12311  }
  12312  if (!ce.emitInitConstructor(needsHomeObject)) {
  12313    //              [stack] CTOR HOMEOBJ
  12314    return false;
  12315  }
  12316 
  12317  if (!emitCreateFieldKeys(classMembers, FieldPlacement::Instance)) {
  12318    return false;
  12319  }
  12320 
  12321 #ifdef ENABLE_DECORATORS
  12322  // TODO: See Bug 1868220 for support for static extra initializers.
  12323  if (!emit1(JSOp::Undefined)) {
  12324    //              [stack] ADDINIT? CTOR HOMEOBJ UNDEFINED
  12325    return false;
  12326  }
  12327  if (!emitUnpickN(2)) {
  12328    //              [stack] ADDINIT? UNDEFINED CTOR HOMEOBJ
  12329    return false;
  12330  }
  12331 #endif
  12332 
  12333  if (!emitCreateMemberInitializers(ce, classMembers, FieldPlacement::Static
  12334 #ifdef ENABLE_DECORATORS
  12335                                    ,
  12336                                    false
  12337 #endif
  12338                                    )) {
  12339    return false;
  12340  }
  12341 
  12342 #ifdef ENABLE_DECORATORS
  12343  if (!emitPickN(2)) {
  12344    //              [stack] ADDINIT? CTOR HOMEOBJ UNDEFINED
  12345    return false;
  12346  }
  12347  if (!emitPopN(1)) {
  12348    //              [stack] ADDINIT? CTOR HOMEOBJ
  12349    return false;
  12350  }
  12351 #endif
  12352 
  12353  if (!emitCreateFieldKeys(classMembers, FieldPlacement::Static)) {
  12354    return false;
  12355  }
  12356 
  12357  if (!emitPropertyList(classMembers, ce, ClassBody)) {
  12358    //              [stack] CTOR HOMEOBJ
  12359    return false;
  12360  }
  12361 
  12362 #ifdef ENABLE_DECORATORS
  12363  if (extraInitializersPresent) {
  12364    if (!emitPickN(2)) {
  12365      //              [stack] CTOR HOMEOBJ ADDINIT
  12366      return false;
  12367    }
  12368    if (!emitPopN(1)) {
  12369      //              [stack] CTOR HOMEOBJ
  12370      return false;
  12371    }
  12372  }
  12373 #endif
  12374 
  12375  if (!ce.emitBinding()) {
  12376    //              [stack] CTOR
  12377    return false;
  12378  }
  12379 
  12380  if (!emitInitializeStaticFields(classMembers)) {
  12381    //              [stack] CTOR
  12382    return false;
  12383  }
  12384 
  12385 #if ENABLE_DECORATORS
  12386  if (!ce.prepareForDecorators()) {
  12387    //            [stack] CTOR
  12388    return false;
  12389  }
  12390  if (classNode->decorators() != nullptr) {
  12391    DecoratorEmitter de(this);
  12392    NameNode* className =
  12393        classNode->names() ? classNode->names()->innerBinding() : nullptr;
  12394    if (!de.emitApplyDecoratorsToClassDefinition(className,
  12395                                                 classNode->decorators())) {
  12396      //            [stack] CTOR
  12397      return false;
  12398    }
  12399  }
  12400 #endif
  12401 
  12402  if (!ce.emitEnd(kind)) {
  12403    //              [stack] # class declaration
  12404    //              [stack]
  12405    //              [stack] # class expression
  12406    //              [stack] CTOR
  12407    return false;
  12408  }
  12409 
  12410  return true;
  12411 }
  12412 
  12413 bool BytecodeEmitter::emitExportDefault(BinaryNode* exportNode) {
  12414  MOZ_ASSERT(exportNode->isKind(ParseNodeKind::ExportDefaultStmt));
  12415 
  12416  ParseNode* valueNode = exportNode->left();
  12417  if (valueNode->isDirectRHSAnonFunction()) {
  12418    MOZ_ASSERT(exportNode->right());
  12419 
  12420    if (!emitAnonymousFunctionWithName(
  12421            valueNode, TaggedParserAtomIndex::WellKnown::default_())) {
  12422      return false;
  12423    }
  12424  } else {
  12425    if (!emitTree(valueNode)) {
  12426      return false;
  12427    }
  12428  }
  12429 
  12430  if (ParseNode* binding = exportNode->right()) {
  12431    if (!emitLexicalInitialization(&binding->as<NameNode>())) {
  12432      return false;
  12433    }
  12434 
  12435    if (!emit1(JSOp::Pop)) {
  12436      return false;
  12437    }
  12438  }
  12439 
  12440  return true;
  12441 }
  12442 
  12443 bool BytecodeEmitter::emitTree(
  12444    ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::WantValue */,
  12445    EmitLineNumberNote emitLineNote /* = EMIT_LINENOTE */) {
  12446  AutoCheckRecursionLimit recursion(fc);
  12447  if (!recursion.check(fc)) {
  12448    return false;
  12449  }
  12450 
  12451  /* Emit notes to tell the current bytecode's source line number.
  12452     However, a couple trees require special treatment; see the
  12453     relevant emitter functions for details. */
  12454  if (emitLineNote == EMIT_LINENOTE &&
  12455      !ParseNodeRequiresSpecialLineNumberNotes(pn)) {
  12456    if (!updateLineNumberNotes(pn->pn_pos.begin)) {
  12457      return false;
  12458    }
  12459  }
  12460 
  12461  switch (pn->getKind()) {
  12462    case ParseNodeKind::Function:
  12463      if (!emitFunction(&pn->as<FunctionNode>())) {
  12464        return false;
  12465      }
  12466      break;
  12467 
  12468    case ParseNodeKind::ParamsBody:
  12469      MOZ_ASSERT_UNREACHABLE(
  12470          "ParamsBody should be handled in emitFunctionScript.");
  12471      break;
  12472 
  12473    case ParseNodeKind::IfStmt:
  12474      if (!emitIf(&pn->as<TernaryNode>())) {
  12475        return false;
  12476      }
  12477      break;
  12478 
  12479    case ParseNodeKind::SwitchStmt:
  12480      if (!emitSwitch(&pn->as<SwitchStatement>())) {
  12481        return false;
  12482      }
  12483      break;
  12484 
  12485    case ParseNodeKind::WhileStmt:
  12486      if (!emitWhile(&pn->as<BinaryNode>())) {
  12487        return false;
  12488      }
  12489      break;
  12490 
  12491    case ParseNodeKind::DoWhileStmt:
  12492      if (!emitDo(&pn->as<BinaryNode>())) {
  12493        return false;
  12494      }
  12495      break;
  12496 
  12497    case ParseNodeKind::ForStmt:
  12498      if (!emitFor(&pn->as<ForNode>())) {
  12499        return false;
  12500      }
  12501      break;
  12502 
  12503    case ParseNodeKind::BreakStmt:
  12504      // Ensure that the column of the 'break' is set properly.
  12505      if (!updateSourceCoordNotes(pn->pn_pos.begin)) {
  12506        return false;
  12507      }
  12508      if (!markStepBreakpoint()) {
  12509        return false;
  12510      }
  12511 
  12512      if (!emitBreak(pn->as<BreakStatement>().label())) {
  12513        return false;
  12514      }
  12515      break;
  12516 
  12517    case ParseNodeKind::ContinueStmt:
  12518      // Ensure that the column of the 'continue' is set properly.
  12519      if (!updateSourceCoordNotes(pn->pn_pos.begin)) {
  12520        return false;
  12521      }
  12522      if (!markStepBreakpoint()) {
  12523        return false;
  12524      }
  12525 
  12526      if (!emitContinue(pn->as<ContinueStatement>().label())) {
  12527        return false;
  12528      }
  12529      break;
  12530 
  12531    case ParseNodeKind::WithStmt:
  12532      if (!emitWith(&pn->as<BinaryNode>())) {
  12533        return false;
  12534      }
  12535      break;
  12536 
  12537    case ParseNodeKind::TryStmt:
  12538      if (!emitTry(&pn->as<TryNode>())) {
  12539        return false;
  12540      }
  12541      break;
  12542 
  12543    case ParseNodeKind::Catch:
  12544      if (!emitCatch(&pn->as<BinaryNode>())) {
  12545        return false;
  12546      }
  12547      break;
  12548 
  12549    case ParseNodeKind::VarStmt:
  12550      if (!emitDeclarationList(&pn->as<ListNode>())) {
  12551        return false;
  12552      }
  12553      break;
  12554 
  12555    case ParseNodeKind::ReturnStmt:
  12556      if (!emitReturn(&pn->as<UnaryNode>())) {
  12557        return false;
  12558      }
  12559      break;
  12560 
  12561    case ParseNodeKind::YieldStarExpr:
  12562      if (!emitYieldStar(pn->as<UnaryNode>().kid())) {
  12563        return false;
  12564      }
  12565      break;
  12566 
  12567    case ParseNodeKind::Generator:
  12568      if (!emit1(JSOp::Generator)) {
  12569        return false;
  12570      }
  12571      break;
  12572 
  12573    case ParseNodeKind::InitialYield:
  12574      if (!emitInitialYield(&pn->as<UnaryNode>())) {
  12575        return false;
  12576      }
  12577      break;
  12578 
  12579    case ParseNodeKind::YieldExpr:
  12580      if (!emitYield(&pn->as<UnaryNode>())) {
  12581        return false;
  12582      }
  12583      break;
  12584 
  12585    case ParseNodeKind::AwaitExpr:
  12586      if (!emitAwaitInInnermostScope(&pn->as<UnaryNode>())) {
  12587        return false;
  12588      }
  12589      break;
  12590 
  12591    case ParseNodeKind::StatementList:
  12592      if (!emitStatementList(&pn->as<ListNode>())) {
  12593        return false;
  12594      }
  12595      break;
  12596 
  12597    case ParseNodeKind::EmptyStmt:
  12598      break;
  12599 
  12600    case ParseNodeKind::ExpressionStmt:
  12601      if (!emitExpressionStatement(&pn->as<UnaryNode>())) {
  12602        return false;
  12603      }
  12604      break;
  12605 
  12606    case ParseNodeKind::LabelStmt:
  12607      if (!emitLabeledStatement(&pn->as<LabeledStatement>())) {
  12608        return false;
  12609      }
  12610      break;
  12611 
  12612    case ParseNodeKind::CommaExpr:
  12613      if (!emitSequenceExpr(&pn->as<ListNode>(), valueUsage)) {
  12614        return false;
  12615      }
  12616      break;
  12617 
  12618    case ParseNodeKind::InitExpr:
  12619    case ParseNodeKind::AssignExpr:
  12620    case ParseNodeKind::AddAssignExpr:
  12621    case ParseNodeKind::SubAssignExpr:
  12622    case ParseNodeKind::BitOrAssignExpr:
  12623    case ParseNodeKind::BitXorAssignExpr:
  12624    case ParseNodeKind::BitAndAssignExpr:
  12625    case ParseNodeKind::LshAssignExpr:
  12626    case ParseNodeKind::RshAssignExpr:
  12627    case ParseNodeKind::UrshAssignExpr:
  12628    case ParseNodeKind::MulAssignExpr:
  12629    case ParseNodeKind::DivAssignExpr:
  12630    case ParseNodeKind::ModAssignExpr:
  12631    case ParseNodeKind::PowAssignExpr: {
  12632      BinaryNode* assignNode = &pn->as<BinaryNode>();
  12633      if (!emitAssignmentOrInit(assignNode->getKind(), assignNode->left(),
  12634                                assignNode->right())) {
  12635        return false;
  12636      }
  12637      break;
  12638    }
  12639 
  12640    case ParseNodeKind::CoalesceAssignExpr:
  12641    case ParseNodeKind::OrAssignExpr:
  12642    case ParseNodeKind::AndAssignExpr:
  12643      if (!emitShortCircuitAssignment(&pn->as<AssignmentNode>())) {
  12644        return false;
  12645      }
  12646      break;
  12647 
  12648    case ParseNodeKind::ConditionalExpr:
  12649      if (!emitConditionalExpression(pn->as<ConditionalExpression>(),
  12650                                     valueUsage)) {
  12651        return false;
  12652      }
  12653      break;
  12654 
  12655    case ParseNodeKind::OrExpr:
  12656    case ParseNodeKind::CoalesceExpr:
  12657    case ParseNodeKind::AndExpr:
  12658      if (!emitShortCircuit(&pn->as<ListNode>(), valueUsage)) {
  12659        return false;
  12660      }
  12661      break;
  12662 
  12663    case ParseNodeKind::StrictEqExpr:
  12664    case ParseNodeKind::EqExpr:
  12665    case ParseNodeKind::StrictNeExpr:
  12666    case ParseNodeKind::NeExpr:
  12667    case ParseNodeKind::LtExpr:
  12668    case ParseNodeKind::GtExpr: {
  12669      bool emitted;
  12670      if (!tryEmitTypeofEq(&pn->as<ListNode>(), &emitted)) {
  12671        return false;
  12672      }
  12673      if (emitted) {
  12674        return true;
  12675      }
  12676    }
  12677      [[fallthrough]];
  12678 
  12679    case ParseNodeKind::AddExpr:
  12680    case ParseNodeKind::SubExpr:
  12681    case ParseNodeKind::BitOrExpr:
  12682    case ParseNodeKind::BitXorExpr:
  12683    case ParseNodeKind::BitAndExpr:
  12684    case ParseNodeKind::LeExpr:
  12685    case ParseNodeKind::GeExpr:
  12686    case ParseNodeKind::InExpr:
  12687    case ParseNodeKind::InstanceOfExpr:
  12688    case ParseNodeKind::LshExpr:
  12689    case ParseNodeKind::RshExpr:
  12690    case ParseNodeKind::UrshExpr:
  12691    case ParseNodeKind::MulExpr:
  12692    case ParseNodeKind::DivExpr:
  12693    case ParseNodeKind::ModExpr:
  12694      if (!emitLeftAssociative(&pn->as<ListNode>())) {
  12695        return false;
  12696      }
  12697      break;
  12698 
  12699    case ParseNodeKind::PrivateInExpr:
  12700      if (!emitPrivateInExpr(&pn->as<ListNode>())) {
  12701        return false;
  12702      }
  12703      break;
  12704 
  12705    case ParseNodeKind::PowExpr:
  12706      if (!emitRightAssociative(&pn->as<ListNode>())) {
  12707        return false;
  12708      }
  12709      break;
  12710 
  12711    case ParseNodeKind::TypeOfNameExpr:
  12712      if (!emitTypeof(&pn->as<UnaryNode>(), JSOp::Typeof)) {
  12713        return false;
  12714      }
  12715      break;
  12716 
  12717    case ParseNodeKind::TypeOfExpr:
  12718      if (!emitTypeof(&pn->as<UnaryNode>(), JSOp::TypeofExpr)) {
  12719        return false;
  12720      }
  12721      break;
  12722 
  12723    case ParseNodeKind::ThrowStmt:
  12724      if (!updateSourceCoordNotes(pn->pn_pos.begin)) {
  12725        return false;
  12726      }
  12727      if (!markStepBreakpoint()) {
  12728        return false;
  12729      }
  12730      [[fallthrough]];
  12731    case ParseNodeKind::VoidExpr:
  12732    case ParseNodeKind::NotExpr:
  12733    case ParseNodeKind::BitNotExpr:
  12734    case ParseNodeKind::PosExpr:
  12735    case ParseNodeKind::NegExpr:
  12736      if (!emitUnary(&pn->as<UnaryNode>())) {
  12737        return false;
  12738      }
  12739      break;
  12740 
  12741    case ParseNodeKind::PreIncrementExpr:
  12742    case ParseNodeKind::PreDecrementExpr:
  12743    case ParseNodeKind::PostIncrementExpr:
  12744    case ParseNodeKind::PostDecrementExpr:
  12745      if (!emitIncOrDec(&pn->as<UnaryNode>(), valueUsage)) {
  12746        return false;
  12747      }
  12748      break;
  12749 
  12750    case ParseNodeKind::DeleteNameExpr:
  12751      if (!emitDeleteName(&pn->as<UnaryNode>())) {
  12752        return false;
  12753      }
  12754      break;
  12755 
  12756    case ParseNodeKind::DeletePropExpr:
  12757      if (!emitDeleteProperty(&pn->as<UnaryNode>())) {
  12758        return false;
  12759      }
  12760      break;
  12761 
  12762    case ParseNodeKind::DeleteElemExpr:
  12763      if (!emitDeleteElement(&pn->as<UnaryNode>())) {
  12764        return false;
  12765      }
  12766      break;
  12767 
  12768    case ParseNodeKind::DeleteExpr:
  12769      if (!emitDeleteExpression(&pn->as<UnaryNode>())) {
  12770        return false;
  12771      }
  12772      break;
  12773 
  12774    case ParseNodeKind::DeleteOptionalChainExpr:
  12775      if (!emitDeleteOptionalChain(&pn->as<UnaryNode>())) {
  12776        return false;
  12777      }
  12778      break;
  12779 
  12780    case ParseNodeKind::OptionalChain:
  12781      if (!emitOptionalChain(&pn->as<UnaryNode>(), valueUsage)) {
  12782        return false;
  12783      }
  12784      break;
  12785 
  12786    case ParseNodeKind::DotExpr: {
  12787      PropertyAccess* prop = &pn->as<PropertyAccess>();
  12788      bool isSuper = prop->isSuper();
  12789      PropOpEmitter poe(this, PropOpEmitter::Kind::Get,
  12790                        isSuper ? PropOpEmitter::ObjKind::Super
  12791                                : PropOpEmitter::ObjKind::Other);
  12792      if (!poe.prepareForObj()) {
  12793        return false;
  12794      }
  12795      if (isSuper) {
  12796        UnaryNode* base = &prop->expression().as<UnaryNode>();
  12797        if (!emitGetThisForSuperBase(base)) {
  12798          //        [stack] THIS
  12799          return false;
  12800        }
  12801      } else {
  12802        if (!emitPropLHS(prop)) {
  12803          //        [stack] OBJ
  12804          return false;
  12805        }
  12806      }
  12807      if (!poe.emitGet(prop->key().atom())) {
  12808        //          [stack] PROP
  12809        return false;
  12810      }
  12811      break;
  12812    }
  12813 
  12814    case ParseNodeKind::ArgumentsLength: {
  12815      if (sc->isFunctionBox() &&
  12816          sc->asFunctionBox()->isEligibleForArgumentsLength() &&
  12817          !sc->asFunctionBox()->needsArgsObj()) {
  12818        if (!emit1(JSOp::ArgumentsLength)) {
  12819          return false;
  12820        }
  12821      } else {
  12822        PropOpEmitter poe(this, PropOpEmitter::Kind::Get,
  12823                          PropOpEmitter::ObjKind::Other);
  12824        if (!poe.prepareForObj()) {
  12825          return false;
  12826        }
  12827 
  12828        NameOpEmitter noe(this, TaggedParserAtomIndex::WellKnown::arguments(),
  12829                          NameOpEmitter::Kind::Get);
  12830        if (!noe.emitGet()) {
  12831          return false;
  12832        }
  12833        if (!poe.emitGet(TaggedParserAtomIndex::WellKnown::length())) {
  12834          return false;
  12835        }
  12836      }
  12837      break;
  12838    }
  12839 
  12840    case ParseNodeKind::ElemExpr: {
  12841      PropertyByValue* elem = &pn->as<PropertyByValue>();
  12842      bool isSuper = elem->isSuper();
  12843      MOZ_ASSERT(!elem->key().isKind(ParseNodeKind::PrivateName));
  12844      ElemOpEmitter eoe(this, ElemOpEmitter::Kind::Get,
  12845                        isSuper ? ElemOpEmitter::ObjKind::Super
  12846                                : ElemOpEmitter::ObjKind::Other);
  12847      if (!emitElemObjAndKey(elem, eoe)) {
  12848        //          [stack] # if Super
  12849        //          [stack] THIS KEY
  12850        //          [stack] # otherwise
  12851        //          [stack] OBJ KEY
  12852        return false;
  12853      }
  12854      if (!eoe.emitGet()) {
  12855        //          [stack] ELEM
  12856        return false;
  12857      }
  12858 
  12859      break;
  12860    }
  12861 
  12862    case ParseNodeKind::PrivateMemberExpr: {
  12863      PrivateMemberAccess* privateExpr = &pn->as<PrivateMemberAccess>();
  12864      PrivateOpEmitter xoe(this, PrivateOpEmitter::Kind::Get,
  12865                           privateExpr->privateName().name());
  12866      if (!emitTree(&privateExpr->expression())) {
  12867        //          [stack] OBJ
  12868        return false;
  12869      }
  12870      if (!xoe.emitReference()) {
  12871        //          [stack] OBJ NAME
  12872        return false;
  12873      }
  12874      if (!xoe.emitGet()) {
  12875        //          [stack] VALUE
  12876        return false;
  12877      }
  12878 
  12879      break;
  12880    }
  12881 
  12882    case ParseNodeKind::NewExpr:
  12883    case ParseNodeKind::TaggedTemplateExpr:
  12884    case ParseNodeKind::CallExpr:
  12885    case ParseNodeKind::SuperCallExpr:
  12886      if (!emitCallOrNew(&pn->as<CallNode>(), valueUsage)) {
  12887        return false;
  12888      }
  12889      break;
  12890 
  12891    case ParseNodeKind::LexicalScope:
  12892      if (!emitLexicalScope(&pn->as<LexicalScopeNode>())) {
  12893        return false;
  12894      }
  12895      break;
  12896 
  12897    case ParseNodeKind::ConstDecl:
  12898    case ParseNodeKind::LetDecl:
  12899      if (!emitDeclarationList(&pn->as<ListNode>())) {
  12900        return false;
  12901      }
  12902      break;
  12903 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
  12904    case ParseNodeKind::AwaitUsingDecl:
  12905    case ParseNodeKind::UsingDecl:
  12906      if (!emitDeclarationList(&pn->as<ListNode>())) {
  12907        return false;
  12908      }
  12909      break;
  12910 #endif
  12911 
  12912    case ParseNodeKind::ImportDecl:
  12913      MOZ_ASSERT(sc->isModuleContext());
  12914      break;
  12915 
  12916    case ParseNodeKind::ExportStmt: {
  12917      MOZ_ASSERT(sc->isModuleContext());
  12918      UnaryNode* node = &pn->as<UnaryNode>();
  12919      ParseNode* decl = node->kid();
  12920      if (decl->getKind() != ParseNodeKind::ExportSpecList) {
  12921        if (!emitTree(decl)) {
  12922          return false;
  12923        }
  12924      }
  12925      break;
  12926    }
  12927 
  12928    case ParseNodeKind::ExportDefaultStmt:
  12929      MOZ_ASSERT(sc->isModuleContext());
  12930      if (!emitExportDefault(&pn->as<BinaryNode>())) {
  12931        return false;
  12932      }
  12933      break;
  12934 
  12935    case ParseNodeKind::ExportFromStmt:
  12936      MOZ_ASSERT(sc->isModuleContext());
  12937      break;
  12938 
  12939    case ParseNodeKind::CallSiteObj:
  12940      if (!emitCallSiteObject(&pn->as<CallSiteNode>())) {
  12941        return false;
  12942      }
  12943      break;
  12944 
  12945    case ParseNodeKind::ArrayExpr:
  12946      if (!emitArrayLiteral(&pn->as<ListNode>())) {
  12947        return false;
  12948      }
  12949      break;
  12950 
  12951    case ParseNodeKind::ObjectExpr:
  12952      if (!emitObject(&pn->as<ListNode>())) {
  12953        return false;
  12954      }
  12955      break;
  12956 
  12957    case ParseNodeKind::Name:
  12958      if (!emitGetName(&pn->as<NameNode>())) {
  12959        return false;
  12960      }
  12961      break;
  12962 
  12963    case ParseNodeKind::PrivateName:
  12964      if (!emitGetPrivateName(&pn->as<NameNode>())) {
  12965        return false;
  12966      }
  12967      break;
  12968 
  12969    case ParseNodeKind::TemplateStringListExpr:
  12970      if (!emitTemplateString(&pn->as<ListNode>())) {
  12971        return false;
  12972      }
  12973      break;
  12974 
  12975    case ParseNodeKind::TemplateStringExpr:
  12976    case ParseNodeKind::StringExpr:
  12977      if (!emitStringOp(JSOp::String, pn->as<NameNode>().atom())) {
  12978        return false;
  12979      }
  12980      break;
  12981 
  12982    case ParseNodeKind::NumberExpr:
  12983      if (!emitNumberOp(pn->as<NumericLiteral>().value())) {
  12984        return false;
  12985      }
  12986      break;
  12987 
  12988    case ParseNodeKind::BigIntExpr:
  12989      if (!emitBigIntOp(&pn->as<BigIntLiteral>())) {
  12990        return false;
  12991      }
  12992      break;
  12993 
  12994    case ParseNodeKind::RegExpExpr: {
  12995      GCThingIndex index;
  12996      if (!perScriptData().gcThingList().append(&pn->as<RegExpLiteral>(),
  12997                                                &index)) {
  12998        return false;
  12999      }
  13000      if (!emitRegExp(index)) {
  13001        return false;
  13002      }
  13003      break;
  13004    }
  13005 
  13006    case ParseNodeKind::TrueExpr:
  13007      if (!emit1(JSOp::True)) {
  13008        return false;
  13009      }
  13010      break;
  13011    case ParseNodeKind::FalseExpr:
  13012      if (!emit1(JSOp::False)) {
  13013        return false;
  13014      }
  13015      break;
  13016    case ParseNodeKind::NullExpr:
  13017      if (!emit1(JSOp::Null)) {
  13018        return false;
  13019      }
  13020      break;
  13021    case ParseNodeKind::RawUndefinedExpr:
  13022      if (!emit1(JSOp::Undefined)) {
  13023        return false;
  13024      }
  13025      break;
  13026 
  13027    case ParseNodeKind::ThisExpr:
  13028      if (!emitThisLiteral(&pn->as<ThisLiteral>())) {
  13029        return false;
  13030      }
  13031      break;
  13032 
  13033    case ParseNodeKind::DebuggerStmt:
  13034      if (!updateSourceCoordNotes(pn->pn_pos.begin)) {
  13035        return false;
  13036      }
  13037      if (!markStepBreakpoint()) {
  13038        return false;
  13039      }
  13040      if (!emit1(JSOp::Debugger)) {
  13041        return false;
  13042      }
  13043      break;
  13044 
  13045    case ParseNodeKind::ClassDecl:
  13046      if (!emitClass(&pn->as<ClassNode>())) {
  13047        return false;
  13048      }
  13049      break;
  13050 
  13051    case ParseNodeKind::NewTargetExpr:
  13052      if (!emitNewTarget(&pn->as<NewTargetNode>())) {
  13053        return false;
  13054      }
  13055      break;
  13056 
  13057    case ParseNodeKind::ImportMetaExpr:
  13058      if (!emit1(JSOp::ImportMeta)) {
  13059        return false;
  13060      }
  13061      break;
  13062 
  13063    case ParseNodeKind::CallImportExpr: {
  13064      BinaryNode* spec = &pn->as<BinaryNode>().right()->as<BinaryNode>();
  13065 
  13066      if (!emitTree(spec->left())) {
  13067        //          [stack] specifier
  13068        return false;
  13069      }
  13070 
  13071      if (!spec->right()->isKind(ParseNodeKind::PosHolder)) {
  13072        //          [stack] specifier options
  13073        if (!emitTree(spec->right())) {
  13074          return false;
  13075        }
  13076      } else {
  13077        //          [stack] specifier undefined
  13078        if (!emit1(JSOp::Undefined)) {
  13079          return false;
  13080        }
  13081      }
  13082 
  13083      if (!emit1(JSOp::DynamicImport)) {
  13084        return false;
  13085      }
  13086 
  13087      break;
  13088    }
  13089 
  13090    case ParseNodeKind::SetThis:
  13091      if (!emitSetThis(&pn->as<BinaryNode>())) {
  13092        return false;
  13093      }
  13094      break;
  13095 
  13096    case ParseNodeKind::PropertyNameExpr:
  13097    case ParseNodeKind::PosHolder:
  13098      MOZ_FALLTHROUGH_ASSERT(
  13099          "Should never try to emit ParseNodeKind::PosHolder or ::Property");
  13100 
  13101    default:
  13102      MOZ_ASSERT(0);
  13103  }
  13104 
  13105  return true;
  13106 }
  13107 
  13108 static bool AllocSrcNote(FrontendContext* fc, SrcNotesVector& notes,
  13109                         unsigned size, unsigned* index) {
  13110  size_t oldLength = notes.length();
  13111 
  13112  if (MOZ_UNLIKELY(oldLength + size > MaxSrcNotesLength)) {
  13113    ReportAllocationOverflow(fc);
  13114    return false;
  13115  }
  13116 
  13117  if (!notes.growByUninitialized(size)) {
  13118    return false;
  13119  }
  13120 
  13121  *index = oldLength;
  13122  return true;
  13123 }
  13124 
  13125 bool BytecodeEmitter::addTryNote(TryNoteKind kind, uint32_t stackDepth,
  13126                                 BytecodeOffset start, BytecodeOffset end) {
  13127  MOZ_ASSERT(!inPrologue());
  13128  return bytecodeSection().tryNoteList().append(kind, stackDepth, start, end);
  13129 }
  13130 
  13131 bool BytecodeEmitter::newSrcNote(SrcNoteType type, unsigned* indexp) {
  13132  SrcNotesVector& notes = bytecodeSection().notes();
  13133  unsigned index;
  13134 
  13135  /*
  13136   * Compute delta from the last annotated bytecode's offset.  If it's too
  13137   * big to fit in sn, allocate one or more xdelta notes and reset sn.
  13138   */
  13139  BytecodeOffset offset = bytecodeSection().offset();
  13140  ptrdiff_t delta = (offset - bytecodeSection().lastNoteOffset()).value();
  13141  bytecodeSection().setLastNoteOffset(offset);
  13142 
  13143  auto allocator = [&](unsigned size) -> SrcNote* {
  13144    if (!AllocSrcNote(fc, notes, size, &index)) {
  13145      return nullptr;
  13146    }
  13147    return &notes[index];
  13148  };
  13149 
  13150  if (!SrcNoteWriter::writeNote(type, delta, allocator)) {
  13151    return false;
  13152  }
  13153 
  13154  if (indexp) {
  13155    *indexp = index;
  13156  }
  13157 
  13158  if (type == SrcNoteType::NewLine || type == SrcNoteType::SetLine) {
  13159    lastLineOnlySrcNoteIndex = index;
  13160  } else {
  13161    lastLineOnlySrcNoteIndex = LastSrcNoteIsNotLineOnly;
  13162  }
  13163 
  13164  return true;
  13165 }
  13166 
  13167 bool BytecodeEmitter::newSrcNote2(SrcNoteType type, ptrdiff_t offset,
  13168                                  unsigned* indexp) {
  13169  unsigned index;
  13170  if (!newSrcNote(type, &index)) {
  13171    return false;
  13172  }
  13173  if (!newSrcNoteOperand(offset)) {
  13174    return false;
  13175  }
  13176  if (indexp) {
  13177    *indexp = index;
  13178  }
  13179  return true;
  13180 }
  13181 
  13182 bool BytecodeEmitter::convertLastNewLineToNewLineColumn(
  13183    JS::LimitedColumnNumberOneOrigin column) {
  13184  SrcNotesVector& notes = bytecodeSection().notes();
  13185  MOZ_ASSERT(lastLineOnlySrcNoteIndex == notes.length() - 1);
  13186  SrcNote* sn = &notes[lastLineOnlySrcNoteIndex];
  13187  MOZ_ASSERT(sn->type() == SrcNoteType::NewLine);
  13188 
  13189  SrcNoteWriter::convertNote(sn, SrcNoteType::NewLineColumn);
  13190  if (!newSrcNoteOperand(SrcNote::NewLineColumn::toOperand(column))) {
  13191    return false;
  13192  }
  13193 
  13194  lastLineOnlySrcNoteIndex = LastSrcNoteIsNotLineOnly;
  13195  return true;
  13196 }
  13197 
  13198 bool BytecodeEmitter::convertLastSetLineToSetLineColumn(
  13199    JS::LimitedColumnNumberOneOrigin column) {
  13200  SrcNotesVector& notes = bytecodeSection().notes();
  13201  // The Line operand is either 1 byte or 4 bytes.
  13202  MOZ_ASSERT(lastLineOnlySrcNoteIndex == notes.length() - 1 - 1 ||
  13203             lastLineOnlySrcNoteIndex == notes.length() - 1 - 4);
  13204  SrcNote* sn = &notes[lastLineOnlySrcNoteIndex];
  13205  MOZ_ASSERT(sn->type() == SrcNoteType::SetLine);
  13206 
  13207  SrcNoteWriter::convertNote(sn, SrcNoteType::SetLineColumn);
  13208  if (!newSrcNoteOperand(SrcNote::SetLineColumn::columnToOperand(column))) {
  13209    return false;
  13210  }
  13211 
  13212  lastLineOnlySrcNoteIndex = LastSrcNoteIsNotLineOnly;
  13213  return true;
  13214 }
  13215 
  13216 bool BytecodeEmitter::newSrcNoteOperand(ptrdiff_t operand) {
  13217  if (!SrcNote::isRepresentableOperand(operand)) {
  13218    reportError(nullptr, JSMSG_NEED_DIET, "script");
  13219    return false;
  13220  }
  13221 
  13222  SrcNotesVector& notes = bytecodeSection().notes();
  13223 
  13224  auto allocator = [&](unsigned size) -> SrcNote* {
  13225    unsigned index;
  13226    if (!AllocSrcNote(fc, notes, size, &index)) {
  13227      return nullptr;
  13228    }
  13229    return &notes[index];
  13230  };
  13231 
  13232  return SrcNoteWriter::writeOperand(operand, allocator);
  13233 }
  13234 
  13235 bool BytecodeEmitter::intoScriptStencil(ScriptIndex scriptIndex) {
  13236  js::UniquePtr<ImmutableScriptData> immutableScriptData =
  13237      createImmutableScriptData();
  13238  if (!immutableScriptData) {
  13239    return false;
  13240  }
  13241 
  13242  MOZ_ASSERT(outermostScope().hasNonSyntacticScopeOnChain() ==
  13243             sc->hasNonSyntacticScope());
  13244 
  13245  auto& things = perScriptData().gcThingList().objects();
  13246  if (!compilationState.appendGCThings(fc, scriptIndex, things)) {
  13247    return false;
  13248  }
  13249 
  13250  // Hand over the ImmutableScriptData instance generated by BCE.
  13251  auto* sharedData =
  13252      SharedImmutableScriptData::createWith(fc, std::move(immutableScriptData));
  13253  if (!sharedData) {
  13254    return false;
  13255  }
  13256 
  13257  // De-duplicate the bytecode within the runtime.
  13258  if (!compilationState.sharedData.addAndShare(fc, scriptIndex, sharedData)) {
  13259    return false;
  13260  }
  13261 
  13262  ScriptStencil& script = compilationState.scriptData[scriptIndex];
  13263  script.setHasSharedData();
  13264 
  13265  // Update flags specific to functions.
  13266  if (sc->isFunctionBox()) {
  13267    FunctionBox* funbox = sc->asFunctionBox();
  13268    MOZ_ASSERT(&script == &funbox->functionStencil());
  13269    funbox->copyUpdatedImmutableFlags();
  13270    MOZ_ASSERT(script.isFunction());
  13271  } else {
  13272    ScriptStencilExtra& scriptExtra = compilationState.scriptExtra[scriptIndex];
  13273    sc->copyScriptExtraFields(scriptExtra);
  13274  }
  13275 
  13276  return true;
  13277 }
  13278 
  13279 SelfHostedIter BytecodeEmitter::getSelfHostedIterFor(
  13280    ParseNode* parseNode) const {
  13281  if (emitterMode == BytecodeEmitter::SelfHosting &&
  13282      parseNode->isKind(ParseNodeKind::CallExpr)) {
  13283    auto* callee = parseNode->as<CallNode>().callee();
  13284    if (callee->isName(TaggedParserAtomIndex::WellKnown::allowContentIter())) {
  13285      return SelfHostedIter::AllowContent;
  13286    }
  13287    if (callee->isName(
  13288            TaggedParserAtomIndex::WellKnown::allowContentIterWith())) {
  13289      return SelfHostedIter::AllowContentWith;
  13290    }
  13291    if (callee->isName(
  13292            TaggedParserAtomIndex::WellKnown::allowContentIterWithNext())) {
  13293      return SelfHostedIter::AllowContentWithNext;
  13294    }
  13295  }
  13296 
  13297  return SelfHostedIter::Deny;
  13298 }
  13299 
  13300 #if defined(DEBUG) || defined(JS_JITSPEW)
  13301 void BytecodeEmitter::dumpAtom(TaggedParserAtomIndex index) const {
  13302  parserAtoms().dump(index);
  13303 }
  13304 #endif