Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: runtime/vm/kernel_to_il.cc

Issue 2931813002: [kernel] Stream kernel_reader (Closed)
Patch Set: Feedback Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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)
OLDNEW
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698