OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_CODE_GENERATOR_X64_H_ | 5 #ifndef VM_CODE_GENERATOR_X64_H_ |
6 #define VM_CODE_GENERATOR_X64_H_ | 6 #define VM_CODE_GENERATOR_X64_H_ |
7 | 7 |
8 #ifndef VM_CODE_GENERATOR_H_ | 8 #ifndef VM_CODE_GENERATOR_H_ |
9 #error Do not include code_generator_x64.h directly; use assembler.h instead. | 9 #error Do not include code_generator_x64.h directly; use code_generator.h. |
10 #endif | 10 #endif |
11 | 11 |
12 #include "vm/allocation.h" | 12 #include "vm/assembler.h" |
13 #include "vm/ast.h" | 13 #include "vm/ast.h" |
14 #include "vm/growable_array.h" | 14 #include "vm/growable_array.h" |
| 15 #include "vm/parser.h" |
15 | 16 |
16 namespace dart { | 17 namespace dart { |
17 | 18 |
18 // Forward declarations. | 19 // Forward declarations. |
19 class Assembler; | 20 class Assembler; |
20 class AstNode; | 21 class AstNode; |
21 class ParsedFunction; | 22 class CodeGenerator; |
| 23 class SourceLabel; |
| 24 |
| 25 |
| 26 class CodeGeneratorState : public StackResource { |
| 27 public: |
| 28 explicit CodeGeneratorState(CodeGenerator* codegen); |
| 29 virtual ~CodeGeneratorState(); |
| 30 |
| 31 CodeGeneratorState* parent() const { return parent_; } |
| 32 |
| 33 AstNode* root_node() const { return root_node_; } |
| 34 void set_root_node(AstNode* value) { root_node_ = value; } |
| 35 bool IsRootNode(AstNode* node) const { |
| 36 return root_node_ == node; |
| 37 } |
| 38 |
| 39 int loop_level() const { return loop_level_; } |
| 40 void set_loop_level(int loop_level) { |
| 41 loop_level_ = loop_level; |
| 42 } |
| 43 |
| 44 int context_level() const { return context_level_; } |
| 45 void set_context_level(int context_level) { |
| 46 context_level_ = context_level; |
| 47 } |
| 48 |
| 49 int try_index() const { return current_try_index_; } |
| 50 void set_try_index(int value) { |
| 51 current_try_index_ = value; |
| 52 } |
| 53 |
| 54 private: |
| 55 CodeGenerator* codegen_; |
| 56 CodeGeneratorState* parent_; |
| 57 AstNode* root_node_; |
| 58 |
| 59 // The loop level reflects the lexical nesting of loop statements, regardless |
| 60 // of the presence of captured variables. |
| 61 int loop_level_; |
| 62 |
| 63 // The runtime context level is only incremented when a new context is |
| 64 // allocated and chained to the list of contexts. This occurs when the scopes |
| 65 // at the current loop level contain captured variables. |
| 66 int context_level_; |
| 67 |
| 68 // We identify each try block in this function with an unique 'try index' |
| 69 // value. |
| 70 // The 'try index' is used to match the try blocks with the corresponding |
| 71 // catch block (if one exists). The PC descriptors generated for |
| 72 // statements in the try block use this index so that it can be matched |
| 73 // to the appropriate catch block. |
| 74 // The 'try index' value is generated by incrementing the try_index_ |
| 75 // variable in the CodeGenerator object. |
| 76 // We store the 'try index' of the block of code that we are |
| 77 // currently generating code for in the current_try_index_ variable. |
| 78 int current_try_index_; |
| 79 |
| 80 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeGeneratorState); |
| 81 }; |
| 82 |
22 | 83 |
23 class CodeGenerator : public AstNodeVisitor { | 84 class CodeGenerator : public AstNodeVisitor { |
24 public: | 85 public: |
25 CodeGenerator(Assembler* assembler, const ParsedFunction& parsed_function) { } | 86 CodeGenerator(Assembler* assembler, const ParsedFunction& parsed_function); |
26 virtual ~CodeGenerator() { } | 87 virtual ~CodeGenerator() { } |
27 | 88 |
28 bool GenerateCode() { | 89 // Accessors. |
29 return false; | 90 Assembler* assembler() const { return assembler_; } |
30 } | |
31 | 91 |
32 // Add an exception handler table to code. | 92 const ParsedFunction& parsed_function() const { return parsed_function_; } |
33 void FinalizeExceptionHandlers(const Code& code) { UNIMPLEMENTED(); } | |
34 | 93 |
35 // Add Pcdescriptors to code. | 94 void GenerateCode(); |
36 void FinalizePcDescriptors(const Code& code) { UNIMPLEMENTED(); } | 95 virtual void GenerateDeferredCode(); |
| 96 |
| 97 #define DEFINE_VISITOR_FUNCTION(type, name) \ |
| 98 virtual void Visit##type(type* node); |
| 99 NODE_LIST(DEFINE_VISITOR_FUNCTION) |
| 100 #undef DEFINE_VISITOR_FUNCTION |
| 101 |
| 102 CodeGeneratorState* state() const { return state_; } |
| 103 void set_state(CodeGeneratorState* state) { state_ = state; } |
| 104 |
| 105 // Add exception handler table to code. |
| 106 void FinalizeExceptionHandlers(const Code& code); |
| 107 |
| 108 // Add pc descriptors to code. |
| 109 void FinalizePcDescriptors(const Code& code); |
37 | 110 |
38 // Allocate and return an arguments descriptor. | 111 // Allocate and return an arguments descriptor. |
39 // Let 'num_names' be the length of 'optional_arguments_names'. | 112 // Let 'num_names' be the length of 'optional_arguments_names'. |
40 // Treat the first 'num_arguments - num_names' arguments as positional and | 113 // Treat the first 'num_arguments - num_names' arguments as positional and |
41 // treat the following 'num_names' arguments as named optional arguments. | 114 // treat the following 'num_names' arguments as named optional arguments. |
42 static const Array& ArgumentsDescriptor( | 115 static const Array& ArgumentsDescriptor( |
43 int num_arguments, | 116 int num_arguments, |
44 const Array& optional_arguments_names); | 117 const Array& optional_arguments_names); |
45 | 118 |
| 119 virtual bool IsOptimizing() const { |
| 120 return false; |
| 121 } |
| 122 |
| 123 virtual void CountBackwardLoop(); |
| 124 |
| 125 void GenerateReturnEpilog(); |
| 126 |
46 private: | 127 private: |
| 128 // TODO(srdjan): Remove the friendship once the two compilers are properly |
| 129 // structured. |
| 130 friend class OptimizingCodeGenerator; |
| 131 |
| 132 // Forward declarations. |
| 133 class DescriptorList; |
| 134 class HandlerList; |
| 135 |
| 136 // Return true if intrinsification was completed and no other code |
| 137 // needs to be generated. |
| 138 virtual bool TryIntrinsify() { return false; } |
| 139 virtual void GeneratePreEntryCode(); |
| 140 void GenerateLegacyEntryCode(); |
| 141 void GenerateEntryCode(); |
| 142 void GenerateLoadVariable(Register dst, const LocalVariable& local); |
| 143 void GeneratePushVariable(const LocalVariable& variable, Register scratch); |
| 144 void GenerateStoreVariable(const LocalVariable& local, |
| 145 Register src, |
| 146 Register scratch); |
| 147 void GenerateLogicalNotOp(UnaryOpNode* node); |
| 148 void GenerateLogicalAndOrOp(BinaryOpNode* node); |
| 149 void GenerateInstanceGetterCall(intptr_t node_id, |
| 150 intptr_t token_index, |
| 151 const String& field_name); |
| 152 void GenerateInstanceSetterCall(intptr_t node_id, |
| 153 intptr_t token_index, |
| 154 const String& field_name); |
| 155 void GenerateBinaryOperatorCall(intptr_t node_id, |
| 156 intptr_t token_index, |
| 157 const char* operator_name); |
| 158 void GenerateStaticGetterCall(intptr_t token_index, |
| 159 const Class& field_class, |
| 160 const String& field_name); |
| 161 void GenerateStaticSetterCall(intptr_t token_index, |
| 162 const Class& field_class, |
| 163 const String& field_name); |
| 164 void GenerateLoadIndexed(intptr_t node_id, intptr_t token_index); |
| 165 void GenerateStoreIndexed(intptr_t node_id, |
| 166 intptr_t token_index, |
| 167 bool preserve_value); |
| 168 |
| 169 // Invokes funtion via an inline cache stub. 'num_args_checked' specifies |
| 170 // the number of call arguments that are being checked in the inline cache. |
| 171 void GenerateInstanceCall(intptr_t node_id, |
| 172 intptr_t token_index, |
| 173 const String& function_name, |
| 174 int num_arguments, |
| 175 const Array& optional_arguments_names, |
| 176 intptr_t num_args_checked); |
| 177 |
| 178 void GenerateInstanceOf(intptr_t node_id, |
| 179 intptr_t token_index, |
| 180 const AbstractType& type, |
| 181 bool negate_result); |
| 182 void GenerateAssertAssignable(intptr_t node_id, |
| 183 intptr_t token_index, |
| 184 const AbstractType& dst_type, |
| 185 const String& dst_name); |
| 186 void GenerateArgumentTypeChecks(); |
| 187 void GenerateConditionTypeCheck(intptr_t node_id, intptr_t token_index); |
| 188 |
| 189 void GenerateInstantiatorTypeArguments(intptr_t token_index); |
| 190 void GenerateTypeArguments(ConstructorCallNode* node, |
| 191 bool is_cls_parameterized); |
| 192 |
| 193 void TestClassAndJump(const Class& cls, Label *label); |
| 194 |
| 195 intptr_t locals_space_size() const { return locals_space_size_; } |
| 196 void set_locals_space_size(intptr_t value) { locals_space_size_ = value; } |
| 197 |
| 198 bool IsResultNeeded(AstNode* node) const; |
| 199 |
| 200 void GenerateCall(intptr_t token_index, const ExternalLabel* ext_label); |
| 201 void GenerateCallRuntime(intptr_t node_id, |
| 202 intptr_t token_index, |
| 203 const RuntimeEntry& entry); |
| 204 |
| 205 void GenerateInlinedFinallyBlocks(SourceLabel* label); |
| 206 |
| 207 void ErrorMsg(intptr_t token_index, const char* format, ...); |
| 208 |
| 209 int generate_next_try_index() { return try_index_ += 1; } |
| 210 |
| 211 void MarkDeoptPoint(intptr_t node_id, intptr_t token_index); |
| 212 void AddCurrentDescriptor(PcDescriptors::Kind kind, |
| 213 intptr_t node_id, |
| 214 intptr_t token_index); |
| 215 |
| 216 Assembler* assembler_; |
| 217 const ParsedFunction& parsed_function_; |
| 218 intptr_t locals_space_size_; |
| 219 CodeGeneratorState* state_; |
| 220 DescriptorList* pc_descriptors_list_; |
| 221 HandlerList* exception_handlers_list_; |
| 222 int try_index_; |
| 223 |
47 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeGenerator); | 224 DISALLOW_IMPLICIT_CONSTRUCTORS(CodeGenerator); |
48 }; | 225 }; |
49 | 226 |
50 } // namespace dart | 227 } // namespace dart |
51 | 228 |
52 #endif // VM_CODE_GENERATOR_X64_H_ | 229 #endif // VM_CODE_GENERATOR_X64_H_ |
OLD | NEW |