1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 /* JS bytecode generation. */
8 
9 #ifndef frontend_BytecodeEmitter_h
10 #define frontend_BytecodeEmitter_h
11 
12 #include "mozilla/Assertions.h"  // MOZ_ASSERT
13 #include "mozilla/Attributes.h"  // MOZ_STACK_CLASS, MOZ_ALWAYS_INLINE, MOZ_NEVER_INLINE, MOZ_RAII
14 #include "mozilla/Maybe.h"   // mozilla::Maybe, mozilla::Some
15 #include "mozilla/Span.h"    // mozilla::Span
16 #include "mozilla/Vector.h"  // mozilla::Vector
17 
18 #include <functional>  // std::function
19 #include <stddef.h>    // ptrdiff_t
20 #include <stdint.h>    // uint16_t, uint32_t
21 
22 #include "jsapi.h"  // CompletionKind
23 
24 #include "frontend/AbstractScopePtr.h"           // ScopeIndex
25 #include "frontend/BCEParserHandle.h"            // BCEParserHandle
26 #include "frontend/BytecodeControlStructures.h"  // NestableControl
27 #include "frontend/BytecodeOffset.h"             // BytecodeOffset
28 #include "frontend/BytecodeSection.h"  // BytecodeSection, PerScriptData, CGScopeList
29 #include "frontend/DestructuringFlavor.h"  // DestructuringFlavor
30 #include "frontend/EitherParser.h"         // EitherParser
31 #include "frontend/ErrorReporter.h"        // ErrorReporter
32 #include "frontend/FullParseHandler.h"     // FullParseHandler
33 #include "frontend/IteratorKind.h"         // IteratorKind
34 #include "frontend/JumpList.h"             // JumpList, JumpTarget
35 #include "frontend/NameAnalysisTypes.h"    // NameLocation
36 #include "frontend/NameCollections.h"      // AtomIndexMap
37 #include "frontend/ParseNode.h"            // ParseNode and subclasses
38 #include "frontend/Parser.h"               // Parser, PropListType
39 #include "frontend/ParserAtom.h"           // TaggedParserAtomIndex
40 #include "frontend/PrivateOpEmitter.h"     // PrivateOpEmitter
41 #include "frontend/ScriptIndex.h"          // ScriptIndex
42 #include "frontend/SharedContext.h"        // SharedContext, TopLevelFunction
43 #include "frontend/SourceNotes.h"          // SrcNoteType
44 #include "frontend/TokenStream.h"          // TokenPos
45 #include "frontend/ValueUsage.h"           // ValueUsage
46 #include "js/RootingAPI.h"                 // JS::Rooted, JS::Handle
47 #include "js/TypeDecls.h"                  // jsbytecode
48 #include "vm/BuiltinObjectKind.h"          // BuiltinObjectKind
49 #include "vm/BytecodeUtil.h"               // JSOp
50 #include "vm/CheckIsObjectKind.h"          // CheckIsObjectKind
51 #include "vm/FunctionPrefixKind.h"         // FunctionPrefixKind
52 #include "vm/GeneratorResumeKind.h"        // GeneratorResumeKind
53 #include "vm/JSFunction.h"                 // JSFunction
54 #include "vm/JSScript.h"       // JSScript, BaseScript, MemberInitializers
55 #include "vm/Runtime.h"        // ReportOutOfMemory
56 #include "vm/SharedStencil.h"  // GCThingIndex
57 #include "vm/StencilEnums.h"   // TryNoteKind
58 #include "vm/StringType.h"     // JSAtom
59 #include "vm/ThrowMsgKind.h"   // ThrowMsgKind, ThrowCondition
60 
61 namespace js {
62 namespace frontend {
63 
64 class CallOrNewEmitter;
65 class ClassEmitter;
66 class ElemOpEmitter;
67 class EmitterScope;
68 class NestableControl;
69 class PropertyEmitter;
70 class PropOpEmitter;
71 class OptionalEmitter;
72 class TDZCheckCache;
73 class TryEmitter;
74 class ScriptStencil;
75 
76 enum class ValueIsOnStack { Yes, No };
77 
78 // [SMDOC] Bytecode emission
79 //
80 // Bytecode emitter class and helper classes for generating bytecode and related
81 // stencil data from AST generated by JS parser.
82 //
83 //
84 // BytecodeEmitter
85 // ---------------
86 //
87 // BytecodeEmitter receives an AST, and utilizes helper classes to generate the
88 // bytecode sequence, and related stencil data.
89 //
90 // BytecodeEmitter can be nested, in order to emit inner non-lazy function
91 // scripts.
92 //
93 //
94 // Bytecode structures
95 // -------------------
96 //
97 // While bytecode is being emitted, it is separated into 2 parts, the prologue
98 // and the main part.  The prologue part contains instantiation of the declared
99 // variables, functions, and special names in function.  The main part contains
100 // the remaining part of the bytecode.
101 //
102 // The generated bytecode is stored into the following 2 classes, before
103 // converting them into stencil data (See ImmutableScriptData and
104 // BytecodeEmitter::createImmutableScriptData):
105 //
106 //   * BytecodeSection
107 //   * PerScriptData
108 //
109 // BytecodeSection stores the bytecode sequence and data directly associated
110 // with opcode or index inside the bytecode sequence.
111 //
112 // PerScriptData contains data referred from the bytecode, that is mostly the
113 // list of GC things.
114 //
115 //
116 // Bindings
117 // --------
118 //
119 // # Scope and bindings
120 //
121 // When emitting AST node that's associated with a given scope, EmitterScope is
122 // allocated to store/cache the bindings information.
123 //
124 // This information is used when emitting an opcode that accesses bindings, to
125 // determine where the binding is stored, and how the binding should be
126 // accessed, including which opcode to use and what operand to use for it.
127 //
128 //
129 // # Temporal Dead Zone (TDZ) check cache
130 //
131 // The spec requires TDZ check for all lexical variable access, but emitting
132 // TDZ check for all operation increases the bytecode size and affects the
133 // performance.  TDZCheckCache is a cache to optimize away unnecessary TDZ check
134 // operations.
135 //
136 // See comments for TDZCheckCache for more details.
137 //
138 //
139 // Control structures
140 // ------------------
141 //
142 // # Jump list
143 //
144 // When emitting jump-related bytecode (if-else, break/continue, try-catch),
145 // forward jump is tracked by JumpList class, in order to patch the jump
146 // after the jump target is emitted.
147 //
148 // See the comment above JumpList class for mode details.
149 //
150 //
151 // # Loop and label
152 //
153 // Control structure related to break/continue is handled by NestableControl and
154 // its subclasses.  Those classes handle jump with labelled and un-labelled
155 // break/continue, stack balancing around them, TDZ check cache for the
156 // loop's basic block, and association between the control and the scope.
157 //
158 //
159 // Emitter helpers
160 // ---------------
161 //
162 // Bytecode sequence or structure specific to certain syntax (e.g. if, for, try)
163 // are handled by emitter helper classes.
164 //
165 // Each emitter helper is defined in *Emitter.{cpp,h} in this directory.
166 //
167 // Emitter helpers should meet the following requirements:
168 //   * helper classes should be ParseNode-agnostic
169 //   * helper classes shouldn't contain `JS::Rooted` field, given they can be
170 //     held in `mozilla::Maybe` in the consumer or other helper classes
171 //   * instantiation (ctor/dtor) of the emitter helper class shouldn't
172 //     modify BytecodeEmitter, except for nestable controls
173 //   * instantiation (ctor/dtor) of the emitter helper class shouldn't
174 //     read BytecodeEmitter field that can change before the first method call.
175 //     Such data should be explicitly passed as parameter, or be accessed inside
176 //     the method
177 //   * methods that emits bytecode should be named `emit*` or `prepareFor*`
178 //   * methods and their names shouldn't require the consumer knowing the
179 //     details of the bytecode sequence/structure that the helper emits
180 //     * implicit branch or scope/control handling should be hidden from the
181 //       consumer
182 //     * If there are multiple operations between bytecode that the consumer
183 //       emits, they should be wrapped into single `emit*` or `prepareFor*`
184 //       method
185 //     e.g.
186 //       // Bad!
187 //       helper.emitJumpAroundA();
188 //       helper.allocateScopeForA();
189 //       ... // emit bytecode for A here
190 //       helper.deallocateScopeForA();
191 //       helper.emitJumpAroundB();
192 //       helper.allocateScopeForB();
193 //       ... // emit bytecode for B here
194 //       helper.deallocateScopeForB();
195 //       helper.emitJumpTarget();
196 //
197 //       // Good!
198 //       helper.prepareForA();
199 //       ... // emit bytecode for A here
200 //       helper.prepareForB();
201 //       ... // emit bytecode for B here
202 //       helper.emitEnd();
203 //   * helper classes should track state transition and assert it in each
204 //     method call, to avoid misuse
205 //   * parameters related to source code offset should use `mozilla::Maybe`,
206 //     to support the case that there's no position information
207 //   * it's recommended to defer receiving parameter until the parameter value
208 //     is actually used in the method, instead of receiving and storing them
209 //     into instance fields
210 //
211 // See comment block above each helper class for more details and example usage.
212 
213 struct MOZ_STACK_CLASS BytecodeEmitter {
214   // Context shared between parsing and bytecode generation.
215   SharedContext* const sc = nullptr;
216 
217   JSContext* const cx = nullptr;
218 
219   // Enclosing function or global context.
220   BytecodeEmitter* const parent = nullptr;
221 
222   BytecodeSection bytecodeSection_;
223 
224  public:
bytecodeSectionBytecodeEmitter225   BytecodeSection& bytecodeSection() { return bytecodeSection_; }
bytecodeSectionBytecodeEmitter226   const BytecodeSection& bytecodeSection() const { return bytecodeSection_; }
227 
228  private:
229   PerScriptData perScriptData_;
230 
231  public:
perScriptDataBytecodeEmitter232   PerScriptData& perScriptData() { return perScriptData_; }
perScriptDataBytecodeEmitter233   const PerScriptData& perScriptData() const { return perScriptData_; }
234 
235  private:
236   // switchToMain sets this to the bytecode offset of the main section.
237   mozilla::Maybe<uint32_t> mainOffset_ = {};
238 
239  public:
240   // Private storage for parser wrapper. DO NOT REFERENCE INTERNALLY. May not be
241   // initialized. Use |parser| instead.
242   mozilla::Maybe<EitherParser> ep_ = {};
243   BCEParserHandle* parser = nullptr;
244 
245   CompilationState& compilationState;
246 
247   uint32_t maxFixedSlots = 0; /* maximum number of fixed frame slots so far */
248 
249   // Index into scopeList of the body scope.
250   GCThingIndex bodyScopeIndex = ScopeNote::NoScopeIndex;
251 
252   EmitterScope* varEmitterScope = nullptr;
253   NestableControl* innermostNestableControl = nullptr;
254   EmitterScope* innermostEmitterScope_ = nullptr;
255   TDZCheckCache* innermostTDZCheckCache = nullptr;
256 
257   // When compiling in self-hosted mode, we have special intrinsics that act as
258   // decorators for exported functions. To keeps things simple, we only allow
259   // these to target the last top-level function emitted. This field tracks that
260   // function.
261   FunctionBox* prevSelfHostedTopLevelFunction = nullptr;
262 
263 #ifdef DEBUG
264   bool unstableEmitterScope = false;
265 
266   friend class AutoCheckUnstableEmitterScope;
267 #endif
268 
parserAtomsBytecodeEmitter269   ParserAtomsTable& parserAtoms() { return compilationState.parserAtoms; }
parserAtomsBytecodeEmitter270   const ParserAtomsTable& parserAtoms() const {
271     return compilationState.parserAtoms;
272   }
273 
innermostEmitterScopeBytecodeEmitter274   EmitterScope* innermostEmitterScope() const {
275     MOZ_ASSERT(!unstableEmitterScope);
276     return innermostEmitterScopeNoCheck();
277   }
innermostEmitterScopeNoCheckBytecodeEmitter278   EmitterScope* innermostEmitterScopeNoCheck() const {
279     return innermostEmitterScope_;
280   }
281 
282   // When parsing internal code such as self-hosted functions or synthetic
283   // class constructors, we do not emit breakpoint and srcnote data since there
284   // is no direcly corresponding user-visible sources.
285   const bool suppressBreakpointsAndSourceNotes = false;
286 
287   // Script contains finally block.
288   bool hasTryFinally = false;
289 
290   enum EmitterMode {
291     Normal,
292 
293     // Emit JSOp::GetIntrinsic instead of JSOp::GetName and assert that
294     // JSOp::GetName and JSOp::*GName don't ever get emitted. See the comment
295     // for the field |selfHostingMode| in Parser.h for details.
296     SelfHosting,
297 
298     // Check the static scope chain of the root function for resolving free
299     // variable accesses in the script.
300     LazyFunction
301   };
302 
303   const EmitterMode emitterMode = Normal;
304 
305   mozilla::Maybe<uint32_t> scriptStartOffset = {};
306 
307   // The end location of a function body that is being emitted.
308   mozilla::Maybe<uint32_t> functionBodyEndPos = {};
309 
310   /*
311    * Note that BytecodeEmitters are magic: they own the arena "top-of-stack"
312    * space above their tempMark points. This means that you cannot alloc from
313    * tempLifoAlloc and save the pointer beyond the next BytecodeEmitter
314    * destruction.
315    */
316  private:
317   // Internal constructor, for delegation use only.
318   BytecodeEmitter(BytecodeEmitter* parent, SharedContext* sc,
319                   CompilationState& compilationState, EmitterMode emitterMode);
320 
321   void initFromBodyPosition(TokenPos bodyPosition);
322 
323   /*
324    * Helper for reporting that we have insufficient args.  pluralizer
325    * should be "s" if requiredArgs is anything other than "1" and ""
326    * if requiredArgs is "1".
327    */
328   void reportNeedMoreArgsError(ParseNode* pn, const char* errorName,
329                                const char* requiredArgs, const char* pluralizer,
330                                const ListNode* argsList);
331 
332  public:
333   BytecodeEmitter(BytecodeEmitter* parent, BCEParserHandle* handle,
334                   SharedContext* sc, CompilationState& compilationState,
335                   EmitterMode emitterMode = Normal);
336 
337   BytecodeEmitter(BytecodeEmitter* parent, const EitherParser& parser,
338                   SharedContext* sc, CompilationState& compilationState,
339                   EmitterMode emitterMode = Normal);
340 
341   template <typename Unit>
342   BytecodeEmitter(BytecodeEmitter* parent,
343                   Parser<FullParseHandler, Unit>* parser, SharedContext* sc,
344                   CompilationState& compilationState,
345                   EmitterMode emitterMode = Normal)
BytecodeEmitterBytecodeEmitter346       : BytecodeEmitter(parent, EitherParser(parser), sc, compilationState,
347                         emitterMode) {}
348 
349   [[nodiscard]] bool init();
350   [[nodiscard]] bool init(TokenPos bodyPosition);
351 
352   template <typename T>
353   T* findInnermostNestableControl() const;
354 
355   template <typename T, typename Predicate /* (T*) -> bool */>
356   T* findInnermostNestableControl(Predicate predicate) const;
357 
358   NameLocation lookupName(TaggedParserAtomIndex name);
359 
360   // See EmitterScope::lookupPrivate for details around brandLoc
361   bool lookupPrivate(TaggedParserAtomIndex name, NameLocation& loc,
362                      mozilla::Maybe<NameLocation>& brandLoc);
363 
364   // To implement Annex B and the formal parameter defaults scope semantics
365   // requires accessing names that would otherwise be shadowed. This method
366   // returns the access location of a name that is known to be bound in a
367   // target scope.
368   mozilla::Maybe<NameLocation> locationOfNameBoundInScope(
369       TaggedParserAtomIndex name, EmitterScope* target);
370 
371   // Get the location of a name known to be bound in a given scope,
372   // starting at the source scope.
373   template <typename T>
374   mozilla::Maybe<NameLocation> locationOfNameBoundInScopeType(
375       TaggedParserAtomIndex name, EmitterScope* source);
376 
377   // Get the location of a name known to be bound in the function scope,
378   // starting at the source scope.
locationOfNameBoundInFunctionScopeBytecodeEmitter379   mozilla::Maybe<NameLocation> locationOfNameBoundInFunctionScope(
380       TaggedParserAtomIndex name) {
381     return locationOfNameBoundInScopeType<FunctionScope>(
382         name, innermostEmitterScope());
383   }
384 
setVarEmitterScopeBytecodeEmitter385   void setVarEmitterScope(EmitterScope* emitterScope) {
386     MOZ_ASSERT(emitterScope);
387     MOZ_ASSERT(!varEmitterScope);
388     varEmitterScope = emitterScope;
389   }
390 
outermostScopeBytecodeEmitter391   AbstractScopePtr outermostScope() const {
392     return perScriptData().gcThingList().firstScope();
393   }
394   AbstractScopePtr innermostScope() const;
395   ScopeIndex innermostScopeIndex() const;
396 
makeAtomIndexBytecodeEmitter397   [[nodiscard]] MOZ_ALWAYS_INLINE bool makeAtomIndex(TaggedParserAtomIndex atom,
398                                                      GCThingIndex* indexp) {
399     MOZ_ASSERT(perScriptData().atomIndices());
400     AtomIndexMap::AddPtr p = perScriptData().atomIndices()->lookupForAdd(atom);
401     if (p) {
402       *indexp = GCThingIndex(p->value());
403       return true;
404     }
405 
406     GCThingIndex index;
407     if (!perScriptData().gcThingList().append(atom, &index)) {
408       return false;
409     }
410 
411     // `atomIndices()` uses uint32_t instead of GCThingIndex, because
412     // GCThingIndex isn't trivial type.
413     if (!perScriptData().atomIndices()->add(p, atom, index.index)) {
414       ReportOutOfMemory(cx);
415       return false;
416     }
417 
418     *indexp = index;
419     return true;
420   }
421 
422   bool isInLoop();
423   [[nodiscard]] bool checkSingletonContext();
424 
425   bool needsImplicitThis();
426 
427   size_t countThisEnvironmentHops();
428   [[nodiscard]] bool emitThisEnvironmentCallee();
429   [[nodiscard]] bool emitSuperBase();
430 
mainOffsetBytecodeEmitter431   uint32_t mainOffset() const { return *mainOffset_; }
432 
inPrologueBytecodeEmitter433   bool inPrologue() const { return mainOffset_.isNothing(); }
434 
switchToMainBytecodeEmitter435   void switchToMain() {
436     MOZ_ASSERT(inPrologue());
437     mainOffset_.emplace(bytecodeSection().code().length());
438   }
439 
setFunctionBodyEndPosBytecodeEmitter440   void setFunctionBodyEndPos(uint32_t pos) {
441     functionBodyEndPos = mozilla::Some(pos);
442   }
443 
setScriptStartOffsetIfUnsetBytecodeEmitter444   void setScriptStartOffsetIfUnset(uint32_t pos) {
445     if (scriptStartOffset.isNothing()) {
446       scriptStartOffset = mozilla::Some(pos);
447     }
448   }
449 
450   void reportError(ParseNode* pn, unsigned errorNumber, ...);
451   void reportError(const mozilla::Maybe<uint32_t>& maybeOffset,
452                    unsigned errorNumber, ...);
453 
454   // Fill in a ScriptStencil using this BCE data.
455   bool intoScriptStencil(ScriptIndex scriptIndex);
456 
457   // If pn contains a useful expression, return true with *answer set to true.
458   // If pn contains a useless expression, return true with *answer set to
459   // false. Return false on error.
460   //
461   // The caller should initialize *answer to false and invoke this function on
462   // an expression statement or similar subtree to decide whether the tree
463   // could produce code that has any side effects.  For an expression
464   // statement, we define useless code as code with no side effects, because
465   // the main effect, the value left on the stack after the code executes,
466   // will be discarded by a pop bytecode.
467   [[nodiscard]] bool checkSideEffects(ParseNode* pn, bool* answer);
468 
469 #ifdef DEBUG
470   [[nodiscard]] bool checkStrictOrSloppy(JSOp op);
471 #endif
472 
473   // Add TryNote to the tryNoteList array. The start and end offset are
474   // relative to current section.
475   [[nodiscard]] bool addTryNote(TryNoteKind kind, uint32_t stackDepth,
476                                 BytecodeOffset start, BytecodeOffset end);
477 
478   // Indicates the emitter should not generate location or debugger source
479   // notes. This lets us avoid generating notes for non-user code.
skipLocationSrcNotesBytecodeEmitter480   bool skipLocationSrcNotes() const {
481     return inPrologue() || suppressBreakpointsAndSourceNotes;
482   }
skipBreakpointSrcNotesBytecodeEmitter483   bool skipBreakpointSrcNotes() const {
484     return inPrologue() || suppressBreakpointsAndSourceNotes;
485   }
486 
487   // Append a new source note of the given type (and therefore size) to the
488   // notes dynamic array, updating noteCount. Return the new note's index
489   // within the array pointed at by current->notes as outparam.
490   [[nodiscard]] bool newSrcNote(SrcNoteType type, unsigned* indexp = nullptr);
491   [[nodiscard]] bool newSrcNote2(SrcNoteType type, ptrdiff_t operand,
492                                  unsigned* indexp = nullptr);
493 
494   [[nodiscard]] bool newSrcNoteOperand(ptrdiff_t operand);
495 
496   // Control whether emitTree emits a line number note.
497   enum EmitLineNumberNote { EMIT_LINENOTE, SUPPRESS_LINENOTE };
498 
499   // Emit code for the tree rooted at pn.
500   [[nodiscard]] bool emitTree(ParseNode* pn,
501                               ValueUsage valueUsage = ValueUsage::WantValue,
502                               EmitLineNumberNote emitLineNote = EMIT_LINENOTE);
503 
504   [[nodiscard]] bool emitOptionalTree(
505       ParseNode* pn, OptionalEmitter& oe,
506       ValueUsage valueUsage = ValueUsage::WantValue);
507 
508   [[nodiscard]] bool emitDeclarationInstantiation(ParseNode* body);
509 
510   // Emit global, eval, or module code for tree rooted at body. Always
511   // encompasses the entire source.
512   [[nodiscard]] bool emitScript(ParseNode* body);
513 
514   // Calculate the `nslots` value for BCEScriptStencil constructor parameter.
515   // Fails if it overflows.
516   [[nodiscard]] bool getNslots(uint32_t* nslots);
517 
518   // Emit function code for the tree rooted at body.
519   [[nodiscard]] bool emitFunctionScript(FunctionNode* funNode);
520 
521   [[nodiscard]] bool markStepBreakpoint();
522   [[nodiscard]] bool markSimpleBreakpoint();
523   [[nodiscard]] bool updateLineNumberNotes(uint32_t offset);
524   [[nodiscard]] bool updateSourceCoordNotes(uint32_t offset);
525 
526   JSOp strictifySetNameOp(JSOp op);
527 
528   [[nodiscard]] bool emitCheck(JSOp op, ptrdiff_t delta,
529                                BytecodeOffset* offset);
530 
531   // Emit one bytecode.
532   [[nodiscard]] bool emit1(JSOp op);
533 
534   // Emit two bytecodes, an opcode (op) with a byte of immediate operand
535   // (op1).
536   [[nodiscard]] bool emit2(JSOp op, uint8_t op1);
537 
538   // Emit three bytecodes, an opcode with two bytes of immediate operands.
539   [[nodiscard]] bool emit3(JSOp op, jsbytecode op1, jsbytecode op2);
540 
541   // Helper to duplicate one or more stack values. |slotFromTop| is the value's
542   // depth on the JS stack, as measured from the top. |count| is the number of
543   // values to duplicate, in theiro original order.
544   [[nodiscard]] bool emitDupAt(unsigned slotFromTop, unsigned count = 1);
545 
546   // Helper to emit JSOp::Pop or JSOp::PopN.
547   [[nodiscard]] bool emitPopN(unsigned n);
548 
549   // Helper to emit JSOp::Swap or JSOp::Pick.
550   [[nodiscard]] bool emitPickN(uint8_t n);
551 
552   // Helper to emit JSOp::Swap or JSOp::Unpick.
553   [[nodiscard]] bool emitUnpickN(uint8_t n);
554 
555   // Helper to emit JSOp::CheckIsObj.
556   [[nodiscard]] bool emitCheckIsObj(CheckIsObjectKind kind);
557 
558   // Helper to emit JSOp::BuiltinObject.
559   [[nodiscard]] bool emitBuiltinObject(BuiltinObjectKind kind);
560 
561   // Push whether the value atop of the stack is non-undefined and non-null.
562   [[nodiscard]] bool emitPushNotUndefinedOrNull();
563 
564   // Emit a bytecode followed by an uint16 immediate operand stored in
565   // big-endian order.
566   [[nodiscard]] bool emitUint16Operand(JSOp op, uint32_t operand);
567 
568   // Emit a bytecode followed by an uint32 immediate operand.
569   [[nodiscard]] bool emitUint32Operand(JSOp op, uint32_t operand);
570 
571   // Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand.
572   [[nodiscard]] bool emitN(JSOp op, size_t extra,
573                            BytecodeOffset* offset = nullptr);
574 
575   [[nodiscard]] bool emitDouble(double dval);
576   [[nodiscard]] bool emitNumberOp(double dval);
577 
578   [[nodiscard]] bool emitBigIntOp(BigIntLiteral* bigint);
579 
580   [[nodiscard]] bool emitThisLiteral(ThisLiteral* pn);
581   [[nodiscard]] bool emitGetFunctionThis(NameNode* thisName);
582   [[nodiscard]] bool emitGetFunctionThis(
583       const mozilla::Maybe<uint32_t>& offset);
584   [[nodiscard]] bool emitGetThisForSuperBase(UnaryNode* superBase);
585   [[nodiscard]] bool emitSetThis(BinaryNode* setThisNode);
586   [[nodiscard]] bool emitCheckDerivedClassConstructorReturn();
587 
588   // Handle jump opcodes and jump targets.
589   [[nodiscard]] bool emitJumpTargetOp(JSOp op, BytecodeOffset* off);
590   [[nodiscard]] bool emitJumpTarget(JumpTarget* target);
591   [[nodiscard]] bool emitJumpNoFallthrough(JSOp op, JumpList* jump);
592   [[nodiscard]] bool emitJump(JSOp op, JumpList* jump);
593   void patchJumpsToTarget(JumpList jump, JumpTarget target);
594   [[nodiscard]] bool emitJumpTargetAndPatch(JumpList jump);
595 
596   [[nodiscard]] bool emitCall(
597       JSOp op, uint16_t argc,
598       const mozilla::Maybe<uint32_t>& sourceCoordOffset);
599   [[nodiscard]] bool emitCall(JSOp op, uint16_t argc, ParseNode* pn = nullptr);
600   [[nodiscard]] bool emitCallIncDec(UnaryNode* incDec);
601 
602   mozilla::Maybe<uint32_t> getOffsetForLoop(ParseNode* nextpn);
603 
604   enum class GotoKind { Break, Continue };
605   [[nodiscard]] bool emitGoto(NestableControl* target, JumpList* jumplist,
606                               GotoKind kind);
607 
608   [[nodiscard]] bool emitGCIndexOp(JSOp op, GCThingIndex index);
609 
610   [[nodiscard]] bool emitAtomOp(JSOp op, TaggedParserAtomIndex atom);
611   [[nodiscard]] bool emitAtomOp(JSOp op, GCThingIndex atomIndex);
612 
613   [[nodiscard]] bool emitArrayLiteral(ListNode* array);
614   [[nodiscard]] bool emitArray(ParseNode* arrayHead, uint32_t count);
615 
616   [[nodiscard]] bool emitInternedScopeOp(GCThingIndex index, JSOp op);
617   [[nodiscard]] bool emitInternedObjectOp(GCThingIndex index, JSOp op);
618   [[nodiscard]] bool emitObjectPairOp(GCThingIndex index1, GCThingIndex index2,
619                                       JSOp op);
620   [[nodiscard]] bool emitRegExp(GCThingIndex index);
621 
622   [[nodiscard]] MOZ_NEVER_INLINE bool emitFunction(FunctionNode* funNode,
623                                                    bool needsProto = false);
624   [[nodiscard]] MOZ_NEVER_INLINE bool emitObject(ListNode* objNode);
625 
626   [[nodiscard]] bool emitHoistedFunctionsInList(ListNode* stmtList);
627 
628   // Can we use the object-literal writer either in singleton-object mode (with
629   // values) or in template mode (field names only, no values) for the property
630   // list?
631   void isPropertyListObjLiteralCompatible(ListNode* obj, bool* withValues,
632                                           bool* withoutValues);
633   bool isArrayObjLiteralCompatible(ParseNode* arrayHead);
634 
635   [[nodiscard]] bool emitPropertyList(ListNode* obj, PropertyEmitter& pe,
636                                       PropListType type);
637 
638   [[nodiscard]] bool emitPropertyListObjLiteral(ListNode* obj,
639                                                 ObjLiteralFlags flags,
640                                                 bool useObjLiteralValues);
641 
642   [[nodiscard]] bool emitDestructuringRestExclusionSetObjLiteral(
643       ListNode* pattern);
644 
645   [[nodiscard]] bool emitObjLiteralArray(ParseNode* arrayHead);
646 
647   // Is a field value OBJLITERAL-compatible?
648   [[nodiscard]] bool isRHSObjLiteralCompatible(ParseNode* value);
649 
650   [[nodiscard]] bool emitObjLiteralValue(ObjLiteralWriter& writer,
651                                          ParseNode* value);
652 
653   mozilla::Maybe<MemberInitializers> setupMemberInitializers(
654       ListNode* classMembers, FieldPlacement placement);
655   [[nodiscard]] bool emitCreateFieldKeys(ListNode* obj,
656                                          FieldPlacement placement);
657   [[nodiscard]] bool emitCreateMemberInitializers(ClassEmitter& ce,
658                                                   ListNode* obj,
659                                                   FieldPlacement placement);
660   const MemberInitializers& findMemberInitializersForCall();
661   [[nodiscard]] bool emitInitializeInstanceMembers();
662   [[nodiscard]] bool emitInitializeStaticFields(ListNode* classMembers);
663 
664   [[nodiscard]] bool emitPrivateMethodInitializers(ClassEmitter& ce,
665                                                    ListNode* obj);
666   [[nodiscard]] bool emitPrivateMethodInitializer(
667       ClassEmitter& ce, ParseNode* prop, ParseNode* propName,
668       TaggedParserAtomIndex storedMethodAtom, AccessorType accessorType);
669 
670   // To catch accidental misuse, emitUint16Operand/emit3 assert that they are
671   // not used to unconditionally emit JSOp::GetLocal. Variable access should
672   // instead be emitted using EmitVarOp. In special cases, when the caller
673   // definitely knows that a given local slot is unaliased, this function may be
674   // used as a non-asserting version of emitUint16Operand.
675   [[nodiscard]] bool emitLocalOp(JSOp op, uint32_t slot);
676 
677   [[nodiscard]] bool emitArgOp(JSOp op, uint16_t slot);
678   [[nodiscard]] bool emitEnvCoordOp(JSOp op, EnvironmentCoordinate ec);
679 
680   [[nodiscard]] bool emitGetNameAtLocation(TaggedParserAtomIndex name,
681                                            const NameLocation& loc);
emitGetNameBytecodeEmitter682   [[nodiscard]] bool emitGetName(TaggedParserAtomIndex name) {
683     return emitGetNameAtLocation(name, lookupName(name));
684   }
685   [[nodiscard]] bool emitGetName(NameNode* name);
686   [[nodiscard]] bool emitGetPrivateName(NameNode* name);
687   [[nodiscard]] bool emitGetPrivateName(TaggedParserAtomIndex name);
688 
689   [[nodiscard]] bool emitTDZCheckIfNeeded(TaggedParserAtomIndex name,
690                                           const NameLocation& loc,
691                                           ValueIsOnStack isOnStack);
692 
693   [[nodiscard]] bool emitNameIncDec(UnaryNode* incDec);
694 
695   [[nodiscard]] bool emitDeclarationList(ListNode* declList);
696   [[nodiscard]] bool emitSingleDeclaration(ListNode* declList, NameNode* decl,
697                                            ParseNode* initializer);
698   [[nodiscard]] bool emitAssignmentRhs(ParseNode* rhs,
699                                        TaggedParserAtomIndex anonFunctionName);
700   [[nodiscard]] bool emitAssignmentRhs(uint8_t offset);
701 
702   [[nodiscard]] bool emitPrepareIteratorResult();
703   [[nodiscard]] bool emitFinishIteratorResult(bool done);
704   [[nodiscard]] bool iteratorResultShape(GCThingIndex* outShape);
705 
706   // Convert and add `writer` data to stencil.
707   // Iff it suceeds, `outIndex` out parameter is initialized to the index of the
708   // object in GC things vector.
709   [[nodiscard]] bool addObjLiteralData(ObjLiteralWriter& writer,
710                                        GCThingIndex* outIndex);
711 
emitGetDotGeneratorInInnermostScopeBytecodeEmitter712   [[nodiscard]] bool emitGetDotGeneratorInInnermostScope() {
713     return emitGetDotGeneratorInScope(*innermostEmitterScope());
714   }
715   [[nodiscard]] bool emitGetDotGeneratorInScope(EmitterScope& currentScope);
716 
717   [[nodiscard]] bool allocateResumeIndex(BytecodeOffset offset,
718                                          uint32_t* resumeIndex);
719   [[nodiscard]] bool allocateResumeIndexRange(
720       mozilla::Span<BytecodeOffset> offsets, uint32_t* firstResumeIndex);
721 
722   [[nodiscard]] bool emitInitialYield(UnaryNode* yieldNode);
723   [[nodiscard]] bool emitYield(UnaryNode* yieldNode);
724   [[nodiscard]] bool emitYieldOp(JSOp op);
725   [[nodiscard]] bool emitYieldStar(ParseNode* iter);
emitAwaitInInnermostScopeBytecodeEmitter726   [[nodiscard]] bool emitAwaitInInnermostScope() {
727     return emitAwaitInScope(*innermostEmitterScope());
728   }
729   [[nodiscard]] bool emitAwaitInInnermostScope(UnaryNode* awaitNode);
730   [[nodiscard]] bool emitAwaitInScope(EmitterScope& currentScope);
731 
732   [[nodiscard]] bool emitPushResumeKind(GeneratorResumeKind kind);
733 
734   [[nodiscard]] bool emitPropLHS(PropertyAccess* prop);
735   [[nodiscard]] bool emitPropIncDec(UnaryNode* incDec);
736 
737   [[nodiscard]] bool emitComputedPropertyName(UnaryNode* computedPropName);
738 
739   [[nodiscard]] bool emitObjAndKey(ParseNode* exprOrSuper, ParseNode* key,
740                                    ElemOpEmitter& eoe);
741 
742   // Emit bytecode to put operands for a JSOp::GetElem/CallElem/SetElem/DelElem
743   // opcode onto the stack in the right order. In the case of SetElem, the
744   // value to be assigned must already be pushed.
745   enum class EmitElemOption { Get, Call, IncDec, CompoundAssign, Ref };
746   [[nodiscard]] bool emitElemOperands(PropertyByValue* elem,
747                                       EmitElemOption opts);
748 
749   [[nodiscard]] bool emitElemObjAndKey(PropertyByValue* elem, bool isSuper,
750                                        ElemOpEmitter& eoe);
751   [[nodiscard]] bool emitElemOpBase(JSOp op);
752 
753   [[nodiscard]] bool emitElemIncDec(UnaryNode* incDec);
754   [[nodiscard]] bool emitObjAndPrivateName(PrivateMemberAccess* elem,
755                                            ElemOpEmitter& eoe);
756   [[nodiscard]] bool emitPrivateIncDec(UnaryNode* incDec);
757 
758   [[nodiscard]] bool emitCatch(BinaryNode* catchClause);
759   [[nodiscard]] bool emitIf(TernaryNode* ifNode);
760   [[nodiscard]] bool emitWith(BinaryNode* withNode);
761 
762   [[nodiscard]] MOZ_NEVER_INLINE bool emitLabeledStatement(
763       const LabeledStatement* labeledStmt);
764   [[nodiscard]] MOZ_NEVER_INLINE bool emitLexicalScope(
765       LexicalScopeNode* lexicalScope);
766   [[nodiscard]] bool emitLexicalScopeBody(
767       ParseNode* body, EmitLineNumberNote emitLineNote = EMIT_LINENOTE);
768   [[nodiscard]] MOZ_NEVER_INLINE bool emitSwitch(SwitchStatement* switchStmt);
769   [[nodiscard]] MOZ_NEVER_INLINE bool emitTry(TryNode* tryNode);
770 
771   [[nodiscard]] bool emitGoSub(JumpList* jump);
772 
773   // emitDestructuringLHSRef emits the lhs expression's reference.
774   // If the lhs expression is object property |OBJ.prop|, it emits |OBJ|.
775   // If it's object element |OBJ[ELEM]|, it emits |OBJ| and |ELEM|.
776   // If there's nothing to evaluate for the reference, it emits nothing.
777   // |emitted| parameter receives the number of values pushed onto the stack.
778   [[nodiscard]] bool emitDestructuringLHSRef(ParseNode* target,
779                                              size_t* emitted);
780 
781   // emitSetOrInitializeDestructuring assumes the lhs expression's reference
782   // and the to-be-destructured value has been pushed on the stack.  It emits
783   // code to destructure a single lhs expression (either a name or a compound
784   // []/{} expression).
785   [[nodiscard]] bool emitSetOrInitializeDestructuring(ParseNode* target,
786                                                       DestructuringFlavor flav);
787 
788   // emitDestructuringObjRestExclusionSet emits the property exclusion set
789   // for the rest-property in an object pattern.
790   [[nodiscard]] bool emitDestructuringObjRestExclusionSet(ListNode* pattern);
791 
792   // emitDestructuringOps assumes the to-be-destructured value has been
793   // pushed on the stack and emits code to destructure each part of a [] or
794   // {} lhs expression.
795   [[nodiscard]] bool emitDestructuringOps(ListNode* pattern,
796                                           DestructuringFlavor flav);
797   [[nodiscard]] bool emitDestructuringOpsArray(ListNode* pattern,
798                                                DestructuringFlavor flav);
799   [[nodiscard]] bool emitDestructuringOpsObject(ListNode* pattern,
800                                                 DestructuringFlavor flav);
801 
802   enum class CopyOption { Filtered, Unfiltered };
803 
804   // Calls either the |CopyDataProperties| or the
805   // |CopyDataPropertiesUnfiltered| intrinsic function, consumes three (or
806   // two in the latter case) elements from the stack.
807   [[nodiscard]] bool emitCopyDataProperties(CopyOption option);
808 
809   // emitIterator expects the iterable to already be on the stack.
810   // It will replace that stack value with the corresponding iterator
811   [[nodiscard]] bool emitIterator();
812 
813   [[nodiscard]] bool emitAsyncIterator();
814 
815   // Pops iterator from the top of the stack. Pushes the result of |.next()|
816   // onto the stack.
817   [[nodiscard]] bool emitIteratorNext(
818       const mozilla::Maybe<uint32_t>& callSourceCoordOffset,
819       IteratorKind kind = IteratorKind::Sync, bool allowSelfHosted = false);
820   [[nodiscard]] bool emitIteratorCloseInScope(
821       EmitterScope& currentScope, IteratorKind iterKind = IteratorKind::Sync,
822       CompletionKind completionKind = CompletionKind::Normal,
823       bool allowSelfHosted = false);
824   [[nodiscard]] bool emitIteratorCloseInInnermostScope(
825       IteratorKind iterKind = IteratorKind::Sync,
826       CompletionKind completionKind = CompletionKind::Normal,
827       bool allowSelfHosted = false) {
828     return emitIteratorCloseInScope(*innermostEmitterScope(), iterKind,
829                                     completionKind, allowSelfHosted);
830   }
831 
832   template <typename InnerEmitter>
833   [[nodiscard]] bool wrapWithDestructuringTryNote(int32_t iterDepth,
834                                                   InnerEmitter emitter);
835 
836   [[nodiscard]] bool defineHoistedTopLevelFunctions(ParseNode* body);
837 
838   // Check if the value on top of the stack is "undefined". If so, replace
839   // that value on the stack with the value defined by |defaultExpr|.
840   // |pattern| is a lhs node of the default expression.  If it's an
841   // identifier and |defaultExpr| is an anonymous function, |SetFunctionName|
842   // is called at compile time.
843   [[nodiscard]] bool emitDefault(ParseNode* defaultExpr, ParseNode* pattern);
844 
845   [[nodiscard]] bool emitAnonymousFunctionWithName(ParseNode* node,
846                                                    TaggedParserAtomIndex name);
847 
848   [[nodiscard]] bool emitAnonymousFunctionWithComputedName(
849       ParseNode* node, FunctionPrefixKind prefixKind);
850 
851   [[nodiscard]] bool setFunName(FunctionBox* fun, TaggedParserAtomIndex name);
852   [[nodiscard]] bool emitInitializer(ParseNode* initializer,
853                                      ParseNode* pattern);
854 
855   [[nodiscard]] bool emitCallSiteObjectArray(ListNode* cookedOrRaw,
856                                              GCThingIndex* outArrayIndex);
857   [[nodiscard]] bool emitCallSiteObject(CallSiteNode* callSiteObj);
858   [[nodiscard]] bool emitTemplateString(ListNode* templateString);
859   [[nodiscard]] bool emitAssignmentOrInit(ParseNodeKind kind, ParseNode* lhs,
860                                           ParseNode* rhs);
861   [[nodiscard]] bool emitShortCircuitAssignment(AssignmentNode* node);
862 
863   [[nodiscard]] bool emitReturn(UnaryNode* returnNode);
864   [[nodiscard]] bool emitExpressionStatement(UnaryNode* exprStmt);
865   [[nodiscard]] bool emitStatementList(ListNode* stmtList);
866 
867   [[nodiscard]] bool emitDeleteName(UnaryNode* deleteNode);
868   [[nodiscard]] bool emitDeleteProperty(UnaryNode* deleteNode);
869   [[nodiscard]] bool emitDeleteElement(UnaryNode* deleteNode);
870   [[nodiscard]] bool emitDeleteExpression(UnaryNode* deleteNode);
871 
872   // Optional methods which emit Optional Jump Target
873   [[nodiscard]] bool emitOptionalChain(UnaryNode* expr, ValueUsage valueUsage);
874   [[nodiscard]] bool emitCalleeAndThisForOptionalChain(UnaryNode* expr,
875                                                        CallNode* callNode,
876                                                        CallOrNewEmitter& cone);
877   [[nodiscard]] bool emitDeleteOptionalChain(UnaryNode* deleteNode);
878 
879   // Optional methods which emit a shortCircuit jump. They need to be called by
880   // a method which emits an Optional Jump Target, see below.
881   [[nodiscard]] bool emitOptionalDotExpression(PropertyAccessBase* expr,
882                                                PropOpEmitter& poe, bool isSuper,
883                                                OptionalEmitter& oe);
884   [[nodiscard]] bool emitOptionalElemExpression(PropertyByValueBase* elem,
885                                                 ElemOpEmitter& eoe,
886                                                 bool isSuper,
887                                                 OptionalEmitter& oe);
888   [[nodiscard]] bool emitOptionalPrivateExpression(
889       PrivateMemberAccessBase* privateExpr, PrivateOpEmitter& xoe,
890       OptionalEmitter& oe);
891   [[nodiscard]] bool emitOptionalCall(CallNode* callNode, OptionalEmitter& oe,
892                                       ValueUsage valueUsage);
893   [[nodiscard]] bool emitDeletePropertyInOptChain(PropertyAccessBase* propExpr,
894                                                   OptionalEmitter& oe);
895   [[nodiscard]] bool emitDeleteElementInOptChain(PropertyByValueBase* elemExpr,
896                                                  OptionalEmitter& oe);
897 
898   // |op| must be JSOp::Typeof or JSOp::TypeofExpr.
899   [[nodiscard]] bool emitTypeof(UnaryNode* typeofNode, JSOp op);
900 
901   [[nodiscard]] bool emitUnary(UnaryNode* unaryNode);
902   [[nodiscard]] bool emitRightAssociative(ListNode* node);
903   [[nodiscard]] bool emitLeftAssociative(ListNode* node);
904   [[nodiscard]] bool emitPrivateInExpr(ListNode* node);
905   [[nodiscard]] bool emitShortCircuit(ListNode* node);
906   [[nodiscard]] bool emitSequenceExpr(
907       ListNode* node, ValueUsage valueUsage = ValueUsage::WantValue);
908 
909   [[nodiscard]] MOZ_NEVER_INLINE bool emitIncOrDec(UnaryNode* incDec);
910 
911   [[nodiscard]] bool emitConditionalExpression(
912       ConditionalExpression& conditional,
913       ValueUsage valueUsage = ValueUsage::WantValue);
914 
915   bool isOptimizableSpreadArgument(ParseNode* expr);
916 
917   [[nodiscard]] ParseNode* getCoordNode(ParseNode* callNode,
918                                         ParseNode* calleeNode, JSOp op,
919                                         ListNode* argsList);
920 
921   [[nodiscard]] bool emitArguments(ListNode* argsList, bool isCall,
922                                    bool isSpread, CallOrNewEmitter& cone);
923   [[nodiscard]] bool emitCallOrNew(
924       CallNode* callNode, ValueUsage valueUsage = ValueUsage::WantValue);
925   [[nodiscard]] bool emitSelfHostedCallFunction(CallNode* callNode);
926   [[nodiscard]] bool emitSelfHostedResumeGenerator(BinaryNode* callNode);
927   [[nodiscard]] bool emitSelfHostedForceInterpreter();
928   [[nodiscard]] bool emitSelfHostedAllowContentIter(BinaryNode* callNode);
929   [[nodiscard]] bool emitSelfHostedDefineDataProperty(BinaryNode* callNode);
930   [[nodiscard]] bool emitSelfHostedGetPropertySuper(BinaryNode* callNode);
931   [[nodiscard]] bool emitSelfHostedHasOwn(BinaryNode* callNode);
932   [[nodiscard]] bool emitSelfHostedToNumeric(BinaryNode* callNode);
933   [[nodiscard]] bool emitSelfHostedToString(BinaryNode* callNode);
934   [[nodiscard]] bool emitSelfHostedGetBuiltinConstructor(BinaryNode* callNode);
935   [[nodiscard]] bool emitSelfHostedGetBuiltinPrototype(BinaryNode* callNode);
936   [[nodiscard]] bool emitSelfHostedGetBuiltinSymbol(BinaryNode* callNode);
937   [[nodiscard]] bool emitSelfHostedSetIsInlinableLargeFunction(
938       BinaryNode* callNode);
939   [[nodiscard]] bool emitSelfHostedSetCanonicalName(BinaryNode* callNode);
940 #ifdef DEBUG
941   [[nodiscard]] bool checkSelfHostedExpectedTopLevel(BinaryNode* callNode,
942                                                      ParseNode* node);
943   [[nodiscard]] bool checkSelfHostedUnsafeGetReservedSlot(BinaryNode* callNode);
944   [[nodiscard]] bool checkSelfHostedUnsafeSetReservedSlot(BinaryNode* callNode);
945 #endif
946 
947   [[nodiscard]] bool emitDo(BinaryNode* doNode);
948   [[nodiscard]] bool emitWhile(BinaryNode* whileNode);
949 
950   [[nodiscard]] bool emitFor(
951       ForNode* forNode, const EmitterScope* headLexicalEmitterScope = nullptr);
952   [[nodiscard]] bool emitCStyleFor(ForNode* forNode,
953                                    const EmitterScope* headLexicalEmitterScope);
954   [[nodiscard]] bool emitForIn(ForNode* forNode,
955                                const EmitterScope* headLexicalEmitterScope);
956   [[nodiscard]] bool emitForOf(ForNode* forNode,
957                                const EmitterScope* headLexicalEmitterScope);
958 
959   [[nodiscard]] bool emitInitializeForInOrOfTarget(TernaryNode* forHead);
960 
961   [[nodiscard]] bool emitBreak(TaggedParserAtomIndex label);
962   [[nodiscard]] bool emitContinue(TaggedParserAtomIndex label);
963 
964   [[nodiscard]] bool emitFunctionFormalParameters(ListNode* paramsBody);
965   [[nodiscard]] bool emitInitializeFunctionSpecialNames();
966   [[nodiscard]] bool emitLexicalInitialization(NameNode* name);
967   [[nodiscard]] bool emitLexicalInitialization(TaggedParserAtomIndex name);
968 
969   // Emit bytecode for the spread operator.
970   //
971   // emitSpread expects the current index (I) of the array, the array itself
972   // and the iterator to be on the stack in that order (iterator on the bottom).
973   // It will pop the iterator and I, then iterate over the iterator by calling
974   // |.next()| and put the results into the I-th element of array with
975   // incrementing I, then push the result I (it will be original I +
976   // iteration count). The stack after iteration will look like |ARRAY INDEX|.
977   [[nodiscard]] bool emitSpread(bool allowSelfHosted = false);
978 
979   enum class ClassNameKind {
980     // The class name is defined through its BindingIdentifier, if present.
981     BindingName,
982 
983     // The class is anonymous and has a statically inferred name.
984     InferredName,
985 
986     // The class is anonymous and has a dynamically computed name.
987     ComputedName
988   };
989 
990   [[nodiscard]] bool emitClass(
991       ClassNode* classNode, ClassNameKind nameKind = ClassNameKind::BindingName,
992       TaggedParserAtomIndex nameForAnonymousClass =
993           TaggedParserAtomIndex::null());
994 
995   [[nodiscard]] bool emitSuperElemOperands(
996       PropertyByValue* elem, EmitElemOption opts = EmitElemOption::Get);
997   [[nodiscard]] bool emitSuperGetElem(PropertyByValue* elem,
998                                       bool isCall = false);
999 
1000   [[nodiscard]] bool emitCalleeAndThis(ParseNode* callee, ParseNode* call,
1001                                        CallOrNewEmitter& cone);
1002 
1003   [[nodiscard]] bool emitOptionalCalleeAndThis(ParseNode* callee,
1004                                                CallNode* call,
1005                                                CallOrNewEmitter& cone,
1006                                                OptionalEmitter& oe);
1007 
1008   [[nodiscard]] bool emitExportDefault(BinaryNode* exportNode);
1009 
emitReturnRvalBytecodeEmitter1010   [[nodiscard]] bool emitReturnRval() { return emit1(JSOp::RetRval); }
1011 
emitCheckPrivateFieldBytecodeEmitter1012   [[nodiscard]] bool emitCheckPrivateField(ThrowCondition throwCondition,
1013                                            ThrowMsgKind msgKind) {
1014     return emit3(JSOp::CheckPrivateField, uint8_t(throwCondition),
1015                  uint8_t(msgKind));
1016   }
1017 
1018   [[nodiscard]] bool emitNewPrivateName(TaggedParserAtomIndex bindingName,
1019                                         TaggedParserAtomIndex symbolName);
1020 
1021   template <class ClassMemberType>
1022   [[nodiscard]] bool emitNewPrivateNames(ListNode* classMembers);
1023 
1024   [[nodiscard]] bool emitNewPrivateNames(TaggedParserAtomIndex privateBrandName,
1025                                          ListNode* classMembers);
1026 
1027   [[nodiscard]] js::UniquePtr<ImmutableScriptData> createImmutableScriptData(
1028       JSContext* cx);
1029 
1030  private:
1031   [[nodiscard]] bool allowSelfHostedIter(ParseNode* parseNode);
1032 
1033   [[nodiscard]] bool emitSelfHostedGetBuiltinConstructorOrPrototype(
1034       BinaryNode* callNode, bool isConstructor);
1035 
1036  public:
1037 #if defined(DEBUG) || defined(JS_JITSPEW)
1038   void dumpAtom(TaggedParserAtomIndex index) const;
1039 #endif
1040 };
1041 
1042 class MOZ_RAII AutoCheckUnstableEmitterScope {
1043 #ifdef DEBUG
1044   bool prev_;
1045   BytecodeEmitter* bce_;
1046 #endif
1047 
1048  public:
1049   AutoCheckUnstableEmitterScope() = delete;
AutoCheckUnstableEmitterScope(BytecodeEmitter * bce)1050   explicit AutoCheckUnstableEmitterScope(BytecodeEmitter* bce)
1051 #ifdef DEBUG
1052       : bce_(bce)
1053 #endif
1054   {
1055 #ifdef DEBUG
1056     prev_ = bce_->unstableEmitterScope;
1057     bce_->unstableEmitterScope = true;
1058 #endif
1059   }
~AutoCheckUnstableEmitterScope()1060   ~AutoCheckUnstableEmitterScope() {
1061 #ifdef DEBUG
1062     bce_->unstableEmitterScope = prev_;
1063 #endif
1064   }
1065 };
1066 
1067 } /* namespace frontend */
1068 } /* namespace js */
1069 
1070 #endif /* frontend_BytecodeEmitter_h */
1071