LCOV - code coverage report
Current view: top level - src/interpreter - bytecode-generator.h (source / functions) Hit Total Coverage
Test: app.info Lines: 9 9 100.0 %
Date: 2017-10-20 Functions: 3 3 100.0 %

          Line data    Source code
       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 AstNodeSourceRanges;
      18             : class AstStringConstants;
      19             : class CompilationInfo;
      20             : enum class SourceRangeKind;
      21             : 
      22             : namespace interpreter {
      23             : 
      24             : class GlobalDeclarationsBuilder;
      25             : class LoopBuilder;
      26             : class BlockCoverageBuilder;
      27             : class BytecodeJumpTable;
      28             : 
      29             : class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
      30             :  public:
      31             :   explicit BytecodeGenerator(CompilationInfo* info);
      32             : 
      33             :   void GenerateBytecode(uintptr_t stack_limit);
      34             :   Handle<BytecodeArray> FinalizeBytecode(Isolate* isolate,
      35             :                                          Handle<Script> script);
      36             : 
      37             : #define DECLARE_VISIT(type) void Visit##type(type* node);
      38             :   AST_NODE_LIST(DECLARE_VISIT)
      39             : #undef DECLARE_VISIT
      40             : 
      41             :   // Visiting function for declarations list and statements are overridden.
      42             :   void VisitDeclarations(Declaration::List* declarations);
      43             :   void VisitStatements(ZoneList<Statement*>* statments);
      44             : 
      45             :  private:
      46             :   class ContextScope;
      47             :   class ControlScope;
      48             :   class ControlScopeForBreakable;
      49             :   class ControlScopeForIteration;
      50             :   class ControlScopeForTopLevel;
      51             :   class ControlScopeForTryCatch;
      52             :   class ControlScopeForTryFinally;
      53             :   class CurrentScope;
      54             :   class ExpressionResultScope;
      55             :   class EffectResultScope;
      56             :   class FeedbackSlotCache;
      57             :   class GlobalDeclarationsBuilder;
      58             :   class RegisterAllocationScope;
      59             :   class TestResultScope;
      60             :   class ValueResultScope;
      61             : 
      62             :   using ToBooleanMode = BytecodeArrayBuilder::ToBooleanMode;
      63             : 
      64             :   enum class TestFallthrough { kThen, kElse, kNone };
      65             :   enum class TypeHint { kAny, kBoolean };
      66             : 
      67             :   void GenerateBytecodeBody();
      68             :   void AllocateDeferredConstants(Isolate* isolate, Handle<Script> script);
      69             : 
      70   254962439 :   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
      71             : 
      72             :   // Dispatched from VisitBinaryOperation.
      73             :   void VisitArithmeticExpression(BinaryOperation* binop);
      74             :   void VisitCommaExpression(BinaryOperation* binop);
      75             :   void VisitLogicalOrExpression(BinaryOperation* binop);
      76             :   void VisitLogicalAndExpression(BinaryOperation* binop);
      77             : 
      78             :   // Dispatched from VisitUnaryOperation.
      79             :   void VisitVoid(UnaryOperation* expr);
      80             :   void VisitTypeOf(UnaryOperation* expr);
      81             :   void VisitNot(UnaryOperation* expr);
      82             :   void VisitDelete(UnaryOperation* expr);
      83             : 
      84             :   // Visits a typeof expression for the value on which to perform the typeof.
      85             :   void VisitForTypeOfValue(Expression* expr);
      86             : 
      87             :   // Used by flow control routines to evaluate loop condition.
      88             :   void VisitCondition(Expression* expr);
      89             : 
      90             :   // Visit the arguments expressions in |args| and store them in |args_regs|,
      91             :   // growing |args_regs| for each argument visited.
      92             :   void VisitArguments(ZoneList<Expression*>* args, RegisterList* arg_regs);
      93             : 
      94             :   // Visit a keyed super property load. The optional
      95             :   // |opt_receiver_out| register will have the receiver stored to it
      96             :   // if it's a valid register. The loaded value is placed in the
      97             :   // accumulator.
      98             :   void VisitKeyedSuperPropertyLoad(Property* property,
      99             :                                    Register opt_receiver_out);
     100             : 
     101             :   // Visit a named super property load. The optional
     102             :   // |opt_receiver_out| register will have the receiver stored to it
     103             :   // if it's a valid register. The loaded value is placed in the
     104             :   // accumulator.
     105             :   void VisitNamedSuperPropertyLoad(Property* property,
     106             :                                    Register opt_receiver_out);
     107             : 
     108             :   void VisitPropertyLoad(Register obj, Property* expr);
     109             :   void VisitPropertyLoadForRegister(Register obj, Property* expr,
     110             :                                     Register destination);
     111             : 
     112             :   void BuildVariableLoad(Variable* variable, HoleCheckMode hole_check_mode,
     113             :                          TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
     114             :   void BuildVariableLoadForAccumulatorValue(
     115             :       Variable* variable, HoleCheckMode hole_check_mode,
     116             :       TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
     117             :   void BuildVariableAssignment(
     118             :       Variable* variable, Token::Value op, HoleCheckMode hole_check_mode,
     119             :       LookupHoistingMode lookup_hoisting_mode = LookupHoistingMode::kNormal);
     120             :   void BuildLiteralCompareNil(Token::Value compare_op, NilValue nil);
     121             :   void BuildReturn(int source_position = kNoSourcePosition);
     122             :   void BuildAsyncReturn(int source_position = kNoSourcePosition);
     123             :   void BuildAsyncGeneratorReturn();
     124             :   void BuildReThrow();
     125             :   void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op);
     126             :   void BuildThrowIfHole(Variable* variable);
     127             : 
     128             :   // Build jump to targets[value], where
     129             :   // start_index <= value < start_index + size.
     130             :   void BuildIndexedJump(Register value, size_t start_index, size_t size,
     131             :                         ZoneVector<BytecodeLabel>& targets);
     132             : 
     133             :   void BuildNewLocalActivationContext();
     134             :   void BuildLocalActivationContextInitialization();
     135             :   void BuildNewLocalBlockContext(Scope* scope);
     136             :   void BuildNewLocalCatchContext(Scope* scope);
     137             :   void BuildNewLocalWithContext(Scope* scope);
     138             : 
     139             :   void BuildGeneratorPrologue();
     140             :   void BuildSuspendPoint(int suspend_id);
     141             : 
     142             :   void BuildAwait(int suspend_id);
     143             : 
     144             :   void BuildGetIterator(Expression* iterable, IteratorType hint);
     145             : 
     146             :   void AllocateTopLevelRegisters();
     147             :   void VisitArgumentsObject(Variable* variable);
     148             :   void VisitRestArgumentsArray(Variable* rest);
     149             :   void VisitCallSuper(Call* call);
     150             :   void VisitClassLiteralProperties(ClassLiteral* expr, Register constructor,
     151             :                                    Register prototype);
     152             :   void BuildClassLiteralNameProperty(ClassLiteral* expr, Register constructor);
     153             :   void BuildClassLiteral(ClassLiteral* expr);
     154             :   void VisitNewTargetVariable(Variable* variable);
     155             :   void VisitThisFunctionVariable(Variable* variable);
     156             :   void BuildGeneratorObjectVariableInitialization();
     157             :   void VisitBlockDeclarationsAndStatements(Block* stmt);
     158             :   void VisitFunctionClosureForContext();
     159             :   void VisitSetHomeObject(Register value, Register home_object,
     160             :                           LiteralProperty* property);
     161             :   void VisitObjectLiteralAccessor(Register home_object,
     162             :                                   ObjectLiteralProperty* property,
     163             :                                   Register value_out);
     164             :   void VisitForInAssignment(Expression* expr);
     165             :   void VisitModuleNamespaceImports();
     166             : 
     167             :   // Builds a logical OR/AND within a test context by rewiring the jumps based
     168             :   // on the expression values.
     169             :   void BuildLogicalTest(Token::Value token, Expression* left,
     170             :                         Expression* right);
     171             : 
     172             :   // Visit the header/body of a loop iteration.
     173             :   void VisitIterationHeader(IterationStatement* stmt,
     174             :                             LoopBuilder* loop_builder);
     175             :   void VisitIterationHeader(int first_suspend_id, int suspend_count,
     176             :                             LoopBuilder* loop_builder);
     177             :   void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop_builder);
     178             : 
     179             :   // Visit a statement and switch scopes, the context is in the accumulator.
     180             :   void VisitInScope(Statement* stmt, Scope* scope);
     181             : 
     182             :   void BuildPushUndefinedIntoRegisterList(RegisterList* reg_list);
     183             : 
     184             :   void BuildLoadPropertyKey(LiteralProperty* property, Register out_reg);
     185             : 
     186             :   int AllocateBlockCoverageSlotIfEnabled(AstNode* node, SourceRangeKind kind);
     187             :   void BuildIncrementBlockCoverageCounterIfEnabled(AstNode* node,
     188             :                                                    SourceRangeKind kind);
     189             :   void BuildIncrementBlockCoverageCounterIfEnabled(int coverage_array_slot);
     190             : 
     191             :   void BuildTest(ToBooleanMode mode, BytecodeLabels* then_labels,
     192             :                  BytecodeLabels* else_labels, TestFallthrough fallthrough);
     193             : 
     194             :   // Visitors for obtaining expression result in the accumulator, in a
     195             :   // register, or just getting the effect. Some visitors return a TypeHint which
     196             :   // specifies the type of the result of the visited expression.
     197             :   TypeHint VisitForAccumulatorValue(Expression* expr);
     198             :   void VisitForAccumulatorValueOrTheHole(Expression* expr);
     199             :   MUST_USE_RESULT Register VisitForRegisterValue(Expression* expr);
     200             :   INLINE(void VisitForRegisterValue(Expression* expr, Register destination));
     201             :   void VisitAndPushIntoRegisterList(Expression* expr, RegisterList* reg_list);
     202             :   void VisitForEffect(Expression* expr);
     203             :   void VisitForTest(Expression* expr, BytecodeLabels* then_labels,
     204             :                     BytecodeLabels* else_labels, TestFallthrough fallthrough);
     205             : 
     206             :   void VisitInSameTestExecutionScope(Expression* expr);
     207             : 
     208             :   Register GetRegisterForLocalVariable(Variable* variable);
     209             : 
     210             :   // Returns the runtime function id for a store to super for the function's
     211             :   // language mode.
     212             :   inline Runtime::FunctionId StoreToSuperRuntimeId();
     213             :   inline Runtime::FunctionId StoreKeyedToSuperRuntimeId();
     214             : 
     215             :   // Returns a cached slot, or create and cache a new slot if one doesn't
     216             :   // already exists.
     217             :   FeedbackSlot GetCachedLoadGlobalICSlot(TypeofMode typeof_mode,
     218             :                                          Variable* variable);
     219             :   FeedbackSlot GetCachedCreateClosureSlot(FunctionLiteral* literal);
     220             : 
     221             :   static constexpr ToBooleanMode ToBooleanModeFromTypeHint(TypeHint type_hint) {
     222             :     return type_hint == TypeHint::kBoolean ? ToBooleanMode::kAlreadyBoolean
     223     1416584 :                                            : ToBooleanMode::kConvertToBoolean;
     224             :   }
     225             : 
     226             :   inline Register generator_object() const;
     227             : 
     228     1543408 :   inline BytecodeArrayBuilder* builder() const { return builder_; }
     229             :   inline Zone* zone() const { return zone_; }
     230             :   inline DeclarationScope* closure_scope() const { return closure_scope_; }
     231             :   inline CompilationInfo* info() const { return info_; }
     232             :   inline const AstStringConstants* ast_string_constants() const {
     233             :     return ast_string_constants_;
     234             :   }
     235             : 
     236             :   inline Scope* current_scope() const { return current_scope_; }
     237      631034 :   inline void set_current_scope(Scope* scope) { current_scope_ = scope; }
     238             : 
     239             :   inline ControlScope* execution_control() const { return execution_control_; }
     240             :   inline void set_execution_control(ControlScope* scope) {
     241    15312392 :     execution_control_ = scope;
     242             :   }
     243             :   inline ContextScope* execution_context() const { return execution_context_; }
     244             :   inline void set_execution_context(ContextScope* context) {
     245     4938115 :     execution_context_ = context;
     246             :   }
     247             :   inline void set_execution_result(ExpressionResultScope* execution_result) {
     248    84764771 :     execution_result_ = execution_result;
     249             :   }
     250             :   ExpressionResultScope* execution_result() const { return execution_result_; }
     251   171323842 :   BytecodeRegisterAllocator* register_allocator() const {
     252             :     return builder()->register_allocator();
     253             :   }
     254             : 
     255             :   GlobalDeclarationsBuilder* globals_builder() {
     256             :     DCHECK_NOT_NULL(globals_builder_);
     257             :     return globals_builder_;
     258             :   }
     259             :   inline LanguageMode language_mode() const;
     260             :   inline FunctionKind function_kind() const;
     261             :   inline FeedbackVectorSpec* feedback_spec();
     262             :   inline int feedback_index(FeedbackSlot slot) const;
     263             : 
     264             :   inline FeedbackSlotCache* feedback_slot_cache() {
     265             :     return feedback_slot_cache_;
     266             :   }
     267             : 
     268             :   inline HandlerTable::CatchPrediction catch_prediction() const {
     269             :     return catch_prediction_;
     270             :   }
     271             :   inline void set_catch_prediction(HandlerTable::CatchPrediction value) {
     272      204244 :     catch_prediction_ = value;
     273             :   }
     274             : 
     275             :   Zone* zone_;
     276             :   BytecodeArrayBuilder* builder_;
     277             :   CompilationInfo* info_;
     278             :   const AstStringConstants* ast_string_constants_;
     279             :   DeclarationScope* closure_scope_;
     280             :   Scope* current_scope_;
     281             : 
     282             :   FeedbackSlotCache* feedback_slot_cache_;
     283             : 
     284             :   GlobalDeclarationsBuilder* globals_builder_;
     285             :   BlockCoverageBuilder* block_coverage_builder_;
     286             :   ZoneVector<GlobalDeclarationsBuilder*> global_declarations_;
     287             :   ZoneVector<std::pair<FunctionLiteral*, size_t>> function_literals_;
     288             :   ZoneVector<std::pair<NativeFunctionLiteral*, size_t>>
     289             :       native_function_literals_;
     290             :   ZoneVector<std::pair<ObjectLiteral*, size_t>> object_literals_;
     291             :   ZoneVector<std::pair<ArrayLiteral*, size_t>> array_literals_;
     292             :   ZoneVector<std::pair<GetTemplateObject*, size_t>> template_objects_;
     293             : 
     294             :   ControlScope* execution_control_;
     295             :   ContextScope* execution_context_;
     296             :   ExpressionResultScope* execution_result_;
     297             : 
     298             :   Register incoming_new_target_or_generator_;
     299             : 
     300             :   BytecodeJumpTable* generator_jump_table_;
     301             :   Register generator_state_;
     302             :   int loop_depth_;
     303             : 
     304             :   HandlerTable::CatchPrediction catch_prediction_;
     305             : };
     306             : 
     307             : }  // namespace interpreter
     308             : }  // namespace internal
     309             : }  // namespace v8
     310             : 
     311             : #endif  // V8_INTERPRETER_BYTECODE_GENERATOR_H_

Generated by: LCOV version 1.10