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/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 (&registers)[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