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