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_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/bytecode-label.h"
11 : #include "src/interpreter/bytecode-register.h"
12 : #include "src/interpreter/bytecodes.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : class AstStringConstants;
18 : class CompilationInfo;
19 :
20 : namespace interpreter {
21 :
22 : class GlobalDeclarationsBuilder;
23 : class LoopBuilder;
24 :
25 : class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
26 : public:
27 : explicit BytecodeGenerator(CompilationInfo* info);
28 :
29 : void GenerateBytecode(uintptr_t stack_limit);
30 : Handle<BytecodeArray> FinalizeBytecode(Isolate* isolate);
31 :
32 : #define DECLARE_VISIT(type) void Visit##type(type* node);
33 : AST_NODE_LIST(DECLARE_VISIT)
34 : #undef DECLARE_VISIT
35 :
36 : // Visiting function for declarations list and statements are overridden.
37 : void VisitDeclarations(Declaration::List* declarations);
38 : void VisitStatements(ZoneList<Statement*>* statments);
39 :
40 : private:
41 : class ContextScope;
42 : class ControlScope;
43 : class ControlScopeForBreakable;
44 : class ControlScopeForIteration;
45 : class ControlScopeForTopLevel;
46 : class ControlScopeForTryCatch;
47 : class ControlScopeForTryFinally;
48 : class CurrentScope;
49 : class ExpressionResultScope;
50 : class EffectResultScope;
51 : class GlobalDeclarationsBuilder;
52 : class RegisterAllocationScope;
53 : class TestResultScope;
54 : class ValueResultScope;
55 :
56 : using ToBooleanMode = BytecodeArrayBuilder::ToBooleanMode;
57 :
58 : enum class TestFallthrough { kThen, kElse, kNone };
59 : enum class TypeHint { kAny, kBoolean };
60 :
61 : void GenerateBytecodeBody();
62 : void AllocateDeferredConstants(Isolate* isolate);
63 :
64 257865478 : DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
65 :
66 : // Dispatched from VisitBinaryOperation.
67 : void VisitArithmeticExpression(BinaryOperation* binop);
68 : void VisitCommaExpression(BinaryOperation* binop);
69 : void VisitLogicalOrExpression(BinaryOperation* binop);
70 : void VisitLogicalAndExpression(BinaryOperation* binop);
71 :
72 : // Dispatched from VisitUnaryOperation.
73 : void VisitVoid(UnaryOperation* expr);
74 : void VisitTypeOf(UnaryOperation* expr);
75 : void VisitNot(UnaryOperation* expr);
76 : void VisitDelete(UnaryOperation* expr);
77 :
78 : // Visits a typeof expression for the value on which to perform the typeof.
79 : void VisitForTypeOfValue(Expression* expr);
80 :
81 : // Used by flow control routines to evaluate loop condition.
82 : void VisitCondition(Expression* expr);
83 :
84 : // Visit the arguments expressions in |args| and store them in |args_regs|,
85 : // growing |args_regs| for each argument visited.
86 : void VisitArguments(ZoneList<Expression*>* args, RegisterList* arg_regs);
87 :
88 : // Visit a keyed super property load. The optional
89 : // |opt_receiver_out| register will have the receiver stored to it
90 : // if it's a valid register. The loaded value is placed in the
91 : // accumulator.
92 : void VisitKeyedSuperPropertyLoad(Property* property,
93 : Register opt_receiver_out);
94 :
95 : // Visit a named super property load. The optional
96 : // |opt_receiver_out| register will have the receiver stored to it
97 : // if it's a valid register. The loaded value is placed in the
98 : // accumulator.
99 : void VisitNamedSuperPropertyLoad(Property* property,
100 : Register opt_receiver_out);
101 :
102 : void VisitPropertyLoad(Register obj, Property* expr);
103 : void VisitPropertyLoadForRegister(Register obj, Property* expr,
104 : Register destination);
105 :
106 : void BuildVariableLoad(Variable* variable, FeedbackSlot slot,
107 : HoleCheckMode hole_check_mode,
108 : TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
109 : void BuildVariableLoadForAccumulatorValue(
110 : Variable* variable, FeedbackSlot slot, HoleCheckMode hole_check_mode,
111 : TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
112 : void BuildVariableAssignment(Variable* variable, Token::Value op,
113 : FeedbackSlot slot,
114 : HoleCheckMode hole_check_mode);
115 : void BuildLiteralCompareNil(Token::Value compare_op, NilValue nil);
116 : void BuildReturn();
117 : void BuildAsyncReturn();
118 : void BuildAsyncGeneratorReturn();
119 : void BuildReThrow();
120 : void BuildAbort(BailoutReason bailout_reason);
121 : void BuildThrowIfHole(Variable* variable);
122 : void BuildThrowReferenceError(const AstRawString* name);
123 : void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op);
124 :
125 : // Build jump to targets[value], where
126 : // start_index <= value < start_index + size.
127 : void BuildIndexedJump(Register value, size_t start_index, size_t size,
128 : ZoneVector<BytecodeLabel>& targets);
129 :
130 : void BuildNewLocalActivationContext();
131 : void BuildLocalActivationContextInitialization();
132 : void BuildNewLocalBlockContext(Scope* scope);
133 : void BuildNewLocalCatchContext(Scope* scope);
134 : void BuildNewLocalWithContext(Scope* scope);
135 :
136 : void VisitGeneratorPrologue();
137 :
138 : void VisitArgumentsObject(Variable* variable);
139 : void VisitRestArgumentsArray(Variable* rest);
140 : void VisitCallSuper(Call* call);
141 : void VisitClassLiteralProperties(ClassLiteral* expr, Register constructor,
142 : Register prototype);
143 : void BuildClassLiteralNameProperty(ClassLiteral* expr, Register constructor);
144 : void VisitThisFunctionVariable(Variable* variable);
145 : void VisitNewTargetVariable(Variable* variable);
146 : void VisitBlockDeclarationsAndStatements(Block* stmt);
147 : void VisitFunctionClosureForContext();
148 : void VisitSetHomeObject(Register value, Register home_object,
149 : LiteralProperty* property, int slot_number = 0);
150 : void VisitObjectLiteralAccessor(Register home_object,
151 : ObjectLiteralProperty* property,
152 : Register value_out);
153 : void VisitForInAssignment(Expression* expr, FeedbackSlot slot);
154 : void VisitModuleNamespaceImports();
155 :
156 : // Visit the header/body of a loop iteration.
157 : void VisitIterationHeader(IterationStatement* stmt,
158 : LoopBuilder* loop_builder);
159 : void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop_builder);
160 :
161 : // Visit a statement and switch scopes, the context is in the accumulator.
162 : void VisitInScope(Statement* stmt, Scope* scope);
163 :
164 : void BuildPushUndefinedIntoRegisterList(RegisterList* reg_list);
165 :
166 : void BuildLoadPropertyKey(LiteralProperty* property, Register out_reg);
167 :
168 : // Visitors for obtaining expression result in the accumulator, in a
169 : // register, or just getting the effect. Some visitors return a TypeHint which
170 : // specifies the type of the result of the visited expression.
171 : TypeHint VisitForAccumulatorValue(Expression* expr);
172 : void VisitForAccumulatorValueOrTheHole(Expression* expr);
173 : MUST_USE_RESULT Register VisitForRegisterValue(Expression* expr);
174 : void VisitForRegisterValue(Expression* expr, Register destination);
175 : void VisitAndPushIntoRegisterList(Expression* expr, RegisterList* reg_list);
176 : void VisitForEffect(Expression* expr);
177 : void VisitForTest(Expression* expr, BytecodeLabels* then_labels,
178 : BytecodeLabels* else_labels, TestFallthrough fallthrough);
179 :
180 : // Returns the runtime function id for a store to super for the function's
181 : // language mode.
182 : inline Runtime::FunctionId StoreToSuperRuntimeId();
183 : inline Runtime::FunctionId StoreKeyedToSuperRuntimeId();
184 :
185 : ToBooleanMode ToBooleanModeFromTypeHint(TypeHint type_hint);
186 :
187 : inline BytecodeArrayBuilder* builder() const { return builder_; }
188 : inline Zone* zone() const { return zone_; }
189 : inline DeclarationScope* closure_scope() const { return closure_scope_; }
190 : inline CompilationInfo* info() const { return info_; }
191 : inline const AstStringConstants* ast_string_constants() const {
192 : return ast_string_constants_;
193 : }
194 :
195 : inline Scope* current_scope() const { return current_scope_; }
196 631900 : inline void set_current_scope(Scope* scope) { current_scope_ = scope; }
197 :
198 : inline ControlScope* execution_control() const { return execution_control_; }
199 : inline void set_execution_control(ControlScope* scope) {
200 15298121 : execution_control_ = scope;
201 : }
202 : inline ContextScope* execution_context() const { return execution_context_; }
203 : inline void set_execution_context(ContextScope* context) {
204 4909519 : execution_context_ = context;
205 : }
206 : inline void set_execution_result(ExpressionResultScope* execution_result) {
207 87424205 : execution_result_ = execution_result;
208 : }
209 : ExpressionResultScope* execution_result() const { return execution_result_; }
210 172250266 : BytecodeRegisterAllocator* register_allocator() const {
211 : return builder()->register_allocator();
212 : }
213 :
214 : GlobalDeclarationsBuilder* globals_builder() {
215 : DCHECK_NOT_NULL(globals_builder_);
216 : return globals_builder_;
217 : }
218 : inline LanguageMode language_mode() const;
219 : int feedback_index(FeedbackSlot slot) const;
220 :
221 : Zone* zone_;
222 : BytecodeArrayBuilder* builder_;
223 : CompilationInfo* info_;
224 : const AstStringConstants* ast_string_constants_;
225 : DeclarationScope* closure_scope_;
226 : Scope* current_scope_;
227 :
228 : GlobalDeclarationsBuilder* globals_builder_;
229 : ZoneVector<GlobalDeclarationsBuilder*> global_declarations_;
230 : ZoneVector<std::pair<FunctionLiteral*, size_t>> function_literals_;
231 : ZoneVector<std::pair<NativeFunctionLiteral*, size_t>>
232 : native_function_literals_;
233 : ZoneVector<std::pair<ObjectLiteral*, size_t>> object_literals_;
234 : ZoneVector<std::pair<ArrayLiteral*, size_t>> array_literals_;
235 :
236 : ControlScope* execution_control_;
237 : ContextScope* execution_context_;
238 : ExpressionResultScope* execution_result_;
239 :
240 : ZoneVector<BytecodeLabel> generator_resume_points_;
241 : Register generator_state_;
242 : int loop_depth_;
243 : };
244 :
245 : } // namespace interpreter
246 : } // namespace internal
247 : } // namespace v8
248 :
249 : #endif // V8_INTERPRETER_BYTECODE_GENERATOR_H_
|