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

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

Issue 2891053003: Add support for converted closures with explicit contexts to VM (Closed)
Patch Set: Created 3 years, 7 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/become.h" 10 #include "vm/become.h"
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 Bool* Object::bool_true_ = NULL; 129 Bool* Object::bool_true_ = NULL;
130 Bool* Object::bool_false_ = NULL; 130 Bool* Object::bool_false_ = NULL;
131 Smi* Object::smi_illegal_cid_ = NULL; 131 Smi* Object::smi_illegal_cid_ = NULL;
132 LanguageError* Object::snapshot_writer_error_ = NULL; 132 LanguageError* Object::snapshot_writer_error_ = NULL;
133 LanguageError* Object::branch_offset_error_ = NULL; 133 LanguageError* Object::branch_offset_error_ = NULL;
134 LanguageError* Object::speculative_inlining_error_ = NULL; 134 LanguageError* Object::speculative_inlining_error_ = NULL;
135 LanguageError* Object::background_compilation_error_ = NULL; 135 LanguageError* Object::background_compilation_error_ = NULL;
136 Array* Object::vm_isolate_snapshot_object_table_ = NULL; 136 Array* Object::vm_isolate_snapshot_object_table_ = NULL;
137 Type* Object::dynamic_type_ = NULL; 137 Type* Object::dynamic_type_ = NULL;
138 Type* Object::void_type_ = NULL; 138 Type* Object::void_type_ = NULL;
139 Type* Object::vector_type_ = NULL;
139 140
140 RawObject* Object::null_ = reinterpret_cast<RawObject*>(RAW_NULL); 141 RawObject* Object::null_ = reinterpret_cast<RawObject*>(RAW_NULL);
141 RawClass* Object::class_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 142 RawClass* Object::class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
142 RawClass* Object::dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 143 RawClass* Object::dynamic_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
144 RawClass* Object::vector_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
143 RawClass* Object::void_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 145 RawClass* Object::void_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
144 RawClass* Object::unresolved_class_class_ = 146 RawClass* Object::unresolved_class_class_ =
145 reinterpret_cast<RawClass*>(RAW_NULL); 147 reinterpret_cast<RawClass*>(RAW_NULL);
146 RawClass* Object::type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 148 RawClass* Object::type_arguments_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
147 RawClass* Object::patch_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 149 RawClass* Object::patch_class_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
148 RawClass* Object::function_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 150 RawClass* Object::function_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
149 RawClass* Object::closure_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 151 RawClass* Object::closure_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
150 RawClass* Object::signature_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL); 152 RawClass* Object::signature_data_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
151 RawClass* Object::redirection_data_class_ = 153 RawClass* Object::redirection_data_class_ =
152 reinterpret_cast<RawClass*>(RAW_NULL); 154 reinterpret_cast<RawClass*>(RAW_NULL);
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 bool_true_ = Bool::ReadOnlyHandle(); 536 bool_true_ = Bool::ReadOnlyHandle();
535 bool_false_ = Bool::ReadOnlyHandle(); 537 bool_false_ = Bool::ReadOnlyHandle();
536 smi_illegal_cid_ = Smi::ReadOnlyHandle(); 538 smi_illegal_cid_ = Smi::ReadOnlyHandle();
537 snapshot_writer_error_ = LanguageError::ReadOnlyHandle(); 539 snapshot_writer_error_ = LanguageError::ReadOnlyHandle();
538 branch_offset_error_ = LanguageError::ReadOnlyHandle(); 540 branch_offset_error_ = LanguageError::ReadOnlyHandle();
539 speculative_inlining_error_ = LanguageError::ReadOnlyHandle(); 541 speculative_inlining_error_ = LanguageError::ReadOnlyHandle();
540 background_compilation_error_ = LanguageError::ReadOnlyHandle(); 542 background_compilation_error_ = LanguageError::ReadOnlyHandle();
541 vm_isolate_snapshot_object_table_ = Array::ReadOnlyHandle(); 543 vm_isolate_snapshot_object_table_ = Array::ReadOnlyHandle();
542 dynamic_type_ = Type::ReadOnlyHandle(); 544 dynamic_type_ = Type::ReadOnlyHandle();
543 void_type_ = Type::ReadOnlyHandle(); 545 void_type_ = Type::ReadOnlyHandle();
546 vector_type_ = Type::ReadOnlyHandle();
544 547
545 *null_object_ = Object::null(); 548 *null_object_ = Object::null();
546 *null_array_ = Array::null(); 549 *null_array_ = Array::null();
547 *null_string_ = String::null(); 550 *null_string_ = String::null();
548 *null_instance_ = Instance::null(); 551 *null_instance_ = Instance::null();
549 *null_type_arguments_ = TypeArguments::null(); 552 *null_type_arguments_ = TypeArguments::null();
550 553
551 // Initialize the empty and zero array handles to null_ in order to be able to 554 // Initialize the empty and zero array handles to null_ in order to be able to
552 // check if the empty and zero arrays were allocated (RAW_NULL is not 555 // check if the empty and zero arrays were allocated (RAW_NULL is not
553 // available). 556 // available).
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 dynamic_class_ = cls.raw(); 896 dynamic_class_ = cls.raw();
894 897
895 cls = Class::New<Instance>(kVoidCid); 898 cls = Class::New<Instance>(kVoidCid);
896 cls.set_num_type_arguments(0); 899 cls.set_num_type_arguments(0);
897 cls.set_num_own_type_arguments(0); 900 cls.set_num_own_type_arguments(0);
898 cls.set_is_finalized(); 901 cls.set_is_finalized();
899 cls.set_is_type_finalized(); 902 cls.set_is_type_finalized();
900 cls.set_is_cycle_free(); 903 cls.set_is_cycle_free();
901 void_class_ = cls.raw(); 904 void_class_ = cls.raw();
902 905
906 cls = Class::New<Instance>(kVectorCid);
907 cls.set_num_type_arguments(0);
908 cls.set_num_own_type_arguments(0);
909 cls.set_is_finalized();
910 cls.set_is_type_finalized();
911 cls.set_is_cycle_free();
912 vector_class_ = cls.raw();
913
903 cls = Class::New<Type>(); 914 cls = Class::New<Type>();
904 cls.set_is_finalized(); 915 cls.set_is_finalized();
905 cls.set_is_type_finalized(); 916 cls.set_is_type_finalized();
906 cls.set_is_cycle_free(); 917 cls.set_is_cycle_free();
907 918
908 cls = dynamic_class_; 919 cls = dynamic_class_;
909 *dynamic_type_ = Type::NewNonParameterizedType(cls); 920 *dynamic_type_ = Type::NewNonParameterizedType(cls);
910 921
911 cls = void_class_; 922 cls = void_class_;
912 *void_type_ = Type::NewNonParameterizedType(cls); 923 *void_type_ = Type::NewNonParameterizedType(cls);
913 924
925 cls = vector_class_;
926 *vector_type_ = Type::NewNonParameterizedType(cls);
927
914 // Allocate and initialize singleton true and false boolean objects. 928 // Allocate and initialize singleton true and false boolean objects.
915 cls = Class::New<Bool>(); 929 cls = Class::New<Bool>();
916 isolate->object_store()->set_bool_class(cls); 930 isolate->object_store()->set_bool_class(cls);
917 *bool_true_ = Bool::New(true); 931 *bool_true_ = Bool::New(true);
918 *bool_false_ = Bool::New(false); 932 *bool_false_ = Bool::New(false);
919 933
920 *smi_illegal_cid_ = Smi::New(kIllegalCid); 934 *smi_illegal_cid_ = Smi::New(kIllegalCid);
921 935
922 String& error_str = String::Handle(); 936 String& error_str = String::Handle();
923 error_str = String::New("SnapshotWriter Error", Heap::kOld); 937 error_str = String::New("SnapshotWriter Error", Heap::kOld);
(...skipping 4552 matching lines...) Expand 10 before | Expand all | Expand 10 after
5476 UNREACHABLE(); 5490 UNREACHABLE();
5477 #else 5491 #else
5478 ASSERT(Thread::Current()->IsMutatorThread()); 5492 ASSERT(Thread::Current()->IsMutatorThread());
5479 ASSERT(value.IsNull() || !value.is_optimized()); 5493 ASSERT(value.IsNull() || !value.is_optimized());
5480 StorePointer(&raw_ptr()->unoptimized_code_, value.raw()); 5494 StorePointer(&raw_ptr()->unoptimized_code_, value.raw());
5481 #endif 5495 #endif
5482 } 5496 }
5483 5497
5484 5498
5485 RawContextScope* Function::context_scope() const { 5499 RawContextScope* Function::context_scope() const {
5486 if (IsClosureFunction()) { 5500 if (IsClosureFunction() || IsConvertedClosureFunction()) {
5487 const Object& obj = Object::Handle(raw_ptr()->data_); 5501 const Object& obj = Object::Handle(raw_ptr()->data_);
5488 ASSERT(!obj.IsNull()); 5502 ASSERT(!obj.IsNull());
5489 return ClosureData::Cast(obj).context_scope(); 5503 return ClosureData::Cast(obj).context_scope();
5490 } 5504 }
5491 return ContextScope::null(); 5505 return ContextScope::null();
5492 } 5506 }
5493 5507
5494 5508
5495 void Function::set_context_scope(const ContextScope& value) const { 5509 void Function::set_context_scope(const ContextScope& value) const {
5496 if (IsClosureFunction()) { 5510 if (IsClosureFunction() || IsConvertedClosureFunction()) {
5497 const Object& obj = Object::Handle(raw_ptr()->data_); 5511 const Object& obj = Object::Handle(raw_ptr()->data_);
5498 ASSERT(!obj.IsNull()); 5512 ASSERT(!obj.IsNull());
5499 ClosureData::Cast(obj).set_context_scope(value); 5513 ClosureData::Cast(obj).set_context_scope(value);
5500 return; 5514 return;
5501 } 5515 }
5502 UNREACHABLE(); 5516 UNREACHABLE();
5503 } 5517 }
5504 5518
5505 5519
5506 RawInstance* Function::implicit_static_closure() const { 5520 RawInstance* Function::implicit_static_closure() const {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
5586 ASSERT(!field.IsNull()); 5600 ASSERT(!field.IsNull());
5587 if (field.token_pos() == token_pos()) { 5601 if (field.token_pos() == token_pos()) {
5588 return field.raw(); 5602 return field.raw();
5589 } 5603 }
5590 } 5604 }
5591 return Field::null(); 5605 return Field::null();
5592 } 5606 }
5593 5607
5594 5608
5595 RawFunction* Function::parent_function() const { 5609 RawFunction* Function::parent_function() const {
5596 if (IsClosureFunction() || IsSignatureFunction()) { 5610 if (IsClosureFunction() || IsConvertedClosureFunction() ||
5611 IsSignatureFunction()) {
5597 const Object& obj = Object::Handle(raw_ptr()->data_); 5612 const Object& obj = Object::Handle(raw_ptr()->data_);
5598 ASSERT(!obj.IsNull()); 5613 ASSERT(!obj.IsNull());
5599 if (IsClosureFunction()) { 5614 if (IsClosureFunction() || IsConvertedClosureFunction()) {
5600 return ClosureData::Cast(obj).parent_function(); 5615 return ClosureData::Cast(obj).parent_function();
5601 } else { 5616 } else {
5602 return SignatureData::Cast(obj).parent_function(); 5617 return SignatureData::Cast(obj).parent_function();
5603 } 5618 }
5604 } 5619 }
5605 return Function::null(); 5620 return Function::null();
5606 } 5621 }
5607 5622
5608 5623
5609 void Function::set_parent_function(const Function& value) const { 5624 void Function::set_parent_function(const Function& value) const {
5610 const Object& obj = Object::Handle(raw_ptr()->data_); 5625 const Object& obj = Object::Handle(raw_ptr()->data_);
5611 ASSERT(!obj.IsNull()); 5626 ASSERT(!obj.IsNull());
5612 if (IsClosureFunction()) { 5627 if (IsClosureFunction() || IsConvertedClosureFunction()) {
5613 ClosureData::Cast(obj).set_parent_function(value); 5628 ClosureData::Cast(obj).set_parent_function(value);
5614 } else { 5629 } else {
5615 ASSERT(IsSignatureFunction()); 5630 ASSERT(IsSignatureFunction());
5616 SignatureData::Cast(obj).set_parent_function(value); 5631 SignatureData::Cast(obj).set_parent_function(value);
5617 } 5632 }
5618 } 5633 }
5619 5634
5620 5635
5621 bool Function::HasGenericParent() const { 5636 bool Function::HasGenericParent() const {
5622 if (IsImplicitClosureFunction()) { 5637 if (IsImplicitClosureFunction()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
5660 const Object& obj = Object::Handle(raw_ptr()->data_); 5675 const Object& obj = Object::Handle(raw_ptr()->data_);
5661 ASSERT(obj.IsArray()); 5676 ASSERT(obj.IsArray());
5662 ASSERT((Array::Cast(obj).At(1) == Object::null()) || value.IsNull()); 5677 ASSERT((Array::Cast(obj).At(1) == Object::null()) || value.IsNull());
5663 Array::Cast(obj).SetAt(1, value); 5678 Array::Cast(obj).SetAt(1, value);
5664 } else { 5679 } else {
5665 ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull()); 5680 ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull());
5666 set_data(value); 5681 set_data(value);
5667 } 5682 }
5668 } 5683 }
5669 5684
5685 RawFunction* Function::converted_closure_function() const {
5686 if (IsClosureFunction() || IsSignatureFunction() || IsFactory()) {
5687 return Function::null();
5688 }
5689 const Object& obj = Object::Handle(raw_ptr()->data_);
5690 ASSERT(obj.IsNull() || obj.IsFunction());
5691 if (obj.IsFunction()) {
5692 return Function::Cast(obj).raw();
5693 }
5694 return Function::null();
5695 }
5696
5697
5698 void Function::set_converted_closure_function(const Function& value) const {
5699 ASSERT(!IsClosureFunction() && !IsSignatureFunction() && !is_native());
5700 ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull());
5701 set_data(value);
5702 }
5703
5670 5704
5671 RawType* Function::ExistingSignatureType() const { 5705 RawType* Function::ExistingSignatureType() const {
5672 const Object& obj = Object::Handle(raw_ptr()->data_); 5706 const Object& obj = Object::Handle(raw_ptr()->data_);
5673 ASSERT(!obj.IsNull()); 5707 ASSERT(!obj.IsNull());
5674 if (IsSignatureFunction()) { 5708 if (IsSignatureFunction()) {
5675 return SignatureData::Cast(obj).signature_type(); 5709 return SignatureData::Cast(obj).signature_type();
5676 } else { 5710 } else {
5677 ASSERT(IsClosureFunction()); 5711 ASSERT(IsClosureFunction() || IsConvertedClosureFunction());
5678 return ClosureData::Cast(obj).signature_type(); 5712 return ClosureData::Cast(obj).signature_type();
5679 } 5713 }
5680 } 5714 }
5681 5715
5682 5716
5683 RawType* Function::SignatureType() const { 5717 RawType* Function::SignatureType() const {
5684 Type& type = Type::Handle(ExistingSignatureType()); 5718 Type& type = Type::Handle(ExistingSignatureType());
5685 if (type.IsNull()) { 5719 if (type.IsNull()) {
5686 // The function type of this function is not yet cached and needs to be 5720 // The function type of this function is not yet cached and needs to be
5687 // constructed and cached here. 5721 // constructed and cached here.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
5722 } 5756 }
5723 5757
5724 5758
5725 void Function::SetSignatureType(const Type& value) const { 5759 void Function::SetSignatureType(const Type& value) const {
5726 const Object& obj = Object::Handle(raw_ptr()->data_); 5760 const Object& obj = Object::Handle(raw_ptr()->data_);
5727 ASSERT(!obj.IsNull()); 5761 ASSERT(!obj.IsNull());
5728 if (IsSignatureFunction()) { 5762 if (IsSignatureFunction()) {
5729 SignatureData::Cast(obj).set_signature_type(value); 5763 SignatureData::Cast(obj).set_signature_type(value);
5730 ASSERT(!value.IsCanonical() || (value.signature() == this->raw())); 5764 ASSERT(!value.IsCanonical() || (value.signature() == this->raw()));
5731 } else { 5765 } else {
5732 ASSERT(IsClosureFunction()); 5766 ASSERT(IsClosureFunction() || IsConvertedClosureFunction());
5733 ClosureData::Cast(obj).set_signature_type(value); 5767 ClosureData::Cast(obj).set_signature_type(value);
5734 } 5768 }
5735 } 5769 }
5736 5770
5737 5771
5738 bool Function::IsRedirectingFactory() const { 5772 bool Function::IsRedirectingFactory() const {
5739 if (!IsFactory() || !is_redirecting()) { 5773 if (!IsFactory() || !is_redirecting()) {
5740 return false; 5774 return false;
5741 } 5775 }
5742 ASSERT(!IsClosureFunction()); // A factory cannot also be a closure. 5776 ASSERT(!IsClosureFunction()); // A factory cannot also be a closure.
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after
6795 NOT_IN_PRECOMPILED(result.set_deoptimization_counter(0)); 6829 NOT_IN_PRECOMPILED(result.set_deoptimization_counter(0));
6796 NOT_IN_PRECOMPILED(result.set_optimized_instruction_count(0)); 6830 NOT_IN_PRECOMPILED(result.set_optimized_instruction_count(0));
6797 NOT_IN_PRECOMPILED(result.set_optimized_call_site_count(0)); 6831 NOT_IN_PRECOMPILED(result.set_optimized_call_site_count(0));
6798 result.set_kernel_function(NULL); 6832 result.set_kernel_function(NULL);
6799 result.set_is_optimizable(is_native ? false : true); 6833 result.set_is_optimizable(is_native ? false : true);
6800 result.set_is_inlinable(true); 6834 result.set_is_inlinable(true);
6801 result.set_allows_hoisting_check_class(true); 6835 result.set_allows_hoisting_check_class(true);
6802 result.set_allows_bounds_check_generalization(true); 6836 result.set_allows_bounds_check_generalization(true);
6803 result.SetInstructionsSafe( 6837 result.SetInstructionsSafe(
6804 Code::Handle(StubCode::LazyCompile_entry()->code())); 6838 Code::Handle(StubCode::LazyCompile_entry()->code()));
6805 if (kind == RawFunction::kClosureFunction) { 6839 if (kind == RawFunction::kClosureFunction ||
6840 kind == RawFunction::kConvertedClosureFunction) {
6806 ASSERT(space == Heap::kOld); 6841 ASSERT(space == Heap::kOld);
6807 const ClosureData& data = ClosureData::Handle(ClosureData::New()); 6842 const ClosureData& data = ClosureData::Handle(ClosureData::New());
6808 result.set_data(data); 6843 result.set_data(data);
6809 } else if (kind == RawFunction::kSignatureFunction) { 6844 } else if (kind == RawFunction::kSignatureFunction) {
6810 const SignatureData& data = 6845 const SignatureData& data =
6811 SignatureData::Handle(SignatureData::New(space)); 6846 SignatureData::Handle(SignatureData::New(space));
6812 result.set_data(data); 6847 result.set_data(data);
6813 } else { 6848 } else {
6814 // Functions other than signature functions have no reason to be allocated 6849 // Functions other than signature functions have no reason to be allocated
6815 // in new space. 6850 // in new space.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
6881 /* is_static = */ parent.is_static(), 6916 /* is_static = */ parent.is_static(),
6882 /* is_const = */ false, 6917 /* is_const = */ false,
6883 /* is_abstract = */ false, 6918 /* is_abstract = */ false,
6884 /* is_external = */ false, 6919 /* is_external = */ false,
6885 /* is_native = */ false, parent_owner, token_pos)); 6920 /* is_native = */ false, parent_owner, token_pos));
6886 result.set_parent_function(parent); 6921 result.set_parent_function(parent);
6887 return result.raw(); 6922 return result.raw();
6888 } 6923 }
6889 6924
6890 6925
6926 RawFunction* Function::NewConvertedClosureFunction(const String& name,
6927 const Function& parent,
6928 TokenPosition token_pos) {
6929 ASSERT(!parent.IsNull());
6930 // Only static top-level functions are allowed to be converted right now.
6931 ASSERT(parent.is_static());
6932 // Use the owner defining the parent function and not the class containing it.
6933 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_);
6934 ASSERT(!parent_owner.IsNull());
6935 const Function& result = Function::Handle(
6936 Function::New(name, RawFunction::kConvertedClosureFunction,
6937 /* is_static = */ true,
6938 /* is_const = */ false,
6939 /* is_abstract = */ false,
6940 /* is_external = */ false,
6941 /* is_native = */ false, parent_owner, token_pos));
6942 result.set_parent_function(parent);
6943 return result.raw();
6944 }
6945
6946
6891 RawFunction* Function::NewSignatureFunction(const Object& owner, 6947 RawFunction* Function::NewSignatureFunction(const Object& owner,
6892 TokenPosition token_pos, 6948 TokenPosition token_pos,
6893 Heap::Space space) { 6949 Heap::Space space) {
6894 const Function& result = Function::Handle(Function::New( 6950 const Function& result = Function::Handle(Function::New(
6895 Symbols::AnonymousSignature(), RawFunction::kSignatureFunction, 6951 Symbols::AnonymousSignature(), RawFunction::kSignatureFunction,
6896 /* is_static = */ false, 6952 /* is_static = */ false,
6897 /* is_const = */ false, 6953 /* is_const = */ false,
6898 /* is_abstract = */ false, 6954 /* is_abstract = */ false,
6899 /* is_external = */ false, 6955 /* is_external = */ false,
6900 /* is_native = */ false, 6956 /* is_native = */ false,
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
7007 void Function::DropUncompiledImplicitClosureFunction() const { 7063 void Function::DropUncompiledImplicitClosureFunction() const {
7008 if (implicit_closure_function() != Function::null()) { 7064 if (implicit_closure_function() != Function::null()) {
7009 const Function& func = Function::Handle(implicit_closure_function()); 7065 const Function& func = Function::Handle(implicit_closure_function());
7010 if (!func.HasCode()) { 7066 if (!func.HasCode()) {
7011 set_implicit_closure_function(Function::Handle()); 7067 set_implicit_closure_function(Function::Handle());
7012 } 7068 }
7013 } 7069 }
7014 } 7070 }
7015 7071
7016 7072
7073 // Converted closure functions represent a pair of a top-level function and a
7074 // vector of captured variables. When being invoked, converted clousre
7075 // functions get the vector as the first argument, and the arguments supplied at
7076 // the invocation are passed as the remaining arguments to that function.
7077 //
7078 // Internally, converted closure functins are represented with the same Closure
7079 // class as implicit closure functions (that are used for dealing with
7080 // tear-offs). The Closure class instances have two fields, one for the
7081 // function, and one for the captured context. Implicit closure functions have
7082 // pre-defined shape of the context: it's a single variable that is used as
7083 // 'this'. Converted closure functions use the context field to store the
7084 // vector of captured variables that will be supplied as the first argument
7085 // during invocation.
7086 //
7087 // The top-level functions used in converted closure functions are generated
7088 // during a front-end transformation in Kernel. Those functions have some
7089 // common properties:
7090 // * they expect the captured context to be passed as the first argument,
7091 // * the first argument should be of Vector type (index-based storage),
7092 // * they retrieve the captured variables from Vectors explicitly, so they
7093 // don't need the variables from the context to be put into their current
7094 // scope.
7095 //
7096 // During closure-conversion pass in Kernel, the contexts are generated
7097 // explicitly and are represented as Vectors. Then they are paired together
7098 // with the top-level functions to form a closure. When the closure, created
7099 // this way, is invoked, it should receive the Vector as the first argument, and
7100 // take the rest of the arguments from the invocation.
7101 //
7102 // Converted cosure functions in VM follow same discipline as implicit closure
7103 // functions, because they are similar in many ways. For further deatils, please
7104 // refer to the following methods:
7105 // -> Function::ConvertedClosureFunction
7106 // -> FlowGraphBuilder::BuildGraphOfConvertedClosureFunction
7107 // -> FlowGraphBuilder::BuildGraph (small change that calls
7108 // BuildGraphOfConvertedClosureFunction)
7109 // -> FlowGraphBuilder::VisitClosureCreation (converted closure functions are
7110 // created here)
7111 //
7112 // Function::ConvertedClosureFunction method follows the logic similar to that
7113 // of Function::ImplicitClosureFunction method.
7114 RawFunction* Function::ConvertedClosureFunction() const {
7115 // Return the existing converted closure function if any.
7116 if (converted_closure_function() != Function::null()) {
7117 return converted_closure_function();
7118 }
7119 ASSERT(!IsSignatureFunction() && !IsClosureFunction());
7120 Thread* thread = Thread::Current();
7121 Zone* zone = thread->zone();
7122 // Create closure function.
7123 const String& closure_name = String::Handle(zone, name());
7124 const Function& closure_function = Function::Handle(
7125 zone, NewConvertedClosureFunction(closure_name, *this, token_pos()));
7126
7127 // Currently only static top-level functions are allowed to be converted.
7128 ASSERT(is_static());
7129 closure_function.set_context_scope(Object::empty_context_scope());
7130
7131 // Set closure function's type parameters.
7132 closure_function.set_type_parameters(
7133 TypeArguments::Handle(zone, type_parameters()));
7134
7135 // Set closure function's result type to this result type.
7136 closure_function.set_result_type(AbstractType::Handle(zone, result_type()));
7137
7138 // Set closure function's end token to this end token.
7139 closure_function.set_end_token_pos(end_token_pos());
7140
7141 // The closurized method stub just calls into the original method and should
7142 // therefore be skipped by the debugger and in stack traces.
7143 closure_function.set_is_debuggable(false);
7144 closure_function.set_is_visible(false);
7145
7146 // Set closure function's formal parameters to this formal parameters,
7147 // removing the first parameter over which the currying is done, and adding
7148 // the closure class instance as the first parameter. So, the overall number
7149 // of fixed parameters doesn't change.
7150 const int num_fixed_params = num_fixed_parameters();
7151 const int num_opt_params = NumOptionalParameters();
7152 const bool has_opt_pos_params = HasOptionalPositionalParameters();
7153 const int num_params = num_fixed_params + num_opt_params;
7154 closure_function.set_num_fixed_parameters(num_fixed_params);
7155 closure_function.SetNumOptionalParameters(num_opt_params, has_opt_pos_params);
7156 closure_function.set_parameter_types(
7157 Array::Handle(zone, Array::New(num_params, Heap::kOld)));
7158 closure_function.set_parameter_names(
7159 Array::Handle(zone, Array::New(num_params, Heap::kOld)));
7160 AbstractType& param_type = AbstractType::Handle(zone);
7161 String& param_name = String::Handle(zone);
7162 // Add implicit closure object as the first parameter.
7163 param_type = Type::DynamicType();
7164 closure_function.SetParameterTypeAt(0, param_type);
7165 closure_function.SetParameterNameAt(0, Symbols::ClosureParameter());
7166 // All the parameters, but the first one, are the same for the top-level
7167 // function being converted, and the method of the closure class that is being
7168 // generated.
7169 for (int i = 1; i < num_params; i++) {
7170 param_type = ParameterTypeAt(i);
7171 closure_function.SetParameterTypeAt(i, param_type);
7172 param_name = ParameterNameAt(i);
7173 closure_function.SetParameterNameAt(i, param_name);
7174 }
7175 closure_function.set_kernel_function(kernel_function());
7176
7177 const Type& signature_type =
7178 Type::Handle(zone, closure_function.SignatureType());
7179 if (!signature_type.IsFinalized()) {
7180 ClassFinalizer::FinalizeType(Class::Handle(zone, Owner()), signature_type);
7181 }
7182 set_converted_closure_function(closure_function);
7183 return closure_function.raw();
7184 }
7185
7186
7187 void Function::DropUncompiledConvertedClosureFunction() const {
7188 if (converted_closure_function() != Function::null()) {
7189 const Function& func = Function::Handle(converted_closure_function());
7190 if (!func.HasCode()) {
7191 set_converted_closure_function(Function::Handle());
7192 }
7193 }
7194 }
7195
7196
7017 RawString* Function::UserVisibleFormalParameters() const { 7197 RawString* Function::UserVisibleFormalParameters() const {
7018 Thread* thread = Thread::Current(); 7198 Thread* thread = Thread::Current();
7019 Zone* zone = thread->zone(); 7199 Zone* zone = thread->zone();
7020 // Typically 3, 5,.. elements in 'pieces', e.g.: 7200 // Typically 3, 5,.. elements in 'pieces', e.g.:
7021 // '_LoadRequest', CommaSpace, '_LoadError'. 7201 // '_LoadRequest', CommaSpace, '_LoadError'.
7022 GrowableHandlePtrArray<const String> pieces(zone, 5); 7202 GrowableHandlePtrArray<const String> pieces(zone, 5);
7023 BuildSignatureParameters(thread, zone, kUserVisibleName, &pieces); 7203 BuildSignatureParameters(thread, zone, kUserVisibleName, &pieces);
7024 return Symbols::FromConcatAll(thread, pieces); 7204 return Symbols::FromConcatAll(thread, pieces);
7025 } 7205 }
7026 7206
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
7501 if (IsNull()) { 7681 if (IsNull()) {
7502 return "Function: null"; 7682 return "Function: null";
7503 } 7683 }
7504 const char* static_str = is_static() ? " static" : ""; 7684 const char* static_str = is_static() ? " static" : "";
7505 const char* abstract_str = is_abstract() ? " abstract" : ""; 7685 const char* abstract_str = is_abstract() ? " abstract" : "";
7506 const char* kind_str = NULL; 7686 const char* kind_str = NULL;
7507 const char* const_str = is_const() ? " const" : ""; 7687 const char* const_str = is_const() ? " const" : "";
7508 switch (kind()) { 7688 switch (kind()) {
7509 case RawFunction::kRegularFunction: 7689 case RawFunction::kRegularFunction:
7510 case RawFunction::kClosureFunction: 7690 case RawFunction::kClosureFunction:
7691 case RawFunction::kConvertedClosureFunction:
7511 case RawFunction::kGetterFunction: 7692 case RawFunction::kGetterFunction:
7512 case RawFunction::kSetterFunction: 7693 case RawFunction::kSetterFunction:
7513 kind_str = ""; 7694 kind_str = "";
7514 break; 7695 break;
7515 case RawFunction::kSignatureFunction: 7696 case RawFunction::kSignatureFunction:
7516 kind_str = " signature"; 7697 kind_str = " signature";
7517 break; 7698 break;
7518 case RawFunction::kConstructor: 7699 case RawFunction::kConstructor:
7519 kind_str = is_static() ? " factory" : " constructor"; 7700 kind_str = is_static() ? " factory" : " constructor";
7520 break; 7701 break;
(...skipping 15813 matching lines...) Expand 10 before | Expand all | Expand 10 after
23334 return UserTag::null(); 23515 return UserTag::null();
23335 } 23516 }
23336 23517
23337 23518
23338 const char* UserTag::ToCString() const { 23519 const char* UserTag::ToCString() const {
23339 const String& tag_label = String::Handle(label()); 23520 const String& tag_label = String::Handle(label());
23340 return tag_label.ToCString(); 23521 return tag_label.ToCString();
23341 } 23522 }
23342 23523
23343 } // namespace dart 23524 } // namespace dart
OLDNEW
« runtime/vm/kernel_to_il.cc ('K') | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698