bytecode-generator.h 8.99 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_INTERPRETER_BYTECODE_GENERATOR_H_
#define V8_INTERPRETER_BYTECODE_GENERATOR_H_

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 13 14 15
#include "src/interpreter/bytecodes.h"

namespace v8 {
namespace internal {
16 17 18

class CompilationInfo;

19 20
namespace interpreter {

21 22
class LoopBuilder;

23
class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
24
 public:
25
  explicit BytecodeGenerator(CompilationInfo* info);
26

27
  Handle<BytecodeArray> MakeBytecode();
28

29
#define DECLARE_VISIT(type) void Visit##type(type* node);
30 31 32
  AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT

33
  // Visiting function for declarations list and statements are overridden.
34 35
  void VisitDeclarations(ZoneList<Declaration*>* declarations);
  void VisitStatements(ZoneList<Statement*>* statments);
36

37
 private:
38
  class AccumulatorResultScope;
39
  class ContextScope;
40
  class ControlScope;
41
  class ControlScopeForBreakable;
42
  class ControlScopeForIteration;
43 44 45
  class ControlScopeForTopLevel;
  class ControlScopeForTryCatch;
  class ControlScopeForTryFinally;
46 47
  class ExpressionResultScope;
  class EffectResultScope;
48
  class GlobalDeclarationsBuilder;
49
  class RegisterResultScope;
50
  class RegisterAllocationScope;
51

52 53
  void GenerateBytecode();
  void GenerateBytecodeBody();
54
  void FinalizeBytecode();
55

56 57
  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();

58
  // Dispatched from VisitBinaryOperation.
59
  void VisitArithmeticExpression(BinaryOperation* binop);
60 61 62
  void VisitCommaExpression(BinaryOperation* binop);
  void VisitLogicalOrExpression(BinaryOperation* binop);
  void VisitLogicalAndExpression(BinaryOperation* binop);
63

64 65 66 67
  // Dispatched from VisitUnaryOperation.
  void VisitVoid(UnaryOperation* expr);
  void VisitTypeOf(UnaryOperation* expr);
  void VisitNot(UnaryOperation* expr);
68
  void VisitDelete(UnaryOperation* expr);
69

70 71 72
  // Used by flow control routines to evaluate loop condition.
  void VisitCondition(Expression* expr);

73 74 75
  // Helper visitors which perform common operations.
  Register VisitArguments(ZoneList<Expression*>* arguments);

76 77 78 79 80 81 82 83 84 85 86 87 88 89
  // Visit a keyed super property load. The optional
  // |opt_receiver_out| register will have the receiver stored to it
  // if it's a valid register. The loaded value is placed in the
  // accumulator.
  void VisitKeyedSuperPropertyLoad(Property* property,
                                   Register opt_receiver_out);

  // Visit a named super property load. The optional
  // |opt_receiver_out| register will have the receiver stored to it
  // if it's a valid register. The loaded value is placed in the
  // accumulator.
  void VisitNamedSuperPropertyLoad(Property* property,
                                   Register opt_receiver_out);

90
  void VisitPropertyLoad(Register obj, Property* expr);
91 92
  void VisitPropertyLoadForAccumulator(Register obj, Property* expr);

93 94 95 96 97 98 99 100
  void VisitVariableLoad(Variable* variable, FeedbackVectorSlot slot,
                         TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
  void VisitVariableLoadForAccumulatorValue(
      Variable* variable, FeedbackVectorSlot slot,
      TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
  MUST_USE_RESULT Register
  VisitVariableLoadForRegisterValue(Variable* variable, FeedbackVectorSlot slot,
                                    TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
101 102
  void VisitVariableAssignment(Variable* variable, Token::Value op,
                               FeedbackVectorSlot slot);
103

104 105 106 107 108 109 110 111
  void BuildNamedSuperPropertyStore(Register receiver, Register home_object,
                                    Register name, Register value);
  void BuildKeyedSuperPropertyStore(Register receiver, Register home_object,
                                    Register key, Register value);
  void BuildNamedSuperPropertyLoad(Register receiver, Register home_object,
                                   Register name);
  void BuildKeyedSuperPropertyLoad(Register receiver, Register home_object,
                                   Register key);
112

113
  void BuildAbort(BailoutReason bailout_reason);
114 115 116
  void BuildThrowIfHole(Handle<String> name);
  void BuildThrowIfNotHole(Handle<String> name);
  void BuildThrowReassignConstant(Handle<String> name);
117
  void BuildThrowReferenceError(Handle<String> name);
118
  void BuildHoleCheckForVariableLoad(Variable* variable);
119
  void BuildHoleCheckForVariableAssignment(Variable* variable, Token::Value op);
120

121 122 123 124 125
  // Build jump to targets[value], where
  // start_index <= value < start_index + size.
  void BuildIndexedJump(Register value, size_t start_index, size_t size,
                        ZoneVector<BytecodeLabel>& targets);

126 127
  void VisitGeneratorPrologue();

128
  void VisitArgumentsObject(Variable* variable);
129
  void VisitRestArgumentsArray(Variable* rest);
130
  void VisitCallSuper(Call* call);
131 132 133 134
  void VisitClassLiteralForRuntimeDefinition(ClassLiteral* expr);
  void VisitClassLiteralProperties(ClassLiteral* expr, Register literal,
                                   Register prototype);
  void VisitClassLiteralStaticPrototypeWithComputedName(Register name);
135 136
  void VisitThisFunctionVariable(Variable* variable);
  void VisitNewTargetVariable(Variable* variable);
137
  void VisitNewLocalFunctionContext();
138
  void VisitBuildLocalActivationContext();
139
  void VisitBlockDeclarationsAndStatements(Block* stmt);
140
  void VisitNewLocalBlockContext(Scope* scope);
141
  void VisitNewLocalCatchContext(Variable* variable);
142
  void VisitNewLocalWithContext();
143
  void VisitFunctionClosureForContext();
144 145 146 147 148
  void VisitSetHomeObject(Register value, Register home_object,
                          ObjectLiteralProperty* property, int slot_number = 0);
  void VisitObjectLiteralAccessor(Register home_object,
                                  ObjectLiteralProperty* property,
                                  Register value_out);
149
  void VisitForInAssignment(Expression* expr, FeedbackVectorSlot slot);
150

151 152 153
  // Visit the header/body of a loop iteration.
  void VisitIterationHeader(IterationStatement* stmt,
                            LoopBuilder* loop_builder);
154 155
  void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop_builder);

156 157 158
  // Visit a statement and switch scopes, the context is in the accumulator.
  void VisitInScope(Statement* stmt, Scope* scope);

159 160
  // Visitors for obtaining expression result in the accumulator, in a
  // register, or just getting the effect.
161 162 163
  void VisitForAccumulatorValue(Expression* expr);
  void VisitForAccumulatorValueOrTheHole(Expression* expr);
  MUST_USE_RESULT Register VisitForRegisterValue(Expression* expr);
164
  void VisitForRegisterValue(Expression* expr, Register destination);
165
  void VisitForEffect(Expression* expr);
166 167 168 169 170

  // Methods for tracking and remapping register.
  void RecordStoreToRegister(Register reg);
  Register LoadFromAliasedRegister(Register reg);

171 172 173 174
  // Initialize an array of temporary registers with consecutive registers.
  template <size_t N>
  void InitializeWithConsecutiveRegisters(Register (&registers)[N]);

175
  inline BytecodeArrayBuilder* builder() const { return builder_; }
176
  inline Isolate* isolate() const { return isolate_; }
177
  inline Zone* zone() const { return zone_; }
178
  inline DeclarationScope* scope() const { return scope_; }
179 180
  inline CompilationInfo* info() const { return info_; }

181 182 183 184 185 186 187
  inline ControlScope* execution_control() const { return execution_control_; }
  inline void set_execution_control(ControlScope* scope) {
    execution_control_ = scope;
  }
  inline ContextScope* execution_context() const { return execution_context_; }
  inline void set_execution_context(ContextScope* context) {
    execution_context_ = context;
188
  }
189 190 191 192
  inline void set_execution_result(ExpressionResultScope* execution_result) {
    execution_result_ = execution_result;
  }
  ExpressionResultScope* execution_result() const { return execution_result_; }
193 194 195 196 197 198 199
  inline void set_register_allocator(
      RegisterAllocationScope* register_allocator) {
    register_allocator_ = register_allocator;
  }
  RegisterAllocationScope* register_allocator() const {
    return register_allocator_;
  }
200

201
  GlobalDeclarationsBuilder* globals_builder() { return globals_builder_; }
202
  inline LanguageMode language_mode() const;
203
  int feedback_index(FeedbackVectorSlot slot) const;
204

205
  Isolate* isolate_;
206
  Zone* zone_;
207
  BytecodeArrayBuilder* builder_;
208
  CompilationInfo* info_;
209
  DeclarationScope* scope_;
210 211
  GlobalDeclarationsBuilder* globals_builder_;
  ZoneVector<GlobalDeclarationsBuilder*> global_declarations_;
212 213 214
  ZoneVector<std::pair<FunctionLiteral*, size_t>> function_literals_;
  ZoneVector<std::pair<NativeFunctionLiteral*, size_t>>
      native_function_literals_;
215 216
  ControlScope* execution_control_;
  ContextScope* execution_context_;
217
  ExpressionResultScope* execution_result_;
218
  RegisterAllocationScope* register_allocator_;
219
  ZoneVector<BytecodeLabel> generator_resume_points_;
220
  Register generator_state_;
221
  int loop_depth_;
222 223 224 225 226 227 228
};

}  // namespace interpreter
}  // namespace internal
}  // namespace v8

#endif  // V8_INTERPRETER_BYTECODE_GENERATOR_H_