1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved.
2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file.
4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/ast.h"
9c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/base/compiler-specific.h"
10c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/globals.h"
11bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/interpreter/bytecode-array-writer.h"
12109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/interpreter/bytecode-register-allocator.h"
13f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/interpreter/bytecode-register.h"
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/interpreter/bytecodes.h"
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/interpreter/constant-array-builder.h"
16109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/interpreter/handler-table-builder.h"
17f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/zone/zone-containers.h"
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 {
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal {
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Isolate;
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace interpreter {
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass BytecodeLabel;
27bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochclass BytecodeNode;
28bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochclass BytecodePipelineStage;
29c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass BytecodeRegisterOptimizer;
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Register;
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
32c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE BytecodeArrayBuilder final
33c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    : public NON_EXPORTED_BASE(ZoneObject) {
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BytecodeArrayBuilder(
36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Isolate* isolate, Zone* zone, int parameter_count, int context_count,
37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      int locals_count, FunctionLiteral* literal = nullptr,
38f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      SourcePositionTableBuilder::RecordingMode source_position_mode =
39f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          SourcePositionTableBuilder::RECORD_SOURCE_POSITIONS);
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<BytecodeArray> ToBytecodeArray(Isolate* isolate);
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
43109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Get the number of parameters expected by function.
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int parameter_count() const {
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_GE(parameter_count_, 0);
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return parameter_count_;
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
49109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Get the number of locals required for bytecode array.
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int locals_count() const {
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_GE(local_register_count_, 0);
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return local_register_count_;
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
55109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Get number of contexts required for bytecode array.
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int context_count() const {
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_GE(context_register_count_, 0);
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return context_register_count_;
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register first_context_register() const;
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register last_context_register() const;
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Returns the number of fixed (non-temporary) registers.
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int fixed_register_count() const { return context_count() + locals_count(); }
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
67109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Returns the number of fixed and temporary registers.
68f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int total_register_count() const {
69f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK_LE(fixed_register_count(),
70f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              register_allocator()->maximum_register_count());
71f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return register_allocator()->maximum_register_count();
72109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
73109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Register Local(int index) const;
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register Parameter(int parameter_index) const;
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Constant loads to accumulator.
78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BytecodeArrayBuilder& LoadConstantPoolEntry(size_t entry);
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& LoadLiteral(v8::internal::Smi* value);
8062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& LoadLiteral(const AstRawString* raw_string);
8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& LoadLiteral(const Scope* scope);
8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& LoadLiteral(const AstValue* ast_value);
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& LoadUndefined();
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& LoadNull();
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& LoadTheHole();
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& LoadTrue();
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& LoadFalse();
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Global loads to the accumulator and stores from the accumulator.
9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& LoadGlobal(const AstRawString* name, int feedback_slot,
9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                   TypeofMode typeof_mode);
9262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& StoreGlobal(const AstRawString* name, int feedback_slot,
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    LanguageMode language_mode);
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
95f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Load the object at |slot_index| at |depth| in the context chain starting
96f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // with |context| into the accumulator.
9762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  enum ContextSlotMutability { kImmutableSlot, kMutableSlot };
98f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& LoadContextSlot(Register context, int slot_index,
9962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                        int depth,
10062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                        ContextSlotMutability immutable);
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
102f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Stores the object in the accumulator into |slot_index| at |depth| in the
103f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // context chain starting with |context|.
104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& StoreContextSlot(Register context, int slot_index,
105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                         int depth);
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
107c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Load from a module variable into the accumulator. |depth| is the depth of
108c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // the current context relative to the module context.
109c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  BytecodeArrayBuilder& LoadModuleVariable(int cell_index, int depth);
110c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
111c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Store from the accumulator into a module variable. |depth| is the depth of
112c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // the current context relative to the module context.
113c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  BytecodeArrayBuilder& StoreModuleVariable(int cell_index, int depth);
114c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Register-accumulator transfers.
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& LoadAccumulatorWithRegister(Register reg);
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& StoreAccumulatorInRegister(Register reg);
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Register-register transfer.
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& MoveRegister(Register from, Register to);
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Named load property.
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& LoadNamedProperty(Register object,
12462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                          const AstRawString* name,
125109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                          int feedback_slot);
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Keyed load property. The key should be in the accumulator.
127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BytecodeArrayBuilder& LoadKeyedProperty(Register object, int feedback_slot);
12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Named load property of the @@iterator symbol.
12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& LoadIteratorProperty(Register object,
13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                             int feedback_slot);
13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Named load property of the @@asyncIterator symbol.
13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& LoadAsyncIteratorProperty(Register object,
13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                  int feedback_slot);
13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Store properties. Flag for NeedsSetFunctionName() should
13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // be in the accumulator.
13762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& StoreDataPropertyInLiteral(
13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Register object, Register name, DataPropertyInLiteralFlags flags,
13962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      int feedback_slot);
14062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
14162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Store a property named by a property name. The value to be stored should be
14262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // in the accumulator.
14362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& StoreNamedProperty(Register object,
14462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           const AstRawString* name,
14562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           int feedback_slot,
14662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           LanguageMode language_mode);
14762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Store a property named by a constant from the constant pool. The value to
14862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // be stored should be in the accumulator.
149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& StoreNamedProperty(Register object,
15062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           size_t constant_pool_entry,
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           int feedback_slot,
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           LanguageMode language_mode);
15362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Store an own property named by a constant from the constant pool. The
15462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // value to be stored should be in the accumulator.
15562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& StoreNamedOwnProperty(Register object,
15662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                              const AstRawString* name,
15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                              int feedback_slot);
15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Store a property keyed by a value in a register. The value to be stored
15962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // should be in the accumulator.
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& StoreKeyedProperty(Register object, Register key,
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           int feedback_slot,
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           LanguageMode language_mode);
16362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Store the home object property. The value to be stored should be in the
16462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // accumulator.
16562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& StoreHomeObjectProperty(Register object,
16662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                int feedback_slot,
16762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                LanguageMode language_mode);
168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Lookup the variable with |name|.
17062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& LoadLookupSlot(const AstRawString* name,
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       TypeofMode typeof_mode);
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
173f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Lookup the variable with |name|, which is known to be at |slot_index| at
174f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // |depth| in the context chain if not shadowed by a context extension
175f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // somewhere in that context chain.
17662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& LoadLookupContextSlot(const AstRawString* name,
177f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                              TypeofMode typeof_mode,
178f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                              int slot_index, int depth);
179f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
180f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Lookup the variable with |name|, which has its feedback in |feedback_slot|
181f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // and is known to be global if not shadowed by a context extension somewhere
182f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // up to |depth| in that context chain.
18362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& LoadLookupGlobalSlot(const AstRawString* name,
184f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                             TypeofMode typeof_mode,
185f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                             int feedback_slot, int depth);
186f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Store value in the accumulator into the variable with |name|.
18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& StoreLookupSlot(const AstRawString* name,
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        LanguageMode language_mode);
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Create a new closure for a SharedFunctionInfo which will be inserted at
19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // constant pool index |shared_function_info_entry|.
19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& CreateClosure(size_t shared_function_info_entry,
19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      int slot, int flags);
195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Create a new local context for a |scope| and a closure which should be
197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // in the accumulator.
19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& CreateBlockContext(const Scope* scope);
199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
200f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Create a new context for a catch block with |exception|, |name|,
20162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // |scope|, and the closure in the accumulator.
202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BytecodeArrayBuilder& CreateCatchContext(Register exception,
20362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           const AstRawString* name,
20462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           const Scope* scope);
205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Create a new context with size |slots|.
207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BytecodeArrayBuilder& CreateFunctionContext(int slots);
208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
20962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Create a new eval context with size |slots|.
21062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& CreateEvalContext(int slots);
21162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
21262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Creates a new context with the given |scope| for a with-statement
213f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // with the |object| in a register and the closure in the accumulator.
21462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& CreateWithContext(Register object, const Scope* scope);
215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Create a new arguments object in the accumulator.
217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type);
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Literals creation.  Constant elements should be in the accumulator.
22062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& CreateRegExpLiteral(const AstRawString* pattern,
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            int literal_index, int flags);
22262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& CreateArrayLiteral(size_t constant_elements_entry,
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           int literal_index, int flags);
22462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& CreateObjectLiteral(size_t constant_properties_entry,
22562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                            int literal_index, int flags,
22662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                            Register output);
227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Push the context in accumulator as the new context, and store in register
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // |context|.
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& PushContext(Register context);
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Pop the current context and replace with |context|.
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& PopContext(Register context);
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Call a JS function. The JSFunction or Callable to be called should be in
236f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // |callable|. The arguments should be in |args|, with the receiver in
237c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // |args[0]|. The call type of the expression is in |call_type|. Type feedback
238c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // is recorded in the |feedback_slot| in the type feedback vector.
239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BytecodeArrayBuilder& Call(
240f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Register callable, RegisterList args, int feedback_slot,
241c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      Call::CallType call_type,
242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      TailCallMode tail_call_mode = TailCallMode::kDisallow);
243109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
24462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Call a JS function. The JSFunction or Callable to be called should be in
24562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // |callable|, the receiver in |args[0]| and the arguments in |args[1]|
24662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // onwards. The final argument must be a spread.
24762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& CallWithSpread(Register callable, RegisterList args);
24862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
24962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Call the Construct operator. The accumulator holds the |new_target|.
250f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // The |constructor| is in a register and arguments are in |args|.
25162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& Construct(Register constructor, RegisterList args,
25262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                  int feedback_slot);
25362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
25462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Call the Construct operator for use with a spread. The accumulator holds
25562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // the |new_target|. The |constructor| is in a register and arguments are in
25662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // |args|. The final argument must be a spread.
25762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& ConstructWithSpread(Register constructor,
25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                            RegisterList args);
259f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Call the runtime function with |function_id| and arguments |args|.
261f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id,
262f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    RegisterList args);
263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Call the runtime function with |function_id| with single argument |arg|.
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id,
265f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                    Register arg);
266f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Call the runtime function with |function_id| with no arguments.
267f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id);
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
269f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Call the runtime function with |function_id| and arguments |args|, that
270f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // returns a pair of values. The return values will be returned in
271f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // |return_pair|.
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id,
273f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                           RegisterList args,
274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                           RegisterList return_pair);
275f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Call the runtime function with |function_id| with single argument |arg|
276f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // that returns a pair of values. The return values will be returned in
277f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // |return_pair|.
278f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id,
279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                           Register arg,
280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                           RegisterList return_pair);
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Call the JS runtime function with |context_index| and arguments |args|.
283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& CallJSRuntime(int context_index, RegisterList args);
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Operators (register holds the lhs value, accumulator holds the rhs value).
286f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Type feedback will be recorded in the |feedback_slot|
287f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg,
288f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                        int feedback_slot);
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Count Operators (value stored in accumulator).
291f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Type feedback will be recorded in the |feedback_slot|
292f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BytecodeArrayBuilder& CountOperation(Token::Value op, int feedback_slot);
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Unary Operators.
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& LogicalNot();
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& TypeOf();
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
29862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Expects a heap object in the accumulator. Returns its super constructor in
29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // the register |out| if it passes the IsConstructor test. Otherwise, it
30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // throws a TypeError exception.
30162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& GetSuperConstructor(Register out);
30262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Deletes property from an object. This expects that accumulator contains
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the key to be deleted and the register contains a reference to the object.
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& Delete(Register object, LanguageMode language_mode);
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Tests.
308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg,
309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                         int feedback_slot = kNoFeedbackSlot);
310f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
311f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // Converts accumulator and stores result in register |out|.
312f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& ConvertAccumulatorToObject(Register out);
313f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& ConvertAccumulatorToName(Register out);
314f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& ConvertAccumulatorToNumber(Register out);
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Flow Control.
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& Bind(BytecodeLabel* label);
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& Bind(const BytecodeLabel& target, BytecodeLabel* label);
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& Jump(BytecodeLabel* label);
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& JumpIfTrue(BytecodeLabel* label);
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& JumpIfFalse(BytecodeLabel* label);
323109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BytecodeArrayBuilder& JumpIfNotHole(BytecodeLabel* label);
32462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& JumpIfJSReceiver(BytecodeLabel* label);
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& JumpIfNull(BytecodeLabel* label);
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& JumpIfUndefined(BytecodeLabel* label);
327f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& JumpLoop(BytecodeLabel* label, int loop_depth);
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
329bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  BytecodeArrayBuilder& StackCheck(int position);
330109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
33162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Sets the pending message to the value in the accumulator, and returns the
33262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // previous pending message in the accumulator.
33362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  BytecodeArrayBuilder& SetPendingMessage();
33462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& Throw();
336109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BytecodeArrayBuilder& ReThrow();
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& Return();
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
339109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Debugger.
340109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BytecodeArrayBuilder& Debugger();
341109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Complex flow control.
343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BytecodeArrayBuilder& ForInPrepare(Register receiver,
344f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                     RegisterList cache_info_triple);
345f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeArrayBuilder& ForInContinue(Register index, Register cache_length);
346109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BytecodeArrayBuilder& ForInNext(Register receiver, Register index,
347f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  RegisterList cache_type_array_pair,
3483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                  int feedback_slot);
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BytecodeArrayBuilder& ForInStep(Register index);
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
351bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Generators.
352bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  BytecodeArrayBuilder& SuspendGenerator(Register generator);
353bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  BytecodeArrayBuilder& ResumeGenerator(Register generator);
354bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
355109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Exception handling.
356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BytecodeArrayBuilder& MarkHandler(int handler_id,
357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                    HandlerTable::CatchPrediction will_catch);
358109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BytecodeArrayBuilder& MarkTryBegin(int handler_id, Register context);
359109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BytecodeArrayBuilder& MarkTryEnd(int handler_id);
360109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
361109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Creates a new handler table entry and returns a {hander_id} identifying the
362109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // entry, so that it can be referenced by above exception handling support.
363109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int NewHandlerEntry() { return handler_table_builder()->NewHandlerEntry(); }
364109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
36562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Gets a constant pool entry.
36662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  size_t GetConstantPoolEntry(const AstRawString* raw_string);
36762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  size_t GetConstantPoolEntry(const AstValue* heap_number);
36862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  size_t GetConstantPoolEntry(const Scope* scope);
36962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define ENTRY_GETTER(NAME, ...) size_t NAME##ConstantPoolEntry();
37062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  SINGLETON_CONSTANT_ENTRY_TYPES(ENTRY_GETTER)
37162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef ENTRY_GETTER
37262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
37362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Allocates a slot in the constant pool which can later be set.
37462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  size_t AllocateDeferredConstantPoolEntry();
37562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // Sets the deferred value into an allocated constant pool entry.
37662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void SetDeferredConstantPoolEntry(size_t entry, Handle<Object> object);
377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void InitializeReturnPosition(FunctionLiteral* literal);
3793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
380f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void SetStatementPosition(Statement* stmt) {
381f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (stmt->position() == kNoSourcePosition) return;
382f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    latest_source_info_.MakeStatementPosition(stmt->position());
383f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
384f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
385f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void SetExpressionPosition(Expression* expr) {
386f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (expr->position() == kNoSourcePosition) return;
387f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (!latest_source_info_.is_statement()) {
388f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // Ensure the current expression position is overwritten with the
389f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // latest value.
390f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      latest_source_info_.MakeExpressionPosition(expr->position());
391f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
392f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
393f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
394f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void SetExpressionAsStatementPosition(Expression* expr) {
395f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (expr->position() == kNoSourcePosition) return;
396f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    latest_source_info_.MakeStatementPosition(expr->position());
397f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
398f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
399f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool RequiresImplicitReturn() const { return !return_seen_in_block_; }
400109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
401c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Returns the raw operand value for the given register or register list.
402c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  uint32_t GetInputRegisterOperand(Register reg);
403c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  uint32_t GetOutputRegisterOperand(Register reg);
404c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  uint32_t GetInputRegisterListOperand(RegisterList reg_list);
405c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  uint32_t GetOutputRegisterListOperand(RegisterList reg_list);
406c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Accessors
408f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeRegisterAllocator* register_allocator() {
409f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return &register_allocator_;
410f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  }
411f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const BytecodeRegisterAllocator* register_allocator() const {
412f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return &register_allocator_;
413f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch  }
414bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Zone* zone() const { return zone_; }
4158389745919cae02139ddc085a63c00d024269cf2Ben Murdoch
416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch private:
417f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  friend class BytecodeRegisterAllocator;
41862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  template <Bytecode bytecode, AccumulatorUse accumulator_use,
41962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            OperandType... operand_types>
420c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  friend class BytecodeNodeBuilder;
421f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
42262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const FeedbackVectorSpec* feedback_vector_spec() const {
42362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return literal_->feedback_vector_spec();
42462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
42562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
426c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Returns the current source position for the given |bytecode|.
427c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  INLINE(BytecodeSourceInfo CurrentSourcePosition(Bytecode bytecode));
428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
429c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#define DECLARE_BYTECODE_OUTPUT(Name, ...)         \
430c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  template <typename... Operands>                  \
431c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  INLINE(void Output##Name(Operands... operands)); \
432c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  template <typename... Operands>                  \
433c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  INLINE(void Output##Name(BytecodeLabel* label, Operands... operands));
434c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  BYTECODE_LIST(DECLARE_BYTECODE_OUTPUT)
435c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#undef DECLARE_OPERAND_TYPE_INFO
436f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool RegisterIsValid(Register reg) const;
438c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool RegisterListIsValid(RegisterList reg_list) const;
439109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
4403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Set position for return.
4413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void SetReturnPosition();
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
443bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Not implemented as the illegal bytecode is used inside internally
444bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // to indicate a bytecode field is not valid or an error has occured
445bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // during bytecode generation.
446bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  BytecodeArrayBuilder& Illegal();
447bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
44862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  template <Bytecode bytecode, AccumulatorUse accumulator_use>
44962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void PrepareToOutputBytecode();
450c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
45113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void LeaveBasicBlock() { return_seen_in_block_ = false; }
45213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
453bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  BytecodeArrayWriter* bytecode_array_writer() {
454bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return &bytecode_array_writer_;
455bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
456bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  BytecodePipelineStage* pipeline() { return pipeline_; }
457109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ConstantArrayBuilder* constant_array_builder() {
458109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return &constant_array_builder_;
459109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
460109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const ConstantArrayBuilder* constant_array_builder() const {
461109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return &constant_array_builder_;
462109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
463109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HandlerTableBuilder* handler_table_builder() {
464109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return &handler_table_builder_;
465109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
466109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Zone* zone_;
46862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FunctionLiteral* literal_;
469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool bytecode_generated_;
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConstantArrayBuilder constant_array_builder_;
471109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  HandlerTableBuilder handler_table_builder_;
47213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  bool return_seen_in_block_;
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int parameter_count_;
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int local_register_count_;
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int context_register_count_;
4763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int return_position_;
477f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BytecodeRegisterAllocator register_allocator_;
478bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  BytecodeArrayWriter bytecode_array_writer_;
479bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  BytecodePipelineStage* pipeline_;
480c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  BytecodeRegisterOptimizer* register_optimizer_;
481bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  BytecodeSourceInfo latest_source_info_;
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
483f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static int const kNoFeedbackSlot = 0;
484f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder);
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace interpreter
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_
493