blob: 0dcc9be62ad6b51bcecf9c32b3473c5c0634f03b [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 {
Ben Murdochc5610432016-08-08 18:44:38 +010014
15class CompilationInfo;
16
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000017namespace interpreter {
18
Ben Murdoch097c5b22016-05-18 11:27:45 +010019class LoopBuilder;
20
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000021class BytecodeGenerator final : public AstVisitor {
22 public:
Ben Murdochc5610432016-08-08 18:44:38 +010023 explicit BytecodeGenerator(CompilationInfo* info);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000024
Ben Murdochc5610432016-08-08 18:44:38 +010025 Handle<BytecodeArray> MakeBytecode();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026
27#define DECLARE_VISIT(type) void Visit##type(type* node) override;
28 AST_NODE_LIST(DECLARE_VISIT)
29#undef DECLARE_VISIT
30
31 // Visiting function for declarations list and statements are overridden.
32 void VisitDeclarations(ZoneList<Declaration*>* declarations) override;
33 void VisitStatements(ZoneList<Statement*>* statments) override;
34
35 private:
36 class ContextScope;
37 class ControlScope;
38 class ControlScopeForBreakable;
39 class ControlScopeForIteration;
Ben Murdoch097c5b22016-05-18 11:27:45 +010040 class ControlScopeForTopLevel;
41 class ControlScopeForTryCatch;
42 class ControlScopeForTryFinally;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000043 class ExpressionResultScope;
44 class EffectResultScope;
45 class AccumulatorResultScope;
46 class RegisterResultScope;
47 class RegisterAllocationScope;
48
49 void MakeBytecodeBody();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000050
51 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
52
53 // Dispatched from VisitBinaryOperation.
54 void VisitArithmeticExpression(BinaryOperation* binop);
55 void VisitCommaExpression(BinaryOperation* binop);
56 void VisitLogicalOrExpression(BinaryOperation* binop);
57 void VisitLogicalAndExpression(BinaryOperation* binop);
58
59 // Dispatched from VisitUnaryOperation.
60 void VisitVoid(UnaryOperation* expr);
61 void VisitTypeOf(UnaryOperation* expr);
62 void VisitNot(UnaryOperation* expr);
63 void VisitDelete(UnaryOperation* expr);
64
65 // Used by flow control routines to evaluate loop condition.
66 void VisitCondition(Expression* expr);
67
68 // Helper visitors which perform common operations.
69 Register VisitArguments(ZoneList<Expression*>* arguments);
70
Ben Murdoch097c5b22016-05-18 11:27:45 +010071 // Visit a keyed super property load. The optional
72 // |opt_receiver_out| register will have the receiver stored to it
73 // if it's a valid register. The loaded value is placed in the
74 // accumulator.
75 void VisitKeyedSuperPropertyLoad(Property* property,
76 Register opt_receiver_out);
77
78 // Visit a named super property load. The optional
79 // |opt_receiver_out| register will have the receiver stored to it
80 // if it's a valid register. The loaded value is placed in the
81 // accumulator.
82 void VisitNamedSuperPropertyLoad(Property* property,
83 Register opt_receiver_out);
84
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000085 void VisitPropertyLoad(Register obj, Property* expr);
86 void VisitPropertyLoadForAccumulator(Register obj, Property* expr);
87
88 void VisitVariableLoad(Variable* variable, FeedbackVectorSlot slot,
89 TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
90 void VisitVariableLoadForAccumulatorValue(
91 Variable* variable, FeedbackVectorSlot slot,
92 TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
93 MUST_USE_RESULT Register
94 VisitVariableLoadForRegisterValue(Variable* variable, FeedbackVectorSlot slot,
95 TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
Ben Murdoch097c5b22016-05-18 11:27:45 +010096 void VisitVariableAssignment(Variable* variable, Token::Value op,
97 FeedbackVectorSlot slot);
98
99 void BuildNamedSuperPropertyStore(Register receiver, Register home_object,
100 Register name, Register value);
101 void BuildKeyedSuperPropertyStore(Register receiver, Register home_object,
102 Register key, Register value);
103 void BuildNamedSuperPropertyLoad(Register receiver, Register home_object,
104 Register name);
105 void BuildKeyedSuperPropertyLoad(Register receiver, Register home_object,
106 Register key);
107
108 void BuildThrowIfHole(Handle<String> name);
109 void BuildThrowIfNotHole(Handle<String> name);
110 void BuildThrowReassignConstant(Handle<String> name);
111 void BuildThrowReferenceError(Handle<String> name);
112 void BuildHoleCheckForVariableLoad(VariableMode mode, Handle<String> name);
113 void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000114
Ben Murdochc5610432016-08-08 18:44:38 +0100115 // Build jump to targets[value], where
116 // start_index <= value < start_index + size.
117 void BuildIndexedJump(Register value, size_t start_index, size_t size,
118 ZoneVector<BytecodeLabel>& targets);
119
120 void VisitGeneratorPrologue();
121
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000122 void VisitArgumentsObject(Variable* variable);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100123 void VisitRestArgumentsArray(Variable* rest);
124 void VisitCallSuper(Call* call);
125 void VisitClassLiteralContents(ClassLiteral* expr);
126 void VisitClassLiteralForRuntimeDefinition(ClassLiteral* expr);
127 void VisitClassLiteralProperties(ClassLiteral* expr, Register literal,
128 Register prototype);
129 void VisitClassLiteralStaticPrototypeWithComputedName(Register name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000130 void VisitThisFunctionVariable(Variable* variable);
131 void VisitNewTargetVariable(Variable* variable);
132 void VisitNewLocalFunctionContext();
133 void VisitBuildLocalActivationContext();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100134 void VisitBlockDeclarationsAndStatements(Block* stmt);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000135 void VisitNewLocalBlockContext(Scope* scope);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100136 void VisitNewLocalCatchContext(Variable* variable);
137 void VisitNewLocalWithContext();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000138 void VisitFunctionClosureForContext();
139 void VisitSetHomeObject(Register value, Register home_object,
140 ObjectLiteralProperty* property, int slot_number = 0);
141 void VisitObjectLiteralAccessor(Register home_object,
142 ObjectLiteralProperty* property,
143 Register value_out);
144 void VisitForInAssignment(Expression* expr, FeedbackVectorSlot slot);
145
Ben Murdochc5610432016-08-08 18:44:38 +0100146 // Visit the header/body of a loop iteration.
147 void VisitIterationHeader(IterationStatement* stmt,
148 LoopBuilder* loop_builder);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100149 void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop_builder);
150
151 // Visit a statement and switch scopes, the context is in the accumulator.
152 void VisitInScope(Statement* stmt, Scope* scope);
153
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000154 // Visitors for obtaining expression result in the accumulator, in a
155 // register, or just getting the effect.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100156 void VisitForAccumulatorValue(Expression* expr);
157 void VisitForAccumulatorValueOrTheHole(Expression* expr);
158 MUST_USE_RESULT Register VisitForRegisterValue(Expression* expr);
159 void VisitForRegisterValue(Expression* expr, Register destination);
160 void VisitForEffect(Expression* expr);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000161
162 // Methods for tracking and remapping register.
163 void RecordStoreToRegister(Register reg);
164 Register LoadFromAliasedRegister(Register reg);
165
Ben Murdoch097c5b22016-05-18 11:27:45 +0100166 // Methods for tracking try-block nesting.
167 bool IsInsideTryCatch() const { return try_catch_nesting_level_ > 0; }
168 bool IsInsideTryFinally() const { return try_finally_nesting_level_ > 0; }
169
170 // Initialize an array of temporary registers with consecutive registers.
171 template <size_t N>
172 void InitializeWithConsecutiveRegisters(Register (&registers)[N]);
173
Ben Murdoch097c5b22016-05-18 11:27:45 +0100174 inline BytecodeArrayBuilder* builder() const { return builder_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000175 inline Isolate* isolate() const { return isolate_; }
176 inline Zone* zone() const { return zone_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000177 inline Scope* scope() const { return scope_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000178 inline CompilationInfo* info() const { return info_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000179
180 inline ControlScope* execution_control() const { return execution_control_; }
181 inline void set_execution_control(ControlScope* scope) {
182 execution_control_ = scope;
183 }
184 inline ContextScope* execution_context() const { return execution_context_; }
185 inline void set_execution_context(ContextScope* context) {
186 execution_context_ = context;
187 }
188 inline void set_execution_result(ExpressionResultScope* execution_result) {
189 execution_result_ = execution_result;
190 }
191 ExpressionResultScope* execution_result() const { return execution_result_; }
192 inline void set_register_allocator(
193 RegisterAllocationScope* register_allocator) {
194 register_allocator_ = register_allocator;
195 }
196 RegisterAllocationScope* register_allocator() const {
197 return register_allocator_;
198 }
199
200 ZoneVector<Handle<Object>>* globals() { return &globals_; }
201 inline LanguageMode language_mode() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000202 int feedback_index(FeedbackVectorSlot slot) const;
203
204 Isolate* isolate_;
205 Zone* zone_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100206 BytecodeArrayBuilder* builder_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000207 CompilationInfo* info_;
208 Scope* scope_;
209 ZoneVector<Handle<Object>> globals_;
210 ControlScope* execution_control_;
211 ContextScope* execution_context_;
212 ExpressionResultScope* execution_result_;
213 RegisterAllocationScope* register_allocator_;
Ben Murdochc5610432016-08-08 18:44:38 +0100214 ZoneVector<BytecodeLabel> generator_resume_points_;
215 Register generator_state_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100216 int try_catch_nesting_level_;
217 int try_finally_nesting_level_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000218};
219
220} // namespace interpreter
221} // namespace internal
222} // namespace v8
223
224#endif // V8_INTERPRETER_BYTECODE_GENERATOR_H_