OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 #ifndef VM_KERNEL_TO_IL_H_ |
| 6 #define VM_KERNEL_TO_IL_H_ |
| 7 |
| 8 #include "vm/growable_array.h" |
| 9 #include "vm/hash_map.h" |
| 10 |
| 11 #include "vm/flow_graph.h" |
| 12 #include "vm/flow_graph_builder.h" |
| 13 #include "vm/intermediate_language.h" |
| 14 #include "vm/kernel.h" |
| 15 |
| 16 namespace dart { |
| 17 namespace kernel { |
| 18 |
| 19 template <typename K, typename V> |
| 20 class Map : public DirectChainedHashMap<RawPointerKeyValueTrait<K, V> > { |
| 21 public: |
| 22 typedef typename RawPointerKeyValueTrait<K, V>::Key Key; |
| 23 typedef typename RawPointerKeyValueTrait<K, V>::Value Value; |
| 24 typedef typename RawPointerKeyValueTrait<K, V>::Pair Pair; |
| 25 |
| 26 inline void Insert(const Key& key, const Value& value) { |
| 27 Pair pair(key, value); |
| 28 DirectChainedHashMap<RawPointerKeyValueTrait<K, V> >::Insert(pair); |
| 29 } |
| 30 |
| 31 inline V Lookup(const Key& key) { |
| 32 Pair* pair = |
| 33 DirectChainedHashMap<RawPointerKeyValueTrait<K, V> >::Lookup(key); |
| 34 if (pair == NULL) { |
| 35 return V(); |
| 36 } else { |
| 37 return pair->value; |
| 38 } |
| 39 } |
| 40 }; |
| 41 |
| 42 class BreakableBlock; |
| 43 class CatchBlock; |
| 44 class FlowGraphBuilder; |
| 45 class SwitchBlock; |
| 46 class TryCatchBlock; |
| 47 class TryFinallyBlock; |
| 48 |
| 49 class Fragment { |
| 50 public: |
| 51 Instruction* entry; |
| 52 Instruction* current; |
| 53 |
| 54 Fragment() : entry(NULL), current(NULL) {} |
| 55 |
| 56 explicit Fragment(Instruction* instruction) |
| 57 : entry(instruction), current(instruction) {} |
| 58 |
| 59 Fragment(Instruction* entry, Instruction* current) |
| 60 : entry(entry), current(current) {} |
| 61 |
| 62 bool is_open() { return entry == NULL || current != NULL; } |
| 63 bool is_closed() { return !is_open(); } |
| 64 |
| 65 Fragment& operator+=(const Fragment& other); |
| 66 Fragment& operator<<=(Instruction* next); |
| 67 |
| 68 Fragment closed(); |
| 69 }; |
| 70 |
| 71 Fragment operator+(const Fragment& first, const Fragment& second); |
| 72 Fragment operator<<(const Fragment& fragment, Instruction* next); |
| 73 |
| 74 typedef ZoneGrowableArray<PushArgumentInstr*>* ArgumentArray; |
| 75 |
| 76 |
| 77 class ActiveClass { |
| 78 public: |
| 79 ActiveClass() |
| 80 : kernel_class(NULL), klass(NULL), member(NULL), kernel_function(NULL) {} |
| 81 |
| 82 // The current enclosing kernel class (if available, otherwise NULL). |
| 83 Class* kernel_class; |
| 84 |
| 85 // The current enclosing class (or the library top-level class). When this is |
| 86 // a library's top-level class, the kernel_class will be NULL. |
| 87 const dart::Class* klass; |
| 88 |
| 89 // The enclosing member (e.g., Constructor, Procedure, or Field) if there |
| 90 // is one. |
| 91 Member* member; |
| 92 |
| 93 // The current function. |
| 94 FunctionNode* kernel_function; |
| 95 }; |
| 96 |
| 97 |
| 98 class ActiveClassScope { |
| 99 public: |
| 100 ActiveClassScope(ActiveClass* active_class, Class* kernel_class, |
| 101 const dart::Class* klass) |
| 102 : active_class_(active_class), saved_(*active_class) { |
| 103 active_class_->kernel_class = kernel_class; |
| 104 active_class_->klass = klass; |
| 105 active_class_->member = NULL; |
| 106 active_class_->kernel_function = NULL; |
| 107 } |
| 108 |
| 109 ~ActiveClassScope() { *active_class_ = saved_; } |
| 110 |
| 111 private: |
| 112 ActiveClass* active_class_; |
| 113 ActiveClass saved_; |
| 114 }; |
| 115 |
| 116 |
| 117 class ActiveMemberScope { |
| 118 public: |
| 119 ActiveMemberScope(ActiveClass* active_class, Member* member) |
| 120 : active_class_(active_class), saved_(*active_class) { |
| 121 // The class and kernel_class is inherited. |
| 122 active_class_->member = member; |
| 123 active_class_->kernel_function = NULL; |
| 124 } |
| 125 |
| 126 ~ActiveMemberScope() { *active_class_ = saved_; } |
| 127 |
| 128 private: |
| 129 ActiveClass* active_class_; |
| 130 ActiveClass saved_; |
| 131 }; |
| 132 |
| 133 |
| 134 class ActiveFunctionScope { |
| 135 public: |
| 136 ActiveFunctionScope(ActiveClass* active_class, FunctionNode* kernel_function) |
| 137 : active_class_(active_class), saved_(*active_class) { |
| 138 // The class, kernel_class, and member are inherited. |
| 139 active_class_->kernel_function = kernel_function; |
| 140 } |
| 141 |
| 142 ~ActiveFunctionScope() { *active_class_ = saved_; } |
| 143 |
| 144 private: |
| 145 ActiveClass* active_class_; |
| 146 ActiveClass saved_; |
| 147 }; |
| 148 |
| 149 |
| 150 class TranslationHelper { |
| 151 public: |
| 152 TranslationHelper(dart::Thread* thread, dart::Zone* zone, Isolate* isolate) |
| 153 : thread_(thread), zone_(zone), isolate_(isolate) {} |
| 154 virtual ~TranslationHelper() {} |
| 155 |
| 156 Thread* thread() { return thread_; } |
| 157 |
| 158 Zone* zone() { return zone_; } |
| 159 |
| 160 Isolate* isolate() { return isolate_; } |
| 161 |
| 162 // Set whether unfinalized classes should be finalized. The base class |
| 163 // implementation used at flow graph construction time looks up classes in the |
| 164 // VM's heap, all of which should already be finalized. |
| 165 virtual void SetFinalize(bool finalize) {} |
| 166 |
| 167 RawInstance* Canonicalize(const Instance& instance); |
| 168 |
| 169 const dart::String& DartString(const char* content, |
| 170 Heap::Space space = Heap::kNew); |
| 171 dart::String& DartString(String* content, Heap::Space space = Heap::kNew); |
| 172 const dart::String& DartSymbol(const char* content) const; |
| 173 dart::String& DartSymbol(String* content) const; |
| 174 |
| 175 const dart::String& DartClassName(Class* kernel_klass); |
| 176 const dart::String& DartConstructorName(Constructor* node); |
| 177 const dart::String& DartProcedureName(Procedure* procedure); |
| 178 |
| 179 const dart::String& DartSetterName(Name* kernel_name); |
| 180 const dart::String& DartGetterName(Name* kernel_name); |
| 181 const dart::String& DartFieldName(Name* kernel_name); |
| 182 const dart::String& DartInitializerName(Name* kernel_name); |
| 183 const dart::String& DartMethodName(Name* kernel_name); |
| 184 const dart::String& DartFactoryName(Class* klass, Name* kernel_name); |
| 185 |
| 186 const Array& ArgumentNames(List<NamedExpression>* named); |
| 187 |
| 188 // A subclass overrides these when reading in the Kernel program in order to |
| 189 // support recursive type expressions (e.g. for "implements X" ... |
| 190 // annotations). |
| 191 virtual RawLibrary* LookupLibraryByKernelLibrary(Library* library); |
| 192 virtual RawClass* LookupClassByKernelClass(Class* klass); |
| 193 |
| 194 RawField* LookupFieldByKernelField(Field* field); |
| 195 RawFunction* LookupStaticMethodByKernelProcedure(Procedure* procedure); |
| 196 RawFunction* LookupConstructorByKernelConstructor(Constructor* constructor); |
| 197 dart::RawFunction* LookupConstructorByKernelConstructor( |
| 198 const dart::Class& owner, Constructor* constructor); |
| 199 |
| 200 dart::Type& GetCanonicalType(const dart::Class& klass); |
| 201 |
| 202 void ReportError(const char* format, ...); |
| 203 void ReportError(const Error& prev_error, const char* format, ...); |
| 204 |
| 205 private: |
| 206 // This will mangle [kernel_name] (if necessary) and make the result a symbol. |
| 207 // The result will be avilable in [name_to_modify] and it is also returned. |
| 208 dart::String& ManglePrivateName(Library* kernel_library, |
| 209 dart::String* name_to_modify, |
| 210 bool symbolize = true); |
| 211 |
| 212 dart::Thread* thread_; |
| 213 dart::Zone* zone_; |
| 214 dart::Isolate* isolate_; |
| 215 }; |
| 216 |
| 217 // Regarding malformed types: |
| 218 // The spec says in section "19.1 Static Types" roughly: |
| 219 // |
| 220 // A type T is malformed iff: |
| 221 // * T does not denote a type in scope |
| 222 // * T refers to a type parameter in a static member |
| 223 // * T is a parametrized Type G<T1, ...> and G is malformed |
| 224 // * T denotes declarations from multiple imports |
| 225 // |
| 226 // Any use of a malformed type gives rise to a static warning. A malformed |
| 227 // type is then interpreted as dynamic by the static type checker and the |
| 228 // runtime unless explicitly specified otherwise. |
| 229 class DartTypeTranslator : public DartTypeVisitor { |
| 230 public: |
| 231 DartTypeTranslator(TranslationHelper* helper, ActiveClass* active_class, |
| 232 bool finalize = true) |
| 233 : translation_helper_(*helper), |
| 234 active_class_(active_class), |
| 235 zone_(helper->zone()), |
| 236 result_(AbstractType::Handle(helper->zone())), |
| 237 finalize_(finalize) {} |
| 238 |
| 239 // Can return a malformed type. |
| 240 AbstractType& TranslateType(DartType* node); |
| 241 |
| 242 // Can return a malformed type. |
| 243 AbstractType& TranslateTypeWithoutFinalization(DartType* node); |
| 244 |
| 245 |
| 246 virtual void VisitDefaultDartType(DartType* node) { UNREACHABLE(); } |
| 247 |
| 248 virtual void VisitInvalidType(InvalidType* node); |
| 249 |
| 250 virtual void VisitFunctionType(FunctionType* node); |
| 251 |
| 252 virtual void VisitTypeParameterType(TypeParameterType* node); |
| 253 |
| 254 virtual void VisitInterfaceType(InterfaceType* node); |
| 255 |
| 256 virtual void VisitDynamicType(DynamicType* node); |
| 257 |
| 258 virtual void VisitVoidType(VoidType* node); |
| 259 |
| 260 // Will return `TypeArguments::null()` in case any of the arguments are |
| 261 // malformed. |
| 262 const TypeArguments& TranslateInstantiatedTypeArguments( |
| 263 const dart::Class& receiver_class, DartType** receiver_type_arguments, |
| 264 intptr_t length); |
| 265 |
| 266 // Will return `TypeArguments::null()` in case any of the arguments are |
| 267 // malformed. |
| 268 const TypeArguments& TranslateTypeArguments(DartType** dart_types, |
| 269 intptr_t length); |
| 270 |
| 271 const Type& ReceiverType(const dart::Class& klass); |
| 272 |
| 273 private: |
| 274 TranslationHelper& translation_helper_; |
| 275 ActiveClass* active_class_; |
| 276 Zone* zone_; |
| 277 AbstractType& result_; |
| 278 |
| 279 bool finalize_; |
| 280 }; |
| 281 |
| 282 |
| 283 // There are several cases when we are compiling constant expressions: |
| 284 // |
| 285 // * constant field initializers: |
| 286 // const FieldName = <expr>; |
| 287 // |
| 288 // * constant expressions: |
| 289 // const [<expr>, ...] |
| 290 // const {<expr> : <expr>, ...} |
| 291 // const Constructor(<expr>, ...) |
| 292 // |
| 293 // * constant default parameters: |
| 294 // f(a, [b = <expr>]) |
| 295 // f(a, {b: <expr>}) |
| 296 // |
| 297 // * constant values to compare in a [SwitchCase] |
| 298 // case <expr>: |
| 299 // |
| 300 // In all cases `<expr>` must be recursively evaluated and canonicalized at |
| 301 // compile-time. |
| 302 class ConstantEvaluator : public ExpressionVisitor { |
| 303 public: |
| 304 ConstantEvaluator(FlowGraphBuilder* builder, Zone* zone, TranslationHelper* h, |
| 305 DartTypeTranslator* type_translator) |
| 306 : builder_(builder), |
| 307 isolate_(Isolate::Current()), |
| 308 zone_(zone), |
| 309 translation_helper_(*h), |
| 310 type_translator_(*type_translator), |
| 311 result_(dart::Instance::Handle(zone)) {} |
| 312 virtual ~ConstantEvaluator() {} |
| 313 |
| 314 Instance& EvaluateExpression(Expression* node); |
| 315 Object& EvaluateExpressionSafe(Expression* node); |
| 316 Instance& EvaluateConstructorInvocation(ConstructorInvocation* node); |
| 317 Instance& EvaluateListLiteral(ListLiteral* node); |
| 318 Instance& EvaluateMapLiteral(MapLiteral* node); |
| 319 |
| 320 virtual void VisitDefaultExpression(Expression* node) { UNREACHABLE(); } |
| 321 |
| 322 virtual void VisitBigintLiteral(BigintLiteral* node); |
| 323 virtual void VisitBoolLiteral(BoolLiteral* node); |
| 324 virtual void VisitDoubleLiteral(DoubleLiteral* node); |
| 325 virtual void VisitIntLiteral(IntLiteral* node); |
| 326 virtual void VisitNullLiteral(NullLiteral* node); |
| 327 virtual void VisitStringLiteral(StringLiteral* node); |
| 328 virtual void VisitSymbolLiteral(SymbolLiteral* node); |
| 329 virtual void VisitTypeLiteral(TypeLiteral* node); |
| 330 |
| 331 virtual void VisitListLiteral(ListLiteral* node); |
| 332 virtual void VisitMapLiteral(MapLiteral* node); |
| 333 |
| 334 virtual void VisitConstructorInvocation(ConstructorInvocation* node); |
| 335 virtual void VisitMethodInvocation(MethodInvocation* node); |
| 336 virtual void VisitStaticGet(StaticGet* node); |
| 337 virtual void VisitVariableGet(VariableGet* node); |
| 338 virtual void VisitLet(Let* node); |
| 339 virtual void VisitStaticInvocation(StaticInvocation* node); |
| 340 virtual void VisitStringConcatenation(StringConcatenation* node); |
| 341 virtual void VisitConditionalExpression(ConditionalExpression* node); |
| 342 virtual void VisitLogicalExpression(LogicalExpression* node); |
| 343 virtual void VisitNot(Not* node); |
| 344 |
| 345 private: |
| 346 // This will translate type arguments form [kernel_arguments]. If no type |
| 347 // arguments are passed and the [target] is a factory then the null type |
| 348 // argument array will be returned. |
| 349 // |
| 350 // If none of these cases apply, NULL will be returned. |
| 351 const TypeArguments* TranslateTypeArguments(const Function& target, |
| 352 dart::Class* target_klass, |
| 353 Arguments* kernel_arguments); |
| 354 |
| 355 const Object& RunFunction(const Function& function, Arguments* arguments, |
| 356 const Instance* receiver = NULL, |
| 357 const TypeArguments* type_args = NULL); |
| 358 |
| 359 const Object& RunFunction(const Function& function, const Array& arguments, |
| 360 const Array& names); |
| 361 |
| 362 RawObject* EvaluateConstConstructorCall(const dart::Class& type_class, |
| 363 const TypeArguments& type_arguments, |
| 364 const Function& constructor, |
| 365 const Object& argument); |
| 366 |
| 367 FlowGraphBuilder* builder_; |
| 368 Isolate* isolate_; |
| 369 Zone* zone_; |
| 370 TranslationHelper& translation_helper_; |
| 371 DartTypeTranslator& type_translator_; |
| 372 |
| 373 Instance& result_; |
| 374 }; |
| 375 |
| 376 |
| 377 struct FunctionScope { |
| 378 FunctionNode* function; |
| 379 LocalScope* scope; |
| 380 }; |
| 381 |
| 382 |
| 383 class ScopeBuildingResult : public ZoneAllocated { |
| 384 public: |
| 385 Map<VariableDeclaration, LocalVariable*> locals; |
| 386 Map<TreeNode, LocalScope*> scopes; |
| 387 GrowableArray<FunctionScope> function_scopes; |
| 388 |
| 389 // Only non-NULL for instance functions. |
| 390 LocalVariable* this_variable = NULL; |
| 391 |
| 392 // Only non-NULL for factory constructor functions. |
| 393 LocalVariable* type_arguments_variable = NULL; |
| 394 |
| 395 // Non-NULL when the function contains a switch statement. |
| 396 LocalVariable* switch_variable = NULL; |
| 397 |
| 398 // Non-NULL when the function contains a return inside a finally block. |
| 399 LocalVariable* finally_return_variable = NULL; |
| 400 |
| 401 // Non-NULL when the function is a setter. |
| 402 LocalVariable* setter_value = NULL; |
| 403 |
| 404 // Non-NULL if the function contains yield statement. |
| 405 // TODO(27590) actual variable is called :await_jump_var, we should rename |
| 406 // it to reflect the fact that it is used for both await and yield. |
| 407 LocalVariable* yield_jump_variable = NULL; |
| 408 |
| 409 // Non-NULL if the function contains yield statement. |
| 410 // TODO(27590) actual variable is called :await_ctx_var, we should rename |
| 411 // it to reflect the fact that it is used for both await and yield. |
| 412 LocalVariable* yield_context_variable = NULL; |
| 413 |
| 414 // Variables used in exception handlers, one per exception handler nesting |
| 415 // level. |
| 416 GrowableArray<LocalVariable*> exception_variables; |
| 417 GrowableArray<LocalVariable*> stack_trace_variables; |
| 418 GrowableArray<LocalVariable*> catch_context_variables; |
| 419 |
| 420 // For-in iterators, one per for-in nesting level. |
| 421 GrowableArray<LocalVariable*> iterator_variables; |
| 422 }; |
| 423 |
| 424 |
| 425 class ScopeBuilder : public RecursiveVisitor { |
| 426 public: |
| 427 ScopeBuilder(ParsedFunction* parsed_function, TreeNode* node) |
| 428 : result_(NULL), |
| 429 parsed_function_(parsed_function), |
| 430 node_(node), |
| 431 zone_(Thread::Current()->zone()), |
| 432 translation_helper_(Thread::Current(), zone_, Isolate::Current()), |
| 433 current_function_scope_(NULL), |
| 434 scope_(NULL), |
| 435 depth_(0), |
| 436 name_index_(0) {} |
| 437 |
| 438 virtual ~ScopeBuilder() {} |
| 439 |
| 440 ScopeBuildingResult* BuildScopes(); |
| 441 |
| 442 virtual void VisitName(Name* node) { /* NOP */ |
| 443 } |
| 444 |
| 445 virtual void VisitThisExpression(ThisExpression* node); |
| 446 virtual void VisitTypeParameterType(TypeParameterType* node); |
| 447 virtual void VisitVariableGet(VariableGet* node); |
| 448 virtual void VisitVariableSet(VariableSet* node); |
| 449 virtual void VisitFunctionExpression(FunctionExpression* node); |
| 450 virtual void VisitLet(Let* node); |
| 451 virtual void VisitBlock(Block* node); |
| 452 virtual void VisitVariableDeclaration(VariableDeclaration* node); |
| 453 virtual void VisitFunctionDeclaration(FunctionDeclaration* node); |
| 454 virtual void VisitWhileStatement(WhileStatement* node); |
| 455 virtual void VisitDoStatement(DoStatement* node); |
| 456 virtual void VisitForStatement(ForStatement* node); |
| 457 virtual void VisitForInStatement(ForInStatement* node); |
| 458 virtual void VisitSwitchStatement(SwitchStatement* node); |
| 459 virtual void VisitReturnStatement(ReturnStatement* node); |
| 460 virtual void VisitTryCatch(TryCatch* node); |
| 461 virtual void VisitTryFinally(TryFinally* node); |
| 462 virtual void VisitYieldStatement(YieldStatement* node); |
| 463 virtual void VisitAssertStatement(AssertStatement* node); |
| 464 |
| 465 virtual void VisitFunctionNode(FunctionNode* node); |
| 466 |
| 467 virtual void VisitConstructor(Constructor* node); |
| 468 |
| 469 private: |
| 470 void EnterScope(TreeNode* node); |
| 471 void ExitScope(); |
| 472 |
| 473 LocalVariable* MakeVariable(const dart::String& name); |
| 474 LocalVariable* MakeVariable(const dart::String& name, const Type& type); |
| 475 |
| 476 void AddParameters(FunctionNode* function, intptr_t pos = 0); |
| 477 void AddParameter(VariableDeclaration* declaration, intptr_t pos); |
| 478 void AddVariable(VariableDeclaration* declaration); |
| 479 void AddExceptionVariable(GrowableArray<LocalVariable*>* variables, |
| 480 const char* prefix, intptr_t nesting_depth); |
| 481 void AddTryVariables(); |
| 482 void AddCatchVariables(); |
| 483 void AddIteratorVariable(); |
| 484 void AddSwitchVariable(); |
| 485 |
| 486 // Record an assignment or reference to a variable. If the occurrence is |
| 487 // in a nested function, ensure that the variable is handled properly as a |
| 488 // captured variable. |
| 489 void LookupVariable(VariableDeclaration* declaration); |
| 490 |
| 491 const dart::String& GenerateName(const char* prefix, intptr_t suffix); |
| 492 |
| 493 void HandleLocalFunction(TreeNode* parent, FunctionNode* function); |
| 494 void HandleSpecialLoad(LocalVariable** variable, const dart::String& symbol); |
| 495 void LookupCapturedVariableByName(LocalVariable** variable, |
| 496 const dart::String& name); |
| 497 |
| 498 |
| 499 struct DepthState { |
| 500 explicit DepthState(intptr_t function) |
| 501 : loop_(0), |
| 502 function_(function), |
| 503 try_(0), |
| 504 catch_(0), |
| 505 finally_(0), |
| 506 for_in_(0) {} |
| 507 |
| 508 intptr_t loop_; |
| 509 intptr_t function_; |
| 510 intptr_t try_; |
| 511 intptr_t catch_; |
| 512 intptr_t finally_; |
| 513 intptr_t for_in_; |
| 514 }; |
| 515 |
| 516 ScopeBuildingResult* result_; |
| 517 ParsedFunction* parsed_function_; |
| 518 TreeNode* node_; |
| 519 |
| 520 Zone* zone_; |
| 521 TranslationHelper translation_helper_; |
| 522 |
| 523 |
| 524 FunctionNode* current_function_node_; |
| 525 LocalScope* current_function_scope_; |
| 526 LocalScope* scope_; |
| 527 DepthState depth_; |
| 528 |
| 529 intptr_t name_index_; |
| 530 }; |
| 531 |
| 532 |
| 533 class FlowGraphBuilder : public TreeVisitor { |
| 534 public: |
| 535 FlowGraphBuilder(TreeNode* node, ParsedFunction* parsed_function, |
| 536 const ZoneGrowableArray<const ICData*>& ic_data_array, |
| 537 InlineExitCollector* exit_collector, intptr_t osr_id, |
| 538 intptr_t first_block_id = 1); |
| 539 virtual ~FlowGraphBuilder(); |
| 540 |
| 541 FlowGraph* BuildGraph(); |
| 542 |
| 543 virtual void VisitDefaultTreeNode(TreeNode* node) { UNREACHABLE(); } |
| 544 |
| 545 virtual void VisitInvalidExpression(InvalidExpression* node); |
| 546 virtual void VisitNullLiteral(NullLiteral* node); |
| 547 virtual void VisitBoolLiteral(BoolLiteral* node); |
| 548 virtual void VisitIntLiteral(IntLiteral* node); |
| 549 virtual void VisitBigintLiteral(BigintLiteral* node); |
| 550 virtual void VisitDoubleLiteral(DoubleLiteral* node); |
| 551 virtual void VisitStringLiteral(StringLiteral* node); |
| 552 virtual void VisitSymbolLiteral(SymbolLiteral* node); |
| 553 virtual void VisitTypeLiteral(TypeLiteral* node); |
| 554 virtual void VisitVariableGet(VariableGet* node); |
| 555 virtual void VisitVariableSet(VariableSet* node); |
| 556 virtual void VisitStaticGet(StaticGet* node); |
| 557 virtual void VisitStaticSet(StaticSet* node); |
| 558 virtual void VisitPropertyGet(PropertyGet* node); |
| 559 virtual void VisitPropertySet(PropertySet* node); |
| 560 virtual void VisitDirectPropertyGet(DirectPropertyGet* node); |
| 561 virtual void VisitDirectPropertySet(DirectPropertySet* node); |
| 562 virtual void VisitStaticInvocation(StaticInvocation* node); |
| 563 virtual void VisitMethodInvocation(MethodInvocation* node); |
| 564 virtual void VisitDirectMethodInvocation(DirectMethodInvocation* node); |
| 565 virtual void VisitConstructorInvocation(ConstructorInvocation* node); |
| 566 virtual void VisitIsExpression(IsExpression* node); |
| 567 virtual void VisitAsExpression(AsExpression* node); |
| 568 virtual void VisitConditionalExpression(ConditionalExpression* node); |
| 569 virtual void VisitLogicalExpression(LogicalExpression* node); |
| 570 virtual void VisitNot(Not* node); |
| 571 virtual void VisitThisExpression(ThisExpression* node); |
| 572 virtual void VisitStringConcatenation(StringConcatenation* node); |
| 573 virtual void VisitListLiteral(ListLiteral* node); |
| 574 virtual void VisitMapLiteral(MapLiteral* node); |
| 575 virtual void VisitFunctionExpression(FunctionExpression* node); |
| 576 virtual void VisitLet(Let* node); |
| 577 virtual void VisitThrow(Throw* node); |
| 578 virtual void VisitRethrow(Rethrow* node); |
| 579 virtual void VisitBlockExpression(BlockExpression* node); |
| 580 |
| 581 virtual void VisitInvalidStatement(InvalidStatement* node); |
| 582 virtual void VisitEmptyStatement(EmptyStatement* node); |
| 583 virtual void VisitBlock(Block* node); |
| 584 virtual void VisitReturnStatement(ReturnStatement* node); |
| 585 virtual void VisitExpressionStatement(ExpressionStatement* node); |
| 586 virtual void VisitVariableDeclaration(VariableDeclaration* node); |
| 587 virtual void VisitFunctionDeclaration(FunctionDeclaration* node); |
| 588 virtual void VisitIfStatement(IfStatement* node); |
| 589 virtual void VisitWhileStatement(WhileStatement* node); |
| 590 virtual void VisitDoStatement(DoStatement* node); |
| 591 virtual void VisitForStatement(ForStatement* node); |
| 592 virtual void VisitForInStatement(ForInStatement* node); |
| 593 virtual void VisitLabeledStatement(LabeledStatement* node); |
| 594 virtual void VisitBreakStatement(BreakStatement* node); |
| 595 virtual void VisitSwitchStatement(SwitchStatement* node); |
| 596 virtual void VisitContinueSwitchStatement(ContinueSwitchStatement* node); |
| 597 virtual void VisitAssertStatement(AssertStatement* node); |
| 598 virtual void VisitTryFinally(TryFinally* node); |
| 599 virtual void VisitTryCatch(TryCatch* node); |
| 600 virtual void VisitYieldStatement(YieldStatement* node); |
| 601 |
| 602 private: |
| 603 FlowGraph* BuildGraphOfFunction(FunctionNode* node, |
| 604 Constructor* constructor = NULL); |
| 605 FlowGraph* BuildGraphOfFieldAccessor(Field* node, |
| 606 LocalVariable* setter_value); |
| 607 FlowGraph* BuildGraphOfStaticFieldInitializer(Field* node); |
| 608 FlowGraph* BuildGraphOfMethodExtractor(const Function& method); |
| 609 FlowGraph* BuildGraphOfImplicitClosureFunction(FunctionNode* kernel_function, |
| 610 const Function& function); |
| 611 FlowGraph* BuildGraphOfNoSuchMethodDispatcher(const Function& function); |
| 612 FlowGraph* BuildGraphOfInvokeFieldDispatcher(const Function& function); |
| 613 |
| 614 Fragment NativeFunctionBody(FunctionNode* kernel_function, |
| 615 const Function& function); |
| 616 |
| 617 void SetupDefaultParameterValues(FunctionNode* function); |
| 618 |
| 619 TargetEntryInstr* BuildTargetEntry(); |
| 620 JoinEntryInstr* BuildJoinEntry(); |
| 621 |
| 622 Fragment TranslateArguments(Arguments* node, Array* argument_names); |
| 623 ArgumentArray GetArguments(int count); |
| 624 |
| 625 Fragment TranslateInitializers(Class* kernel_klass, |
| 626 List<Initializer>* initialiers); |
| 627 |
| 628 Fragment TranslateStatement(Statement* statement); |
| 629 Fragment TranslateCondition(Expression* expression, bool* negate); |
| 630 Fragment TranslateExpression(Expression* expression); |
| 631 |
| 632 Fragment TranslateFinallyFinalizers(TryFinallyBlock* outer_finally, |
| 633 intptr_t target_context_depth); |
| 634 |
| 635 Fragment TranslateFunctionNode(FunctionNode* node, TreeNode* parent); |
| 636 |
| 637 Fragment EnterScope(TreeNode* node, bool* new_context = NULL); |
| 638 Fragment ExitScope(TreeNode* node); |
| 639 |
| 640 Fragment LoadContextAt(int depth); |
| 641 Fragment AdjustContextTo(int depth); |
| 642 |
| 643 Fragment PushContext(int size); |
| 644 Fragment PopContext(); |
| 645 |
| 646 Fragment LoadInstantiatorTypeArguments(); |
| 647 Fragment InstantiateTypeArguments(const TypeArguments& type_arguments); |
| 648 Fragment TranslateInstantiatedTypeArguments( |
| 649 const TypeArguments& type_arguments); |
| 650 |
| 651 Fragment AllocateContext(int size); |
| 652 Fragment AllocateObject(const dart::Class& klass, intptr_t argument_count); |
| 653 Fragment AllocateObject(const dart::Class& klass, |
| 654 const Function& closure_function); |
| 655 Fragment BooleanNegate(); |
| 656 Fragment StrictCompare(Token::Kind kind, bool number_check = false); |
| 657 Fragment BranchIfTrue(TargetEntryInstr** then_entry, |
| 658 TargetEntryInstr** otherwise_entry, |
| 659 bool negate = false); |
| 660 Fragment BranchIfNull(TargetEntryInstr** then_entry, |
| 661 TargetEntryInstr** otherwise_entry, |
| 662 bool negate = false); |
| 663 Fragment BranchIfEqual(TargetEntryInstr** then_entry, |
| 664 TargetEntryInstr** otherwise_entry, |
| 665 bool negate = false); |
| 666 Fragment BranchIfStrictEqual(TargetEntryInstr** then_entry, |
| 667 TargetEntryInstr** otherwise_entry); |
| 668 Fragment CatchBlockEntry(const Array& handler_types, intptr_t handler_index); |
| 669 Fragment TryCatch(int try_handler_index); |
| 670 Fragment CheckStackOverflowInPrologue(); |
| 671 Fragment CheckStackOverflow(); |
| 672 Fragment CloneContext(); |
| 673 Fragment Constant(const Object& value); |
| 674 Fragment CreateArray(); |
| 675 Fragment Goto(JoinEntryInstr* destination); |
| 676 Fragment IntConstant(int64_t value); |
| 677 Fragment InstanceCall(const dart::String& name, Token::Kind kind, |
| 678 intptr_t argument_count, intptr_t num_args_checked = 1); |
| 679 Fragment InstanceCall(const dart::String& name, Token::Kind kind, |
| 680 intptr_t argument_count, const Array& argument_names, |
| 681 intptr_t num_args_checked = 1); |
| 682 Fragment ClosureCall(int argument_count, const Array& argument_names); |
| 683 Fragment ThrowException(); |
| 684 Fragment RethrowException(int catch_try_index); |
| 685 Fragment LoadClassId(); |
| 686 Fragment LoadField(const dart::Field& field); |
| 687 Fragment LoadField(intptr_t offset, intptr_t class_id = kDynamicCid); |
| 688 Fragment LoadNativeField(MethodRecognizer::Kind kind, intptr_t offset, |
| 689 const Type& type, intptr_t class_id, |
| 690 bool is_immutable = false); |
| 691 Fragment LoadLocal(LocalVariable* variable); |
| 692 Fragment InitStaticField(const dart::Field& field); |
| 693 Fragment LoadStaticField(); |
| 694 Fragment NullConstant(); |
| 695 Fragment NativeCall(const dart::String* name, const Function* function); |
| 696 Fragment PushArgument(); |
| 697 Fragment Return(); |
| 698 Fragment StaticCall(const Function& target, intptr_t argument_count); |
| 699 Fragment StaticCall(const Function& target, intptr_t argument_count, |
| 700 const Array& argument_names); |
| 701 Fragment StoreIndexed(intptr_t class_id); |
| 702 Fragment StoreInstanceField(const dart::Field& field); |
| 703 Fragment StoreInstanceField(intptr_t offset); |
| 704 Fragment StoreLocal(LocalVariable* variable); |
| 705 Fragment StoreStaticField(const dart::Field& field); |
| 706 Fragment StringInterpolate(); |
| 707 Fragment ThrowTypeError(); |
| 708 Fragment ThrowNoSuchMethodError(); |
| 709 Fragment BuildImplicitClosureCreation(const Function& target); |
| 710 |
| 711 dart::RawFunction* LookupMethodByMember(Member* target, |
| 712 const dart::String& method_name); |
| 713 |
| 714 LocalVariable* MakeTemporary(); |
| 715 LocalVariable* MakeNonTemporary(const dart::String& symbol); |
| 716 |
| 717 intptr_t CurrentTryIndex(); |
| 718 intptr_t AllocateTryIndex() { return next_used_try_index_++; } |
| 719 |
| 720 void AddVariable(VariableDeclaration* declaration, LocalVariable* variable); |
| 721 void AddParameter(VariableDeclaration* declaration, LocalVariable* variable, |
| 722 intptr_t pos); |
| 723 dart::LocalVariable* LookupVariable(VariableDeclaration* var); |
| 724 |
| 725 void SetTempIndex(Definition* definition); |
| 726 |
| 727 void Push(Definition* definition); |
| 728 Value* Pop(); |
| 729 Fragment Drop(); |
| 730 |
| 731 bool IsInlining() { return exit_collector_ != NULL; } |
| 732 |
| 733 Token::Kind MethodKind(const dart::String& name); |
| 734 |
| 735 void InlineBailout(const char* reason); |
| 736 |
| 737 Zone* zone_; |
| 738 TranslationHelper translation_helper_; |
| 739 |
| 740 // The node we are currently compiling (e.g. FunctionNode, Constructor, |
| 741 // Field) |
| 742 TreeNode* node_; |
| 743 |
| 744 ParsedFunction* parsed_function_; |
| 745 intptr_t osr_id_; |
| 746 const ZoneGrowableArray<const ICData*>& ic_data_array_; |
| 747 InlineExitCollector* exit_collector_; |
| 748 |
| 749 intptr_t next_block_id_; |
| 750 intptr_t AllocateBlockId() { return next_block_id_++; } |
| 751 |
| 752 intptr_t next_function_id_; |
| 753 intptr_t AllocateFunctionId() { return next_function_id_++; } |
| 754 |
| 755 intptr_t context_depth_; |
| 756 intptr_t loop_depth_; |
| 757 intptr_t try_depth_; |
| 758 intptr_t catch_depth_; |
| 759 intptr_t for_in_depth_; |
| 760 Fragment fragment_; |
| 761 Value* stack_; |
| 762 intptr_t pending_argument_count_; |
| 763 |
| 764 GraphEntryInstr* graph_entry_; |
| 765 |
| 766 ScopeBuildingResult* scopes_; |
| 767 |
| 768 struct YieldContinuation { |
| 769 Instruction* entry; |
| 770 intptr_t try_index; |
| 771 |
| 772 YieldContinuation(Instruction* entry, intptr_t try_index) |
| 773 : entry(entry), try_index(try_index) {} |
| 774 |
| 775 YieldContinuation() |
| 776 : entry(NULL), try_index(CatchClauseNode::kInvalidTryIndex) {} |
| 777 }; |
| 778 |
| 779 GrowableArray<YieldContinuation> yield_continuations_; |
| 780 |
| 781 LocalVariable* CurrentException() { |
| 782 return scopes_->exception_variables[catch_depth_ - 1]; |
| 783 } |
| 784 LocalVariable* CurrentStackTrace() { |
| 785 return scopes_->stack_trace_variables[catch_depth_ - 1]; |
| 786 } |
| 787 LocalVariable* CurrentCatchContext() { |
| 788 return scopes_->catch_context_variables[try_depth_]; |
| 789 } |
| 790 |
| 791 // A chained list of breakable blocks. Chaining and lookup is done by the |
| 792 // [BreakableBlock] class. |
| 793 BreakableBlock* breakable_block_; |
| 794 |
| 795 // A chained list of switch blocks. Chaining and lookup is done by the |
| 796 // [SwitchBlock] class. |
| 797 SwitchBlock* switch_block_; |
| 798 |
| 799 // A chained list of try-finally blocks. Chaining and lookup is done by the |
| 800 // [TryFinallyBlock] class. |
| 801 TryFinallyBlock* try_finally_block_; |
| 802 |
| 803 // A chained list of try-catch blocks. Chaining and lookup is done by the |
| 804 // [TryCatchBlock] class. |
| 805 TryCatchBlock* try_catch_block_; |
| 806 intptr_t next_used_try_index_; |
| 807 |
| 808 // A chained list of catch blocks. Chaining and lookup is done by the |
| 809 // [CatchBlock] class. |
| 810 CatchBlock* catch_block_; |
| 811 |
| 812 ActiveClass active_class_; |
| 813 DartTypeTranslator type_translator_; |
| 814 ConstantEvaluator constant_evaluator_; |
| 815 |
| 816 friend class BreakableBlock; |
| 817 friend class CatchBlock; |
| 818 friend class ConstantEvaluator; |
| 819 friend class DartTypeTranslator; |
| 820 friend class ScopeBuilder; |
| 821 friend class SwitchBlock; |
| 822 friend class TryCatchBlock; |
| 823 friend class TryFinallyBlock; |
| 824 }; |
| 825 |
| 826 } // namespace kernel |
| 827 } // namespace dart |
| 828 |
| 829 |
| 830 #endif // VM_KERNEL_TO_IL_H_ |
OLD | NEW |