blob: 3adca6bc24bf7d88db97cfeff5dd0de0e0a488b3 [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_GENERATOR_H_
6#define V8_INTERPRETER_BYTECODE_GENERATOR_H_
7
8#include "src/ast/ast.h"
9#include "src/interpreter/bytecode-array-builder.h"
Ben Murdoch61f157c2016-09-16 13:49:30 +010010#include "src/interpreter/bytecode-label.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000011#include "src/interpreter/bytecodes.h"
12
13namespace v8 {
14namespace internal {
Ben Murdochc5610432016-08-08 18:44:38 +010015
16class CompilationInfo;
17
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000018namespace interpreter {
19
Ben Murdoch097c5b22016-05-18 11:27:45 +010020class LoopBuilder;
21
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000022class BytecodeGenerator final : public AstVisitor {
23 public:
Ben Murdochc5610432016-08-08 18:44:38 +010024 explicit BytecodeGenerator(CompilationInfo* info);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000025
Ben Murdochc5610432016-08-08 18:44:38 +010026 Handle<BytecodeArray> MakeBytecode();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027
28#define DECLARE_VISIT(type) void Visit##type(type* node) override;
29 AST_NODE_LIST(DECLARE_VISIT)
30#undef DECLARE_VISIT
31
32 // Visiting function for declarations list and statements are overridden.
33 void VisitDeclarations(ZoneList<Declaration*>* declarations) override;
34 void VisitStatements(ZoneList<Statement*>* statments) override;
35
36 private:
37 class ContextScope;
38 class ControlScope;
39 class ControlScopeForBreakable;
40 class ControlScopeForIteration;
Ben Murdoch097c5b22016-05-18 11:27:45 +010041 class ControlScopeForTopLevel;
42 class ControlScopeForTryCatch;
43 class ControlScopeForTryFinally;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 class ExpressionResultScope;
45 class EffectResultScope;
46 class AccumulatorResultScope;
47 class RegisterResultScope;
48 class RegisterAllocationScope;
49
50 void MakeBytecodeBody();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000051
52 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
53
54 // Dispatched from VisitBinaryOperation.
55 void VisitArithmeticExpression(BinaryOperation* binop);
56 void VisitCommaExpression(BinaryOperation* binop);
57 void VisitLogicalOrExpression(BinaryOperation* binop);
58 void VisitLogicalAndExpression(BinaryOperation* binop);
59
60 // Dispatched from VisitUnaryOperation.
61 void VisitVoid(UnaryOperation* expr);
62 void VisitTypeOf(UnaryOperation* expr);
63 void VisitNot(UnaryOperation* expr);
64 void VisitDelete(UnaryOperation* expr);
65
66 // Used by flow control routines to evaluate loop condition.
67 void VisitCondition(Expression* expr);
68
69 // Helper visitors which perform common operations.
70 Register VisitArguments(ZoneList<Expression*>* arguments);
71
Ben Murdoch097c5b22016-05-18 11:27:45 +010072 // Visit a keyed super property load. The optional
73 // |opt_receiver_out| register will have the receiver stored to it
74 // if it's a valid register. The loaded value is placed in the
75 // accumulator.
76 void VisitKeyedSuperPropertyLoad(Property* property,
77 Register opt_receiver_out);
78
79 // Visit a named super property load. The optional
80 // |opt_receiver_out| register will have the receiver stored to it
81 // if it's a valid register. The loaded value is placed in the
82 // accumulator.
83 void VisitNamedSuperPropertyLoad(Property* property,
84 Register opt_receiver_out);
85
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000086 void VisitPropertyLoad(Register obj, Property* expr);
87 void VisitPropertyLoadForAccumulator(Register obj, Property* expr);
88
89 void VisitVariableLoad(Variable* variable, FeedbackVectorSlot slot,
90 TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
91 void VisitVariableLoadForAccumulatorValue(
92 Variable* variable, FeedbackVectorSlot slot,
93 TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
94 MUST_USE_RESULT Register
95 VisitVariableLoadForRegisterValue(Variable* variable, FeedbackVectorSlot slot,
96 TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
Ben Murdoch097c5b22016-05-18 11:27:45 +010097 void VisitVariableAssignment(Variable* variable, Token::Value op,
98 FeedbackVectorSlot slot);
99
100 void BuildNamedSuperPropertyStore(Register receiver, Register home_object,
101 Register name, Register value);
102 void BuildKeyedSuperPropertyStore(Register receiver, Register home_object,
103 Register key, Register value);
104 void BuildNamedSuperPropertyLoad(Register receiver, Register home_object,
105 Register name);
106 void BuildKeyedSuperPropertyLoad(Register receiver, Register home_object,
107 Register key);
108
Ben Murdoch61f157c2016-09-16 13:49:30 +0100109 void BuildAbort(BailoutReason bailout_reason);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100110 void BuildThrowIfHole(Handle<String> name);
111 void BuildThrowIfNotHole(Handle<String> name);
112 void BuildThrowReassignConstant(Handle<String> name);
113 void BuildThrowReferenceError(Handle<String> name);
114 void BuildHoleCheckForVariableLoad(VariableMode mode, Handle<String> name);
115 void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116
Ben Murdochc5610432016-08-08 18:44:38 +0100117 // Build jump to targets[value], where
118 // start_index <= value < start_index + size.
119 void BuildIndexedJump(Register value, size_t start_index, size_t size,
120 ZoneVector<BytecodeLabel>& targets);
121
122 void VisitGeneratorPrologue();
123
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000124 void VisitArgumentsObject(Variable* variable);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100125 void VisitRestArgumentsArray(Variable* rest);
126 void VisitCallSuper(Call* call);
127 void VisitClassLiteralContents(ClassLiteral* expr);
128 void VisitClassLiteralForRuntimeDefinition(ClassLiteral* expr);
129 void VisitClassLiteralProperties(ClassLiteral* expr, Register literal,
130 Register prototype);
131 void VisitClassLiteralStaticPrototypeWithComputedName(Register name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000132 void VisitThisFunctionVariable(Variable* variable);
133 void VisitNewTargetVariable(Variable* variable);
134 void VisitNewLocalFunctionContext();
135 void VisitBuildLocalActivationContext();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100136 void VisitBlockDeclarationsAndStatements(Block* stmt);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000137 void VisitNewLocalBlockContext(Scope* scope);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100138 void VisitNewLocalCatchContext(Variable* variable);
139 void VisitNewLocalWithContext();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000140 void VisitFunctionClosureForContext();
141 void VisitSetHomeObject(Register value, Register home_object,
142 ObjectLiteralProperty* property, int slot_number = 0);
143 void VisitObjectLiteralAccessor(Register home_object,
144 ObjectLiteralProperty* property,
145 Register value_out);
146 void VisitForInAssignment(Expression* expr, FeedbackVectorSlot slot);
147
Ben Murdochc5610432016-08-08 18:44:38 +0100148 // Visit the header/body of a loop iteration.
149 void VisitIterationHeader(IterationStatement* stmt,
150 LoopBuilder* loop_builder);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100151 void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop_builder);
152
153 // Visit a statement and switch scopes, the context is in the accumulator.
154 void VisitInScope(Statement* stmt, Scope* scope);
155
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000156 // Visitors for obtaining expression result in the accumulator, in a
157 // register, or just getting the effect.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100158 void VisitForAccumulatorValue(Expression* expr);
159 void VisitForAccumulatorValueOrTheHole(Expression* expr);
160 MUST_USE_RESULT Register VisitForRegisterValue(Expression* expr);
161 void VisitForRegisterValue(Expression* expr, Register destination);
162 void VisitForEffect(Expression* expr);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000163
164 // Methods for tracking and remapping register.
165 void RecordStoreToRegister(Register reg);
166 Register LoadFromAliasedRegister(Register reg);
167
Ben Murdoch097c5b22016-05-18 11:27:45 +0100168 // Methods for tracking try-block nesting.
169 bool IsInsideTryCatch() const { return try_catch_nesting_level_ > 0; }
170 bool IsInsideTryFinally() const { return try_finally_nesting_level_ > 0; }
171
172 // Initialize an array of temporary registers with consecutive registers.
173 template <size_t N>
174 void InitializeWithConsecutiveRegisters(Register (&registers)[N]);
175
Ben Murdoch097c5b22016-05-18 11:27:45 +0100176 inline BytecodeArrayBuilder* builder() const { return builder_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000177 inline Isolate* isolate() const { return isolate_; }
178 inline Zone* zone() const { return zone_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000179 inline Scope* scope() const { return scope_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000180 inline CompilationInfo* info() const { return info_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000181
182 inline ControlScope* execution_control() const { return execution_control_; }
183 inline void set_execution_control(ControlScope* scope) {
184 execution_control_ = scope;
185 }
186 inline ContextScope* execution_context() const { return execution_context_; }
187 inline void set_execution_context(ContextScope* context) {
188 execution_context_ = context;
189 }
190 inline void set_execution_result(ExpressionResultScope* execution_result) {
191 execution_result_ = execution_result;
192 }
193 ExpressionResultScope* execution_result() const { return execution_result_; }
194 inline void set_register_allocator(
195 RegisterAllocationScope* register_allocator) {
196 register_allocator_ = register_allocator;
197 }
198 RegisterAllocationScope* register_allocator() const {
199 return register_allocator_;
200 }
201
202 ZoneVector<Handle<Object>>* globals() { return &globals_; }
203 inline LanguageMode language_mode() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000204 int feedback_index(FeedbackVectorSlot slot) const;
205
206 Isolate* isolate_;
207 Zone* zone_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100208 BytecodeArrayBuilder* builder_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000209 CompilationInfo* info_;
210 Scope* scope_;
211 ZoneVector<Handle<Object>> globals_;
212 ControlScope* execution_control_;
213 ContextScope* execution_context_;
214 ExpressionResultScope* execution_result_;
215 RegisterAllocationScope* register_allocator_;
Ben Murdochc5610432016-08-08 18:44:38 +0100216 ZoneVector<BytecodeLabel> generator_resume_points_;
217 Register generator_state_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100218 int try_catch_nesting_level_;
219 int try_finally_nesting_level_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000220};
221
222} // namespace interpreter
223} // namespace internal
224} // namespace v8
225
226#endif // V8_INTERPRETER_BYTECODE_GENERATOR_H_