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