blob: 4ef173890c0e880d0adbf63fcd48821dd31ec077 [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"
10#include "src/interpreter/bytecodes.h"
11
12namespace v8 {
13namespace internal {
14namespace interpreter {
15
Ben Murdoch097c5b22016-05-18 11:27:45 +010016class LoopBuilder;
17
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000018class BytecodeGenerator final : public AstVisitor {
19 public:
20 BytecodeGenerator(Isolate* isolate, Zone* zone);
21
22 Handle<BytecodeArray> MakeBytecode(CompilationInfo* info);
23
24#define DECLARE_VISIT(type) void Visit##type(type* node) override;
25 AST_NODE_LIST(DECLARE_VISIT)
26#undef DECLARE_VISIT
27
28 // Visiting function for declarations list and statements are overridden.
29 void VisitDeclarations(ZoneList<Declaration*>* declarations) override;
30 void VisitStatements(ZoneList<Statement*>* statments) override;
31
32 private:
33 class ContextScope;
34 class ControlScope;
35 class ControlScopeForBreakable;
36 class ControlScopeForIteration;
Ben Murdoch097c5b22016-05-18 11:27:45 +010037 class ControlScopeForTopLevel;
38 class ControlScopeForTryCatch;
39 class ControlScopeForTryFinally;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 class ExpressionResultScope;
41 class EffectResultScope;
42 class AccumulatorResultScope;
43 class RegisterResultScope;
44 class RegisterAllocationScope;
45
46 void MakeBytecodeBody();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000047
48 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
49
50 // Dispatched from VisitBinaryOperation.
51 void VisitArithmeticExpression(BinaryOperation* binop);
52 void VisitCommaExpression(BinaryOperation* binop);
53 void VisitLogicalOrExpression(BinaryOperation* binop);
54 void VisitLogicalAndExpression(BinaryOperation* binop);
55
56 // Dispatched from VisitUnaryOperation.
57 void VisitVoid(UnaryOperation* expr);
58 void VisitTypeOf(UnaryOperation* expr);
59 void VisitNot(UnaryOperation* expr);
60 void VisitDelete(UnaryOperation* expr);
61
62 // Used by flow control routines to evaluate loop condition.
63 void VisitCondition(Expression* expr);
64
65 // Helper visitors which perform common operations.
66 Register VisitArguments(ZoneList<Expression*>* arguments);
67
Ben Murdoch097c5b22016-05-18 11:27:45 +010068 // Visit a keyed super property load. The optional
69 // |opt_receiver_out| register will have the receiver stored to it
70 // if it's a valid register. The loaded value is placed in the
71 // accumulator.
72 void VisitKeyedSuperPropertyLoad(Property* property,
73 Register opt_receiver_out);
74
75 // Visit a named super property load. The optional
76 // |opt_receiver_out| register will have the receiver stored to it
77 // if it's a valid register. The loaded value is placed in the
78 // accumulator.
79 void VisitNamedSuperPropertyLoad(Property* property,
80 Register opt_receiver_out);
81
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000082 void VisitPropertyLoad(Register obj, Property* expr);
83 void VisitPropertyLoadForAccumulator(Register obj, Property* expr);
84
85 void VisitVariableLoad(Variable* variable, FeedbackVectorSlot slot,
86 TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
87 void VisitVariableLoadForAccumulatorValue(
88 Variable* variable, FeedbackVectorSlot slot,
89 TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
90 MUST_USE_RESULT Register
91 VisitVariableLoadForRegisterValue(Variable* variable, FeedbackVectorSlot slot,
92 TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
Ben Murdoch097c5b22016-05-18 11:27:45 +010093 void VisitVariableAssignment(Variable* variable, Token::Value op,
94 FeedbackVectorSlot slot);
95
96 void BuildNamedSuperPropertyStore(Register receiver, Register home_object,
97 Register name, Register value);
98 void BuildKeyedSuperPropertyStore(Register receiver, Register home_object,
99 Register key, Register value);
100 void BuildNamedSuperPropertyLoad(Register receiver, Register home_object,
101 Register name);
102 void BuildKeyedSuperPropertyLoad(Register receiver, Register home_object,
103 Register key);
104
105 void BuildThrowIfHole(Handle<String> name);
106 void BuildThrowIfNotHole(Handle<String> name);
107 void BuildThrowReassignConstant(Handle<String> name);
108 void BuildThrowReferenceError(Handle<String> name);
109 void BuildHoleCheckForVariableLoad(VariableMode mode, Handle<String> name);
110 void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000111
112 void VisitArgumentsObject(Variable* variable);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100113 void VisitRestArgumentsArray(Variable* rest);
114 void VisitCallSuper(Call* call);
115 void VisitClassLiteralContents(ClassLiteral* expr);
116 void VisitClassLiteralForRuntimeDefinition(ClassLiteral* expr);
117 void VisitClassLiteralProperties(ClassLiteral* expr, Register literal,
118 Register prototype);
119 void VisitClassLiteralStaticPrototypeWithComputedName(Register name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120 void VisitThisFunctionVariable(Variable* variable);
121 void VisitNewTargetVariable(Variable* variable);
122 void VisitNewLocalFunctionContext();
123 void VisitBuildLocalActivationContext();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100124 void VisitBlockDeclarationsAndStatements(Block* stmt);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000125 void VisitNewLocalBlockContext(Scope* scope);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100126 void VisitNewLocalCatchContext(Variable* variable);
127 void VisitNewLocalWithContext();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000128 void VisitFunctionClosureForContext();
129 void VisitSetHomeObject(Register value, Register home_object,
130 ObjectLiteralProperty* property, int slot_number = 0);
131 void VisitObjectLiteralAccessor(Register home_object,
132 ObjectLiteralProperty* property,
133 Register value_out);
134 void VisitForInAssignment(Expression* expr, FeedbackVectorSlot slot);
135
Ben Murdoch097c5b22016-05-18 11:27:45 +0100136 // Visit the body of a loop iteration.
137 void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop_builder);
138
139 // Visit a statement and switch scopes, the context is in the accumulator.
140 void VisitInScope(Statement* stmt, Scope* scope);
141
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000142 // Visitors for obtaining expression result in the accumulator, in a
143 // register, or just getting the effect.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100144 void VisitForAccumulatorValue(Expression* expr);
145 void VisitForAccumulatorValueOrTheHole(Expression* expr);
146 MUST_USE_RESULT Register VisitForRegisterValue(Expression* expr);
147 void VisitForRegisterValue(Expression* expr, Register destination);
148 void VisitForEffect(Expression* expr);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000149
150 // Methods for tracking and remapping register.
151 void RecordStoreToRegister(Register reg);
152 Register LoadFromAliasedRegister(Register reg);
153
Ben Murdoch097c5b22016-05-18 11:27:45 +0100154 // Methods for tracking try-block nesting.
155 bool IsInsideTryCatch() const { return try_catch_nesting_level_ > 0; }
156 bool IsInsideTryFinally() const { return try_finally_nesting_level_ > 0; }
157
158 // Initialize an array of temporary registers with consecutive registers.
159 template <size_t N>
160 void InitializeWithConsecutiveRegisters(Register (&registers)[N]);
161
162 inline void set_builder(BytecodeArrayBuilder* builder) { builder_ = builder; }
163 inline BytecodeArrayBuilder* builder() const { return builder_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000164
165 inline Isolate* isolate() const { return isolate_; }
166 inline Zone* zone() const { return zone_; }
167
168 inline Scope* scope() const { return scope_; }
169 inline void set_scope(Scope* scope) { scope_ = scope; }
170 inline CompilationInfo* info() const { return info_; }
171 inline void set_info(CompilationInfo* info) { info_ = info; }
172
173 inline ControlScope* execution_control() const { return execution_control_; }
174 inline void set_execution_control(ControlScope* scope) {
175 execution_control_ = scope;
176 }
177 inline ContextScope* execution_context() const { return execution_context_; }
178 inline void set_execution_context(ContextScope* context) {
179 execution_context_ = context;
180 }
181 inline void set_execution_result(ExpressionResultScope* execution_result) {
182 execution_result_ = execution_result;
183 }
184 ExpressionResultScope* execution_result() const { return execution_result_; }
185 inline void set_register_allocator(
186 RegisterAllocationScope* register_allocator) {
187 register_allocator_ = register_allocator;
188 }
189 RegisterAllocationScope* register_allocator() const {
190 return register_allocator_;
191 }
192
193 ZoneVector<Handle<Object>>* globals() { return &globals_; }
194 inline LanguageMode language_mode() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000195 int feedback_index(FeedbackVectorSlot slot) const;
196
197 Isolate* isolate_;
198 Zone* zone_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100199 BytecodeArrayBuilder* builder_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000200 CompilationInfo* info_;
201 Scope* scope_;
202 ZoneVector<Handle<Object>> globals_;
203 ControlScope* execution_control_;
204 ContextScope* execution_context_;
205 ExpressionResultScope* execution_result_;
206 RegisterAllocationScope* register_allocator_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100207 int try_catch_nesting_level_;
208 int try_finally_nesting_level_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000209};
210
211} // namespace interpreter
212} // namespace internal
213} // namespace v8
214
215#endif // V8_INTERPRETER_BYTECODE_GENERATOR_H_