• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_INTERPRETER_BYTECODE_GENERATOR_H_
6 #define V8_INTERPRETER_BYTECODE_GENERATOR_H_
7 
8 #include "src/ast/ast.h"
9 #include "src/interpreter/bytecode-array-builder.h"
10 #include "src/interpreter/bytecode-label.h"
11 #include "src/interpreter/bytecode-register.h"
12 #include "src/interpreter/bytecodes.h"
13 #include "src/objects/feedback-vector.h"
14 #include "src/objects/function-kind.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 class AstNodeSourceRanges;
20 class AstStringConstants;
21 class BytecodeArray;
22 class UnoptimizedCompilationInfo;
23 enum class SourceRangeKind;
24 
25 namespace interpreter {
26 
27 class TopLevelDeclarationsBuilder;
28 class LoopBuilder;
29 class BlockCoverageBuilder;
30 class BytecodeJumpTable;
31 
32 class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
33  public:
34   explicit BytecodeGenerator(
35       LocalIsolate* local_isolate, Zone* zone, UnoptimizedCompilationInfo* info,
36       const AstStringConstants* ast_string_constants,
37       std::vector<FunctionLiteral*>* eager_inner_literals,
38       Handle<Script> script);
39 
40   void GenerateBytecode(uintptr_t stack_limit);
41   template <typename IsolateT>
42   Handle<BytecodeArray> FinalizeBytecode(IsolateT* isolate,
43                                          Handle<Script> script);
44   template <typename IsolateT>
45   Handle<ByteArray> FinalizeSourcePositionTable(IsolateT* isolate);
46 
47 #ifdef DEBUG
48   int CheckBytecodeMatches(BytecodeArray bytecode);
49 #endif
50 
51 #define DECLARE_VISIT(type) void Visit##type(type* node);
52   AST_NODE_LIST(DECLARE_VISIT)
53 #undef DECLARE_VISIT
54 
55   // Visiting function for declarations list and statements are overridden.
56   void VisitModuleDeclarations(Declaration::List* declarations);
57   void VisitGlobalDeclarations(Declaration::List* declarations);
58   void VisitDeclarations(Declaration::List* declarations);
59   void VisitStatements(const ZonePtrList<Statement>* statments);
60 
61  private:
62   class AccumulatorPreservingScope;
63   class ContextScope;
64   class ControlScope;
65   class ControlScopeForBreakable;
66   class ControlScopeForIteration;
67   class ControlScopeForTopLevel;
68   class ControlScopeForTryCatch;
69   class ControlScopeForTryFinally;
70   class CurrentScope;
71   class EffectResultScope;
72   class ExpressionResultScope;
73   class FeedbackSlotCache;
74   class IteratorRecord;
75   class MultipleEntryBlockContextScope;
76   class LoopScope;
77   class NaryCodeCoverageSlots;
78   class OptionalChainNullLabelScope;
79   class RegisterAllocationScope;
80   class TestResultScope;
81   class TopLevelDeclarationsBuilder;
82   class ValueResultScope;
83 
84   using ToBooleanMode = BytecodeArrayBuilder::ToBooleanMode;
85 
86   enum class TestFallthrough { kThen, kElse, kNone };
87   enum class TypeHint { kAny, kBoolean, kString };
88   enum class AccumulatorPreservingMode { kNone, kPreserve };
89 
90   // An assignment has to evaluate its LHS before its RHS, but has to assign to
91   // the LHS after both evaluations are done. This class stores the data
92   // computed in the LHS evaulation that has to live across the RHS evaluation,
93   // and is used in the actual LHS assignment.
94   class AssignmentLhsData {
95    public:
96     static AssignmentLhsData NonProperty(Expression* expr);
97     static AssignmentLhsData NamedProperty(Expression* object_expr,
98                                            Register object,
99                                            const AstRawString* name);
100     static AssignmentLhsData KeyedProperty(Register object, Register key);
101     static AssignmentLhsData PrivateMethodOrAccessor(AssignType type,
102                                                      Property* property,
103                                                      Register object,
104                                                      Register key);
105     static AssignmentLhsData NamedSuperProperty(
106         RegisterList super_property_args);
107     static AssignmentLhsData KeyedSuperProperty(
108         RegisterList super_property_args);
109 
assign_type()110     AssignType assign_type() const { return assign_type_; }
expr()111     Expression* expr() const {
112       DCHECK(assign_type_ == NON_PROPERTY || assign_type_ == PRIVATE_METHOD ||
113              assign_type_ == PRIVATE_GETTER_ONLY ||
114              assign_type_ == PRIVATE_SETTER_ONLY ||
115              assign_type_ == PRIVATE_GETTER_AND_SETTER);
116       return expr_;
117     }
object_expr()118     Expression* object_expr() const {
119       DCHECK_EQ(assign_type_, NAMED_PROPERTY);
120       return object_expr_;
121     }
object()122     Register object() const {
123       DCHECK(assign_type_ == NAMED_PROPERTY || assign_type_ == KEYED_PROPERTY ||
124              assign_type_ == PRIVATE_METHOD ||
125              assign_type_ == PRIVATE_GETTER_ONLY ||
126              assign_type_ == PRIVATE_SETTER_ONLY ||
127              assign_type_ == PRIVATE_GETTER_AND_SETTER);
128       return object_;
129     }
key()130     Register key() const {
131       DCHECK(assign_type_ == KEYED_PROPERTY || assign_type_ == PRIVATE_METHOD ||
132              assign_type_ == PRIVATE_GETTER_ONLY ||
133              assign_type_ == PRIVATE_SETTER_ONLY ||
134              assign_type_ == PRIVATE_GETTER_AND_SETTER);
135       return key_;
136     }
name()137     const AstRawString* name() const {
138       DCHECK(assign_type_ == NAMED_PROPERTY);
139       return name_;
140     }
super_property_args()141     RegisterList super_property_args() const {
142       DCHECK(assign_type_ == NAMED_SUPER_PROPERTY ||
143              assign_type_ == KEYED_SUPER_PROPERTY);
144       return super_property_args_;
145     }
146 
147    private:
AssignmentLhsData(AssignType assign_type,Expression * expr,RegisterList super_property_args,Register object,Register key,Expression * object_expr,const AstRawString * name)148     AssignmentLhsData(AssignType assign_type, Expression* expr,
149                       RegisterList super_property_args, Register object,
150                       Register key, Expression* object_expr,
151                       const AstRawString* name)
152         : assign_type_(assign_type),
153           expr_(expr),
154           super_property_args_(super_property_args),
155           object_(object),
156           key_(key),
157           object_expr_(object_expr),
158           name_(name) {}
159 
160     AssignType assign_type_;
161 
162     // Different assignment types use different fields:
163     //
164     // NON_PROPERTY: expr
165     // NAMED_PROPERTY: object_expr, object, name
166     // KEYED_PROPERTY, PRIVATE_METHOD: object, key
167     // NAMED_SUPER_PROPERTY: super_property_args
168     // KEYED_SUPER_PROPERT:  super_property_args
169     Expression* expr_;
170     RegisterList super_property_args_;
171     Register object_;
172     Register key_;
173     Expression* object_expr_;
174     const AstRawString* name_;
175   };
176 
177   void GenerateBytecodeBody();
178   template <typename IsolateT>
179   void AllocateDeferredConstants(IsolateT* isolate, Handle<Script> script);
180 
181   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
182 
183   // Dispatched from VisitBinaryOperation.
184   void VisitArithmeticExpression(BinaryOperation* binop);
185   void VisitCommaExpression(BinaryOperation* binop);
186   void VisitLogicalOrExpression(BinaryOperation* binop);
187   void VisitLogicalAndExpression(BinaryOperation* binop);
188   void VisitNullishExpression(BinaryOperation* binop);
189 
190   // Dispatched from VisitNaryOperation.
191   void VisitNaryArithmeticExpression(NaryOperation* expr);
192   void VisitNaryCommaExpression(NaryOperation* expr);
193   void VisitNaryLogicalOrExpression(NaryOperation* expr);
194   void VisitNaryLogicalAndExpression(NaryOperation* expr);
195   void VisitNaryNullishExpression(NaryOperation* expr);
196 
197   // Dispatched from VisitUnaryOperation.
198   void VisitVoid(UnaryOperation* expr);
199   void VisitTypeOf(UnaryOperation* expr);
200   void VisitNot(UnaryOperation* expr);
201   void VisitDelete(UnaryOperation* expr);
202 
203   // Visits a typeof expression for the value on which to perform the typeof.
204   void VisitForTypeOfValue(Expression* expr);
205 
206   // Used by flow control routines to evaluate loop condition.
207   void VisitCondition(Expression* expr);
208 
209   // Visit the arguments expressions in |args| and store them in |args_regs|,
210   // growing |args_regs| for each argument visited.
211   void VisitArguments(const ZonePtrList<Expression>* args,
212                       RegisterList* arg_regs);
213 
214   // Visit a keyed super property load. The optional
215   // |opt_receiver_out| register will have the receiver stored to it
216   // if it's a valid register. The loaded value is placed in the
217   // accumulator.
218   void VisitKeyedSuperPropertyLoad(Property* property,
219                                    Register opt_receiver_out);
220 
221   // Visit a named super property load. The optional
222   // |opt_receiver_out| register will have the receiver stored to it
223   // if it's a valid register. The loaded value is placed in the
224   // accumulator.
225   void VisitNamedSuperPropertyLoad(Property* property,
226                                    Register opt_receiver_out);
227 
228   void VisitPropertyLoad(Register obj, Property* expr);
229   void VisitPropertyLoadForRegister(Register obj, Property* expr,
230                                     Register destination);
231 
232   AssignmentLhsData PrepareAssignmentLhs(
233       Expression* lhs, AccumulatorPreservingMode accumulator_preserving_mode =
234                            AccumulatorPreservingMode::kNone);
235   void BuildAssignment(const AssignmentLhsData& data, Token::Value op,
236                        LookupHoistingMode lookup_hoisting_mode);
237 
238   void BuildThisVariableLoad();
239 
240   void BuildDeclareCall(Runtime::FunctionId id);
241 
242   Expression* GetDestructuringDefaultValue(Expression** target);
243   void BuildDestructuringArrayAssignment(
244       ArrayLiteral* pattern, Token::Value op,
245       LookupHoistingMode lookup_hoisting_mode);
246   void BuildDestructuringObjectAssignment(
247       ObjectLiteral* pattern, Token::Value op,
248       LookupHoistingMode lookup_hoisting_mode);
249 
250   void BuildLoadNamedProperty(const Expression* object_expr, Register object,
251                               const AstRawString* name);
252   void BuildSetNamedProperty(const Expression* object_expr, Register object,
253                              const AstRawString* name);
254   void BuildStoreGlobal(Variable* variable);
255 
256   void BuildVariableLoad(Variable* variable, HoleCheckMode hole_check_mode,
257                          TypeofMode typeof_mode = TypeofMode::kNotInside);
258   void BuildVariableLoadForAccumulatorValue(
259       Variable* variable, HoleCheckMode hole_check_mode,
260       TypeofMode typeof_mode = TypeofMode::kNotInside);
261   void BuildVariableAssignment(
262       Variable* variable, Token::Value op, HoleCheckMode hole_check_mode,
263       LookupHoistingMode lookup_hoisting_mode = LookupHoistingMode::kNormal);
264   void BuildLiteralCompareNil(Token::Value compare_op,
265                               BytecodeArrayBuilder::NilValue nil);
266   void BuildReturn(int source_position);
267   void BuildAsyncReturn(int source_position);
268   void BuildAsyncGeneratorReturn();
269   void BuildReThrow();
270   void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op);
271   void BuildThrowIfHole(Variable* variable);
272 
273   void BuildNewLocalActivationContext();
274   void BuildLocalActivationContextInitialization();
275   void BuildNewLocalBlockContext(Scope* scope);
276   void BuildNewLocalCatchContext(Scope* scope);
277   void BuildNewLocalWithContext(Scope* scope);
278 
279   void BuildGeneratorPrologue();
280   void BuildSuspendPoint(int position);
281 
282   void BuildAwait(int position = kNoSourcePosition);
283   void BuildAwait(Expression* await_expr);
284 
285   void BuildFinalizeIteration(IteratorRecord iterator, Register done,
286                               Register iteration_continuation_token);
287 
288   void BuildGetIterator(IteratorType hint);
289 
290   // Create an IteratorRecord with pre-allocated registers holding the next
291   // method and iterator object.
292   IteratorRecord BuildGetIteratorRecord(Register iterator_next,
293                                         Register iterator_object,
294                                         IteratorType hint);
295 
296   // Create an IteratorRecord allocating new registers to hold the next method
297   // and iterator object.
298   IteratorRecord BuildGetIteratorRecord(IteratorType hint);
299   void BuildIteratorNext(const IteratorRecord& iterator, Register next_result);
300   void BuildIteratorClose(const IteratorRecord& iterator,
301                           Expression* expr = nullptr);
302   void BuildCallIteratorMethod(Register iterator, const AstRawString* method,
303                                RegisterList receiver_and_args,
304                                BytecodeLabel* if_called,
305                                BytecodeLabels* if_notcalled);
306 
307   void BuildFillArrayWithIterator(IteratorRecord iterator, Register array,
308                                   Register index, Register value,
309                                   FeedbackSlot next_value_slot,
310                                   FeedbackSlot next_done_slot,
311                                   FeedbackSlot index_slot,
312                                   FeedbackSlot element_slot);
313   // Create Array literals. |expr| can be nullptr, but if provided,
314   // a boilerplate will be used to create an initial array for elements
315   // before the first spread.
316   void BuildCreateArrayLiteral(const ZonePtrList<Expression>* elements,
317                                ArrayLiteral* expr);
318   void BuildCreateObjectLiteral(Register literal, uint8_t flags, size_t entry);
319   void AllocateTopLevelRegisters();
320   void VisitArgumentsObject(Variable* variable);
321   void VisitRestArgumentsArray(Variable* rest);
322   void VisitCallSuper(Call* call);
323   void BuildInvalidPropertyAccess(MessageTemplate tmpl, Property* property);
324   void BuildPrivateBrandCheck(Property* property, Register object);
325   void BuildPrivateMethodIn(Variable* private_name,
326                             Expression* object_expression);
327   void BuildPrivateGetterAccess(Register obj, Register access_pair);
328   void BuildPrivateSetterAccess(Register obj, Register access_pair,
329                                 Register value);
330   void BuildPrivateMethods(ClassLiteral* expr, bool is_static,
331                            Register home_object);
332   void BuildClassProperty(ClassLiteral::Property* property);
333   void BuildClassLiteral(ClassLiteral* expr, Register name);
334   void VisitClassLiteral(ClassLiteral* expr, Register name);
335   void VisitNewTargetVariable(Variable* variable);
336   void VisitThisFunctionVariable(Variable* variable);
337   void BuildPrivateBrandInitialization(Register receiver, Variable* brand);
338   void BuildInstanceMemberInitialization(Register constructor,
339                                          Register instance);
340   void BuildGeneratorObjectVariableInitialization();
341   void VisitBlockDeclarationsAndStatements(Block* stmt);
342   void VisitLiteralAccessor(LiteralProperty* property, Register value_out);
343   void VisitForInAssignment(Expression* expr);
344   void VisitModuleNamespaceImports();
345 
346   // Visit a logical OR/AND within a test context, rewiring the jumps based
347   // on the expression values.
348   void VisitLogicalTest(Token::Value token, Expression* left, Expression* right,
349                         int right_coverage_slot);
350   void VisitNaryLogicalTest(Token::Value token, NaryOperation* expr,
351                             const NaryCodeCoverageSlots* coverage_slots);
352 
353   // Visit a (non-RHS) test for a logical op, which falls through if the test
354   // fails or jumps to the appropriate labels if it succeeds.
355   void VisitLogicalTestSubExpression(Token::Value token, Expression* expr,
356                                      BytecodeLabels* then_labels,
357                                      BytecodeLabels* else_labels,
358                                      int coverage_slot);
359 
360   // Helpers for binary and nary logical op value expressions.
361   bool VisitLogicalOrSubExpression(Expression* expr, BytecodeLabels* end_labels,
362                                    int coverage_slot);
363   bool VisitLogicalAndSubExpression(Expression* expr,
364                                     BytecodeLabels* end_labels,
365                                     int coverage_slot);
366 
367   // Helper for binary and nary nullish op value expressions.
368   bool VisitNullishSubExpression(Expression* expr, BytecodeLabels* end_labels,
369                                  int coverage_slot);
370 
371   // Visit the body of a loop iteration.
372   void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop_builder);
373 
374   // Visit a statement and switch scopes, the context is in the accumulator.
375   void VisitInScope(Statement* stmt, Scope* scope);
376 
377   void BuildPushUndefinedIntoRegisterList(RegisterList* reg_list);
378 
379   void BuildLoadPropertyKey(LiteralProperty* property, Register out_reg);
380 
381   int AllocateBlockCoverageSlotIfEnabled(AstNode* node, SourceRangeKind kind);
382   int AllocateNaryBlockCoverageSlotIfEnabled(NaryOperation* node, size_t index);
383 
384   void BuildIncrementBlockCoverageCounterIfEnabled(AstNode* node,
385                                                    SourceRangeKind kind);
386   void BuildIncrementBlockCoverageCounterIfEnabled(int coverage_array_slot);
387 
388   void BuildTest(ToBooleanMode mode, BytecodeLabels* then_labels,
389                  BytecodeLabels* else_labels, TestFallthrough fallthrough);
390 
391   template <typename TryBodyFunc, typename CatchBodyFunc>
392   void BuildTryCatch(TryBodyFunc try_body_func, CatchBodyFunc catch_body_func,
393                      HandlerTable::CatchPrediction catch_prediction,
394                      TryCatchStatement* stmt_for_coverage = nullptr);
395   template <typename TryBodyFunc, typename FinallyBodyFunc>
396   void BuildTryFinally(TryBodyFunc try_body_func,
397                        FinallyBodyFunc finally_body_func,
398                        HandlerTable::CatchPrediction catch_prediction,
399                        TryFinallyStatement* stmt_for_coverage = nullptr);
400 
401   template <typename ExpressionFunc>
402   void BuildOptionalChain(ExpressionFunc expression_func);
403 
404   // Visitors for obtaining expression result in the accumulator, in a
405   // register, or just getting the effect. Some visitors return a TypeHint which
406   // specifies the type of the result of the visited expression.
407   TypeHint VisitForAccumulatorValue(Expression* expr);
408   void VisitForAccumulatorValueOrTheHole(Expression* expr);
409   V8_WARN_UNUSED_RESULT Register VisitForRegisterValue(Expression* expr);
410   V8_INLINE void VisitForRegisterValue(Expression* expr, Register destination);
411   void VisitAndPushIntoRegisterList(Expression* expr, RegisterList* reg_list);
412   void VisitForEffect(Expression* expr);
413   void VisitForTest(Expression* expr, BytecodeLabels* then_labels,
414                     BytecodeLabels* else_labels, TestFallthrough fallthrough);
415   void VisitForNullishTest(Expression* expr, BytecodeLabels* then_labels,
416                            BytecodeLabels* test_next_labels,
417                            BytecodeLabels* else_labels);
418 
419   void VisitInSameTestExecutionScope(Expression* expr);
420 
421   Register GetRegisterForLocalVariable(Variable* variable);
422 
423   // Returns the runtime function id for a store to super for the function's
424   // language mode.
425   inline Runtime::FunctionId StoreToSuperRuntimeId();
426   inline Runtime::FunctionId StoreKeyedToSuperRuntimeId();
427 
428   // Returns a cached slot, or create and cache a new slot if one doesn't
429   // already exists.
430   FeedbackSlot GetCachedLoadGlobalICSlot(TypeofMode typeof_mode,
431                                          Variable* variable);
432   FeedbackSlot GetCachedStoreGlobalICSlot(LanguageMode language_mode,
433                                           Variable* variable);
434   FeedbackSlot GetCachedLoadICSlot(const Expression* expr,
435                                    const AstRawString* name);
436   FeedbackSlot GetCachedLoadSuperICSlot(const AstRawString* name);
437   FeedbackSlot GetCachedStoreICSlot(const Expression* expr,
438                                     const AstRawString* name);
439   FeedbackSlot GetDummyCompareICSlot();
440 
441   int GetCachedCreateClosureSlot(FunctionLiteral* literal);
442 
443   void AddToEagerLiteralsIfEager(FunctionLiteral* literal);
444 
ToBooleanModeFromTypeHint(TypeHint type_hint)445   static constexpr ToBooleanMode ToBooleanModeFromTypeHint(TypeHint type_hint) {
446     return type_hint == TypeHint::kBoolean ? ToBooleanMode::kAlreadyBoolean
447                                            : ToBooleanMode::kConvertToBoolean;
448   }
449 
450   inline Register generator_object() const;
451 
builder()452   inline BytecodeArrayBuilder* builder() { return &builder_; }
zone()453   inline Zone* zone() const { return zone_; }
closure_scope()454   inline DeclarationScope* closure_scope() const { return closure_scope_; }
info()455   inline UnoptimizedCompilationInfo* info() const { return info_; }
ast_string_constants()456   inline const AstStringConstants* ast_string_constants() const {
457     return ast_string_constants_;
458   }
459 
current_scope()460   inline Scope* current_scope() const { return current_scope_; }
set_current_scope(Scope * scope)461   inline void set_current_scope(Scope* scope) { current_scope_ = scope; }
462 
execution_control()463   inline ControlScope* execution_control() const { return execution_control_; }
set_execution_control(ControlScope * scope)464   inline void set_execution_control(ControlScope* scope) {
465     execution_control_ = scope;
466   }
execution_context()467   inline ContextScope* execution_context() const { return execution_context_; }
set_execution_context(ContextScope * context)468   inline void set_execution_context(ContextScope* context) {
469     execution_context_ = context;
470   }
set_execution_result(ExpressionResultScope * execution_result)471   inline void set_execution_result(ExpressionResultScope* execution_result) {
472     execution_result_ = execution_result;
473   }
execution_result()474   ExpressionResultScope* execution_result() const { return execution_result_; }
register_allocator()475   BytecodeRegisterAllocator* register_allocator() {
476     return builder()->register_allocator();
477   }
478 
top_level_builder()479   TopLevelDeclarationsBuilder* top_level_builder() {
480     DCHECK_NOT_NULL(top_level_builder_);
481     return top_level_builder_;
482   }
483   inline LanguageMode language_mode() const;
484   inline FunctionKind function_kind() const;
485   inline FeedbackVectorSpec* feedback_spec();
486   inline int feedback_index(FeedbackSlot slot) const;
487 
feedback_slot_cache()488   inline FeedbackSlotCache* feedback_slot_cache() {
489     return feedback_slot_cache_;
490   }
491 
catch_prediction()492   inline HandlerTable::CatchPrediction catch_prediction() const {
493     return catch_prediction_;
494   }
set_catch_prediction(HandlerTable::CatchPrediction value)495   inline void set_catch_prediction(HandlerTable::CatchPrediction value) {
496     catch_prediction_ = value;
497   }
498 
current_loop_scope()499   LoopScope* current_loop_scope() const { return current_loop_scope_; }
set_current_loop_scope(LoopScope * loop_scope)500   void set_current_loop_scope(LoopScope* loop_scope) {
501     current_loop_scope_ = loop_scope;
502   }
503 
504   LocalIsolate* local_isolate_;
505   Zone* zone_;
506   BytecodeArrayBuilder builder_;
507   UnoptimizedCompilationInfo* info_;
508   const AstStringConstants* ast_string_constants_;
509   DeclarationScope* closure_scope_;
510   Scope* current_scope_;
511 
512   // External vector of literals to be eagerly compiled.
513   std::vector<FunctionLiteral*>* eager_inner_literals_;
514   Handle<Script> script_;
515 
516   FeedbackSlotCache* feedback_slot_cache_;
517 
518   TopLevelDeclarationsBuilder* top_level_builder_;
519   BlockCoverageBuilder* block_coverage_builder_;
520   ZoneVector<std::pair<FunctionLiteral*, size_t>> function_literals_;
521   ZoneVector<std::pair<NativeFunctionLiteral*, size_t>>
522       native_function_literals_;
523   ZoneVector<std::pair<ObjectLiteralBoilerplateBuilder*, size_t>>
524       object_literals_;
525   ZoneVector<std::pair<ArrayLiteralBoilerplateBuilder*, size_t>>
526       array_literals_;
527   ZoneVector<std::pair<ClassLiteral*, size_t>> class_literals_;
528   ZoneVector<std::pair<GetTemplateObject*, size_t>> template_objects_;
529 
530   ControlScope* execution_control_;
531   ContextScope* execution_context_;
532   ExpressionResultScope* execution_result_;
533 
534   Register incoming_new_target_or_generator_;
535 
536   BytecodeLabels* optional_chaining_null_labels_;
537 
538   // Dummy feedback slot for compare operations, where we don't care about
539   // feedback
540   SharedFeedbackSlot dummy_feedback_slot_;
541 
542   BytecodeJumpTable* generator_jump_table_;
543   int suspend_count_;
544   // TODO(solanes): assess if we can move loop_depth_ into LoopScope.
545   int loop_depth_;
546 
547   LoopScope* current_loop_scope_;
548 
549   HandlerTable::CatchPrediction catch_prediction_;
550 };
551 
552 }  // namespace interpreter
553 }  // namespace internal
554 }  // namespace v8
555 
556 #endif  // V8_INTERPRETER_BYTECODE_GENERATOR_H_
557