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