arai-a / smoosh-sync

Automation to make jsparagus and SpiderMonkey bytecode in sync
2 stars 0 forks source link

/js/src/vm/Opcodes.h and 27 more files have been updated (efefbf74) #225

Closed github-actions[bot] closed 3 years ago

github-actions[bot] commented 3 years ago

Files

Changesets

Diffs

/js/src/frontend/BytecodeEmitter.cpp

--- e8aa11e608f02a827e7baac9203d0992fce435e8/js/src/frontend/BytecodeEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/BytecodeEmitter.cpp
@@ -198,20 +198,20 @@ template <typename T, typename Predicate
 T* BytecodeEmitter::findInnermostNestableControl(Predicate predicate) const {
   return NestableControl::findNearest<T>(innermostNestableControl, predicate);
 }

 NameLocation BytecodeEmitter::lookupName(TaggedParserAtomIndex name) {
   return innermostEmitterScope()->lookup(this, name);
 }

-bool BytecodeEmitter::lookupPrivate(TaggedParserAtomIndex name,
+void BytecodeEmitter::lookupPrivate(TaggedParserAtomIndex name,
                                     NameLocation& loc,
                                     Maybe<NameLocation>& brandLoc) {
-  return innermostEmitterScope()->lookupPrivate(this, name, loc, brandLoc);
+  innermostEmitterScope()->lookupPrivate(this, name, loc, brandLoc);
 }

 Maybe<NameLocation> BytecodeEmitter::locationOfNameBoundInScope(
     TaggedParserAtomIndex name, EmitterScope* target) {
   return innermostEmitterScope()->locationBoundInScope(name, target);
 }

 template <typename T>
@@ -630,34 +630,30 @@ bool BytecodeEmitter::updateSourceCoordN
       return false;
     }
     bytecodeSection().setLastColumn(columnIndex, offset);
     bytecodeSection().updateSeparatorPositionIfPresent();
   }
   return true;
 }

-Maybe<uint32_t> BytecodeEmitter::getOffsetForLoop(ParseNode* nextpn) {
-  if (!nextpn) {
-    return Nothing();
-  }
-
+uint32_t BytecodeEmitter::getOffsetForLoop(ParseNode* nextpn) {
   // Try to give the JSOp::LoopHead the same line number as the next
   // instruction. nextpn is often a block, in which case the next instruction
   // typically comes from the first statement inside.
   if (nextpn->is<LexicalScopeNode>()) {
     nextpn = nextpn->as<LexicalScopeNode>().scopeBody();
   }
   if (nextpn->isKind(ParseNodeKind::StatementList)) {
     if (ParseNode* firstStatement = nextpn->as<ListNode>().head()) {
       nextpn = firstStatement;
     }
   }

-  return Some(nextpn->pn_pos.begin);
+  return nextpn->pn_pos.begin;
 }

 bool BytecodeEmitter::emitUint16Operand(JSOp op, uint32_t operand) {
   MOZ_ASSERT(operand <= UINT16_MAX);
   if (!emit3(op, UINT16_LO(operand), UINT16_HI(operand))) {
     return false;
   }
   return true;
@@ -1656,20 +1652,17 @@ void BytecodeEmitter::reportError(ParseN
   va_start(args, errorNumber);

   parser->errorReporter().errorWithNotesAtVA(nullptr, AsVariant(offset),
                                              errorNumber, &args);

   va_end(args);
 }

-void BytecodeEmitter::reportError(const Maybe<uint32_t>& maybeOffset,
-                                  unsigned errorNumber, ...) {
-  uint32_t offset = maybeOffset ? *maybeOffset : *scriptStartOffset;
-
+void BytecodeEmitter::reportError(uint32_t offset, unsigned errorNumber, ...) {
   va_list args;
   va_start(args, errorNumber);

   parser->errorReporter().errorWithNotesAtVA(nullptr, AsVariant(offset),
                                              errorNumber, &args);

   va_end(args);
 }
@@ -2156,17 +2149,17 @@ bool BytecodeEmitter::emitNumberOp(doubl
  */
 MOZ_NEVER_INLINE bool BytecodeEmitter::emitSwitch(SwitchStatement* switchStmt) {
   LexicalScopeNode& lexical = switchStmt->lexicalForCaseList();
   MOZ_ASSERT(lexical.isKind(ParseNodeKind::LexicalScope));
   ListNode* cases = &lexical.scopeBody()->as<ListNode>();
   MOZ_ASSERT(cases->isKind(ParseNodeKind::StatementList));

   SwitchEmitter se(this);
-  if (!se.emitDiscriminant(Some(switchStmt->discriminant().pn_pos.begin))) {
+  if (!se.emitDiscriminant(switchStmt->discriminant().pn_pos.begin)) {
     return false;
   }

   if (!markStepBreakpoint()) {
     return false;
   }
   if (!emitTree(&switchStmt->discriminant())) {
     return false;
@@ -5694,17 +5687,17 @@ bool BytecodeEmitter::emitForOf(ForNode*
   }

   if (headLexicalEmitterScope) {
     DebugOnly<ParseNode*> forOfTarget = forOfHead->kid1();
     MOZ_ASSERT(forOfTarget->isKind(ParseNodeKind::LetDecl) ||
                forOfTarget->isKind(ParseNodeKind::ConstDecl));
   }

-  if (!forOf.emitInitialize(Some(forOfHead->pn_pos.begin))) {
+  if (!forOf.emitInitialize(forOfHead->pn_pos.begin)) {
     //              [stack] NEXT ITER VALUE
     return false;
   }

   if (!emitInitializeForInOrOfTarget(forOfHead)) {
     //              [stack] NEXT ITER VALUE
     return false;
   }
@@ -5716,17 +5709,17 @@ bool BytecodeEmitter::emitForOf(ForNode*

   // Perform the loop body.
   ParseNode* forBody = forOfLoop->body();
   if (!emitTree(forBody)) {
     //              [stack] NEXT ITER UNDEF
     return false;
   }

-  if (!forOf.emitEnd(Some(forHeadExpr->pn_pos.begin))) {
+  if (!forOf.emitEnd(forHeadExpr->pn_pos.begin)) {
     //              [stack]
     return false;
   }

   return true;
 }

 bool BytecodeEmitter::emitForIn(ForNode* forInLoop,
@@ -5818,17 +5811,17 @@ bool BytecodeEmitter::emitForIn(ForNode*

   // Perform the loop body.
   ParseNode* forBody = forInLoop->body();
   if (!emitTree(forBody)) {
     //              [stack] ITER ITERVAL
     return false;
   }

-  if (!forIn.emitEnd(Some(forInHead->pn_pos.begin))) {
+  if (!forIn.emitEnd(forInHead->pn_pos.begin)) {
     //              [stack]
     return false;
   }

   return true;
 }

 /* C-style `for (init; cond; update) ...` loop. */
@@ -5927,17 +5920,17 @@ bool BytecodeEmitter::emitCStyleFor(
       return false;
     }
     if (!emitTree(update, ValueUsage::IgnoreValue)) {
       //            [stack] VAL
       return false;
     }
   }

-  if (!cfor.emitEnd(Some(forNode->pn_pos.begin))) {
+  if (!cfor.emitEnd(forNode->pn_pos.begin)) {
     //              [stack]
     return false;
   }

   return true;
 }

 bool BytecodeEmitter::emitFor(ForNode* forNode,
@@ -6026,18 +6019,17 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::e

   return true;
 }

 bool BytecodeEmitter::emitDo(BinaryNode* doNode) {
   ParseNode* bodyNode = doNode->left();

   DoWhileEmitter doWhile(this);
-  if (!doWhile.emitBody(Some(doNode->pn_pos.begin),
-                        getOffsetForLoop(bodyNode))) {
+  if (!doWhile.emitBody(doNode->pn_pos.begin, getOffsetForLoop(bodyNode))) {
     return false;
   }

   if (!emitTree(bodyNode)) {
     return false;
   }

   if (!doWhile.emitCond()) {
@@ -6063,18 +6055,18 @@ bool BytecodeEmitter::emitDo(BinaryNode*
 }

 bool BytecodeEmitter::emitWhile(BinaryNode* whileNode) {
   ParseNode* bodyNode = whileNode->right();

   WhileEmitter wh(this);

   ParseNode* condNode = whileNode->left();
-  if (!wh.emitCond(Some(whileNode->pn_pos.begin), getOffsetForLoop(condNode),
-                   Some(whileNode->pn_pos.end))) {
+  if (!wh.emitCond(whileNode->pn_pos.begin, getOffsetForLoop(condNode),
+                   whileNode->pn_pos.end)) {
     return false;
   }

   if (!updateSourceCoordNotes(condNode->pn_pos.begin)) {
     return false;
   }
   if (!markStepBreakpoint()) {
     return false;
@@ -6132,25 +6124,18 @@ bool BytecodeEmitter::emitContinue(Tagge
   }
   return emitGoto(target, &target->continues, GotoKind::Continue);
 }

 bool BytecodeEmitter::emitGetFunctionThis(NameNode* thisName) {
   MOZ_ASSERT(sc->hasFunctionThisBinding());
   MOZ_ASSERT(thisName->isName(TaggedParserAtomIndex::WellKnown::dotThis()));

-  return emitGetFunctionThis(Some(thisName->pn_pos.begin));
-}
-
-bool BytecodeEmitter::emitGetFunctionThis(
-    const mozilla::Maybe<uint32_t>& offset) {
-  if (offset) {
-    if (!updateLineNumberNotes(*offset)) {
-      return false;
-    }
+  if (!updateLineNumberNotes(thisName->pn_pos.begin)) {
+    return false;
   }

   if (!emitGetName(TaggedParserAtomIndex::WellKnown::dotThis())) {
     //              [stack] THIS
     return false;
   }
   if (sc->needsThisTDZChecks()) {
     if (!emit1(JSOp::CheckThis)) {
@@ -7033,17 +7018,17 @@ bool BytecodeEmitter::emitExpressionStat
       useful = true;
     }
   }

   if (useful) {
     ValueUsage valueUsage =
         wantval ? ValueUsage::WantValue : ValueUsage::IgnoreValue;
     ExpressionStatementEmitter ese(this, valueUsage);
-    if (!ese.prepareForExpr(Some(exprStmt->pn_pos.begin))) {
+    if (!ese.prepareForExpr(exprStmt->pn_pos.begin)) {
       return false;
     }
     if (!markStepBreakpoint()) {
       return false;
     }
     if (!emitTree(expr, valueUsage)) {
       return false;
     }
@@ -8179,17 +8164,17 @@ bool BytecodeEmitter::emitOptionalCall(C
     }
   }

   if (!emitArguments(argsList, /* isCall = */ true, isSpread, cone)) {
     //              [stack] CALLEE THIS ARGS...
     return false;
   }

-  if (!cone.emitEnd(argc, Some(coordNode->pn_pos.begin))) {
+  if (!cone.emitEnd(argc, coordNode->pn_pos.begin)) {
     //              [stack] RVAL
     return false;
   }

   return true;
 }

 bool BytecodeEmitter::emitCallOrNew(
@@ -8316,17 +8301,17 @@ bool BytecodeEmitter::emitCallOrNew(
   }
   if (!emitArguments(argsList, isCall, isSpread, cone)) {
     //              [stack] CALLEE THIS ARGS...
     return false;
   }

   ParseNode* coordNode = getCoordNode(callNode, calleeNode, op, argsList);

-  if (!cone.emitEnd(argc, Some(coordNode->pn_pos.begin))) {
+  if (!cone.emitEnd(argc, coordNode->pn_pos.begin)) {
     //              [stack] RVAL
     return false;
   }

   return true;
 }

 // This list must be kept in the same order in several places:
@@ -9001,46 +8986,46 @@ bool BytecodeEmitter::emitPropertyList(L
       // is created elsewhere.
       ClassField* field = &propdef->as<ClassField>();
       if (field->name().getKind() == ParseNodeKind::ComputedName) {
         auto fieldKeys =
             field->isStatic()
                 ? TaggedParserAtomIndex::WellKnown::dotStaticFieldKeys()
                 : TaggedParserAtomIndex::WellKnown::dotFieldKeys();
         if (!emitGetName(fieldKeys)) {
-          //        [stack] CTOR? OBJ ARRAY
+          //        [stack] CTOR OBJ ARRAY
           return false;
         }

         ParseNode* nameExpr = field->name().as<UnaryNode>().kid();

         if (!emitTree(nameExpr, ValueUsage::WantValue, EMIT_LINENOTE)) {
-          //        [stack] CTOR? OBJ ARRAY KEY
+          //        [stack] CTOR OBJ ARRAY KEY
           return false;
         }

         if (!emit1(JSOp::ToPropertyKey)) {
-          //        [stack] CTOR? OBJ ARRAY KEY
+          //        [stack] CTOR OBJ ARRAY KEY
           return false;
         }

         size_t fieldKeysIndex;
         if (field->isStatic()) {
           fieldKeysIndex = curStaticFieldKeyIndex++;
         } else {
           fieldKeysIndex = curFieldKeyIndex++;
         }

         if (!emitUint32Operand(JSOp::InitElemArray, fieldKeysIndex)) {
-          //        [stack] CTOR? OBJ ARRAY
+          //        [stack] CTOR OBJ ARRAY
           return false;
         }

         if (!emit1(JSOp::Pop)) {
-          //        [stack] CTOR? OBJ
+          //        [stack] CTOR OBJ
           return false;
         }
       }
       continue;
     }

     if (propdef->isKind(ParseNodeKind::StaticClassBlock)) {
       // Static class blocks are emitted as part of
@@ -9056,17 +9041,17 @@ bool BytecodeEmitter::emitPropertyList(L
       continue;
     }

     // Handle __proto__: v specially because *only* this form, and no other
     // involving "__proto__", performs [[Prototype]] mutation.
     if (propdef->isKind(ParseNodeKind::MutateProto)) {
       //            [stack] OBJ
       MOZ_ASSERT(type == ObjectLiteral);
-      if (!pe.prepareForProtoValue(Some(propdef->pn_pos.begin))) {
+      if (!pe.prepareForProtoValue(propdef->pn_pos.begin)) {
         //          [stack] OBJ
         return false;
       }
       if (!emitTree(propdef->as<UnaryNode>().kid())) {
         //          [stack] OBJ PROTO
         return false;
       }
       if (!pe.emitMutateProto()) {
@@ -9074,17 +9059,17 @@ bool BytecodeEmitter::emitPropertyList(L
         return false;
       }
       continue;
     }

     if (propdef->isKind(ParseNodeKind::Spread)) {
       MOZ_ASSERT(type == ObjectLiteral);
       //            [stack] OBJ
-      if (!pe.prepareForSpreadOperand(Some(propdef->pn_pos.begin))) {
+      if (!pe.prepareForSpreadOperand(propdef->pn_pos.begin)) {
         //          [stack] OBJ OBJ
         return false;
       }
       if (!emitTree(propdef->as<UnaryNode>().kid())) {
         //          [stack] OBJ OBJ VAL
         return false;
       }
       if (!pe.emitSpread()) {
@@ -9181,17 +9166,17 @@ bool BytecodeEmitter::emitPropertyList(L

     PropertyEmitter::Kind kind =
         (type == ClassBody && propdef->as<ClassMethod>().isStatic())
             ? PropertyEmitter::Kind::Static
             : PropertyEmitter::Kind::Prototype;
     if (key->isKind(ParseNodeKind::NumberExpr) ||
         key->isKind(ParseNodeKind::BigIntExpr)) {
       //            [stack] CTOR? OBJ
-      if (!pe.prepareForIndexPropKey(Some(propdef->pn_pos.begin), kind)) {
+      if (!pe.prepareForIndexPropKey(propdef->pn_pos.begin, kind)) {
         //          [stack] CTOR? OBJ CTOR?
         return false;
       }
       if (key->isKind(ParseNodeKind::NumberExpr)) {
         if (!emitNumberOp(key->as<NumericLiteral>().value())) {
           //        [stack] CTOR? OBJ CTOR? KEY
           return false;
         }
@@ -9206,131 +9191,166 @@ bool BytecodeEmitter::emitPropertyList(L
         return false;
       }
       if (!emitValue()) {
         //          [stack] CTOR? OBJ CTOR? KEY VAL
         return false;
       }

       if (!pe.emitInitIndexOrComputed(accessorType)) {
+        //          [stack] CTOR? OBJ
         return false;
       }

       continue;
     }

     if (key->isKind(ParseNodeKind::ObjectPropertyName) ||
         key->isKind(ParseNodeKind::StringExpr)) {
       //            [stack] CTOR? OBJ

+      auto keyAtom = key->as<NameNode>().atom();
+
       // emitClass took care of constructor already.
       if (type == ClassBody &&
-          key->as<NameNode>().atom() ==
-              TaggedParserAtomIndex::WellKnown::constructor() &&
+          keyAtom == TaggedParserAtomIndex::WellKnown::constructor() &&
           !propdef->as<ClassMethod>().isStatic()) {
         continue;
       }

-      if (!pe.prepareForPropValue(Some(propdef->pn_pos.begin), kind)) {
+      if (!pe.prepareForPropValue(propdef->pn_pos.begin, kind)) {
         //          [stack] CTOR? OBJ CTOR?
         return false;
       }

       if (!emitValue()) {
         //          [stack] CTOR? OBJ CTOR? VAL
         return false;
       }

-      auto keyAtom = key->as<NameNode>().atom();
-
       if (!pe.emitInit(accessorType, keyAtom)) {
+        //          [stack] CTOR? OBJ
+        return false;
+      }
+
+      continue;
+    }
+
+    if (key->isKind(ParseNodeKind::ComputedName)) {
+      //            [stack] CTOR? OBJ
+
+      if (!pe.prepareForComputedPropKey(propdef->pn_pos.begin, kind)) {
+        //          [stack] CTOR? OBJ CTOR?
+        return false;
+      }
+      if (!emitTree(key->as<UnaryNode>().kid())) {
+        //          [stack] CTOR? OBJ CTOR? KEY
+        return false;
+      }
+      if (!pe.prepareForComputedPropValue()) {
+        //          [stack] CTOR? OBJ CTOR? KEY
+        return false;
+      }
+      if (!emitValue()) {
+        //          [stack] CTOR? OBJ CTOR? KEY VAL
+        return false;
+      }
+
+      if (!pe.emitInitIndexOrComputed(accessorType)) {
+        //          [stack] CTOR? OBJ
         return false;
       }

       continue;
     }

-    if (key->isKind(ParseNodeKind::PrivateName) &&
-        !prop->as<ClassMethod>().isStatic()) {
+    MOZ_ASSERT(key->isKind(ParseNodeKind::PrivateName));
+    MOZ_ASSERT(type == ClassBody);
+
+    auto* privateName = &key->as<NameNode>();
+
+    if (kind == PropertyEmitter::Kind::Prototype) {
       MOZ_ASSERT(accessorType == AccessorType::None);
       if (!pe.prepareForPrivateMethod()) {
-        //          [stack] CTOR? OBJ
+        //          [stack] CTOR OBJ
         return false;
       }
-      NameOpEmitter noe(this, key->as<NameNode>().atom(),
+      NameOpEmitter noe(this, privateName->atom(),
                         NameOpEmitter::Kind::SimpleAssignment);
+
+      // Ensure the NameOp emitter doesn't push an environment onto the stack,
+      // because that would change the stack location of the home object.
+      MOZ_ASSERT(noe.loc().kind() == NameLocation::Kind::FrameSlot ||
+                 noe.loc().kind() == NameLocation::Kind::EnvironmentCoordinate);
+
       if (!noe.prepareForRhs()) {
-        //          [stack] CTOR? OBJ
+        //          [stack] CTOR OBJ
         return false;
       }
       if (!emitValue()) {
-        //          [stack] CTOR? OBJ METHOD
+        //          [stack] CTOR OBJ METHOD
         return false;
       }
       if (!noe.emitAssignment()) {
-        //          [stack] CTOR? OBJ METHOD
+        //          [stack] CTOR OBJ METHOD
         return false;
       }
       if (!emit1(JSOp::Pop)) {
-        //          [stack] CTOR? OBJ
+        //          [stack] CTOR OBJ
         return false;
       }
       if (!pe.skipInit()) {
-        //          [stack] CTOR? OBJ
+        //          [stack] CTOR OBJ
         return false;
       }
       continue;
     }

-    MOZ_ASSERT(key->isKind(ParseNodeKind::ComputedName) ||
-               key->isKind(ParseNodeKind::PrivateName));
+    MOZ_ASSERT(kind == PropertyEmitter::Kind::Static);

-    //              [stack] CTOR? OBJ
+    //              [stack] CTOR OBJ

-    if (!pe.prepareForComputedPropKey(Some(propdef->pn_pos.begin), kind)) {
-      //            [stack] CTOR? OBJ CTOR?
+    if (!pe.prepareForPrivateStaticMethod(propdef->pn_pos.begin)) {
+      //            [stack] CTOR OBJ CTOR
       return false;
     }
-    if (key->is<NameNode>()) {
-      if (!emitGetPrivateName(&key->as<NameNode>())) {
-        //          [stack] CTOR? OBJ CTOR? KEY
-        return false;
-      }
-    } else {
-      if (!emitTree(key->as<UnaryNode>().kid())) {
-        //          [stack] CTOR? OBJ CTOR? KEY
-        return false;
-      }
-    }
-    if (!pe.prepareForComputedPropValue()) {
-      //            [stack] CTOR? OBJ CTOR? KEY
+    if (!emitGetPrivateName(privateName)) {
+      //            [stack] CTOR OBJ CTOR KEY
       return false;
     }
     if (!emitValue()) {
-      //            [stack] CTOR? OBJ CTOR? KEY VAL
+      //            [stack] CTOR OBJ CTOR KEY VAL
       return false;
     }

-    if (!pe.emitInitIndexOrComputed(accessorType)) {
+    if (!pe.emitPrivateStaticMethod(accessorType)) {
+      //            [stack] CTOR OBJ
       return false;
     }

-    if (key->isKind(ParseNodeKind::PrivateName) &&
-        key->as<NameNode>().privateNameKind() == PrivateNameKind::Setter) {
-      if (!emitGetPrivateName(&key->as<NameNode>())) {
-        //          [stack] THIS NAME
+    if (privateName->privateNameKind() == PrivateNameKind::Setter) {
+      if (!emitDupAt(1)) {
+        //          [stack] CTOR OBJ CTOR
+        return false;
+      }
+      if (!emitGetPrivateName(privateName)) {
+        //          [stack] CTOR OBJ CTOR NAME
         return false;
       }
       if (!emitAtomOp(JSOp::GetIntrinsic,
                       TaggedParserAtomIndex::WellKnown::NoPrivateGetter())) {
-        //          [stack] THIS NAME FUN
+        //          [stack] CTOR OBJ CTOR NAME FUN
         return false;
       }
       if (!emit1(JSOp::InitHiddenElemGetter)) {
-        //          [stack] THIS
+        //          [stack] CTOR OBJ CTOR
+        return false;
+      }
+      if (!emit1(JSOp::Pop)) {
+        //          [stack] CTOR OBJ
         return false;
       }
     }
   }

   return true;
 }

@@ -9976,16 +9996,25 @@ bool BytecodeEmitter::emitInitializeInst
     if (!emitGetName(TaggedParserAtomIndex::WellKnown::dotThis())) {
       //            [stack] THIS
       return false;
     }
     if (!emitGetName(TaggedParserAtomIndex::WellKnown::dotPrivateBrand())) {
       //            [stack] THIS BRAND
       return false;
     }
+    if (!emitCheckPrivateField(ThrowCondition::ThrowHas,
+                               ThrowMsgKind::PrivateBrandDoubleInit)) {
+      //            [stack] THIS BRAND BOOL
+      return false;
+    }
+    if (!emit1(JSOp::Pop)) {
+      //            [stack] THIS BRAND
+      return false;
+    }
     if (!emitBuiltinObject(BuiltinObjectKind::FunctionPrototype)) {
       //            [stack] THIS BRAND GETTER
       return false;
     }
     if (!emit1(JSOp::InitHiddenElemGetter)) {
       //            [stack] THIS
       return false;
     }
@@ -10665,36 +10694,17 @@ static MOZ_ALWAYS_INLINE ParseNode* Find
       }
     }
   }
   return nullptr;
 }

 bool BytecodeEmitter::emitNewPrivateName(TaggedParserAtomIndex bindingName,
                                          TaggedParserAtomIndex symbolName) {
-  // TODO: Add a new bytecode to create private names.
-  if (!emitAtomOp(JSOp::GetIntrinsic,
-                  TaggedParserAtomIndex::WellKnown::NewPrivateName())) {
-    //              [stack] HERITAGE NEWPRIVATENAME
-    return false;
-  }
-
-  // Push `undefined` as `this` parameter for call.
-  if (!emit1(JSOp::Undefined)) {
-    //              [stack] HERITAGE NEWPRIVATENAME UNDEFINED
-    return false;
-  }
-
-  if (!emitAtomOp(JSOp::String, symbolName)) {
-    //              [stack] HERITAGE NEWPRIVATENAME UNDEFINED NAME
-    return false;
-  }
-
-  int argc = 1;
-  if (!emitCall(JSOp::Call, argc)) {
+  if (!emitAtomOp(JSOp::NewPrivateName, symbolName)) {
     //              [stack] HERITAGE PRIVATENAME
     return false;
   }

   // Add a binding for #name => privatename
   if (!emitLexicalInitialization(bindingName)) {
     //              [stack] HERITAGE PRIVATENAME
     return false;

/js/src/frontend/BytecodeEmitter.h

--- e8aa11e608f02a827e7baac9203d0992fce435e8/js/src/frontend/BytecodeEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/BytecodeEmitter.h
@@ -197,18 +197,16 @@ enum class ValueIsOnStack { Yes, No };
 //       // Good!
 //       helper.prepareForA();
 //       ... // emit bytecode for A here
 //       helper.prepareForB();
 //       ... // emit bytecode for B here
 //       helper.emitEnd();
 //   * helper classes should track state transition and assert it in each
 //     method call, to avoid misuse
-//   * parameters related to source code offset should use `mozilla::Maybe`,
-//     to support the case that there's no position information
 //   * it's recommended to defer receiving parameter until the parameter value
 //     is actually used in the method, instead of receiving and storing them
 //     into instance fields
 //
 // See comment block above each helper class for more details and example usage.

 struct MOZ_STACK_CLASS BytecodeEmitter {
   // Context shared between parsing and bytecode generation.
@@ -357,17 +355,17 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
   T* findInnermostNestableControl() const;

   template <typename T, typename Predicate /* (T*) -> bool */>
   T* findInnermostNestableControl(Predicate predicate) const;

   NameLocation lookupName(TaggedParserAtomIndex name);

   // See EmitterScope::lookupPrivate for details around brandLoc
-  bool lookupPrivate(TaggedParserAtomIndex name, NameLocation& loc,
+  void lookupPrivate(TaggedParserAtomIndex name, NameLocation& loc,
                      mozilla::Maybe<NameLocation>& brandLoc);

   // To implement Annex B and the formal parameter defaults scope semantics
   // requires accessing names that would otherwise be shadowed. This method
   // returns the access location of a name that is known to be bound in a
   // target scope.
   mozilla::Maybe<NameLocation> locationOfNameBoundInScope(
       TaggedParserAtomIndex name, EmitterScope* target);
@@ -447,18 +445,17 @@ struct MOZ_STACK_CLASS BytecodeEmitter {

   void setScriptStartOffsetIfUnset(uint32_t pos) {
     if (scriptStartOffset.isNothing()) {
       scriptStartOffset = mozilla::Some(pos);
     }
   }

   void reportError(ParseNode* pn, unsigned errorNumber, ...);
-  void reportError(const mozilla::Maybe<uint32_t>& maybeOffset,
-                   unsigned errorNumber, ...);
+  void reportError(uint32_t offset, unsigned errorNumber, ...);

   // Fill in a ScriptStencil using this BCE data.
   bool intoScriptStencil(ScriptIndex scriptIndex);

   // If pn contains a useful expression, return true with *answer set to true.
   // If pn contains a useless expression, return true with *answer set to
   // false. Return false on error.
   //
@@ -578,18 +575,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter {

   [[nodiscard]] bool emitDouble(double dval);
   [[nodiscard]] bool emitNumberOp(double dval);

   [[nodiscard]] bool emitBigIntOp(BigIntLiteral* bigint);

   [[nodiscard]] bool emitThisLiteral(ThisLiteral* pn);
   [[nodiscard]] bool emitGetFunctionThis(NameNode* thisName);
-  [[nodiscard]] bool emitGetFunctionThis(
-      const mozilla::Maybe<uint32_t>& offset);
   [[nodiscard]] bool emitGetThisForSuperBase(UnaryNode* superBase);
   [[nodiscard]] bool emitSetThis(BinaryNode* setThisNode);
   [[nodiscard]] bool emitCheckDerivedClassConstructorReturn();

   // Handle jump opcodes and jump targets.
   [[nodiscard]] bool emitJumpTargetOp(JSOp op, BytecodeOffset* off);
   [[nodiscard]] bool emitJumpTarget(JumpTarget* target);
   [[nodiscard]] bool emitJumpNoFallthrough(JSOp op, JumpList* jump);
@@ -598,17 +593,17 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
   [[nodiscard]] bool emitJumpTargetAndPatch(JumpList jump);

   [[nodiscard]] bool emitCall(
       JSOp op, uint16_t argc,
       const mozilla::Maybe<uint32_t>& sourceCoordOffset);
   [[nodiscard]] bool emitCall(JSOp op, uint16_t argc, ParseNode* pn = nullptr);
   [[nodiscard]] bool emitCallIncDec(UnaryNode* incDec);

-  mozilla::Maybe<uint32_t> getOffsetForLoop(ParseNode* nextpn);
+  uint32_t getOffsetForLoop(ParseNode* nextpn);

   enum class GotoKind { Break, Continue };
   [[nodiscard]] bool emitGoto(NestableControl* target, JumpList* jumplist,
                               GotoKind kind);

   [[nodiscard]] bool emitGCIndexOp(JSOp op, GCThingIndex index);

   [[nodiscard]] bool emitAtomOp(JSOp op, TaggedParserAtomIndex atom);

/js/src/frontend/CForEmitter.cpp

--- 62b49458f8192c3a423d4081dfce34cfb06db9da/js/src/frontend/CForEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/CForEmitter.cpp
@@ -133,17 +133,17 @@ bool CForEmitter::emitUpdate(Update upda
   }

 #ifdef DEBUG
   state_ = State::Update;
 #endif
   return true;
 }

-bool CForEmitter::emitEnd(const Maybe<uint32_t>& forPos) {
+bool CForEmitter::emitEnd(uint32_t forPos) {
   MOZ_ASSERT(state_ == State::Update);

   if (update_ == Update::Present) {
     tdzCache_.reset();

     //              [stack] UPDATE

     if (!bce_->emit1(JSOp::Pop)) {
@@ -152,20 +152,18 @@ bool CForEmitter::emitEnd(const Maybe<ui
     }
   }

   if (cond_ == Cond::Missing && update_ == Update::Missing) {
     // If there is no condition clause and no update clause, mark
     // the loop-ending "goto" with the location of the "for".
     // This ensures that the debugger will stop on each loop
     // iteration.
-    if (forPos) {
-      if (!bce_->updateSourceCoordNotes(*forPos)) {
-        return false;
-      }
+    if (!bce_->updateSourceCoordNotes(forPos)) {
+      return false;
     }
   }

   // Emit the loop-closing jump.
   if (!loopInfo_->emitLoopEnd(bce_, JSOp::Goto, TryNoteKind::Loop)) {
     //              [stack]
     return false;
   }

/js/src/frontend/CForEmitter.h

--- 1f385759e3f5f8e8070ef7f0442562d74cbb97e8/js/src/frontend/CForEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/CForEmitter.h
@@ -27,30 +27,30 @@ class EmitterScope;
 // Usage: (check for the return value is omitted for simplicity)
 //
 //   `for (init; cond; update) body`
 //     CForEmitter cfor(this, headLexicalEmitterScopeForLet or nullptr);
 //     cfor.emitInit(Some(offset_of_init));
 //     emit(init); // without pushing value
 //     cfor.emitCond(Some(offset_of_cond));
 //     emit(cond);
-//     cfor.emitBody(CForEmitter::Cond::Present, Some(offset_of_body));
+//     cfor.emitBody(CForEmitter::Cond::Present);
 //     emit(body);
 //     cfor.emitUpdate(CForEmitter::Update::Present, Some(offset_of_update)));
 //     emit(update);
-//     cfor.emitEnd(Some(offset_of_for));
+//     cfor.emitEnd(offset_of_for);
 //
 //   `for (;;) body`
 //     CForEmitter cfor(this, nullptr);
 //     cfor.emitInit(Nothing());
 //     cfor.emitCond(Nothing());
-//     cfor.emitBody(CForEmitter::Cond::Missing, Some(offset_of_body));
+//     cfor.emitBody(CForEmitter::Cond::Missing);
 //     emit(body);
 //     cfor.emitUpdate(CForEmitter::Update::Missing, Nothing());
-//     cfor.emitEnd(Some(offset_of_for));
+//     cfor.emitEnd(offset_of_for);
 //
 class MOZ_STACK_CLASS CForEmitter {
   // Basic structure of the bytecode (not complete).
   //
   // If `cond` is not empty:
   //     {init}
   //   loop:
   //     JSOp::LoopHead
@@ -162,15 +162,15 @@ class MOZ_STACK_CLASS CForEmitter {
   //   forPos
   //
   // Can be Nothing() if not available.
   [[nodiscard]] bool emitInit(const mozilla::Maybe<uint32_t>& initPos);
   [[nodiscard]] bool emitCond(const mozilla::Maybe<uint32_t>& condPos);
   [[nodiscard]] bool emitBody(Cond cond);
   [[nodiscard]] bool emitUpdate(Update update,
                                 const mozilla::Maybe<uint32_t>& updatePos);
-  [[nodiscard]] bool emitEnd(const mozilla::Maybe<uint32_t>& forPos);
+  [[nodiscard]] bool emitEnd(uint32_t forPos);
 };

 } /* namespace frontend */
 } /* namespace js */

 #endif /* frontend_CForEmitter_h */

/js/src/frontend/CallOrNewEmitter.cpp

--- a48c2c09a753f141b990e38f93fb62eedaed1606/js/src/frontend/CallOrNewEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/CallOrNewEmitter.cpp
@@ -10,18 +10,16 @@
 #include "frontend/NameOpEmitter.h"
 #include "frontend/SharedContext.h"
 #include "vm/Opcodes.h"
 #include "vm/StringType.h"

 using namespace js;
 using namespace js::frontend;

-using mozilla::Maybe;
-
 CallOrNewEmitter::CallOrNewEmitter(BytecodeEmitter* bce, JSOp op,
                                    ArgumentsKind argumentsKind,
                                    ValueUsage valueUsage)
     : bce_(bce), op_(op), argumentsKind_(argumentsKind) {
   if (op_ == JSOp::Call && valueUsage == ValueUsage::IgnoreValue) {
     op_ = JSOp::CallIgnoresRv;
   }

@@ -235,17 +233,17 @@ bool CallOrNewEmitter::emitSpreadArgumen
 bool CallOrNewEmitter::wantSpreadIteration() {
   MOZ_ASSERT(state_ == State::SpreadIteration);
   MOZ_ASSERT(isSpread());

   state_ = State::Arguments;
   return !isPassthroughRest();
 }

-bool CallOrNewEmitter::emitEnd(uint32_t argc, const Maybe<uint32_t>& beginPos) {
+bool CallOrNewEmitter::emitEnd(uint32_t argc, uint32_t beginPos) {
   MOZ_ASSERT(state_ == State::Arguments);

   if (isSingleSpread()) {
     if (!ifNotOptimizable_->emitEnd()) {
       //            [stack] CALLEE THIS ARR
       return false;
     }

@@ -261,38 +259,36 @@ bool CallOrNewEmitter::emitEnd(uint32_t
       // Repush the callee as new.target
       uint32_t effectiveArgc = isSpread() ? 1 : argc;
       if (!bce_->emitDupAt(effectiveArgc + 1)) {
         //          [stack] CALLEE THIS ARR CALLEE
         return false;
       }
     }
   }
-  if (beginPos) {
-    if (!bce_->updateSourceCoordNotes(*beginPos)) {
-      return false;
-    }
+  if (!bce_->updateSourceCoordNotes(beginPos)) {
+    return false;
   }
   if (!bce_->markSimpleBreakpoint()) {
     return false;
   }
   if (!isSpread()) {
     if (!bce_->emitCall(op_, argc)) {
       //            [stack] RVAL
       return false;
     }
   } else {
     if (!bce_->emit1(op_)) {
       //            [stack] RVAL
       return false;
     }
   }

-  if (isEval() && beginPos) {
-    uint32_t lineNum = bce_->parser->errorReporter().lineAt(*beginPos);
+  if (isEval()) {
+    uint32_t lineNum = bce_->parser->errorReporter().lineAt(beginPos);
     if (!bce_->emitUint32Operand(JSOp::Lineno, lineNum)) {
       return false;
     }
   }

   state_ = State::End;
   return true;
 }

/js/src/frontend/CallOrNewEmitter.h

--- 051adeafc417ce9630ef4421ad959a47211ac0fc/js/src/frontend/CallOrNewEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/CallOrNewEmitter.h
@@ -34,105 +34,105 @@ struct BytecodeEmitter;
 //   `print(arg);`
 //     CallOrNewEmitter cone(this, JSOp::Call,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     cone.emitNameCallee(print);
 //     cone.emitThis();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //
 //   `callee.prop(arg1, arg2);`
 //     CallOrNewEmitter cone(this, JSOp::Call,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     PropOpEmitter& poe = cone.prepareForPropCallee(false);
 //     ... emit `callee.prop` with `poe` here...
 //     cone.emitThis();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg1);
 //     emit(arg2);
-//     cone.emitEnd(2, Some(offset_of_callee));
+//     cone.emitEnd(2, offset_of_callee);
 //
 //   `callee[key](arg);`
 //     CallOrNewEmitter cone(this, JSOp::Call,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     ElemOpEmitter& eoe = cone.prepareForElemCallee(false);
 //     ... emit `callee[key]` with `eoe` here...
 //     cone.emitThis();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //
 //   `callee.#method(arg);`
 //     CallOrNewEmitter cone(this, JSOp::Call,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     PrivateOpEmitter& xoe = cone.prepareForPrivateCallee();
 //     ... emit `callee.#method` with `xoe` here...
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //
 //   `(function() { ... })(arg);`
 //     CallOrNewEmitter cone(this, JSOp::Call,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     cone.prepareForFunctionCallee();
 //     emit(function);
 //     cone.emitThis();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //
 //   `super(arg);`
 //     CallOrNewEmitter cone(this, JSOp::Call,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     cone.emitSuperCallee();
 //     cone.emitThis();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //
 //   `(some_other_expression)(arg);`
 //     CallOrNewEmitter cone(this, JSOp::Call,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     cone.prepareForOtherCallee();
 //     emit(some_other_expression);
 //     cone.emitThis();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //
 //   `print(...arg);`
 //     CallOrNewEmitter cone(this, JSOp::SpreadCall,
 //                           CallOrNewEmitter::ArgumentsKind::SingleSpread,
 //                           ValueUsage::WantValue);
 //     cone.emitNameCallee(print);
 //     cone.emitThis();
 //     if (cone.wantSpreadOperand()) {
 //       emit(arg)
 //     }
 //     cone.emitSpreadArgumentsTest();
 //     emit([...arg]);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //
 //   `new f(arg);`
 //     CallOrNewEmitter cone(this, JSOp::New,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     cone.emitNameCallee(f);
 //     cone.emitThis();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //
 class MOZ_STACK_CLASS CallOrNewEmitter {
  public:
   enum class ArgumentsKind {
     Other,

     // Specify this for the following case:
     //
@@ -327,18 +327,15 @@ class MOZ_STACK_CLASS CallOrNewEmitter {
   [[nodiscard]] bool wantSpreadIteration();

   // Parameters are the offset in the source code for each character below:
   //
   //   callee(arg);
   //   ^
   //   |
   //   beginPos
-  //
-  // Can be Nothing() if not available.
-  [[nodiscard]] bool emitEnd(uint32_t argc,
-                             const mozilla::Maybe<uint32_t>& beginPos);
+  [[nodiscard]] bool emitEnd(uint32_t argc, uint32_t beginPos);
 };

 } /* namespace frontend */
 } /* namespace js */

 #endif /* frontend_CallOrNewEmitter_h */

/js/src/frontend/DefaultEmitter.cpp

--- 199ff346e675e967b82a2dbb28fa43c45ac53238/js/src/frontend/DefaultEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/DefaultEmitter.cpp
@@ -9,17 +9,16 @@
 #include "mozilla/Assertions.h"  // MOZ_ASSERT

 #include "frontend/BytecodeEmitter.h"  // BytecodeEmitter
 #include "vm/Opcodes.h"                // JSOp

 using namespace js;
 using namespace js::frontend;

-using mozilla::Maybe;
 using mozilla::Nothing;

 DefaultEmitter::DefaultEmitter(BytecodeEmitter* bce) : bce_(bce) {}

 bool DefaultEmitter::prepareForDefault() {
   MOZ_ASSERT(state_ == State::Start);

   //                [stack] VALUE

/js/src/frontend/DoWhileEmitter.cpp

--- af48b695bea3268b0db1123d7c67a729cbffac3a/js/src/frontend/DoWhileEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/DoWhileEmitter.cpp
@@ -9,40 +9,34 @@
 #include "frontend/BytecodeEmitter.h"
 #include "frontend/SourceNotes.h"
 #include "vm/Opcodes.h"
 #include "vm/StencilEnums.h"  // TryNoteKind

 using namespace js;
 using namespace js::frontend;

-using mozilla::Maybe;
-using mozilla::Nothing;
-
 DoWhileEmitter::DoWhileEmitter(BytecodeEmitter* bce) : bce_(bce) {}

-bool DoWhileEmitter::emitBody(const Maybe<uint32_t>& doPos,
-                              const Maybe<uint32_t>& bodyPos) {
+bool DoWhileEmitter::emitBody(uint32_t doPos, uint32_t bodyPos) {
   MOZ_ASSERT(state_ == State::Start);

   // Ensure that the column of the 'do' is set properly.
-  if (doPos) {
-    if (!bce_->updateSourceCoordNotes(*doPos)) {
-      return false;
-    }
+  if (!bce_->updateSourceCoordNotes(doPos)) {
+    return false;
   }

   // We need a nop here to make it possible to set a breakpoint on `do`.
   if (!bce_->emit1(JSOp::Nop)) {
     return false;
   }

   loopInfo_.emplace(bce_, StatementKind::DoLoop);

-  if (!loopInfo_->emitLoopHead(bce_, bodyPos)) {
+  if (!loopInfo_->emitLoopHead(bce_, mozilla::Some(bodyPos))) {
     return false;
   }

 #ifdef DEBUG
   state_ = State::Body;
 #endif
   return true;
 }

/js/src/frontend/DoWhileEmitter.h

--- bfaa95b5e04a36143ef2d3cff446cdda75cb5fab/js/src/frontend/DoWhileEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/DoWhileEmitter.h
@@ -20,17 +20,17 @@ namespace frontend {
 struct BytecodeEmitter;

 // Class for emitting bytecode for do-while loop.
 //
 // Usage: (check for the return value is omitted for simplicity)
 //
 //   `do body while (cond);`
 //     DoWhileEmitter doWhile(this);
-//     doWhile.emitBody(Some(offset_of_do), Some(offset_of_body));
+//     doWhile.emitBody(offset_of_do, offset_of_body);
 //     emit(body);
 //     doWhile.emitCond();
 //     emit(cond);
 //     doWhile.emitEnd();
 //
 class MOZ_STACK_CLASS DoWhileEmitter {
   BytecodeEmitter* bce_;

@@ -64,20 +64,17 @@ class MOZ_STACK_CLASS DoWhileEmitter {
   // Parameters are the offset in the source code for each character below:
   //
   //   do { ... } while ( x < 20 );
   //   ^  ^
   //   |  |
   //   |  bodyPos
   //   |
   //   doPos
-  //
-  // Can be Nothing() if not available.
-  [[nodiscard]] bool emitBody(const mozilla::Maybe<uint32_t>& doPos,
-                              const mozilla::Maybe<uint32_t>& bodyPos);
+  [[nodiscard]] bool emitBody(uint32_t doPos, uint32_t bodyPos);
   [[nodiscard]] bool emitCond();
   [[nodiscard]] bool emitEnd();
 };

 } /* namespace frontend */
 } /* namespace js */

 #endif /* frontend_DoWhileEmitter_h */

/js/src/frontend/EmitterScope.cpp

--- b4978b94e6054328409c38ba4c365c1132fef20c/js/src/frontend/EmitterScope.cpp
+++ 4036a68b398ad551903599206007598802bcf95f/js/src/frontend/EmitterScope.cpp
@@ -1002,17 +1002,17 @@ uint32_t EmitterScope::CountEnclosingCom
   while ((emitterScope = emitterScope->enclosing(&bce))) {
     if (emitterScope->hasEnvironment()) {
       environments++;
     }
   }
   return environments;
 }

-bool EmitterScope::lookupPrivate(BytecodeEmitter* bce,
+void EmitterScope::lookupPrivate(BytecodeEmitter* bce,
                                  TaggedParserAtomIndex name, NameLocation& loc,
                                  mozilla::Maybe<NameLocation>& brandLoc) {
   loc = lookup(bce, name);

   // Private Brand checking relies on the ability to construct a new
   // environment coordinate for a name at a fixed offset, which will
   // correspond to the private brand for that class.
   //
@@ -1060,17 +1060,17 @@ bool EmitterScope::lookupPrivate(Bytecod
       uint32_t external_hops = cacheEntry->environmentCoordinate().hops();

       brandLoc = Some(NameLocation::DebugEnvironmentCoordinate(
           BindingKind::Synthetic, compilation_hops + external_hops,
           ClassBodyLexicalEnvironmentObject::privateBrandSlot()));
     } else {
       brandLoc = Nothing();
     }
-    return true;
+    return;
   }

   if (loc.bindingKind() == BindingKind::PrivateMethod) {
     uint32_t hops = 0;
     if (loc.kind() == NameLocation::Kind::EnvironmentCoordinate) {
       hops = loc.environmentCoordinate().hops();
     } else {
       // If we have a FrameSlot, then our innermost emitter scope must be a
@@ -1080,17 +1080,16 @@ bool EmitterScope::lookupPrivate(Bytecod
     }

     brandLoc = Some(NameLocation::EnvironmentCoordinate(
         BindingKind::Synthetic, hops,
         ClassBodyLexicalEnvironmentObject::privateBrandSlot()));
   } else {
     brandLoc = Nothing();
   }
-  return true;
 }

 Maybe<NameLocation> EmitterScope::locationBoundInScope(
     TaggedParserAtomIndex name, EmitterScope* target) {
   // The target scope must be an intra-frame enclosing scope of this
   // one. Count the number of extra hops to reach it.
   uint8_t extraHops = 0;
   for (EmitterScope* es = this; es != target; es = es->enclosingInFrame()) {

/js/src/frontend/EmitterScope.h

--- ea02687ba7fefa71bfaad3294ca8328b7fe706b0/js/src/frontend/EmitterScope.h
+++ 4036a68b398ad551903599206007598802bcf95f/js/src/frontend/EmitterScope.h
@@ -187,20 +187,17 @@ class EmitterScope : public Nestable<Emi
   // have `.privateBrand` bindings. In a normal `lookup`, the inner binding
   // would shadow the outer one.
   //
   // This method instead sets `brandLoc` to the location of the `.privateBrand`
   // binding in the same class body as the private name `name`, ignoring
   // shadowing. If `name` refers to a name that is actually stamped onto the
   // target object (anything other than a non-static private method), then
   // `brandLoc` is set to Nothing.
-  //
-  // To handle cases where it's not possible to find the private brand, this
-  // method has to be fallible.
-  bool lookupPrivate(BytecodeEmitter* bce, TaggedParserAtomIndex name,
+  void lookupPrivate(BytecodeEmitter* bce, TaggedParserAtomIndex name,
                      NameLocation& loc, mozilla::Maybe<NameLocation>& brandLoc);

   mozilla::Maybe<NameLocation> locationBoundInScope(TaggedParserAtomIndex name,
                                                     EmitterScope* target);

   // For a given emitter scope, return the number of enclosing environments in
   // the current compilation (this excludes environments that could enclose the
   // compilation, like would happen for an eval copmilation).

/js/src/frontend/ExpressionStatementEmitter.cpp

--- 199ff346e675e967b82a2dbb28fa43c45ac53238/js/src/frontend/ExpressionStatementEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/ExpressionStatementEmitter.cpp
@@ -13,24 +13,21 @@ using namespace js;
 using namespace js::frontend;

 using mozilla::Maybe;

 ExpressionStatementEmitter::ExpressionStatementEmitter(BytecodeEmitter* bce,
                                                        ValueUsage valueUsage)
     : bce_(bce), valueUsage_(valueUsage) {}

-bool ExpressionStatementEmitter::prepareForExpr(
-    const Maybe<uint32_t>& beginPos) {
+bool ExpressionStatementEmitter::prepareForExpr(uint32_t beginPos) {
   MOZ_ASSERT(state_ == State::Start);

-  if (beginPos) {
-    if (!bce_->updateSourceCoordNotes(*beginPos)) {
-      return false;
-    }
+  if (!bce_->updateSourceCoordNotes(beginPos)) {
+    return false;
   }

 #ifdef DEBUG
   depth_ = bce_->bytecodeSection().stackDepth();
   state_ = State::Expr;
 #endif
   return true;
 }

/js/src/frontend/ExpressionStatementEmitter.h

--- bfaa95b5e04a36143ef2d3cff446cdda75cb5fab/js/src/frontend/ExpressionStatementEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/ExpressionStatementEmitter.h
@@ -3,17 +3,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

 #ifndef frontend_ExpressionStatementEmitter_h
 #define frontend_ExpressionStatementEmitter_h

 #include "mozilla/Attributes.h"
-#include "mozilla/Maybe.h"

 #include <stdint.h>

 #include "frontend/ValueUsage.h"

 namespace js {
 namespace frontend {

@@ -24,17 +23,17 @@ struct BytecodeEmitter;
 // Usage: (check for the return value is omitted for simplicity)
 //
 //   `expr;`
 //     // IgnoreValue if this is in normal script.
 //     // WantValue if this is in eval script.
 //     ValueUsage valueUsage = ...;
 //
 //     ExpressionStatementEmitter ese(this, valueUsage);
-//     ese.prepareForExpr(Some(offset_of_expr));
+//     ese.prepareForExpr(offset_of_expr);
 //     emit(expr);
 //     ese.emitEnd();
 //
 class MOZ_STACK_CLASS ExpressionStatementEmitter {
   BytecodeEmitter* bce_;

 #ifdef DEBUG
   // The stack depth before emitting expression.
@@ -67,18 +66,16 @@ class MOZ_STACK_CLASS ExpressionStatemen
   ExpressionStatementEmitter(BytecodeEmitter* bce, ValueUsage valueUsage);

   // Parameters are the offset in the source code for each character below:
   //
   //   expr;
   //   ^
   //   |
   //   beginPos
-  //
-  // Can be Nothing() if not available.
-  [[nodiscard]] bool prepareForExpr(const mozilla::Maybe<uint32_t>& beginPos);
+  [[nodiscard]] bool prepareForExpr(uint32_t beginPos);
   [[nodiscard]] bool emitEnd();
 };

 }  // namespace frontend
 }  // namespace js

 #endif /* frontend_ExpressionStatementEmitter_h */

/js/src/frontend/ForInEmitter.cpp

--- af48b695bea3268b0db1123d7c67a729cbffac3a/js/src/frontend/ForInEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/ForInEmitter.cpp
@@ -11,17 +11,16 @@
 #include "frontend/SourceNotes.h"
 #include "vm/Opcodes.h"
 #include "vm/Scope.h"
 #include "vm/StencilEnums.h"  // TryNoteKind

 using namespace js;
 using namespace js::frontend;

-using mozilla::Maybe;
 using mozilla::Nothing;

 ForInEmitter::ForInEmitter(BytecodeEmitter* bce,
                            const EmitterScope* headLexicalEmitterScope)
     : bce_(bce), headLexicalEmitterScope_(headLexicalEmitterScope) {}

 bool ForInEmitter::emitIterated() {
   MOZ_ASSERT(state_ == State::Start);
@@ -106,24 +105,22 @@ bool ForInEmitter::emitBody() {
              "iterator and iterval must be left on the stack");

 #ifdef DEBUG
   state_ = State::Body;
 #endif
   return true;
 }

-bool ForInEmitter::emitEnd(const Maybe<uint32_t>& forPos) {
+bool ForInEmitter::emitEnd(uint32_t forPos) {
   MOZ_ASSERT(state_ == State::Body);

-  if (forPos) {
-    // Make sure this code is attributed to the "for".
-    if (!bce_->updateSourceCoordNotes(*forPos)) {
-      return false;
-    }
+  // Make sure this code is attributed to the "for".
+  if (!bce_->updateSourceCoordNotes(forPos)) {
+    return false;
   }

   if (!loopInfo_->emitContinueTarget(bce_)) {
     //              [stack] ITER ITERVAL
     return false;
   }

   if (!bce_->emit1(JSOp::Pop)) {

/js/src/frontend/ForInEmitter.h

--- bfaa95b5e04a36143ef2d3cff446cdda75cb5fab/js/src/frontend/ForInEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/ForInEmitter.h
@@ -29,17 +29,17 @@ class EmitterScope;
 //     // headLexicalEmitterScope: lexical scope for init
 //     ForInEmitter forIn(this, headLexicalEmitterScope);
 //     forIn.emitIterated();
 //     emit(iterated);
 //     forIn.emitInitialize();
 //     emit(init);
 //     forIn.emitBody();
 //     emit(body);
-//     forIn.emitEnd(Some(offset_of_for));
+//     forIn.emitEnd(offset_of_for);
 //
 class MOZ_STACK_CLASS ForInEmitter {
   BytecodeEmitter* bce_;

 #ifdef DEBUG
   // The stack depth before emitting initialize code inside loop.
   int32_t loopDepth_ = 0;
 #endif
@@ -100,20 +100,18 @@ class MOZ_STACK_CLASS ForInEmitter {
                const EmitterScope* headLexicalEmitterScope);

   // Parameters are the offset in the source code for each character below:
   //
   //   for ( var x in obj ) { ... }
   //   ^
   //   |
   //   forPos
-  //
-  // Can be Nothing() if not available.
   [[nodiscard]] bool emitIterated();
   [[nodiscard]] bool emitInitialize();
   [[nodiscard]] bool emitBody();
-  [[nodiscard]] bool emitEnd(const mozilla::Maybe<uint32_t>& forPos);
+  [[nodiscard]] bool emitEnd(uint32_t forPos);
 };

 } /* namespace frontend */
 } /* namespace js */

 #endif /* frontend_ForInEmitter_h */

/js/src/frontend/ForOfEmitter.cpp

--- af48b695bea3268b0db1123d7c67a729cbffac3a/js/src/frontend/ForOfEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/ForOfEmitter.cpp
@@ -13,17 +13,16 @@
 #include "frontend/SourceNotes.h"
 #include "vm/Opcodes.h"
 #include "vm/Scope.h"
 #include "vm/StencilEnums.h"  // TryNoteKind

 using namespace js;
 using namespace js::frontend;

-using mozilla::Maybe;
 using mozilla::Nothing;

 ForOfEmitter::ForOfEmitter(BytecodeEmitter* bce,
                            const EmitterScope* headLexicalEmitterScope,
                            bool allowSelfHostedIter, IteratorKind iterKind)
     : bce_(bce),
       allowSelfHostedIter_(allowSelfHostedIter),
       iterKind_(iterKind),
@@ -38,17 +37,17 @@ bool ForOfEmitter::emitIterated() {
   tdzCacheForIteratedValue_.emplace(bce_);

 #ifdef DEBUG
   state_ = State::Iterated;
 #endif
   return true;
 }

-bool ForOfEmitter::emitInitialize(const Maybe<uint32_t>& forPos) {
+bool ForOfEmitter::emitInitialize(uint32_t forPos) {
   MOZ_ASSERT(state_ == State::Iterated);

   tdzCacheForIteratedValue_.reset();

   if (iterKind_ == IteratorKind::Async) {
     if (!bce_->emitAsyncIterator()) {
       //            [stack] NEXT ITER
       return false;
@@ -96,28 +95,27 @@ bool ForOfEmitter::emitInitialize(const
     }
   }

 #ifdef DEBUG
   loopDepth_ = bce_->bytecodeSection().stackDepth();
 #endif

   // Make sure this code is attributed to the "for".
-  if (forPos) {
-    if (!bce_->updateSourceCoordNotes(*forPos)) {
-      return false;
-    }
+  if (!bce_->updateSourceCoordNotes(forPos)) {
+    return false;
   }

   if (!bce_->emit1(JSOp::Dup2)) {
     //              [stack] NEXT ITER NEXT ITER
     return false;
   }

-  if (!bce_->emitIteratorNext(forPos, iterKind_, allowSelfHostedIter_)) {
+  if (!bce_->emitIteratorNext(mozilla::Some(forPos), iterKind_,
+                              allowSelfHostedIter_)) {
     //              [stack] NEXT ITER RESULT
     return false;
   }

   if (!bce_->emit1(JSOp::Dup)) {
     //              [stack] NEXT ITER RESULT RESULT
     return false;
   }
@@ -163,17 +161,17 @@ bool ForOfEmitter::emitBody() {
              "operation");

 #ifdef DEBUG
   state_ = State::Body;
 #endif
   return true;
 }

-bool ForOfEmitter::emitEnd(const Maybe<uint32_t>& iteratedPos) {
+bool ForOfEmitter::emitEnd(uint32_t iteratedPos) {
   MOZ_ASSERT(state_ == State::Body);

   MOZ_ASSERT(bce_->bytecodeSection().stackDepth() == loopDepth_ + 1,
              "the stack must be balanced around the for-of body");

   if (!loopInfo_->emitEndCodeNeedingIteratorClose(bce_)) {
     //              [stack] NEXT ITER VALUE
     return false;
@@ -183,20 +181,18 @@ bool ForOfEmitter::emitEnd(const Maybe<u
     //              [stack] NEXT ITER VALUE
     return false;
   }

   // We use the iterated value's position to attribute the backedge,
   // which corresponds to the iteration protocol.
   // This is a bit misleading for 2nd and later iterations and might need
   // some fix (bug 1482003).
-  if (iteratedPos) {
-    if (!bce_->updateSourceCoordNotes(*iteratedPos)) {
-      return false;
-    }
+  if (!bce_->updateSourceCoordNotes(iteratedPos)) {
+    return false;
   }

   if (!bce_->emit1(JSOp::Pop)) {
     //              [stack] NEXT ITER
     return false;
   }

   if (!loopInfo_->emitLoopEnd(bce_, JSOp::Goto, TryNoteKind::ForOf)) {

/js/src/frontend/ForOfEmitter.h

--- bfaa95b5e04a36143ef2d3cff446cdda75cb5fab/js/src/frontend/ForOfEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/ForOfEmitter.h
@@ -27,21 +27,21 @@ class EmitterScope;
 //
 // Usage: (check for the return value is omitted for simplicity)
 //
 //   `for (init of iterated) body`
 //     // headLexicalEmitterScope: lexical scope for init
 //     ForOfEmitter forOf(this, headLexicalEmitterScope);
 //     forOf.emitIterated();
 //     emit(iterated);
-//     forOf.emitInitialize(Some(offset_of_for));
+//     forOf.emitInitialize(offset_of_for);
 //     emit(init);
 //     forOf.emitBody();
 //     emit(body);
-//     forOf.emitEnd(Some(offset_of_iterated));
+//     forOf.emitEnd(offset_of_iterated);
 //
 class MOZ_STACK_CLASS ForOfEmitter {
   BytecodeEmitter* bce_;

 #ifdef DEBUG
   // The stack depth before emitting IteratorNext code inside loop.
   int32_t loopDepth_ = 0;
 #endif
@@ -98,20 +98,18 @@ class MOZ_STACK_CLASS ForOfEmitter {
   // The offset in the source code for each character below:
   //
   //   for ( var x of obj ) { ... }
   //   ^              ^
   //   |              |
   //   |              iteratedPos
   //   |
   //   forPos
-  //
-  // Can be Nothing() if not available.
   [[nodiscard]] bool emitIterated();
-  [[nodiscard]] bool emitInitialize(const mozilla::Maybe<uint32_t>& forPos);
+  [[nodiscard]] bool emitInitialize(uint32_t forPos);
   [[nodiscard]] bool emitBody();
-  [[nodiscard]] bool emitEnd(const mozilla::Maybe<uint32_t>& iteratedPos);
+  [[nodiscard]] bool emitEnd(uint32_t iteratedPos);
 };

 } /* namespace frontend */
 } /* namespace js */

 #endif /* frontend_ForOfEmitter_h */

/js/src/frontend/ObjectEmitter.cpp

--- c4c9cea546f97dd8b9ed769b2e9344bf1f689ca3/js/src/frontend/ObjectEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/ObjectEmitter.cpp
@@ -30,26 +30,24 @@

 using namespace js;
 using namespace js::frontend;

 using mozilla::Maybe;

 PropertyEmitter::PropertyEmitter(BytecodeEmitter* bce) : bce_(bce) {}

-bool PropertyEmitter::prepareForProtoValue(const Maybe<uint32_t>& keyPos) {
+bool PropertyEmitter::prepareForProtoValue(uint32_t keyPos) {
   MOZ_ASSERT(propertyState_ == PropertyState::Start ||
              propertyState_ == PropertyState::Init);

   //                [stack] CTOR? OBJ CTOR?

-  if (keyPos) {
-    if (!bce_->updateSourceCoordNotes(*keyPos)) {
-      return false;
-    }
+  if (!bce_->updateSourceCoordNotes(keyPos)) {
+    return false;
   }

 #ifdef DEBUG
   propertyState_ = PropertyState::ProtoValue;
 #endif
   return true;
 }

@@ -64,27 +62,24 @@ bool PropertyEmitter::emitMutateProto()
   }

 #ifdef DEBUG
   propertyState_ = PropertyState::Init;
 #endif
   return true;
 }

-bool PropertyEmitter::prepareForSpreadOperand(
-    const Maybe<uint32_t>& spreadPos) {
+bool PropertyEmitter::prepareForSpreadOperand(uint32_t spreadPos) {
   MOZ_ASSERT(propertyState_ == PropertyState::Start ||
              propertyState_ == PropertyState::Init);

   //                [stack] OBJ

-  if (spreadPos) {
-    if (!bce_->updateSourceCoordNotes(*spreadPos)) {
-      return false;
-    }
+  if (!bce_->updateSourceCoordNotes(spreadPos)) {
+    return false;
   }
   if (!bce_->emit1(JSOp::Dup)) {
     //              [stack] OBJ OBJ
     return false;
   }

 #ifdef DEBUG
   propertyState_ = PropertyState::SpreadOperand;
@@ -103,27 +98,26 @@ bool PropertyEmitter::emitSpread() {
   }

 #ifdef DEBUG
   propertyState_ = PropertyState::Init;
 #endif
   return true;
 }

-MOZ_ALWAYS_INLINE bool PropertyEmitter::prepareForProp(
-    const Maybe<uint32_t>& keyPos, bool isStatic, bool isIndexOrComputed) {
+MOZ_ALWAYS_INLINE bool PropertyEmitter::prepareForProp(uint32_t keyPos,
+                                                       bool isStatic,
+                                                       bool isIndexOrComputed) {
   isStatic_ = isStatic;
   isIndexOrComputed_ = isIndexOrComputed;

   //                [stack] CTOR? OBJ

-  if (keyPos) {
-    if (!bce_->updateSourceCoordNotes(*keyPos)) {
-      return false;
-    }
+  if (!bce_->updateSourceCoordNotes(keyPos)) {
+    return false;
   }

   if (isStatic_) {
     if (!bce_->emit1(JSOp::Dup2)) {
       //            [stack] CTOR HOMEOBJ CTOR HOMEOBJ
       return false;
     }
     if (!bce_->emit1(JSOp::Pop)) {
@@ -133,25 +127,48 @@ MOZ_ALWAYS_INLINE bool PropertyEmitter::
   }

   return true;
 }

 bool PropertyEmitter::prepareForPrivateMethod() {
   MOZ_ASSERT(propertyState_ == PropertyState::Start ||
              propertyState_ == PropertyState::Init);
+  MOZ_ASSERT(isClass_);
+
+  isStatic_ = false;
+  isIndexOrComputed_ = false;

 #ifdef DEBUG
   propertyState_ = PropertyState::PrivateMethodValue;
 #endif
   return true;
 }

-bool PropertyEmitter::prepareForPropValue(const Maybe<uint32_t>& keyPos,
-                                          Kind kind /* = Kind::Prototype */) {
+bool PropertyEmitter::prepareForPrivateStaticMethod(uint32_t keyPos) {
+  MOZ_ASSERT(propertyState_ == PropertyState::Start ||
+             propertyState_ == PropertyState::Init);
+  MOZ_ASSERT(isClass_);
+
+  //                [stack] CTOR OBJ
+
+  if (!prepareForProp(keyPos,
+                      /* isStatic_ = */ true,
+                      /* isIndexOrComputed = */ true)) {
+    //              [stack] CTOR OBJ CTOR
+    return false;
+  }
+
+#ifdef DEBUG
+  propertyState_ = PropertyState::PrivateStaticMethod;
+#endif
+  return true;
+}
+
+bool PropertyEmitter::prepareForPropValue(uint32_t keyPos, Kind kind) {
   MOZ_ASSERT(propertyState_ == PropertyState::Start ||
              propertyState_ == PropertyState::Init);

   //                [stack] CTOR? OBJ

   if (!prepareForProp(keyPos,
                       /* isStatic_ = */ kind == Kind::Static,
                       /* isIndexOrComputed = */ false)) {
@@ -160,18 +177,17 @@ bool PropertyEmitter::prepareForPropValu
   }

 #ifdef DEBUG
   propertyState_ = PropertyState::PropValue;
 #endif
   return true;
 }

-bool PropertyEmitter::prepareForIndexPropKey(
-    const Maybe<uint32_t>& keyPos, Kind kind /* = Kind::Prototype */) {
+bool PropertyEmitter::prepareForIndexPropKey(uint32_t keyPos, Kind kind) {
   MOZ_ASSERT(propertyState_ == PropertyState::Start ||
              propertyState_ == PropertyState::Init);

   //                [stack] CTOR? OBJ

   if (!prepareForProp(keyPos,
                       /* isStatic_ = */ kind == Kind::Static,
                       /* isIndexOrComputed = */ true)) {
@@ -191,18 +207,17 @@ bool PropertyEmitter::prepareForIndexPro
   //                [stack] CTOR? OBJ CTOR? KEY

 #ifdef DEBUG
   propertyState_ = PropertyState::IndexValue;
 #endif
   return true;
 }

-bool PropertyEmitter::prepareForComputedPropKey(
-    const Maybe<uint32_t>& keyPos, Kind kind /* = Kind::Prototype */) {
+bool PropertyEmitter::prepareForComputedPropKey(uint32_t keyPos, Kind kind) {
   MOZ_ASSERT(propertyState_ == PropertyState::Start ||
              propertyState_ == PropertyState::Init);

   //                [stack] CTOR? OBJ

   if (!prepareForProp(keyPos,
                       /* isStatic_ = */ kind == Kind::Static,
                       /* isIndexOrComputed = */ true)) {
@@ -230,16 +245,17 @@ bool PropertyEmitter::prepareForComputed
   propertyState_ = PropertyState::ComputedValue;
 #endif
   return true;
 }

 bool PropertyEmitter::emitInitHomeObject() {
   MOZ_ASSERT(propertyState_ == PropertyState::PropValue ||
              propertyState_ == PropertyState::PrivateMethodValue ||
+             propertyState_ == PropertyState::PrivateStaticMethod ||
              propertyState_ == PropertyState::IndexValue ||
              propertyState_ == PropertyState::ComputedValue);

   //                [stack] CTOR? HOMEOBJ CTOR? KEY? FUN

   // There are the following values on the stack conditionally, between
   // HOMEOBJ and FUN:
   //   * the 2nd CTOR if isStatic_
@@ -262,16 +278,18 @@ bool PropertyEmitter::emitInitHomeObject
     return false;
   }

 #ifdef DEBUG
   if (propertyState_ == PropertyState::PropValue) {
     propertyState_ = PropertyState::InitHomeObj;
   } else if (propertyState_ == PropertyState::PrivateMethodValue) {
     propertyState_ = PropertyState::InitHomeObjForPrivateMethod;
+  } else if (propertyState_ == PropertyState::PrivateStaticMethod) {
+    propertyState_ = PropertyState::InitHomeObjForPrivateStaticMethod;
   } else if (propertyState_ == PropertyState::IndexValue) {
     propertyState_ = PropertyState::InitHomeObjForIndex;
   } else {
     propertyState_ = PropertyState::InitHomeObjForComputed;
   }
 #endif
   return true;
 }
@@ -282,35 +300,47 @@ bool PropertyEmitter::emitInit(AccessorT
     case AccessorType::None:
       return emitInit(isClass_ ? JSOp::InitHiddenProp : JSOp::InitProp, key);
     case AccessorType::Getter:
       return emitInit(
           isClass_ ? JSOp::InitHiddenPropGetter : JSOp::InitPropGetter, key);
     case AccessorType::Setter:
       return emitInit(
           isClass_ ? JSOp::InitHiddenPropSetter : JSOp::InitPropSetter, key);
-    default:
-      MOZ_CRASH("Invalid op");
   }
+  MOZ_CRASH("Invalid op");
 }

 bool PropertyEmitter::emitInitIndexOrComputed(AccessorType accessorType) {
   switch (accessorType) {
     case AccessorType::None:
       return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElem
                                               : JSOp::InitElem);
     case AccessorType::Getter:
       return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElemGetter
                                               : JSOp::InitElemGetter);
     case AccessorType::Setter:
       return emitInitIndexOrComputed(isClass_ ? JSOp::InitHiddenElemSetter
                                               : JSOp::InitElemSetter);
-    default:
-      MOZ_CRASH("Invalid op");
   }
+  MOZ_CRASH("Invalid op");
+}
+
+bool PropertyEmitter::emitPrivateStaticMethod(AccessorType accessorType) {
+  MOZ_ASSERT(isClass_);
+
+  switch (accessorType) {
+    case AccessorType::None:
+      return emitInitIndexOrComputed(JSOp::InitLockedElem);
+    case AccessorType::Getter:
+      return emitInitIndexOrComputed(JSOp::InitHiddenElemGetter);
+    case AccessorType::Setter:
+      return emitInitIndexOrComputed(JSOp::InitHiddenElemSetter);
+  }
+  MOZ_CRASH("Invalid op");
 }

 bool PropertyEmitter::emitInit(JSOp op, TaggedParserAtomIndex key) {
   MOZ_ASSERT(propertyState_ == PropertyState::PropValue ||
              propertyState_ == PropertyState::InitHomeObj);

   MOZ_ASSERT(op == JSOp::InitProp || op == JSOp::InitHiddenProp ||
              op == JSOp::InitPropGetter || op == JSOp::InitHiddenPropGetter ||
@@ -341,21 +371,25 @@ bool PropertyEmitter::skipInit() {
 #endif
   return true;
 }

 bool PropertyEmitter::emitInitIndexOrComputed(JSOp op) {
   MOZ_ASSERT(propertyState_ == PropertyState::IndexValue ||
              propertyState_ == PropertyState::InitHomeObjForIndex ||
              propertyState_ == PropertyState::ComputedValue ||
-             propertyState_ == PropertyState::InitHomeObjForComputed);
+             propertyState_ == PropertyState::InitHomeObjForComputed ||
+             propertyState_ == PropertyState::PrivateStaticMethod ||
+             propertyState_ ==
+                 PropertyState::InitHomeObjForPrivateStaticMethod);

   MOZ_ASSERT(op == JSOp::InitElem || op == JSOp::InitHiddenElem ||
-             op == JSOp::InitElemGetter || op == JSOp::InitHiddenElemGetter ||
-             op == JSOp::InitElemSetter || op == JSOp::InitHiddenElemSetter);
+             op == JSOp::InitLockedElem || op == JSOp::InitElemGetter ||
+             op == JSOp::InitHiddenElemGetter || op == JSOp::InitElemSetter ||
+             op == JSOp::InitHiddenElemSetter);

   //                [stack] CTOR? OBJ CTOR? KEY VAL

   if (!bce_->emit1(op)) {
     //              [stack] CTOR? OBJ CTOR?
     return false;
   }

/js/src/frontend/ObjectEmitter.h

--- c4c9cea546f97dd8b9ed769b2e9344bf1f689ca3/js/src/frontend/ObjectEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/ObjectEmitter.h
@@ -99,17 +99,37 @@ class MOZ_STACK_CLASS PropertyEmitter {
   //    |    +--------------------->| InitHomeObjFor- |----+         |
   //    |                           | PrivateMethod   |    |         |
   //    |                           +-----------------+    |         |
   //    |                                                  |         |
   //    |    +---------------------------------------------+         |
   //    |    |                                                       |
   //    |    | skipInit                                              |
   //    |    +------------------------------------------------------>+
-  //    |                                                            |
+  //    |                                                            ^
+  //    | [private static method]                                    |
+  //    |   prepareForPrivateStaticMethod  +---------------------+   |
+  //    +--------------------------------->| PrivateStaticMethod |-+ |
+  //    |                                  +---------------------+ | |
+  //    |                                                          | |
+  //    |  +-------------------------------------------------------+ |
+  //    |  |                                                         |
+  //    |  +-+-------------------------------------------------+     |
+  //    |    |                                                 |     |
+  //    |    | [method with super                              |     |
+  //    |    | emitInitHomeObject   +---------------------+    v     |
+  //    |    +--------------------->| InitHomeObjFor-     |----+     |
+  //    |                           | PrivateStaticMethod |    |     |
+  //    |                           +---------------------+    |     |
+  //    |                                                      |     |
+  //    |      +-----------------------------------------------+     |
+  //    |      |                                                     |
+  //    |      | emitPrivateStaticMethod                             |
+  //    |      +---------------------------------------------------->+
+  //    |                                                            ^
   //    | [index property/method/accessor]                           |
   //    |   prepareForIndexPropKey  +----------+                     |
   //    +-------------------------->| IndexKey |-+                   |
   //    |                           +----------+ |                   |
   //    |                                        |                   |
   //    |  +-------------------------------------+                   |
   //    |  |                                                         |
   //    |  | prepareForIndexPropValue +------------+                 |
@@ -124,17 +144,17 @@ class MOZ_STACK_CLASS PropertyEmitter {
   //    |      |   emitInitHomeObject +---------------------+     v  |
   //    |      +--------------------->| InitHomeObjForIndex |---->+  |
   //    |                             +---------------------+     |  |
   //    |                                                         |  |
   //    |      +--------------------------------------------------+  |
   //    |      |                                                     |
   //    |      | emitInitIndexOrComputed                             |
   //    |      +---------------------------------------------------->+
-  //    |                                                            |
+  //    |                                                            ^
   //    | [computed property/method/accessor]                        |
   //    |   prepareForComputedPropKey  +-------------+               |
   //    +----------------------------->| ComputedKey |-+             |
   //    |                              +-------------+ |             |
   //    |                                              |             |
   //    |  +-------------------------------------------+             |
   //    |  |                                                         |
   //    |  | prepareForComputedPropValue +---------------+           |
@@ -176,16 +196,22 @@ class MOZ_STACK_CLASS PropertyEmitter {
     InitHomeObj,

     // After calling prepareForPrivateMethod.
     PrivateMethodValue,

     // After calling emitInitHomeObject, from PrivateMethod.
     InitHomeObjForPrivateMethod,

+    // After calling prepareForPrivateStaticMethod.
+    PrivateStaticMethod,
+
+    // After calling emitInitHomeObject, from PrivateStaticMethod.
+    InitHomeObjForPrivateStaticMethod,
+
     // After calling prepareForIndexPropKey.
     IndexKey,

     // prepareForIndexPropValue.
     IndexValue,

     // After calling emitInitHomeObject, from IndexValue.
     InitHomeObjForIndex,
@@ -216,67 +242,67 @@ class MOZ_STACK_CLASS PropertyEmitter {
   explicit PropertyEmitter(BytecodeEmitter* bce);

   // Parameters are the offset in the source code for each character below:
   //
   // { __proto__: protoValue }
   //   ^
   //   |
   //   keyPos
-  [[nodiscard]] bool prepareForProtoValue(
-      const mozilla::Maybe<uint32_t>& keyPos);
+  [[nodiscard]] bool prepareForProtoValue(uint32_t keyPos);
   [[nodiscard]] bool emitMutateProto();

   // { ...obj }
   //   ^
   //   |
   //   spreadPos
-  [[nodiscard]] bool prepareForSpreadOperand(
-      const mozilla::Maybe<uint32_t>& spreadPos);
+  [[nodiscard]] bool prepareForSpreadOperand(uint32_t spreadPos);
   [[nodiscard]] bool emitSpread();

   // { key: value }
   //   ^
   //   |
   //   keyPos
-  [[nodiscard]] bool prepareForPropValue(const mozilla::Maybe<uint32_t>& keyPos,
-                                         Kind kind = Kind::Prototype);
+  [[nodiscard]] bool prepareForPropValue(uint32_t keyPos, Kind kind);

   [[nodiscard]] bool prepareForPrivateMethod();

+  [[nodiscard]] bool prepareForPrivateStaticMethod(uint32_t keyPos);
+
   // { 1: value }
   //   ^
   //   |
   //   keyPos
-  [[nodiscard]] bool prepareForIndexPropKey(
-      const mozilla::Maybe<uint32_t>& keyPos, Kind kind = Kind::Prototype);
+  [[nodiscard]] bool prepareForIndexPropKey(uint32_t keyPos, Kind kind);
   [[nodiscard]] bool prepareForIndexPropValue();

   // { [ key ]: value }
   //   ^
   //   |
   //   keyPos
-  [[nodiscard]] bool prepareForComputedPropKey(
-      const mozilla::Maybe<uint32_t>& keyPos, Kind kind = Kind::Prototype);
+  [[nodiscard]] bool prepareForComputedPropKey(uint32_t keyPos, Kind kind);
   [[nodiscard]] bool prepareForComputedPropValue();

   [[nodiscard]] bool emitInitHomeObject();

   // @param key
   //        Property key
   [[nodiscard]] bool emitInit(AccessorType accessorType,
                               TaggedParserAtomIndex key);

   [[nodiscard]] bool emitInitIndexOrComputed(AccessorType accessorType);

+  [[nodiscard]] bool emitPrivateStaticMethod(AccessorType accessorType);
+
   [[nodiscard]] bool skipInit();

  private:
-  [[nodiscard]] MOZ_ALWAYS_INLINE bool prepareForProp(
-      const mozilla::Maybe<uint32_t>& keyPos, bool isStatic, bool isComputed);
+  [[nodiscard]] MOZ_ALWAYS_INLINE bool prepareForProp(uint32_t keyPos,
+                                                      bool isStatic,
+                                                      bool isComputed);

   // @param op
   //        Opcode for initializing property
   // @param key
   //        Atom of the property if the property key is not computed
   [[nodiscard]] bool emitInit(JSOp op, TaggedParserAtomIndex key);
   [[nodiscard]] bool emitInitIndexOrComputed(JSOp op);

@@ -291,106 +317,106 @@ class MOZ_STACK_CLASS PropertyEmitter {
 //     ObjectEmitter oe(this);
 //     oe.emitObject(0);
 //     oe.emitEnd();
 //
 //   `{ prop: 10 }`
 //     ObjectEmitter oe(this);
 //     oe.emitObject(1);
 //
-//     oe.prepareForPropValue(Some(offset_of_prop));
+//     oe.prepareForPropValue(offset_of_prop);
 //     emit(10);
 //     oe.emitInitProp(atom_of_prop);
 //
 //     oe.emitEnd();
 //
 //   `{ prop: function() {} }`, when property value is anonymous function
 //     ObjectEmitter oe(this);
 //     oe.emitObject(1);
 //
-//     oe.prepareForPropValue(Some(offset_of_prop));
+//     oe.prepareForPropValue(offset_of_prop);
 //     emit(function);
 //     oe.emitInitProp(atom_of_prop);
 //
 //     oe.emitEnd();
 //
 //   `{ get prop() { ... }, set prop(v) { ... } }`
 //     ObjectEmitter oe(this);
 //     oe.emitObject(2);
 //
-//     oe.prepareForPropValue(Some(offset_of_prop));
+//     oe.prepareForPropValue(offset_of_prop);
 //     emit(function_for_getter);
 //     oe.emitInitGetter(atom_of_prop);
 //
-//     oe.prepareForPropValue(Some(offset_of_prop));
+//     oe.prepareForPropValue(offset_of_prop);
 //     emit(function_for_setter);
 //     oe.emitInitSetter(atom_of_prop);
 //
 //     oe.emitEnd();
 //
 //   `{ 1: 10, get 2() { ... }, set 3(v) { ... } }`
 //     ObjectEmitter oe(this);
 //     oe.emitObject(3);
 //
-//     oe.prepareForIndexPropKey(Some(offset_of_prop));
+//     oe.prepareForIndexPropKey(offset_of_prop);
 //     emit(1);
 //     oe.prepareForIndexPropValue();
 //     emit(10);
 //     oe.emitInitIndexedProp();
 //
-//     oe.prepareForIndexPropKey(Some(offset_of_opening_bracket));
+//     oe.prepareForIndexPropKey(offset_of_opening_bracket);
 //     emit(2);
 //     oe.prepareForIndexPropValue();
 //     emit(function_for_getter);
 //     oe.emitInitIndexGetter();
 //
-//     oe.prepareForIndexPropKey(Some(offset_of_opening_bracket));
+//     oe.prepareForIndexPropKey(offset_of_opening_bracket);
 //     emit(3);
 //     oe.prepareForIndexPropValue();
 //     emit(function_for_setter);
 //     oe.emitInitIndexSetter();
 //
 //     oe.emitEnd();
 //
 //   `{ [prop1]: 10, get [prop2]() { ... }, set [prop3](v) { ... } }`
 //     ObjectEmitter oe(this);
 //     oe.emitObject(3);
 //
-//     oe.prepareForComputedPropKey(Some(offset_of_opening_bracket));
+//     oe.prepareForComputedPropKey(offset_of_opening_bracket);
 //     emit(prop1);
 //     oe.prepareForComputedPropValue();
 //     emit(10);
 //     oe.emitInitComputedProp();
 //
-//     oe.prepareForComputedPropKey(Some(offset_of_opening_bracket));
+//     oe.prepareForComputedPropKey(offset_of_opening_bracket);
 //     emit(prop2);
 //     oe.prepareForComputedPropValue();
 //     emit(function_for_getter);
 //     oe.emitInitComputedGetter();
 //
-//     oe.prepareForComputedPropKey(Some(offset_of_opening_bracket));
+//     oe.prepareForComputedPropKey(offset_of_opening_bracket);
 //     emit(prop3);
 //     oe.prepareForComputedPropValue();
 //     emit(function_for_setter);
 //     oe.emitInitComputedSetter();
 //
 //     oe.emitEnd();
 //
 //   `{ __proto__: obj }`
 //     ObjectEmitter oe(this);
 //     oe.emitObject(1);
-//     oe.prepareForProtoValue(Some(offset_of___proto__));
+//     oe.prepareForProtoValue(offset_of___proto__);
 //     emit(obj);
 //     oe.emitMutateProto();
 //     oe.emitEnd();
 //
 //   `{ ...obj }`
 //     ObjectEmitter oe(this);
 //     oe.emitObject(1);
-//     oe.prepareForSpreadOperand(Some(offset_of_triple_dots));
+//     oe.prepareForSpreadOperand(offset_of_triple_dots);
 //     emit(obj);
 //     oe.emitSpread();
 //     oe.emitEnd();
 //
 class MOZ_STACK_CLASS ObjectEmitter : public PropertyEmitter {
  private:
 #ifdef DEBUG
   // The state of this emitter.
@@ -516,51 +542,51 @@ class MOZ_RAII AutoSaveLocalStrictMode {
 //         ce.emitMemberInitializerHomeObject();
 //       }
 //       ce.emitStoreMemberInitializer();
 //     }
 //     ce.emitMemberInitializersEnd();
 //
 //   `m() {}` in class
 //     // after emitInitConstructor
-//     ce.prepareForPropValue(Some(offset_of_m));
+//     ce.prepareForPropValue(offset_of_m);
 //     emit(function_for_m);
 //     ce.emitInitProp(atom_of_m);
 //
 //   `m() { super.f(); }` in class
 //     // after emitInitConstructor
-//     ce.prepareForPropValue(Some(offset_of_m));
+//     ce.prepareForPropValue(offset_of_m);
 //     emit(function_for_m);
 //     ce.emitInitHomeObject();
 //     ce.emitInitProp(atom_of_m);
 //
 //   `async m() { super.f(); }` in class
 //     // after emitInitConstructor
-//     ce.prepareForPropValue(Some(offset_of_m));
+//     ce.prepareForPropValue(offset_of_m);
 //     emit(function_for_m);
 //     ce.emitInitHomeObject();
 //     ce.emitInitProp(atom_of_m);
 //
 //   `get p() { super.f(); }` in class
 //     // after emitInitConstructor
-//     ce.prepareForPropValue(Some(offset_of_p));
+//     ce.prepareForPropValue(offset_of_p);
 //     emit(function_for_p);
 //     ce.emitInitHomeObject();
 //     ce.emitInitGetter(atom_of_m);
 //
 //   `static m() {}` in class
 //     // after emitInitConstructor
-//     ce.prepareForPropValue(Some(offset_of_m),
+//     ce.prepareForPropValue(offset_of_m,
 //                            PropertyEmitter::Kind::Static);
 //     emit(function_for_m);
 //     ce.emitInitProp(atom_of_m);
 //
 //   `static get [p]() { super.f(); }` in class
 //     // after emitInitConstructor
-//     ce.prepareForComputedPropValue(Some(offset_of_m),
+//     ce.prepareForComputedPropValue(offset_of_m,
 //                                    PropertyEmitter::Kind::Static);
 //     emit(p);
 //     ce.prepareForComputedPropValue();
 //     emit(function_for_m);
 //     ce.emitInitHomeObject();
 //     ce.emitInitComputedGetter();
 //
 class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter {

/js/src/frontend/OptionalEmitter.h

--- bfaa95b5e04a36143ef2d3cff446cdda75cb5fab/js/src/frontend/OptionalEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/OptionalEmitter.h
@@ -73,76 +73,76 @@ struct BytecodeEmitter;
 //     CallOrNewEmitter cone(this, JSOp::Call,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     cone.emitNameCallee(print);
 //     cone.emitThis();
 //     oe.emitShortCircuitForCall();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //     oe.emitOptionalJumpTarget(JSOp::Undefined);
 //
 //   `callee.prop?.(arg1, arg2);`
 //     OptionalEmitter oe(this);
 //     CallOrNewEmitter cone(this, JSOp::Call,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     PropOpEmitter& poe = cone.prepareForPropCallee(false);
 //     ... emit `callee.prop` with `poe` here...
 //     cone.emitThis();
 //     oe.emitShortCircuitForCall();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg1);
 //     emit(arg2);
-//     cone.emitEnd(2, Some(offset_of_callee));
+//     cone.emitEnd(2, offset_of_callee);
 //     oe.emitOptionalJumpTarget(JSOp::Undefined);
 //
 //   `callee[key]?.(arg);`
 //     OptionalEmitter oe(this);
 //     CallOrNewEmitter cone(this, JSOp::Call,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     ElemOpEmitter& eoe = cone.prepareForElemCallee(false);
 //     ... emit `callee[key]` with `eoe` here...
 //     cone.emitThis();
 //     oe.emitShortCircuitForCall();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //     oe.emitOptionalJumpTarget(JSOp::Undefined);
 //
 //   `(function() { ... })?.(arg);`
 //     OptionalEmitter oe(this);
 //     CallOrNewEmitter cone(this, JSOp::Call,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     cone.prepareForFunctionCallee();
 //     emit(function);
 //     cone.emitThis();
 //     oe.emitShortCircuitForCall();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //     oe.emitOptionalJumpTarget(JSOp::Undefined);
 //
 //   `(a?b)();`
 //     OptionalEmitter oe(this);
 //     CallOrNewEmitter cone(this, JSOP_CALL,
 //                           CallOrNewEmitter::ArgumentsKind::Other,
 //                           ValueUsage::WantValue);
 //     cone.prepareForFunctionCallee();
 //     emit(optionalChain);
 //     cone.emitThis();
 //     oe.emitOptionalJumpTarget(JSOp::Undefined,
 //                               OptionalEmitter::Kind::Reference);
 //     oe.emitShortCircuitForCall();
 //     cone.prepareForNonSpreadArguments();
 //     emit(arg);
-//     cone.emitEnd(1, Some(offset_of_callee));
+//     cone.emitEnd(1, offset_of_callee);
 //     oe.emitOptionalJumpTarget(JSOp::Undefined);
 //
 class MOZ_RAII OptionalEmitter {
  public:
   OptionalEmitter(BytecodeEmitter* bce, int32_t initialDepth);

  private:
   BytecodeEmitter* bce_;

/js/src/frontend/SwitchEmitter.cpp

--- 673607f3df3da9a5e80268203368416655df0a03/js/src/frontend/SwitchEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/SwitchEmitter.cpp
@@ -20,18 +20,16 @@
 #include "util/BitArray.h"
 #include "vm/BytecodeUtil.h"  // SET_JUMP_OFFSET, JUMP_OFFSET_LEN, SET_RESUMEINDEX
 #include "vm/Opcodes.h"       // JSOp, JSOpLength_TableSwitch
 #include "vm/Runtime.h"       // ReportOutOfMemory

 using namespace js;
 using namespace js::frontend;

-using mozilla::Maybe;
-
 bool SwitchEmitter::TableGenerator::addNumber(int32_t caseValue) {
   if (isInvalid()) {
     return true;
   }

   if (unsigned(caseValue + int(Bit(15))) >= unsigned(Bit(16))) {
     setInvalid();
     return true;
@@ -103,25 +101,23 @@ uint32_t SwitchEmitter::TableGenerator::
 uint32_t SwitchEmitter::TableGenerator::tableLength() const {
   MOZ_ASSERT(finished_);
   MOZ_ASSERT(isValid());
   return tableLength_;
 }

 SwitchEmitter::SwitchEmitter(BytecodeEmitter* bce) : bce_(bce) {}

-bool SwitchEmitter::emitDiscriminant(const Maybe<uint32_t>& switchPos) {
+bool SwitchEmitter::emitDiscriminant(uint32_t switchPos) {
   MOZ_ASSERT(state_ == State::Start);
   switchPos_ = switchPos;

-  if (switchPos_) {
-    // Ensure that the column of the switch statement is set properly.
-    if (!bce_->updateSourceCoordNotes(*switchPos_)) {
-      return false;
-    }
+  // Ensure that the column of the switch statement is set properly.
+  if (!bce_->updateSourceCoordNotes(switchPos_)) {
+    return false;
   }

   state_ = State::Discriminant;
   return true;
 }

 bool SwitchEmitter::emitLexical(LexicalScope::ParserData* bindings) {
   MOZ_ASSERT(state_ == State::Discriminant);

/js/src/frontend/SwitchEmitter.h

--- 1f385759e3f5f8e8070ef7f0442562d74cbb97e8/js/src/frontend/SwitchEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/SwitchEmitter.h
@@ -30,17 +30,17 @@ namespace frontend {
 struct BytecodeEmitter;

 // Class for emitting bytecode for switch-case-default block.
 //
 // Usage: (check for the return value is omitted for simplicity)
 //
 //   `switch (discriminant) { case c1_expr: c1_body; }`
 //     SwitchEmitter se(this);
-//     se.emitDiscriminant(Some(offset_of_switch));
+//     se.emitDiscriminant(offset_of_switch);
 //     emit(discriminant);
 //
 //     se.validateCaseCount(1);
 //     se.emitCond();
 //
 //     se.prepareForCaseValue();
 //     emit(c1_expr);
 //     se.emitCaseJump();
@@ -48,17 +48,17 @@ struct BytecodeEmitter;
 //     se.emitCaseBody();
 //     emit(c1_body);
 //
 //     se.emitEnd();
 //
 //   `switch (discriminant) { case c1_expr: c1_body; case c2_expr: c2_body;
 //                            default: def_body; }`
 //     SwitchEmitter se(this);
-//     se.emitDiscriminant(Some(offset_of_switch));
+//     se.emitDiscriminant(offset_of_switch);
 //     emit(discriminant);
 //
 //     se.validateCaseCount(2);
 //     se.emitCond();
 //
 //     se.prepareForCaseValue();
 //     emit(c1_expr);
 //     se.emitCaseJump();
@@ -83,17 +83,17 @@ struct BytecodeEmitter;
 //     SwitchEmitter::TableGenerator tableGen(this);
 //     tableGen.addNumber(c1_expr_value);
 //     tableGen.addNumber(c2_expr_value);
 //     tableGen.finish(2);
 //
 //     // If `!tableGen.isValid()` here, `emitCond` should be used instead.
 //
 //     SwitchEmitter se(this);
-//     se.emitDiscriminant(Some(offset_of_switch));
+//     se.emitDiscriminant(offset_of_switch);
 //     emit(discriminant);
 //     se.validateCaseCount(2);
 //     se.emitTable(tableGen);
 //
 //     se.emitCaseBody(c1_expr_value, tableGen);
 //     emit(c1_body);
 //
 //     se.emitCaseBody(c2_expr_value, tableGen);
@@ -107,17 +107,17 @@ struct BytecodeEmitter;
 //     SwitchEmitter::TableGenerator tableGen(bce);
 //     tableGen.addNumber(c1_expr_value);
 //     tableGen.addNumber(c2_expr_value);
 //     tableGen.finish(2);
 //
 //     // If `!tableGen.isValid()` here, `emitCond` should be used instead.
 //
 //     SwitchEmitter se(this);
-//     se.emitDiscriminant(Some(offset_of_switch));
+//     se.emitDiscriminant(offset_of_switch);
 //     emit(discriminant);
 //     se.validateCaseCount(2);
 //     se.emitTable(tableGen);
 //
 //     se.emitCaseBody(c1_expr_value, tableGen);
 //     emit(c1_body);
 //
 //     se.emitCaseBody(c2_expr_value, tableGen);
@@ -126,17 +126,17 @@ struct BytecodeEmitter;
 //     se.emitDefaultBody();
 //     emit(def_body);
 //
 //     se.emitEnd();
 //
 //   `switch (discriminant) { case c1_expr: c1_body; }`
 //   in case c1_body contains lexical bindings
 //     SwitchEmitter se(this);
-//     se.emitDiscriminant(Some(offset_of_switch));
+//     se.emitDiscriminant(offset_of_switch);
 //     emit(discriminant);
 //
 //     se.validateCaseCount(1);
 //
 //     se.emitLexical(bindings);
 //
 //     se.emitCond();
 //
@@ -147,17 +147,17 @@ struct BytecodeEmitter;
 //     se.emitCaseBody();
 //     emit(c1_body);
 //
 //     se.emitEnd();
 //
 //   `switch (discriminant) { case c1_expr: c1_body; }`
 //   in case c1_body contains hosted functions
 //     SwitchEmitter se(this);
-//     se.emitDiscriminant(Some(offset_of_switch));
+//     se.emitDiscriminant(offset_of_switch);
 //     emit(discriminant);
 //
 //     se.validateCaseCount(1);
 //
 //     se.emitLexical(bindings);
 //     emit(hosted functions);
 //
 //     se.emitCond();
@@ -321,17 +321,17 @@ class MOZ_STACK_CLASS SwitchEmitter {
   mozilla::Maybe<EmitterScope> emitterScope_;

   // Instantiated while emitting case expression and case/default body.
   mozilla::Maybe<TDZCheckCache> tdzCacheCaseAndBody_;

   // Control for switch.
   mozilla::Maybe<BreakableControl> controlInfo_;

-  mozilla::Maybe<uint32_t> switchPos_;
+  uint32_t switchPos_ = 0;

   // Cond Switch:
   //   Offset of each JSOp::Case.
   // Table Switch:
   //   Offset of each JSOp::JumpTarget for case.
   js::Vector<BytecodeOffset, 32, SystemAllocPolicy> caseOffsets_;

   // The state of this emitter.
@@ -426,20 +426,17 @@ class MOZ_STACK_CLASS SwitchEmitter {
   explicit SwitchEmitter(BytecodeEmitter* bce);

   // `switchPos` is the offset in the source code for the character below:
   //
   //   switch ( cond ) { ... }
   //   ^
   //   |
   //   switchPos
-  //
-  // Can be Nothing() if not available.
-  [[nodiscard]] bool emitDiscriminant(
-      const mozilla::Maybe<uint32_t>& switchPos);
+  [[nodiscard]] bool emitDiscriminant(uint32_t switchPos);

   // `caseCount` should be the number of cases in the switch statement,
   // excluding the default case.
   [[nodiscard]] bool validateCaseCount(uint32_t caseCount);

   // `bindings` is a lexical scope for the entire switch, in case there's
   // let/const effectively directly under case or default blocks.
   [[nodiscard]] bool emitLexical(LexicalScope::ParserData* bindings);

/js/src/frontend/WhileEmitter.cpp

--- a670453eafa37490a13b0e2c86640ba2b7854886/js/src/frontend/WhileEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/WhileEmitter.cpp
@@ -9,46 +9,42 @@
 #include "frontend/BytecodeEmitter.h"
 #include "frontend/SourceNotes.h"
 #include "vm/Opcodes.h"
 #include "vm/StencilEnums.h"  // TryNoteKind

 using namespace js;
 using namespace js::frontend;

-using mozilla::Maybe;
-
 WhileEmitter::WhileEmitter(BytecodeEmitter* bce) : bce_(bce) {}

-bool WhileEmitter::emitCond(const Maybe<uint32_t>& whilePos,
-                            const Maybe<uint32_t>& condPos,
-                            const Maybe<uint32_t>& endPos) {
+bool WhileEmitter::emitCond(uint32_t whilePos, uint32_t condPos,
+                            uint32_t endPos) {
   MOZ_ASSERT(state_ == State::Start);

   // If we have a single-line while, like "while (x) ;", we want to emit the
   // line note before the loop, so that the debugger sees a single entry point.
   // This way, if there is a breakpoint on the line, it will only fire once; and
   // "next"ing will skip the whole loop. However, for the multi-line case we
   // want to emit the line note for the JSOp::LoopHead, so that "cont" stops on
   // each iteration -- but without a stop before the first iteration.
-  if (whilePos && endPos &&
-      bce_->parser->errorReporter().lineAt(*whilePos) ==
-          bce_->parser->errorReporter().lineAt(*endPos)) {
-    if (!bce_->updateSourceCoordNotes(*whilePos)) {
+  if (bce_->parser->errorReporter().lineAt(whilePos) ==
+      bce_->parser->errorReporter().lineAt(endPos)) {
+    if (!bce_->updateSourceCoordNotes(whilePos)) {
       return false;
     }
     // Emit a Nop to ensure the source position is not part of the loop.
     if (!bce_->emit1(JSOp::Nop)) {
       return false;
     }
   }

   loopInfo_.emplace(bce_, StatementKind::WhileLoop);

-  if (!loopInfo_->emitLoopHead(bce_, condPos)) {
+  if (!loopInfo_->emitLoopHead(bce_, mozilla::Some(condPos))) {
     return false;
   }

 #ifdef DEBUG
   state_ = State::Cond;
 #endif
   return true;
 }

/js/src/frontend/WhileEmitter.h

--- bfaa95b5e04a36143ef2d3cff446cdda75cb5fab/js/src/frontend/WhileEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/WhileEmitter.h
@@ -21,19 +21,19 @@ namespace frontend {
 struct BytecodeEmitter;

 // Class for emitting bytecode for while loop.
 //
 // Usage: (check for the return value is omitted for simplicity)
 //
 //   `while (cond) body`
 //     WhileEmitter wh(this);
-//     wh.emitCond(Some(offset_of_while),
-//                 Some(offset_of_body),
-//                 Some(offset_of_end));
+//     wh.emitCond(offset_of_while,
+//                 offset_of_body,
+//                 offset_of_end);
 //     emit(cond);
 //     wh.emitBody();
 //     emit(body);
 //     wh.emitEnd();
 //
 class MOZ_STACK_CLASS WhileEmitter {
   BytecodeEmitter* bce_;

@@ -73,21 +73,18 @@ class MOZ_STACK_CLASS WhileEmitter {
   //   while ( x < 20 ) { ... }
   //   ^       ^              ^
   //   |       |              |
   //   |       |              endPos_
   //   |       |
   //   |       condPos_
   //   |
   //   whilePos_
-  //
-  // Can be Nothing() if not available.
-  [[nodiscard]] bool emitCond(const mozilla::Maybe<uint32_t>& whilePos,
-                              const mozilla::Maybe<uint32_t>& condPos,
-                              const mozilla::Maybe<uint32_t>& endPos);
+  [[nodiscard]] bool emitCond(uint32_t whilePos, uint32_t condPos,
+                              uint32_t endPos);
   [[nodiscard]] bool emitBody();
   [[nodiscard]] bool emitEnd();
 };

 } /* namespace frontend */
 } /* namespace js */

 #endif /* frontend_WhileEmitter_h */

/js/src/vm/BytecodeUtil.cpp

--- 84ccc63222c2237308430c9491ffb2d274b7977e/js/src/vm/BytecodeUtil.cpp
+++ 5e6d1848ce620a905a1d5de23ca5b9e4e0eaa2af/js/src/vm/BytecodeUtil.cpp
@@ -2134,16 +2134,19 @@ bool ExpressionDecompiler::decompilePC(j

       case JSOp::AsyncAwait:
       case JSOp::AsyncResolve:
         return write("PROMISE");

       case JSOp::CheckPrivateField:
         return write("HasPrivateField");

+      case JSOp::NewPrivateName:
+        return write("PRIVATENAME");
+
       case JSOp::CheckReturn:
         return write("RVAL");

       default:
         break;
     }
     return write("<unknown>");
   }

/js/src/vm/BytecodeUtil.h

--- c85486b5c6ba261d009b92030646b45f3bec1bcb/js/src/vm/BytecodeUtil.h
+++ 0d2d24449e42955da48a8b4ebf3e6802f6d55ef9/js/src/vm/BytecodeUtil.h
@@ -573,16 +573,17 @@ inline void GetCheckPrivateFieldOperands
   *throwCondition = static_cast<ThrowCondition>(throwConditionByte);
   *throwKind = static_cast<ThrowMsgKind>(throwKindByte);

   MOZ_ASSERT(*throwCondition == ThrowCondition::ThrowHas ||
              *throwCondition == ThrowCondition::ThrowHasNot ||
              *throwCondition == ThrowCondition::OnlyCheckRhs);

   MOZ_ASSERT(*throwKind == ThrowMsgKind::PrivateDoubleInit ||
+             *throwKind == ThrowMsgKind::PrivateBrandDoubleInit ||
              *throwKind == ThrowMsgKind::MissingPrivateOnGet ||
              *throwKind == ThrowMsgKind::MissingPrivateOnSet);
 }

 // Return true iff the combination of the ThrowCondition and hasOwn result
 // will throw an exception.
 static inline bool CheckPrivateFieldWillThrow(ThrowCondition condition,
                                               bool hasOwn) {

/js/src/vm/Opcodes.h

--- 84ccc63222c2237308430c9491ffb2d274b7977e/js/src/vm/Opcodes.h
+++ 5e6d1848ce620a905a1d5de23ca5b9e4e0eaa2af/js/src/vm/Opcodes.h
@@ -1157,24 +1157,32 @@
      *
      * Two arguments:
      *   - throwCondition: One of the ThrowConditions defined in
      *     ThrowMsgKind.h. Determines why (or if) this op will throw.
      *   - msgKind: One of the ThrowMsgKinds defined in ThrowMsgKind.h, which
      *     maps to one of the messages in js.msg. Note: It's not possible to
      *     pass arguments to the message at the moment.
      *
-     *   Category: Control flow
      *   Category: Objects
      *   Type: Accessing properties
      *   Operands: ThrowCondition throwCondition, ThrowMsgKind msgKind
      *   Stack: obj, key => obj, key, (obj.hasOwnProperty(id))
      */ \
     MACRO(CheckPrivateField, check_private_field, NULL, 3, 2, 3, JOF_TWO_UINT8|JOF_CHECKSTRICT|JOF_IC) \
     /*
+     * Push a new private name.
+     *
+     *   Category: Objects
+     *   Type: Accessing properties
+     *   Operands: uint32_t nameIndex
+     *   Stack: => private_name
+     */ \
+    MACRO(NewPrivateName, new_private_name, NULL, 5, 0, 1, JOF_ATOM) \
+    /*
      * Push the SuperBase of the method `callee`. The SuperBase is
      * `callee.[[HomeObject]].[[GetPrototypeOf]]()`, the object where `super`
      * property lookups should begin.
      *
      * `callee` must be a function that has a HomeObject that's an object,
      * typically produced by `JSOp::Callee` or `JSOp::EnvCallee`.
      *
      * Implements: [GetSuperBase][1], except that instead of the environment,
@@ -3509,17 +3517,16 @@

 // clang-format on

 /*
  * In certain circumstances it may be useful to "pad out" the opcode space to
  * a power of two.  Use this macro to do so.
  */
 #define FOR_EACH_TRAILING_UNUSED_OPCODE(MACRO) \
-  MACRO(227)                                   \
   MACRO(228)                                   \
   MACRO(229)                                   \
   MACRO(230)                                   \
   MACRO(231)                                   \
   MACRO(232)                                   \
   MACRO(233)                                   \
   MACRO(234)                                   \
   MACRO(235)                                   \

/js/src/vm/SharedStencil.h

--- b4978b94e6054328409c38ba4c365c1132fef20c/js/src/vm/SharedStencil.h
+++ efefbf74d3fc868e103a2a1ab22568c05dc92a46/js/src/vm/SharedStencil.h
@@ -510,17 +510,20 @@ class alignas(uint32_t) ImmutableScriptD

   static js::UniquePtr<ImmutableScriptData> new_(
       JSContext* cx, uint32_t codeLength, uint32_t noteLength,
       uint32_t numResumeOffsets, uint32_t numScopeNotes, uint32_t numTryNotes);

   static js::UniquePtr<ImmutableScriptData> new_(JSContext* cx,
                                                  uint32_t totalSize);

-  uint32_t computedSize();
+  // Validate internal offsets of the data structure seems reasonable. This is
+  // for diagnositic purposes only to detect severe corruption. This is not a
+  // security boundary!
+  bool validateLayout(uint32_t expectedSize);

  private:
   static mozilla::CheckedInt<uint32_t> sizeFor(uint32_t codeLength,
                                                uint32_t noteLength,
                                                uint32_t numResumeOffsets,
                                                uint32_t numScopeNotes,
                                                uint32_t numTryNotes);
arai-a commented 3 years ago

handled by https://github.com/mozilla-spidermonkey/jsparagus/pull/643 https://bugzilla.mozilla.org/show_bug.cgi?id=1725086