Home | History | Annotate | Download | only in interpreter
      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 
    173   inline BytecodeArrayBuilder* builder() const { return builder_; }
    174   inline Zone* zone() const { return zone_; }
    175   inline DeclarationScope* scope() const { return scope_; }
    176   inline CompilationInfo* info() const { return info_; }
    177 
    178   inline ControlScope* execution_control() const { return execution_control_; }
    179   inline void set_execution_control(ControlScope* scope) {
    180     execution_control_ = scope;
    181   }
    182   inline ContextScope* execution_context() const { return execution_context_; }
    183   inline void set_execution_context(ContextScope* context) {
    184     execution_context_ = context;
    185   }
    186   inline void set_execution_result(ExpressionResultScope* execution_result) {
    187     execution_result_ = execution_result;
    188   }
    189   ExpressionResultScope* execution_result() const { return execution_result_; }
    190   BytecodeRegisterAllocator* register_allocator() const {
    191     return builder()->register_allocator();
    192   }
    193 
    194   GlobalDeclarationsBuilder* globals_builder() { return globals_builder_; }
    195   inline LanguageMode language_mode() const;
    196   int feedback_index(FeedbackVectorSlot slot) const;
    197 
    198   Handle<Name> home_object_symbol() const { return home_object_symbol_; }
    199   Handle<Name> prototype_string() const { return prototype_string_; }
    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