blob: 4446a635968a95f69c4e99afe810f64dfa45310d [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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"
Ben Murdoch097c5b22016-05-18 11:27:45 +01009#include "src/interpreter/bytecode-register-allocator.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/interpreter/bytecodes.h"
11#include "src/interpreter/constant-array-builder.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010012#include "src/interpreter/handler-table-builder.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010013#include "src/interpreter/source-position-table.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000014#include "src/zone-containers.h"
15
16namespace v8 {
17namespace internal {
18
19class Isolate;
20
21namespace interpreter {
22
23class BytecodeLabel;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000024class Register;
25
Ben Murdochda12d292016-06-02 14:46:10 +010026class BytecodeArrayBuilder final : public ZoneObject {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +010028 BytecodeArrayBuilder(Isolate* isolate, Zone* zone, int parameter_count,
Ben Murdochda12d292016-06-02 14:46:10 +010029 int context_count, int locals_count,
30 FunctionLiteral* literal = nullptr);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000031 ~BytecodeArrayBuilder();
32
33 Handle<BytecodeArray> ToBytecodeArray();
34
Ben Murdoch097c5b22016-05-18 11:27:45 +010035 // Get the number of parameters expected by function.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000036 int parameter_count() const {
37 DCHECK_GE(parameter_count_, 0);
38 return parameter_count_;
39 }
40
Ben Murdoch097c5b22016-05-18 11:27:45 +010041 // Get the number of locals required for bytecode array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042 int locals_count() const {
43 DCHECK_GE(local_register_count_, 0);
44 return local_register_count_;
45 }
46
Ben Murdoch097c5b22016-05-18 11:27:45 +010047 // Get number of contexts required for bytecode array.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000048 int context_count() const {
49 DCHECK_GE(context_register_count_, 0);
50 return context_register_count_;
51 }
52
53 Register first_context_register() const;
54 Register last_context_register() const;
55
56 // Returns the number of fixed (non-temporary) registers.
57 int fixed_register_count() const { return context_count() + locals_count(); }
58
Ben Murdoch097c5b22016-05-18 11:27:45 +010059 // Returns the number of fixed and temporary registers.
60 int fixed_and_temporary_register_count() const {
61 return fixed_register_count() + temporary_register_count();
62 }
63
64 int temporary_register_count() const {
65 return temporary_register_allocator()->allocation_count();
66 }
67
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068 Register Parameter(int parameter_index) const;
69
70 // Return true if the register |reg| represents a parameter or a
71 // local.
72 bool RegisterIsParameterOrLocal(Register reg) const;
73
Ben Murdoch097c5b22016-05-18 11:27:45 +010074 // Returns true if the register |reg| is a live temporary register.
75 bool TemporaryRegisterIsLive(Register reg) const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076
77 // Constant loads to accumulator.
78 BytecodeArrayBuilder& LoadLiteral(v8::internal::Smi* value);
79 BytecodeArrayBuilder& LoadLiteral(Handle<Object> object);
80 BytecodeArrayBuilder& LoadUndefined();
81 BytecodeArrayBuilder& LoadNull();
82 BytecodeArrayBuilder& LoadTheHole();
83 BytecodeArrayBuilder& LoadTrue();
84 BytecodeArrayBuilder& LoadFalse();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000085
86 // Global loads to the accumulator and stores from the accumulator.
87 BytecodeArrayBuilder& LoadGlobal(const Handle<String> name, int feedback_slot,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000088 TypeofMode typeof_mode);
89 BytecodeArrayBuilder& StoreGlobal(const Handle<String> name,
90 int feedback_slot,
91 LanguageMode language_mode);
92
93 // Load the object at |slot_index| in |context| into the accumulator.
94 BytecodeArrayBuilder& LoadContextSlot(Register context, int slot_index);
95
96 // Stores the object in the accumulator into |slot_index| of |context|.
97 BytecodeArrayBuilder& StoreContextSlot(Register context, int slot_index);
98
99 // Register-accumulator transfers.
100 BytecodeArrayBuilder& LoadAccumulatorWithRegister(Register reg);
101 BytecodeArrayBuilder& StoreAccumulatorInRegister(Register reg);
102
103 // Register-register transfer.
104 BytecodeArrayBuilder& MoveRegister(Register from, Register to);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105
106 // Named load property.
107 BytecodeArrayBuilder& LoadNamedProperty(Register object,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100108 const Handle<Name> name,
109 int feedback_slot);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000110 // Keyed load property. The key should be in the accumulator.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100111 BytecodeArrayBuilder& LoadKeyedProperty(Register object, int feedback_slot);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000112
113 // Store properties. The value to be stored should be in the accumulator.
114 BytecodeArrayBuilder& StoreNamedProperty(Register object,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100115 const Handle<Name> name,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116 int feedback_slot,
117 LanguageMode language_mode);
118 BytecodeArrayBuilder& StoreKeyedProperty(Register object, Register key,
119 int feedback_slot,
120 LanguageMode language_mode);
121
122 // Lookup the variable with |name|.
123 BytecodeArrayBuilder& LoadLookupSlot(const Handle<String> name,
124 TypeofMode typeof_mode);
125
126 // Store value in the accumulator into the variable with |name|.
127 BytecodeArrayBuilder& StoreLookupSlot(const Handle<String> name,
128 LanguageMode language_mode);
129
130 // Create a new closure for the SharedFunctionInfo.
131 BytecodeArrayBuilder& CreateClosure(Handle<SharedFunctionInfo> shared_info,
132 PretenureFlag tenured);
133
134 // Create a new arguments object in the accumulator.
135 BytecodeArrayBuilder& CreateArguments(CreateArgumentsType type);
136
137 // Literals creation. Constant elements should be in the accumulator.
138 BytecodeArrayBuilder& CreateRegExpLiteral(Handle<String> pattern,
139 int literal_index, int flags);
140 BytecodeArrayBuilder& CreateArrayLiteral(Handle<FixedArray> constant_elements,
141 int literal_index, int flags);
142 BytecodeArrayBuilder& CreateObjectLiteral(
143 Handle<FixedArray> constant_properties, int literal_index, int flags);
144
145 // Push the context in accumulator as the new context, and store in register
146 // |context|.
147 BytecodeArrayBuilder& PushContext(Register context);
148
149 // Pop the current context and replace with |context|.
150 BytecodeArrayBuilder& PopContext(Register context);
151
152 // Call a JS function. The JSFunction or Callable to be called should be in
Ben Murdoch097c5b22016-05-18 11:27:45 +0100153 // |callable|, the receiver should be in |receiver_args| and all subsequent
154 // arguments should be in registers <receiver_args + 1> to
155 // <receiver_args + receiver_arg_count - 1>.
156 BytecodeArrayBuilder& Call(
157 Register callable, Register receiver_args, size_t receiver_arg_count,
158 int feedback_slot, TailCallMode tail_call_mode = TailCallMode::kDisallow);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000159
Ben Murdoch097c5b22016-05-18 11:27:45 +0100160 BytecodeArrayBuilder& TailCall(Register callable, Register receiver_args,
161 size_t receiver_arg_count, int feedback_slot) {
162 return Call(callable, receiver_args, receiver_arg_count, feedback_slot,
163 TailCallMode::kAllow);
164 }
165
166 // Call the new operator. The accumulator holds the |new_target|.
167 // The |constructor| is in a register followed by |arg_count|
168 // consecutive arguments starting at |first_arg| for the constuctor
169 // invocation.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000170 BytecodeArrayBuilder& New(Register constructor, Register first_arg,
171 size_t arg_count);
172
173 // Call the runtime function with |function_id|. The first argument should be
174 // in |first_arg| and all subsequent arguments should be in registers
Ben Murdoch097c5b22016-05-18 11:27:45 +0100175 // <first_arg + 1> to <first_arg + arg_count - 1>.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176 BytecodeArrayBuilder& CallRuntime(Runtime::FunctionId function_id,
177 Register first_arg, size_t arg_count);
178
179 // Call the runtime function with |function_id| that returns a pair of values.
180 // The first argument should be in |first_arg| and all subsequent arguments
Ben Murdoch097c5b22016-05-18 11:27:45 +0100181 // should be in registers <first_arg + 1> to <first_arg + arg_count - 1>. The
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000182 // return values will be returned in <first_return> and <first_return + 1>.
183 BytecodeArrayBuilder& CallRuntimeForPair(Runtime::FunctionId function_id,
184 Register first_arg, size_t arg_count,
185 Register first_return);
186
187 // Call the JS runtime function with |context_index|. The the receiver should
Ben Murdoch097c5b22016-05-18 11:27:45 +0100188 // be in |receiver_args| and all subsequent arguments should be in registers
189 // <receiver + 1> to <receiver + receiver_args_count - 1>.
190 BytecodeArrayBuilder& CallJSRuntime(int context_index, Register receiver_args,
191 size_t receiver_args_count);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000192
193 // Operators (register holds the lhs value, accumulator holds the rhs value).
Ben Murdoch097c5b22016-05-18 11:27:45 +0100194 BytecodeArrayBuilder& BinaryOperation(Token::Value binop, Register reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000195
196 // Count Operators (value stored in accumulator).
Ben Murdoch097c5b22016-05-18 11:27:45 +0100197 BytecodeArrayBuilder& CountOperation(Token::Value op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000198
199 // Unary Operators.
200 BytecodeArrayBuilder& LogicalNot();
201 BytecodeArrayBuilder& TypeOf();
202
203 // Deletes property from an object. This expects that accumulator contains
204 // the key to be deleted and the register contains a reference to the object.
205 BytecodeArrayBuilder& Delete(Register object, LanguageMode language_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000206
207 // Tests.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100208 BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000209
210 // Casts.
211 BytecodeArrayBuilder& CastAccumulatorToBoolean();
212 BytecodeArrayBuilder& CastAccumulatorToJSObject();
213 BytecodeArrayBuilder& CastAccumulatorToName();
214 BytecodeArrayBuilder& CastAccumulatorToNumber();
215
216 // Flow Control.
217 BytecodeArrayBuilder& Bind(BytecodeLabel* label);
218 BytecodeArrayBuilder& Bind(const BytecodeLabel& target, BytecodeLabel* label);
219
220 BytecodeArrayBuilder& Jump(BytecodeLabel* label);
221 BytecodeArrayBuilder& JumpIfTrue(BytecodeLabel* label);
222 BytecodeArrayBuilder& JumpIfFalse(BytecodeLabel* label);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100223 BytecodeArrayBuilder& JumpIfNotHole(BytecodeLabel* label);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000224 BytecodeArrayBuilder& JumpIfNull(BytecodeLabel* label);
225 BytecodeArrayBuilder& JumpIfUndefined(BytecodeLabel* label);
226
Ben Murdoch097c5b22016-05-18 11:27:45 +0100227 BytecodeArrayBuilder& StackCheck();
228
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000229 BytecodeArrayBuilder& Throw();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100230 BytecodeArrayBuilder& ReThrow();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000231 BytecodeArrayBuilder& Return();
232
Ben Murdoch097c5b22016-05-18 11:27:45 +0100233 // Debugger.
234 BytecodeArrayBuilder& Debugger();
235
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000236 // Complex flow control.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100237 BytecodeArrayBuilder& ForInPrepare(Register cache_info_triple);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000238 BytecodeArrayBuilder& ForInDone(Register index, Register cache_length);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100239 BytecodeArrayBuilder& ForInNext(Register receiver, Register index,
Ben Murdochda12d292016-06-02 14:46:10 +0100240 Register cache_type_array_pair,
241 int feedback_slot);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000242 BytecodeArrayBuilder& ForInStep(Register index);
243
Ben Murdoch097c5b22016-05-18 11:27:45 +0100244 // Exception handling.
245 BytecodeArrayBuilder& MarkHandler(int handler_id, bool will_catch);
246 BytecodeArrayBuilder& MarkTryBegin(int handler_id, Register context);
247 BytecodeArrayBuilder& MarkTryEnd(int handler_id);
248
249 // Creates a new handler table entry and returns a {hander_id} identifying the
250 // entry, so that it can be referenced by above exception handling support.
251 int NewHandlerEntry() { return handler_table_builder()->NewHandlerEntry(); }
252
Ben Murdochda12d292016-06-02 14:46:10 +0100253 void InitializeReturnPosition(FunctionLiteral* literal);
254
Ben Murdoch097c5b22016-05-18 11:27:45 +0100255 void SetStatementPosition(Statement* stmt);
256 void SetExpressionPosition(Expression* expr);
Ben Murdochda12d292016-06-02 14:46:10 +0100257 void SetExpressionAsStatementPosition(Expression* expr);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100258
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000259 // Accessors
260 Zone* zone() const { return zone_; }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100261 TemporaryRegisterAllocator* temporary_register_allocator() {
262 return &temporary_allocator_;
263 }
264 const TemporaryRegisterAllocator* temporary_register_allocator() const {
265 return &temporary_allocator_;
266 }
267
Ben Murdochda12d292016-06-02 14:46:10 +0100268 void EnsureReturn();
269
270 static OperandScale OperandSizesToScale(
271 OperandSize size0, OperandSize size1 = OperandSize::kByte,
272 OperandSize size2 = OperandSize::kByte,
273 OperandSize size3 = OperandSize::kByte);
274
275 static OperandSize SizeForRegisterOperand(Register reg);
276 static OperandSize SizeForSignedOperand(int value);
277 static OperandSize SizeForUnsignedOperand(int value);
278 static OperandSize SizeForUnsignedOperand(size_t value);
279
280 static uint32_t RegisterOperand(Register reg);
281 static Register RegisterFromOperand(uint32_t operand);
282 static uint32_t SignedOperand(int value, OperandSize size);
283 static uint32_t UnsignedOperand(int value);
284 static uint32_t UnsignedOperand(size_t value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000285
286 private:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100287 class PreviousBytecodeHelper;
288 friend class BytecodeRegisterAllocator;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000289
290 static Bytecode BytecodeForBinaryOperation(Token::Value op);
291 static Bytecode BytecodeForCountOperation(Token::Value op);
292 static Bytecode BytecodeForCompareOperation(Token::Value op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000293 static Bytecode BytecodeForStoreIC(LanguageMode language_mode);
294 static Bytecode BytecodeForKeyedStoreIC(LanguageMode language_mode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100295 static Bytecode BytecodeForLoadGlobal(TypeofMode typeof_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000296 static Bytecode BytecodeForStoreGlobal(LanguageMode language_mode);
297 static Bytecode BytecodeForStoreLookupSlot(LanguageMode language_mode);
298 static Bytecode BytecodeForCreateArguments(CreateArgumentsType type);
299 static Bytecode BytecodeForDelete(LanguageMode language_mode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100300 static Bytecode BytecodeForCall(TailCallMode tail_call_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000301
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000302 static Bytecode GetJumpWithConstantOperand(Bytecode jump_smi8_operand);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000303 static Bytecode GetJumpWithToBoolean(Bytecode jump_smi8_operand);
304
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000305 template <size_t N>
Ben Murdochda12d292016-06-02 14:46:10 +0100306 INLINE(void Output(Bytecode bytecode, uint32_t (&operands)[N],
307 OperandScale operand_scale = OperandScale::kSingle));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000308 void Output(Bytecode bytecode);
Ben Murdochda12d292016-06-02 14:46:10 +0100309 void OutputScaled(Bytecode bytecode, OperandScale operand_scale,
310 uint32_t operand0, uint32_t operand1, uint32_t operand2,
311 uint32_t operand3);
312 void OutputScaled(Bytecode bytecode, OperandScale operand_scale,
313 uint32_t operand0, uint32_t operand1, uint32_t operand2);
314 void OutputScaled(Bytecode bytecode, OperandScale operand_scale,
315 uint32_t operand0, uint32_t operand1);
316 void OutputScaled(Bytecode bytecode, OperandScale operand_scale,
317 uint32_t operand0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000318
319 BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode,
320 BytecodeLabel* label);
321 void PatchJump(const ZoneVector<uint8_t>::iterator& jump_target,
322 const ZoneVector<uint8_t>::iterator& jump_location);
323 void PatchIndirectJumpWith8BitOperand(
324 const ZoneVector<uint8_t>::iterator& jump_location, int delta);
325 void PatchIndirectJumpWith16BitOperand(
326 const ZoneVector<uint8_t>::iterator& jump_location, int delta);
Ben Murdochda12d292016-06-02 14:46:10 +0100327 void PatchIndirectJumpWith32BitOperand(
328 const ZoneVector<uint8_t>::iterator& jump_location, int delta);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000329
330 void LeaveBasicBlock();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000331
Ben Murdochda12d292016-06-02 14:46:10 +0100332 bool OperandIsValid(Bytecode bytecode, OperandScale operand_scale,
333 int operand_index, uint32_t operand_value) const;
334 bool RegisterIsValid(Register reg, OperandSize reg_size) const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000335
Ben Murdoch097c5b22016-05-18 11:27:45 +0100336 bool LastBytecodeInSameBlock() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000337 bool NeedToBooleanCast();
338 bool IsRegisterInAccumulator(Register reg);
339
Ben Murdochda12d292016-06-02 14:46:10 +0100340 // Set position for return.
341 void SetReturnPosition();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000342
343 // Gets a constant pool entry for the |object|.
344 size_t GetConstantPoolEntry(Handle<Object> object);
345
Ben Murdoch097c5b22016-05-18 11:27:45 +0100346 ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; }
347 const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; }
348 Isolate* isolate() const { return isolate_; }
349 ConstantArrayBuilder* constant_array_builder() {
350 return &constant_array_builder_;
351 }
352 const ConstantArrayBuilder* constant_array_builder() const {
353 return &constant_array_builder_;
354 }
355 HandlerTableBuilder* handler_table_builder() {
356 return &handler_table_builder_;
357 }
358 SourcePositionTableBuilder* source_position_table_builder() {
359 return &source_position_table_builder_;
360 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100361
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000362 Isolate* isolate_;
363 Zone* zone_;
364 ZoneVector<uint8_t> bytecodes_;
365 bool bytecode_generated_;
366 ConstantArrayBuilder constant_array_builder_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100367 HandlerTableBuilder handler_table_builder_;
368 SourcePositionTableBuilder source_position_table_builder_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000369 size_t last_block_end_;
370 size_t last_bytecode_start_;
371 bool exit_seen_in_block_;
372 int unbound_jumps_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000373 int parameter_count_;
374 int local_register_count_;
375 int context_register_count_;
Ben Murdochda12d292016-06-02 14:46:10 +0100376 int return_position_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100377 TemporaryRegisterAllocator temporary_allocator_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000378
379 DISALLOW_COPY_AND_ASSIGN(BytecodeArrayBuilder);
380};
381
382
383// A label representing a branch target in a bytecode array. When a
384// label is bound, it represents a known position in the bytecode
385// array. For labels that are forward references there can be at most
386// one reference whilst it is unbound.
387class BytecodeLabel final {
388 public:
389 BytecodeLabel() : bound_(false), offset_(kInvalidOffset) {}
390
391 bool is_bound() const { return bound_; }
392 size_t offset() const { return offset_; }
393
394 private:
395 static const size_t kInvalidOffset = static_cast<size_t>(-1);
396
397 void bind_to(size_t offset) {
398 DCHECK(!bound_ && offset != kInvalidOffset);
399 offset_ = offset;
400 bound_ = true;
401 }
402
403 void set_referrer(size_t offset) {
404 DCHECK(!bound_ && offset != kInvalidOffset && offset_ == kInvalidOffset);
405 offset_ = offset;
406 }
407
408 bool is_forward_target() const {
409 return offset() != kInvalidOffset && !is_bound();
410 }
411
412 // There are three states for a label:
413 // bound_ offset_
414 // UNSET false kInvalidOffset
415 // FORWARD_TARGET false Offset of referring jump
416 // BACKWARD_TARGET true Offset of label in bytecode array when bound
417 bool bound_;
418 size_t offset_;
419
420 friend class BytecodeArrayBuilder;
421};
422
423} // namespace interpreter
424} // namespace internal
425} // namespace v8
426
427#endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_