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