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/bytecodes.h" 12 13 namespace v8 { 14 namespace internal { 15 16 class CompilationInfo; 17 18 namespace interpreter { 19 20 class LoopBuilder; 21 22 class BytecodeGenerator final : public AstVisitor { 23 public: 24 explicit BytecodeGenerator(CompilationInfo* info); 25 26 Handle<BytecodeArray> MakeBytecode(); 27 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; 41 class ControlScopeForTopLevel; 42 class ControlScopeForTryCatch; 43 class ControlScopeForTryFinally; 44 class ExpressionResultScope; 45 class EffectResultScope; 46 class AccumulatorResultScope; 47 class RegisterResultScope; 48 class RegisterAllocationScope; 49 50 void MakeBytecodeBody(); 51 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 72 // 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 86 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); 97 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 109 void BuildAbort(BailoutReason bailout_reason); 110 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); 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 VisitGeneratorPrologue(); 123 124 void VisitArgumentsObject(Variable* variable); 125 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); 132 void VisitThisFunctionVariable(Variable* variable); 133 void VisitNewTargetVariable(Variable* variable); 134 void VisitNewLocalFunctionContext(); 135 void VisitBuildLocalActivationContext(); 136 void VisitBlockDeclarationsAndStatements(Block* stmt); 137 void VisitNewLocalBlockContext(Scope* scope); 138 void VisitNewLocalCatchContext(Variable* variable); 139 void VisitNewLocalWithContext(); 140 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 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 // Visitors for obtaining expression result in the accumulator, in a 157 // register, or just getting the effect. 158 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); 163 164 // Methods for tracking and remapping register. 165 void RecordStoreToRegister(Register reg); 166 Register LoadFromAliasedRegister(Register reg); 167 168 // 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 (®isters)[N]); 175 176 inline BytecodeArrayBuilder* builder() const { return builder_; } 177 inline Isolate* isolate() const { return isolate_; } 178 inline Zone* zone() const { return zone_; } 179 inline Scope* scope() const { return scope_; } 180 inline CompilationInfo* info() const { return info_; } 181 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; 204 int feedback_index(FeedbackVectorSlot slot) const; 205 206 Isolate* isolate_; 207 Zone* zone_; 208 BytecodeArrayBuilder* builder_; 209 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_; 216 ZoneVector<BytecodeLabel> generator_resume_points_; 217 Register generator_state_; 218 int try_catch_nesting_level_; 219 int try_finally_nesting_level_; 220 }; 221 222 } // namespace interpreter 223 } // namespace internal 224 } // namespace v8 225 226 #endif // V8_INTERPRETER_BYTECODE_GENERATOR_H_ 227