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 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 
    174   inline BytecodeArrayBuilder* builder() const { return builder_; }
    175   inline Zone* zone() const { return zone_; }
    176   inline DeclarationScope* closure_scope() const { return closure_scope_; }
    177   inline CompilationInfo* info() const { return info_; }
    178 
    179   inline Scope* current_scope() const { return current_scope_; }
    180   inline void set_current_scope(Scope* scope) { current_scope_ = scope; }
    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   BytecodeRegisterAllocator* register_allocator() const {
    195     return builder()->register_allocator();
    196   }
    197 
    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 
    205   const AstRawString* prototype_string() const { return prototype_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