OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |