OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 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 | 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 #include <set> | 5 #include <set> |
6 | 6 |
7 #include "vm/kernel_to_il.h" | 7 #include "vm/kernel_to_il.h" |
8 | 8 |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/intermediate_language.h" | 10 #include "vm/intermediate_language.h" |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 return name; | 435 return name; |
436 } | 436 } |
437 | 437 |
438 | 438 |
439 const dart::String& TranslationHelper::DartFieldName(Name* kernel_name) { | 439 const dart::String& TranslationHelper::DartFieldName(Name* kernel_name) { |
440 dart::String& name = DartString(kernel_name->string_index()); | 440 dart::String& name = DartString(kernel_name->string_index()); |
441 return ManglePrivateName(kernel_name->library(), &name); | 441 return ManglePrivateName(kernel_name->library(), &name); |
442 } | 442 } |
443 | 443 |
444 | 444 |
| 445 const dart::String& TranslationHelper::DartFieldName(NameIndex parent, |
| 446 StringIndex field) { |
| 447 dart::String& name = DartString(field); |
| 448 return ManglePrivateName(parent, &name); |
| 449 } |
| 450 |
| 451 |
445 const dart::String& TranslationHelper::DartInitializerName(Name* kernel_name) { | 452 const dart::String& TranslationHelper::DartInitializerName(Name* kernel_name) { |
446 // The [DartFieldName] will take care of mangling the name. | 453 // The [DartFieldName] will take care of mangling the name. |
447 dart::String& name = | 454 dart::String& name = |
448 dart::String::Handle(Z, DartFieldName(kernel_name).raw()); | 455 dart::String::Handle(Z, DartFieldName(kernel_name).raw()); |
449 name = Symbols::FromConcat(thread_, Symbols::InitPrefix(), name); | 456 name = Symbols::FromConcat(thread_, Symbols::InitPrefix(), name); |
450 return name; | 457 return name; |
451 } | 458 } |
452 | 459 |
453 | 460 |
454 const dart::String& TranslationHelper::DartMethodName(NameIndex method) { | 461 const dart::String& TranslationHelper::DartMethodName(NameIndex method) { |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
678 stack_(NULL), | 685 stack_(NULL), |
679 pending_argument_count_(0), | 686 pending_argument_count_(0), |
680 graph_entry_(NULL), | 687 graph_entry_(NULL), |
681 scopes_(NULL), | 688 scopes_(NULL), |
682 breakable_block_(NULL), | 689 breakable_block_(NULL), |
683 switch_block_(NULL), | 690 switch_block_(NULL), |
684 try_finally_block_(NULL), | 691 try_finally_block_(NULL), |
685 try_catch_block_(NULL), | 692 try_catch_block_(NULL), |
686 next_used_try_index_(0), | 693 next_used_try_index_(0), |
687 catch_block_(NULL), | 694 catch_block_(NULL), |
688 type_translator_(&translation_helper_, | |
689 &active_class_, | |
690 /* finalize= */ true), | |
691 streaming_flow_graph_builder_(NULL) { | 695 streaming_flow_graph_builder_(NULL) { |
692 Script& script = Script::Handle(Z, parsed_function->function().script()); | 696 Script& script = Script::Handle(Z, parsed_function->function().script()); |
693 H.SetStringOffsets(TypedData::Handle(Z, script.kernel_string_offsets())); | 697 H.SetStringOffsets(TypedData::Handle(Z, script.kernel_string_offsets())); |
694 H.SetStringData(TypedData::Handle(Z, script.kernel_string_data())); | 698 H.SetStringData(TypedData::Handle(Z, script.kernel_string_data())); |
695 H.SetCanonicalNames(TypedData::Handle(Z, script.kernel_canonical_names())); | 699 H.SetCanonicalNames(TypedData::Handle(Z, script.kernel_canonical_names())); |
696 } | 700 } |
697 | 701 |
698 | 702 |
699 FlowGraphBuilder::~FlowGraphBuilder() { | 703 FlowGraphBuilder::~FlowGraphBuilder() { |
700 if (streaming_flow_graph_builder_ != NULL) { | 704 if (streaming_flow_graph_builder_ != NULL) { |
(...skipping 29 matching lines...) Expand all Loading... |
730 while (CurrentTryIndex() != target_try_index) { | 734 while (CurrentTryIndex() != target_try_index) { |
731 try_catch_block_ = try_catch_block_->outer(); | 735 try_catch_block_ = try_catch_block_->outer(); |
732 changed_try_index = true; | 736 changed_try_index = true; |
733 } | 737 } |
734 if (changed_try_index) { | 738 if (changed_try_index) { |
735 JoinEntryInstr* entry = BuildJoinEntry(); | 739 JoinEntryInstr* entry = BuildJoinEntry(); |
736 instructions += Goto(entry); | 740 instructions += Goto(entry); |
737 instructions = Fragment(instructions.entry, entry); | 741 instructions = Fragment(instructions.entry, entry); |
738 } | 742 } |
739 | 743 |
740 Statement* finalizer = try_finally_block_->finalizer(); | |
741 intptr_t finalizer_kernel_offset = | 744 intptr_t finalizer_kernel_offset = |
742 try_finally_block_->finalizer_kernel_offset(); | 745 try_finally_block_->finalizer_kernel_offset(); |
743 try_finally_block_ = try_finally_block_->outer(); | 746 try_finally_block_ = try_finally_block_->outer(); |
744 if (finalizer != NULL) { | 747 instructions += streaming_flow_graph_builder_->BuildStatementAt( |
745 UNREACHABLE(); | 748 finalizer_kernel_offset); |
746 } else { | |
747 instructions += streaming_flow_graph_builder_->BuildStatementAt( | |
748 finalizer_kernel_offset); | |
749 } | |
750 | 749 |
751 // We only need to make sure that if the finalizer ended normally, we | 750 // We only need to make sure that if the finalizer ended normally, we |
752 // continue towards the next outer try-finally. | 751 // continue towards the next outer try-finally. |
753 if (!instructions.is_open()) break; | 752 if (!instructions.is_open()) break; |
754 } | 753 } |
755 | 754 |
756 if (instructions.is_open() && target_context_depth != -1) { | 755 if (instructions.is_open() && target_context_depth != -1) { |
757 // A target context depth of -1 indicates that the code after this | 756 // A target context depth of -1 indicates that the code after this |
758 // will not care about the context chain so we can leave it any way we | 757 // will not care about the context chain so we can leave it any way we |
759 // want after the last finalizer. That is used when returning. | 758 // want after the last finalizer. That is used when returning. |
(...skipping 1614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2374 ASSERT(!stack_->definition()->HasSSATemp()); | 2373 ASSERT(!stack_->definition()->HasSSATemp()); |
2375 arguments->data()[i] = stack_->definition()->AsPushArgument(); | 2374 arguments->data()[i] = stack_->definition()->AsPushArgument(); |
2376 Drop(); | 2375 Drop(); |
2377 } | 2376 } |
2378 pending_argument_count_ -= count; | 2377 pending_argument_count_ -= count; |
2379 ASSERT(pending_argument_count_ >= 0); | 2378 ASSERT(pending_argument_count_ >= 0); |
2380 return arguments; | 2379 return arguments; |
2381 } | 2380 } |
2382 | 2381 |
2383 | 2382 |
2384 #define STREAM_EXPRESSION_IF_POSSIBLE(node) \ | |
2385 if (node->can_stream()) { \ | |
2386 fragment_ = streaming_flow_graph_builder_->BuildExpressionAt( \ | |
2387 node->kernel_offset()); \ | |
2388 return; \ | |
2389 } | |
2390 | |
2391 | |
2392 AbstractType& DartTypeTranslator::TranslateType(DartType* node) { | |
2393 node->AcceptDartTypeVisitor(this); | |
2394 | |
2395 // We return a new `ZoneHandle` here on purpose: The intermediate language | |
2396 // instructions do not make a copy of the handle, so we do it. | |
2397 return AbstractType::ZoneHandle(Z, result_.raw()); | |
2398 } | |
2399 | |
2400 | |
2401 AbstractType& DartTypeTranslator::TranslateTypeWithoutFinalization( | |
2402 DartType* node) { | |
2403 bool saved_finalize = finalize_; | |
2404 finalize_ = false; | |
2405 AbstractType& result = TranslateType(node); | |
2406 finalize_ = saved_finalize; | |
2407 return result; | |
2408 } | |
2409 | |
2410 | |
2411 const AbstractType& DartTypeTranslator::TranslateVariableType( | |
2412 VariableDeclaration* variable) { | |
2413 AbstractType& abstract_type = TranslateType(variable->type()); | |
2414 | |
2415 // We return a new `ZoneHandle` here on purpose: The intermediate language | |
2416 // instructions do not make a copy of the handle, so we do it. | |
2417 AbstractType& type = Type::ZoneHandle(Z); | |
2418 | |
2419 if (abstract_type.IsMalformed()) { | |
2420 type = AbstractType::dynamic_type().raw(); | |
2421 } else { | |
2422 type = result_.raw(); | |
2423 } | |
2424 | |
2425 return type; | |
2426 } | |
2427 | |
2428 | |
2429 void DartTypeTranslator::VisitInvalidType(InvalidType* node) { | |
2430 result_ = ClassFinalizer::NewFinalizedMalformedType( | |
2431 Error::Handle(Z), // No previous error. | |
2432 Script::Handle(Z, Script::null()), TokenPosition::kNoSource, | |
2433 "[InvalidType] in Kernel IR."); | |
2434 } | |
2435 | |
2436 | |
2437 void DartTypeTranslator::VisitFunctionType(FunctionType* node) { | |
2438 // The spec describes in section "19.1 Static Types": | |
2439 // | |
2440 // Any use of a malformed type gives rise to a static warning. A | |
2441 // malformed type is then interpreted as dynamic by the static type | |
2442 // checker and the runtime unless explicitly specified otherwise. | |
2443 // | |
2444 // So we convert malformed return/parameter types to `dynamic`. | |
2445 TypeParameterScope scope(this, &node->type_parameters()); | |
2446 | |
2447 Function& signature_function = Function::ZoneHandle( | |
2448 Z, Function::NewSignatureFunction(*active_class_->klass, | |
2449 TokenPosition::kNoSource)); | |
2450 | |
2451 node->return_type()->AcceptDartTypeVisitor(this); | |
2452 if (result_.IsMalformed()) { | |
2453 result_ = AbstractType::dynamic_type().raw(); | |
2454 } | |
2455 signature_function.set_result_type(result_); | |
2456 | |
2457 const intptr_t positional_count = node->positional_parameters().length(); | |
2458 const intptr_t named_count = node->named_parameters().length(); | |
2459 const intptr_t all_count = positional_count + named_count; | |
2460 const intptr_t required_count = node->required_parameter_count(); | |
2461 | |
2462 // The additional first parameter is the receiver type (set to dynamic). | |
2463 signature_function.set_num_fixed_parameters(1 + required_count); | |
2464 signature_function.SetNumOptionalParameters( | |
2465 all_count - required_count, positional_count > required_count); | |
2466 | |
2467 const Array& parameter_types = | |
2468 Array::Handle(Z, Array::New(1 + all_count, Heap::kOld)); | |
2469 signature_function.set_parameter_types(parameter_types); | |
2470 const Array& parameter_names = | |
2471 Array::Handle(Z, Array::New(1 + all_count, Heap::kOld)); | |
2472 signature_function.set_parameter_names(parameter_names); | |
2473 | |
2474 intptr_t pos = 0; | |
2475 parameter_types.SetAt(pos, AbstractType::dynamic_type()); | |
2476 parameter_names.SetAt(pos, H.DartSymbol("_receiver_")); | |
2477 pos++; | |
2478 for (intptr_t i = 0; i < positional_count; i++, pos++) { | |
2479 node->positional_parameters()[i]->AcceptDartTypeVisitor(this); | |
2480 if (result_.IsMalformed()) { | |
2481 result_ = AbstractType::dynamic_type().raw(); | |
2482 } | |
2483 parameter_types.SetAt(pos, result_); | |
2484 parameter_names.SetAt(pos, H.DartSymbol("noname")); | |
2485 } | |
2486 for (intptr_t i = 0; i < named_count; i++, pos++) { | |
2487 NamedParameter* parameter = node->named_parameters()[i]; | |
2488 parameter->type()->AcceptDartTypeVisitor(this); | |
2489 if (result_.IsMalformed()) { | |
2490 result_ = AbstractType::dynamic_type().raw(); | |
2491 } | |
2492 parameter_types.SetAt(pos, result_); | |
2493 parameter_names.SetAt(pos, H.DartSymbol(parameter->name())); | |
2494 } | |
2495 | |
2496 Type& signature_type = | |
2497 Type::ZoneHandle(Z, signature_function.SignatureType()); | |
2498 | |
2499 if (finalize_) { | |
2500 signature_type ^= | |
2501 ClassFinalizer::FinalizeType(*active_class_->klass, signature_type); | |
2502 // Do not refer to signature_function anymore, since it may have been | |
2503 // replaced during canonicalization. | |
2504 signature_function = Function::null(); | |
2505 } | |
2506 | |
2507 result_ = signature_type.raw(); | |
2508 } | |
2509 | |
2510 | |
2511 static intptr_t FindTypeParameterIndex(List<TypeParameter>* parameters, | |
2512 TypeParameter* param) { | |
2513 for (intptr_t i = 0; i < parameters->length(); i++) { | |
2514 if (param == (*parameters)[i]) { | |
2515 return i; | |
2516 } | |
2517 } | |
2518 return -1; | |
2519 } | |
2520 | |
2521 | |
2522 void DartTypeTranslator::VisitTypeParameterType(TypeParameterType* node) { | |
2523 for (TypeParameterScope* scope = type_parameter_scope_; scope != NULL; | |
2524 scope = scope->outer()) { | |
2525 const intptr_t index = | |
2526 FindTypeParameterIndex(scope->parameters(), node->parameter()); | |
2527 if (index >= 0) { | |
2528 result_ ^= dart::Type::DynamicType(); | |
2529 return; | |
2530 } | |
2531 } | |
2532 | |
2533 if ((active_class_->member != NULL) && active_class_->member->IsProcedure()) { | |
2534 Procedure* procedure = Procedure::Cast(active_class_->member); | |
2535 if ((procedure->function() != NULL) && | |
2536 (procedure->function()->type_parameters().length() > 0)) { | |
2537 // | |
2538 // WARNING: This is a little hackish: | |
2539 // | |
2540 // We have a static factory constructor. The kernel IR gives the factory | |
2541 // constructor function it's own type parameters (which are equal in name | |
2542 // and number to the ones of the enclosing class). | |
2543 // I.e., | |
2544 // | |
2545 // class A<T> { | |
2546 // factory A.x() { return new B<T>(); } | |
2547 // } | |
2548 // | |
2549 // is basically translated to this: | |
2550 // | |
2551 // class A<T> { | |
2552 // static A.x<T'>() { return new B<T'>(); } | |
2553 // } | |
2554 // | |
2555 const intptr_t index = FindTypeParameterIndex( | |
2556 &procedure->function()->type_parameters(), node->parameter()); | |
2557 if (index >= 0) { | |
2558 if (procedure->kind() == Procedure::kFactory) { | |
2559 // The index of the type parameter in [parameters] is | |
2560 // the same index into the `klass->type_parameters()` array. | |
2561 result_ ^= | |
2562 TypeArguments::Handle(Z, active_class_->klass->type_parameters()) | |
2563 .TypeAt(index); | |
2564 } else { | |
2565 result_ ^= dart::Type::DynamicType(); | |
2566 } | |
2567 return; | |
2568 } | |
2569 } | |
2570 } | |
2571 | |
2572 ASSERT(active_class_->kernel_class != NULL); | |
2573 List<TypeParameter>* parameters = | |
2574 &active_class_->kernel_class->type_parameters(); | |
2575 const intptr_t index = FindTypeParameterIndex(parameters, node->parameter()); | |
2576 if (index >= 0) { | |
2577 // The index of the type parameter in [parameters] is | |
2578 // the same index into the `klass->type_parameters()` array. | |
2579 result_ ^= TypeArguments::Handle(Z, active_class_->klass->type_parameters()) | |
2580 .TypeAt(index); | |
2581 return; | |
2582 } | |
2583 | |
2584 UNREACHABLE(); | |
2585 } | |
2586 | |
2587 | |
2588 void DartTypeTranslator::VisitInterfaceType(InterfaceType* node) { | |
2589 // NOTE: That an interface type like `T<A, B>` is considered to be | |
2590 // malformed iff `T` is malformed. | |
2591 // => We therefore ignore errors in `A` or `B`. | |
2592 const TypeArguments& type_arguments = TranslateTypeArguments( | |
2593 node->type_arguments().raw_array(), node->type_arguments().length()); | |
2594 | |
2595 | |
2596 Object& klass = Object::Handle(Z, H.LookupClassByKernelClass(node->klass())); | |
2597 result_ = Type::New(klass, type_arguments, TokenPosition::kNoSource); | |
2598 if (finalize_) { | |
2599 ASSERT(active_class_->klass != NULL); | |
2600 result_ = ClassFinalizer::FinalizeType(*active_class_->klass, result_); | |
2601 } | |
2602 } | |
2603 | |
2604 | |
2605 void DartTypeTranslator::VisitDynamicType(DynamicType* node) { | |
2606 result_ = Object::dynamic_type().raw(); | |
2607 } | |
2608 | |
2609 | |
2610 void DartTypeTranslator::VisitVoidType(VoidType* node) { | |
2611 result_ = Object::void_type().raw(); | |
2612 } | |
2613 | |
2614 | |
2615 void DartTypeTranslator::VisitBottomType(BottomType* node) { | |
2616 result_ = | |
2617 dart::Class::Handle(Z, I->object_store()->null_class()).CanonicalType(); | |
2618 } | |
2619 | |
2620 | |
2621 const TypeArguments& DartTypeTranslator::TranslateTypeArguments( | |
2622 DartType** dart_types, | |
2623 intptr_t length) { | |
2624 bool only_dynamic = true; | |
2625 for (intptr_t i = 0; i < length; i++) { | |
2626 if (!dart_types[i]->IsDynamicType()) { | |
2627 only_dynamic = false; | |
2628 break; | |
2629 } | |
2630 } | |
2631 TypeArguments& type_arguments = TypeArguments::ZoneHandle(Z); | |
2632 if (!only_dynamic) { | |
2633 type_arguments = TypeArguments::New(length); | |
2634 for (intptr_t i = 0; i < length; i++) { | |
2635 dart_types[i]->AcceptDartTypeVisitor(this); | |
2636 if (result_.IsMalformed()) { | |
2637 type_arguments = TypeArguments::null(); | |
2638 return type_arguments; | |
2639 } | |
2640 type_arguments.SetTypeAt(i, result_); | |
2641 } | |
2642 if (finalize_) { | |
2643 type_arguments = type_arguments.Canonicalize(); | |
2644 } | |
2645 } | |
2646 return type_arguments; | |
2647 } | |
2648 | |
2649 | |
2650 const TypeArguments& DartTypeTranslator::TranslateInstantiatedTypeArguments( | |
2651 const dart::Class& receiver_class, | |
2652 DartType** receiver_type_arguments, | |
2653 intptr_t length) { | |
2654 const TypeArguments& type_arguments = | |
2655 TranslateTypeArguments(receiver_type_arguments, length); | |
2656 if (type_arguments.IsNull()) return type_arguments; | |
2657 | |
2658 // We make a temporary [Type] object and use `ClassFinalizer::FinalizeType` to | |
2659 // finalize the argument types. | |
2660 // (This can for example make the [type_arguments] vector larger) | |
2661 Type& type = Type::Handle( | |
2662 Z, Type::New(receiver_class, type_arguments, TokenPosition::kNoSource)); | |
2663 if (finalize_) { | |
2664 type ^= ClassFinalizer::FinalizeType(*active_class_->klass, type); | |
2665 } | |
2666 | |
2667 const TypeArguments& instantiated_type_arguments = | |
2668 TypeArguments::ZoneHandle(Z, type.arguments()); | |
2669 return instantiated_type_arguments; | |
2670 } | |
2671 | |
2672 | |
2673 const Type& DartTypeTranslator::ReceiverType(const dart::Class& klass) { | |
2674 ASSERT(!klass.IsNull()); | |
2675 ASSERT(!klass.IsTypedefClass()); | |
2676 // Note that if klass is _Closure, the returned type will be _Closure, | |
2677 // and not the signature type. | |
2678 Type& type = Type::ZoneHandle(Z, klass.CanonicalType()); | |
2679 if (!type.IsNull()) { | |
2680 return type; | |
2681 } | |
2682 type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()), | |
2683 klass.token_pos()); | |
2684 if (klass.is_type_finalized()) { | |
2685 type ^= ClassFinalizer::FinalizeType(klass, type); | |
2686 klass.SetCanonicalType(type); | |
2687 } | |
2688 return type; | |
2689 } | |
2690 | |
2691 RawObject* EvaluateMetadata(const dart::Field& metadata_field) { | 2383 RawObject* EvaluateMetadata(const dart::Field& metadata_field) { |
2692 LongJumpScope jump; | 2384 LongJumpScope jump; |
2693 if (setjmp(*jump.Set()) == 0) { | 2385 if (setjmp(*jump.Set()) == 0) { |
2694 Thread* thread = Thread::Current(); | 2386 Thread* thread = Thread::Current(); |
2695 Zone* zone_ = thread->zone(); | 2387 Zone* zone_ = thread->zone(); |
2696 TranslationHelper helper(thread); | 2388 TranslationHelper helper(thread); |
2697 Script& script = Script::Handle(Z, metadata_field.Script()); | 2389 Script& script = Script::Handle(Z, metadata_field.Script()); |
2698 helper.SetStringOffsets( | 2390 helper.SetStringOffsets( |
2699 TypedData::Handle(Z, script.kernel_string_offsets())); | 2391 TypedData::Handle(Z, script.kernel_string_offsets())); |
2700 helper.SetStringData(TypedData::Handle(Z, script.kernel_string_data())); | 2392 helper.SetStringData(TypedData::Handle(Z, script.kernel_string_data())); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2739 thread->clear_sticky_error(); | 2431 thread->clear_sticky_error(); |
2740 return error.raw(); | 2432 return error.raw(); |
2741 } | 2433 } |
2742 } | 2434 } |
2743 | 2435 |
2744 | 2436 |
2745 } // namespace kernel | 2437 } // namespace kernel |
2746 } // namespace dart | 2438 } // namespace dart |
2747 | 2439 |
2748 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 2440 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |