v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
bytecode-array-builder.h
Go to the documentation of this file.
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_ARRAY_BUILDER_H_
6#define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_
7
8#include <optional>
9
10#include "src/ast/ast.h"
12#include "src/common/globals.h"
21
22namespace v8 {
23namespace internal {
24
25class BytecodeArray;
26class FeedbackVectorSpec;
27class Isolate;
28
29namespace interpreter {
30
31class BytecodeLabel;
32class BytecodeLoopHeader;
33class BytecodeNode;
34class BytecodeRegisterOptimizer;
35class BytecodeJumpTable;
36class Register;
37
39 public:
41 Zone* zone, int parameter_count, int locals_count,
42 FeedbackVectorSpec* feedback_vector_spec = nullptr,
44 SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS);
45
48
49 template <typename IsolateT>
51 Handle<BytecodeArray> ToBytecodeArray(IsolateT* isolate);
52 template <typename IsolateT>
54 DirectHandle<TrustedByteArray> ToSourcePositionTable(IsolateT* isolate);
55
56#ifdef DEBUG
57 int CheckBytecodeMatches(Tagged<BytecodeArray> bytecode);
58#endif
59
60 // Get the number of parameters expected by function.
61 uint16_t parameter_count() const { return parameter_count_; }
62 uint16_t max_arguments() const { return max_arguments_; }
63
64 void UpdateMaxArguments(uint16_t max_arguments) {
65 max_arguments_ = std::max(max_arguments_, max_arguments);
66 }
67
68 // Get the number of locals required for bytecode array.
69 int locals_count() const {
70 DCHECK_GE(local_register_count_, 0);
71 return local_register_count_;
72 }
73
74 // Returns the number of fixed (non-temporary) registers.
75 int fixed_register_count() const { return locals_count(); }
76
77 // Returns the number of fixed and temporary registers.
79 DCHECK_LE(fixed_register_count(),
80 register_allocator()->maximum_register_count());
81 return register_allocator()->maximum_register_count();
82 }
83
84 Register Local(int index) const;
85 Register Parameter(int parameter_index) const;
86 Register Receiver() const;
87
88 // Constant loads to accumulator.
89 BytecodeArrayBuilder& LoadConstantPoolEntry(size_t entry);
90 BytecodeArrayBuilder& LoadLiteral(Tagged<Smi> value);
91 BytecodeArrayBuilder& LoadLiteral(double value);
92 BytecodeArrayBuilder& LoadLiteral(const AstRawString* raw_string);
93 BytecodeArrayBuilder& LoadLiteral(const AstConsString* cons_string);
94 BytecodeArrayBuilder& LoadLiteral(const Scope* scope);
95 BytecodeArrayBuilder& LoadLiteral(AstBigInt bigint);
96 BytecodeArrayBuilder& LoadUndefined();
97 BytecodeArrayBuilder& LoadNull();
98 BytecodeArrayBuilder& LoadTheHole();
99 BytecodeArrayBuilder& LoadTrue();
100 BytecodeArrayBuilder& LoadFalse();
101 BytecodeArrayBuilder& LoadBoolean(bool value);
102
103 // Global loads to the accumulator and stores from the accumulator.
104 BytecodeArrayBuilder& LoadGlobal(const AstRawString* name, int feedback_slot,
105 TypeofMode typeof_mode);
106 BytecodeArrayBuilder& StoreGlobal(const AstRawString* name,
107 int feedback_slot);
108
109 // Load the object at |variable| at |depth| in the context chain starting
110 // with |context| into the accumulator.
111 enum ContextSlotMutability { kImmutableSlot, kMutableSlot };
112 BytecodeArrayBuilder& LoadContextSlot(Register context, Variable* variable,
113 int depth,
114 ContextSlotMutability immutable);
115
116 // Stores the object in the accumulator into |variable| at |depth| in the
117 // context chain starting with |context|.
118 BytecodeArrayBuilder& StoreContextSlot(Register context, Variable* variable,
119 int depth);
120
121 // Load from a module variable into the accumulator. |depth| is the depth of
122 // the current context relative to the module context.
123 BytecodeArrayBuilder& LoadModuleVariable(int cell_index, int depth);
124
125 // Store from the accumulator into a module variable. |depth| is the depth of
126 // the current context relative to the module context.
127 BytecodeArrayBuilder& StoreModuleVariable(int cell_index, int depth);
128
129 // Register-accumulator transfers.
130 BytecodeArrayBuilder& LoadAccumulatorWithRegister(Register reg);
131 BytecodeArrayBuilder& StoreAccumulatorInRegister(Register reg);
132
133 // Register-register transfer.
134 BytecodeArrayBuilder& MoveRegister(Register from, Register to);
135
136 // Named load property.
137 BytecodeArrayBuilder& LoadNamedProperty(Register object,
138 const AstRawString* name,
139 int feedback_slot);
140
141 BytecodeArrayBuilder& LoadNamedPropertyFromSuper(Register object,
142 const AstRawString* name,
143 int feedback_slot);
144
145 // Keyed load property. The key should be in the accumulator.
146 BytecodeArrayBuilder& LoadKeyedProperty(Register object, int feedback_slot);
147
148 BytecodeArrayBuilder& LoadEnumeratedKeyedProperty(Register object,
149 Register enum_index,
150 Register cache_type,
151 int feedback_slot);
152
153 // Named load property of the @@iterator symbol.
154 BytecodeArrayBuilder& LoadIteratorProperty(Register object,
155 int feedback_slot);
156
157 // Load and call property of the @@iterator symbol
158 BytecodeArrayBuilder& GetIterator(Register object, int load_feedback_slot,
159 int call_feedback_slot);
160
161 // Named load property of the @@asyncIterator symbol.
162 BytecodeArrayBuilder& LoadAsyncIteratorProperty(Register object,
163 int feedback_slot);
164
165 // Store properties. Flag for NeedsSetFunctionName() should
166 // be in the accumulator.
167 BytecodeArrayBuilder& DefineKeyedOwnPropertyInLiteral(
168 Register object, Register name,
169 DefineKeyedOwnPropertyInLiteralFlags flags, int feedback_slot);
170
171 // Set a property named by a property name, trigger the setters and
172 // set traps if necessary. The value to be set should be in the
173 // accumulator.
174 BytecodeArrayBuilder& SetNamedProperty(Register object,
175 const AstRawString* name,
176 int feedback_slot,
177 LanguageMode language_mode);
178
179 // Set a property named by a constant from the constant pool,
180 // trigger the setters and set traps if necessary. The value to be
181 // set should be in the accumulator.
182 BytecodeArrayBuilder& SetNamedProperty(Register object,
183 size_t constant_pool_entry,
184 int feedback_slot,
185 LanguageMode language_mode);
186
187 // Define an own property named by a constant from the constant pool,
188 // trigger the defineProperty traps if necessary. The value to be
189 // defined should be in the accumulator.
190 BytecodeArrayBuilder& DefineNamedOwnProperty(Register object,
191 const AstRawString* name,
192 int feedback_slot);
193
194 // Set a property keyed by a value in a register, trigger the setters and
195 // set traps if necessary. The value to be set should be in the
196 // accumulator.
197 BytecodeArrayBuilder& SetKeyedProperty(Register object, Register key,
198 int feedback_slot,
199 LanguageMode language_mode);
200
201 // Define an own property keyed by a value in a register, trigger the
202 // defineProperty traps if necessary. The value to be defined should be
203 // in the accumulator.
204 BytecodeArrayBuilder& DefineKeyedOwnProperty(
206 int feedback_slot);
207
208 // Store an own element in an array literal. The value to be stored should be
209 // in the accumulator.
210 BytecodeArrayBuilder& StoreInArrayLiteral(Register array, Register index,
211 int feedback_slot);
212
213 // Store the class fields property. The initializer to be stored should
214 // be in the accumulator.
215 BytecodeArrayBuilder& StoreClassFieldsInitializer(Register constructor,
216 int feedback_slot);
217
218 // Load class fields property.
219 BytecodeArrayBuilder& LoadClassFieldsInitializer(Register constructor,
220 int feedback_slot);
221
222 // Lookup the variable with |name|.
223 BytecodeArrayBuilder& LoadLookupSlot(const AstRawString* name,
224 TypeofMode typeof_mode);
225
226 // Lookup the variable with |name|, which is known to be at |slot_index| at
227 // |depth| in the context chain if not shadowed by a context extension
228 // somewhere in that context chain.
229 BytecodeArrayBuilder& LoadLookupContextSlot(const AstRawString* name,
230 TypeofMode typeof_mode,
231 ContextKind context_kind,
232 int slot_index, int depth);
233
234 // Lookup the variable with |name|, which has its feedback in |feedback_slot|
235 // and is known to be global if not shadowed by a context extension somewhere
236 // up to |depth| in that context chain.
237 BytecodeArrayBuilder& LoadLookupGlobalSlot(const AstRawString* name,
238 TypeofMode typeof_mode,
239 int feedback_slot, int depth);
240
241 // Store value in the accumulator into the variable with |name|.
242 BytecodeArrayBuilder& StoreLookupSlot(
243 const AstRawString* name, LanguageMode language_mode,
244 LookupHoistingMode lookup_hoisting_mode);
245
246 // Create a new closure for a SharedFunctionInfo which will be inserted at
247 // constant pool index |shared_function_info_entry|.
248 BytecodeArrayBuilder& CreateClosure(size_t shared_function_info_entry,
249 int slot, int flags);
250
251 // Create a new local context for a |scope|.
252 BytecodeArrayBuilder& CreateBlockContext(const Scope* scope);
253
254 // Create a new context for a catch block with |exception| and |scope|.
255 BytecodeArrayBuilder& CreateCatchContext(Register exception,
256 const Scope* scope);
257
258 // Create a new context with the given |scope| and size |slots|.
259 BytecodeArrayBuilder& CreateFunctionContext(const Scope* scope, int slots);
260
261 // Create a new eval context with the given |scope| and size |slots|.
262 BytecodeArrayBuilder& CreateEvalContext(const Scope* scope, int slots);
263
264 // Creates a new context with the given |scope| for a with-statement
265 // with the |object| in a register.
266 BytecodeArrayBuilder& CreateWithContext(Register object, const Scope* scope);
267
268 // Create a new arguments object in the accumulator.
269 BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type);
270
271 // Literals creation. Constant elements should be in the accumulator.
272 BytecodeArrayBuilder& CreateRegExpLiteral(const AstRawString* pattern,
273 int literal_index, int flags);
274 BytecodeArrayBuilder& CreateArrayLiteral(size_t constant_elements_entry,
275 int literal_index, int flags);
276 BytecodeArrayBuilder& CreateEmptyArrayLiteral(int literal_index);
277 BytecodeArrayBuilder& CreateArrayFromIterable();
278 BytecodeArrayBuilder& CreateObjectLiteral(size_t constant_properties_entry,
279 int literal_index, int flags);
280 BytecodeArrayBuilder& CreateEmptyObjectLiteral();
281 BytecodeArrayBuilder& CloneObject(Register source, int flags,
282 int feedback_slot);
283
284 // Gets or creates the template for a TemplateObjectDescription which will
285 // be inserted at constant pool index |template_object_description_entry|.
287 size_t template_object_description_entry, int feedback_slot);
288
289 // Push the context in accumulator as the new context, and store in register
290 // |context|.
291 BytecodeArrayBuilder& PushContext(Register context);
292
293 // Pop the current context and replace with |context|.
294 BytecodeArrayBuilder& PopContext(Register context);
295
296 // Call a JS function which is known to be a property of a JS object. The
297 // JSFunction or Callable to be called should be in |callable|. The arguments
298 // should be in |args|, with the receiver in |args[0]|. Type feedback is
299 // recorded in the |feedback_slot| in the type feedback vector.
300 BytecodeArrayBuilder& CallProperty(Register callable, RegisterList args,
301 int feedback_slot);
302
303 // Call a JS function with an known undefined receiver. The JSFunction or
304 // Callable to be called should be in |callable|. The arguments should be in
305 // |args|, with no receiver as it is implicitly set to undefined. Type
306 // feedback is recorded in the |feedback_slot| in the type feedback vector.
307 BytecodeArrayBuilder& CallUndefinedReceiver(Register callable,
309 int feedback_slot);
310
311 // Call a JS function with an any receiver, possibly (but not necessarily)
312 // undefined. The JSFunction or Callable to be called should be in |callable|.
313 // The arguments should be in |args|, with the receiver in |args[0]|. Type
314 // feedback is recorded in the |feedback_slot| in the type feedback vector.
315 BytecodeArrayBuilder& CallAnyReceiver(Register callable, RegisterList args,
316 int feedback_slot);
317
318 // Tail call into a JS function. The JSFunction or Callable to be called
319 // should be in |callable|. The arguments should be in |args|, with the
320 // receiver in |args[0]|. Type feedback is recorded in the |feedback_slot| in
321 // the type feedback vector.
323 int feedback_slot);
324
325 // Call a JS function. The JSFunction or Callable to be called should be in
326 // |callable|, the receiver in |args[0]| and the arguments in |args[1]|
327 // onwards. The final argument must be a spread.
328 BytecodeArrayBuilder& CallWithSpread(Register callable, RegisterList args,
329 int feedback_slot);
330
331 // Call the Construct operator. The accumulator holds the |new_target|.
332 // The |constructor| is in a register and arguments are in |args|.
333 BytecodeArrayBuilder& Construct(Register constructor, RegisterList args,
334 int feedback_slot);
335
336 // Call the Construct operator for use with a spread. The accumulator holds
337 // the |new_target|. The |constructor| is in a register and arguments are in
338 // |args|. The final argument must be a spread.
339 BytecodeArrayBuilder& ConstructWithSpread(Register constructor,
341 int feedback_slot);
342
343 // Call the Construct operator, forwarding all arguments passed to the current
344 // interpreted frame, including the receiver. The accumulator holds the
345 // |new_target|. The |constructor| is in a register.
346 BytecodeArrayBuilder& ConstructForwardAllArgs(Register constructor,
347 int feedback_slot);
348
349 // Call the runtime function with |function_id| and arguments |args|.
352 // Call the runtime function with |function_id| with single argument |arg|.
354 Register arg);
355 // Call the runtime function with |function_id| with no arguments.
357
358 // Call the runtime function with |function_id| and arguments |args|, that
359 // returns a pair of values. The return values will be returned in
360 // |return_pair|.
361 BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id,
363 RegisterList return_pair);
364 // Call the runtime function with |function_id| with single argument |arg|
365 // that returns a pair of values. The return values will be returned in
366 // |return_pair|.
367 BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id,
368 Register arg,
369 RegisterList return_pair);
370
371 // Call the JS runtime function with |context_index| and arguments |args|,
372 // with no receiver as it is implicitly set to undefined.
373 BytecodeArrayBuilder& CallJSRuntime(int context_index, RegisterList args);
374
375 // Operators (register holds the lhs value, accumulator holds the rhs value).
376 // Type feedback will be recorded in the |feedback_slot|
378 int feedback_slot);
379 // Same as above, but lhs in the accumulator and rhs in |literal|.
380 BytecodeArrayBuilder& BinaryOperationSmiLiteral(Token::Value binop,
382 int feedback_slot);
383
384 // Unary and Count Operators (value stored in accumulator).
385 // Type feedback will be recorded in the |feedback_slot|
386 BytecodeArrayBuilder& UnaryOperation(Token::Value op, int feedback_slot);
387
388 enum class ToBooleanMode {
389 kConvertToBoolean, // Perform ToBoolean conversion on accumulator.
390 kAlreadyBoolean, // Accumulator is already a Boolean.
391 };
392
393 // Unary Operators.
394 BytecodeArrayBuilder& LogicalNot(ToBooleanMode mode);
395 BytecodeArrayBuilder& TypeOf(int feedback_slot);
396
397 // Expects a heap object in the accumulator. Returns its super constructor in
398 // the register |out| if it passes the IsConstructor test. Otherwise, it
399 // throws a TypeError exception.
400 BytecodeArrayBuilder& GetSuperConstructor(Register out);
401
402 BytecodeArrayBuilder& FindNonDefaultConstructorOrConstruct(
403 Register this_function, Register new_target, RegisterList output);
404
405 // Deletes property from an object. This expects that accumulator contains
406 // the key to be deleted and the register contains a reference to the object.
407 BytecodeArrayBuilder& Delete(Register object, LanguageMode language_mode);
408
409 // JavaScript defines two kinds of 'nil'.
410 enum NilValue { kNullValue, kUndefinedValue };
411
412 // Tests.
414 int feedback_slot);
415 BytecodeArrayBuilder& CompareReference(Register reg);
416 BytecodeArrayBuilder& CompareUndetectable();
417 BytecodeArrayBuilder& CompareUndefined();
418 BytecodeArrayBuilder& CompareNull();
419 BytecodeArrayBuilder& CompareNil(Token::Value op, NilValue nil);
420 BytecodeArrayBuilder& CompareTypeOf(
421 TestTypeOfFlags::LiteralFlag literal_flag);
422
423 // Converts accumulator and stores result in register |out|.
424 BytecodeArrayBuilder& ToObject(Register out);
425
426 // Converts accumulator and stores result back in accumulator.
427 BytecodeArrayBuilder& ToName();
429 BytecodeArrayBuilder& ToBoolean(ToBooleanMode mode);
430 BytecodeArrayBuilder& ToNumber(int feedback_slot);
431 BytecodeArrayBuilder& ToNumeric(int feedback_slot);
432
433 // Exception handling.
434 BytecodeArrayBuilder& MarkHandler(int handler_id,
436 BytecodeArrayBuilder& MarkTryBegin(int handler_id, Register context);
437 BytecodeArrayBuilder& MarkTryEnd(int handler_id);
438
439 // Flow Control.
442 BytecodeArrayBuilder& Bind(BytecodeJumpTable* jump_table, int case_value);
443
445 BytecodeArrayBuilder& JumpLoop(BytecodeLoopHeader* loop_header,
446 int loop_depth, int position,
447 int feedback_slot);
448
449 BytecodeArrayBuilder& JumpIfTrue(ToBooleanMode mode, BytecodeLabel* label);
450 BytecodeArrayBuilder& JumpIfFalse(ToBooleanMode mode, BytecodeLabel* label);
451 BytecodeArrayBuilder& JumpIfJSReceiver(BytecodeLabel* label);
454 BytecodeArrayBuilder& JumpIfUndefined(BytecodeLabel* label);
455 BytecodeArrayBuilder& JumpIfUndefinedOrNull(BytecodeLabel* label);
456 BytecodeArrayBuilder& JumpIfNotUndefined(BytecodeLabel* label);
458 NilValue nil);
460 NilValue nil);
461 BytecodeArrayBuilder& JumpIfForInDone(BytecodeLabel* label, Register index,
462 Register cache_length);
463
464 BytecodeArrayBuilder& SwitchOnSmiNoFeedback(BytecodeJumpTable* jump_table);
465
466 // Sets the pending message to the value in the accumulator, and returns the
467 // previous pending message in the accumulator.
468 BytecodeArrayBuilder& SetPendingMessage();
469
471 BytecodeArrayBuilder& ReThrow();
472 BytecodeArrayBuilder& Abort(AbortReason reason);
473 BytecodeArrayBuilder& Return();
474 BytecodeArrayBuilder& ThrowReferenceErrorIfHole(const AstRawString* name);
475 BytecodeArrayBuilder& ThrowSuperNotCalledIfHole();
476 BytecodeArrayBuilder& ThrowSuperAlreadyCalledIfNotHole();
477 BytecodeArrayBuilder& ThrowIfNotSuperConstructor(Register constructor);
478
479 // Debugger.
480 BytecodeArrayBuilder& Debugger();
481
482 // Increment the block counter at the given slot (block code coverage).
483 BytecodeArrayBuilder& IncBlockCounter(int slot);
484
485 // Complex flow control.
486 BytecodeArrayBuilder& ForInEnumerate(Register receiver);
487 BytecodeArrayBuilder& ForInPrepare(RegisterList cache_info_triple,
488 int feedback_slot);
490 RegisterList cache_type_array_pair,
491 int feedback_slot);
492 BytecodeArrayBuilder& ForInStep(Register index);
493
494 // Generators.
495 BytecodeArrayBuilder& SuspendGenerator(Register generator,
497 int suspend_id);
498 BytecodeArrayBuilder& SwitchOnGeneratorState(Register generator,
499 BytecodeJumpTable* jump_table);
500 BytecodeArrayBuilder& ResumeGenerator(Register generator,
502
503 // Creates a new handler table entry and returns a {hander_id} identifying the
504 // entry, so that it can be referenced by above exception handling support.
505 int NewHandlerEntry() { return handler_table_builder()->NewHandlerEntry(); }
506
507 // Allocates a new jump table of given |size| and |case_value_base| in the
508 // constant pool.
509 BytecodeJumpTable* AllocateJumpTable(int size, int case_value_base);
510
512 return register_optimizer_;
513 }
514
515 // Gets a constant pool entry.
516 size_t GetConstantPoolEntry(const AstRawString* raw_string);
517 size_t GetConstantPoolEntry(const AstConsString* cons_string);
518 size_t GetConstantPoolEntry(AstBigInt bigint);
519 size_t GetConstantPoolEntry(const Scope* scope);
520 size_t GetConstantPoolEntry(double number);
521#define ENTRY_GETTER(NAME, ...) size_t NAME##ConstantPoolEntry();
523#undef ENTRY_GETTER
524
525 // Allocates a slot in the constant pool which can later be set.
526 size_t AllocateDeferredConstantPoolEntry();
527 // Sets the deferred value into an allocated constant pool entry.
528 void SetDeferredConstantPoolEntry(size_t entry, Handle<Object> object);
529
531
533 SetStatementPosition(stmt->position());
534 }
535
536 std::optional<BytecodeSourceInfo> MaybePopSourcePosition(int scope_start) {
537 if (!latest_source_info_.is_valid() ||
538 latest_source_info_.source_position() < scope_start) {
539 return std::nullopt;
540 }
541 BytecodeSourceInfo source_info = latest_source_info_;
542 latest_source_info_.set_invalid();
543 return source_info;
544 }
545
547 DCHECK(!latest_source_info_.is_valid());
548 latest_source_info_ = source_info;
549 }
550
552 if (position == kNoSourcePosition) return;
553 latest_source_info_.MakeStatementPosition(position);
554 }
555
557 SetExpressionPosition(expr->position());
558 }
559
561 if (position == kNoSourcePosition) return;
562 if (!latest_source_info_.is_statement()) {
563 // Ensure the current expression position is overwritten with the
564 // latest value.
565 latest_source_info_.MakeExpressionPosition(position);
566 }
567 }
568
570 SetStatementPosition(expr->position());
571 }
572
574 return bytecode_array_writer_.RemainderOfBlockIsDead();
575 }
576
577 // Returns the raw operand value for the given register or register list.
578 uint32_t GetInputRegisterOperand(Register reg);
579 uint32_t GetOutputRegisterOperand(Register reg);
580 uint32_t GetInputOutputRegisterOperand(Register reg);
581 uint32_t GetInputRegisterListOperand(RegisterList reg_list);
582 uint32_t GetOutputRegisterListOperand(RegisterList reg_list);
583
584 // Outputs raw register transfer bytecodes without going through the register
585 // optimizer.
586 void OutputLdarRaw(Register reg);
587 void OutputStarRaw(Register reg);
588 void OutputMovRaw(Register src, Register dest);
589
590 void EmitFunctionStartSourcePosition(int position);
591
592 // Accessors
594 return &register_allocator_;
595 }
597 return &register_allocator_;
598 }
599 Zone* zone() const { return zone_; }
600
601 private:
603 template <Bytecode bytecode, ImplicitRegisterUse implicit_register_use,
604 OperandType... operand_types>
606
608 return feedback_vector_spec_;
609 }
610
611 // Returns the current source position for the given |bytecode|.
613
614#define DECLARE_BYTECODE_OUTPUT(Name, ...) \
615 template <typename... Operands> \
616 V8_INLINE BytecodeNode Create##Name##Node(Operands... operands); \
617 template <typename... Operands> \
618 V8_INLINE void Output##Name(Operands... operands); \
619 template <typename... Operands> \
620 V8_INLINE void Output##Name(BytecodeLabel* label, Operands... operands);
622#undef DECLARE_OPERAND_TYPE_INFO
623
624 V8_INLINE void OutputJumpLoop(BytecodeLoopHeader* loop_header, int loop_depth,
625 int feedback_slot);
626 V8_INLINE void OutputSwitchOnSmiNoFeedback(BytecodeJumpTable* jump_table);
627
628 bool RegisterIsValid(Register reg) const;
629 bool RegisterListIsValid(RegisterList reg_list) const;
630
631 // Sets a deferred source info which should be emitted before any future
632 // source info (either attached to a following bytecode or as a nop).
633 void SetDeferredSourceInfo(BytecodeSourceInfo source_info);
634 // Either attach deferred source info to node, or emit it as a nop bytecode
635 // if node already have valid source info.
636 void AttachOrEmitDeferredSourceInfo(BytecodeNode* node);
637
638 // Write bytecode to bytecode array.
639 void Write(BytecodeNode* node);
640 void WriteJump(BytecodeNode* node, BytecodeLabel* label);
641 void WriteJumpLoop(BytecodeNode* node, BytecodeLoopHeader* loop_header);
642 void WriteSwitch(BytecodeNode* node, BytecodeJumpTable* label);
643
644 // Not implemented as the illegal bytecode is used inside internally
645 // to indicate a bytecode field is not valid or an error has occurred
646 // during bytecode generation.
648
649 template <Bytecode bytecode, ImplicitRegisterUse implicit_register_use>
650 void PrepareToOutputBytecode();
651
653 return &bytecode_array_writer_;
654 }
656 return &constant_array_builder_;
657 }
659 return &constant_array_builder_;
660 }
662 return &handler_table_builder_;
663 }
664
678};
679
680V8_EXPORT_PRIVATE std::ostream& operator<<(
681 std::ostream& os, const BytecodeArrayBuilder::ToBooleanMode& mode);
682
683} // namespace interpreter
684} // namespace internal
685} // namespace v8
686
687#endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_
int16_t parameter_count
Definition builtins.cc:67
interpreter::Bytecode bytecode
Definition builtins.cc:43
#define ENTRY_GETTER(NAME,...)
#define DECLARE_BYTECODE_OUTPUT(Name,...)
#define BYTECODE_LIST(V, V_TSA)
Definition bytecodes.h:479
int position() const
Definition ast.h:155
const BytecodeRegisterAllocator * register_allocator() const
const ConstantArrayBuilder * constant_array_builder() const
BytecodeArrayBuilder(const BytecodeArrayBuilder &)=delete
void PushSourcePosition(BytecodeSourceInfo source_info)
std::optional< BytecodeSourceInfo > MaybePopSourcePosition(int scope_start)
V8_INLINE BytecodeSourceInfo CurrentSourcePosition(Bytecode bytecode)
BytecodeArrayBuilder & operator=(const BytecodeArrayBuilder &)=delete
BytecodeArrayBuilder & TailCall(Register callable, RegisterList args, int feedback_slot)
const FeedbackVectorSpec * feedback_vector_spec() const
void InitializeReturnPosition(FunctionLiteral *literal)
Zone * zone_
#define SINGLETON_CONSTANT_ENTRY_TYPES(V)
constexpr const char * ToString(DataViewOp op)
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
DirectHandle< Object > new_target
Definition execution.cc:75
Label label
#define EXPORT_TEMPLATE_DECLARE(export)
TNode< Object > receiver
std::string pattern
LiftoffRegister reg
FunctionLiteral * literal
Definition liveedit.cc:294
int position
Definition liveedit.cc:290
RegListBase< RegisterT > registers
std::ostream & operator<<(std::ostream &os, PaddingSpace padding)
constexpr int kNoSourcePosition
Definition globals.h:850
int ToNumber(Register reg)
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define V8_INLINE
Definition v8config.h:500
std::unique_ptr< ValueMirror > key