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 4554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5478 UNREACHABLE(); | 5492 UNREACHABLE(); |
5479 #else | 5493 #else |
5480 ASSERT(Thread::Current()->IsMutatorThread()); | 5494 ASSERT(Thread::Current()->IsMutatorThread()); |
5481 ASSERT(value.IsNull() || !value.is_optimized()); | 5495 ASSERT(value.IsNull() || !value.is_optimized()); |
5482 StorePointer(&raw_ptr()->unoptimized_code_, value.raw()); | 5496 StorePointer(&raw_ptr()->unoptimized_code_, value.raw()); |
5483 #endif | 5497 #endif |
5484 } | 5498 } |
5485 | 5499 |
5486 | 5500 |
5487 RawContextScope* Function::context_scope() const { | 5501 RawContextScope* Function::context_scope() const { |
5488 if (IsClosureFunction()) { | 5502 if (IsClosureFunction() || IsConvertedClosureFunction()) { |
5489 const Object& obj = Object::Handle(raw_ptr()->data_); | 5503 const Object& obj = Object::Handle(raw_ptr()->data_); |
5490 ASSERT(!obj.IsNull()); | 5504 ASSERT(!obj.IsNull()); |
5491 return ClosureData::Cast(obj).context_scope(); | 5505 return ClosureData::Cast(obj).context_scope(); |
5492 } | 5506 } |
5493 return ContextScope::null(); | 5507 return ContextScope::null(); |
5494 } | 5508 } |
5495 | 5509 |
5496 | 5510 |
5497 void Function::set_context_scope(const ContextScope& value) const { | 5511 void Function::set_context_scope(const ContextScope& value) const { |
5498 if (IsClosureFunction()) { | 5512 if (IsClosureFunction() || IsConvertedClosureFunction()) { |
5499 const Object& obj = Object::Handle(raw_ptr()->data_); | 5513 const Object& obj = Object::Handle(raw_ptr()->data_); |
5500 ASSERT(!obj.IsNull()); | 5514 ASSERT(!obj.IsNull()); |
5501 ClosureData::Cast(obj).set_context_scope(value); | 5515 ClosureData::Cast(obj).set_context_scope(value); |
5502 return; | 5516 return; |
5503 } | 5517 } |
5504 UNREACHABLE(); | 5518 UNREACHABLE(); |
5505 } | 5519 } |
5506 | 5520 |
5507 | 5521 |
5508 RawInstance* Function::implicit_static_closure() const { | 5522 RawInstance* Function::implicit_static_closure() const { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5588 ASSERT(!field.IsNull()); | 5602 ASSERT(!field.IsNull()); |
5589 if (field.token_pos() == token_pos()) { | 5603 if (field.token_pos() == token_pos()) { |
5590 return field.raw(); | 5604 return field.raw(); |
5591 } | 5605 } |
5592 } | 5606 } |
5593 return Field::null(); | 5607 return Field::null(); |
5594 } | 5608 } |
5595 | 5609 |
5596 | 5610 |
5597 RawFunction* Function::parent_function() const { | 5611 RawFunction* Function::parent_function() const { |
5598 if (IsClosureFunction() || IsSignatureFunction()) { | 5612 if (IsClosureFunction() || IsConvertedClosureFunction() || |
| 5613 IsSignatureFunction()) { |
5599 const Object& obj = Object::Handle(raw_ptr()->data_); | 5614 const Object& obj = Object::Handle(raw_ptr()->data_); |
5600 ASSERT(!obj.IsNull()); | 5615 ASSERT(!obj.IsNull()); |
5601 if (IsClosureFunction()) { | 5616 if (IsClosureFunction() || IsConvertedClosureFunction()) { |
5602 return ClosureData::Cast(obj).parent_function(); | 5617 return ClosureData::Cast(obj).parent_function(); |
5603 } else { | 5618 } else { |
5604 return SignatureData::Cast(obj).parent_function(); | 5619 return SignatureData::Cast(obj).parent_function(); |
5605 } | 5620 } |
5606 } | 5621 } |
5607 return Function::null(); | 5622 return Function::null(); |
5608 } | 5623 } |
5609 | 5624 |
5610 | 5625 |
5611 void Function::set_parent_function(const Function& value) const { | 5626 void Function::set_parent_function(const Function& value) const { |
5612 const Object& obj = Object::Handle(raw_ptr()->data_); | 5627 const Object& obj = Object::Handle(raw_ptr()->data_); |
5613 ASSERT(!obj.IsNull()); | 5628 ASSERT(!obj.IsNull()); |
5614 if (IsClosureFunction()) { | 5629 if (IsClosureFunction() || IsConvertedClosureFunction()) { |
5615 ClosureData::Cast(obj).set_parent_function(value); | 5630 ClosureData::Cast(obj).set_parent_function(value); |
5616 } else { | 5631 } else { |
5617 ASSERT(IsSignatureFunction()); | 5632 ASSERT(IsSignatureFunction()); |
5618 SignatureData::Cast(obj).set_parent_function(value); | 5633 SignatureData::Cast(obj).set_parent_function(value); |
5619 } | 5634 } |
5620 } | 5635 } |
5621 | 5636 |
5622 | 5637 |
5623 bool Function::HasGenericParent() const { | 5638 bool Function::HasGenericParent() const { |
5624 if (IsImplicitClosureFunction()) { | 5639 if (IsImplicitClosureFunction()) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5662 const Object& obj = Object::Handle(raw_ptr()->data_); | 5677 const Object& obj = Object::Handle(raw_ptr()->data_); |
5663 ASSERT(obj.IsArray()); | 5678 ASSERT(obj.IsArray()); |
5664 ASSERT((Array::Cast(obj).At(1) == Object::null()) || value.IsNull()); | 5679 ASSERT((Array::Cast(obj).At(1) == Object::null()) || value.IsNull()); |
5665 Array::Cast(obj).SetAt(1, value); | 5680 Array::Cast(obj).SetAt(1, value); |
5666 } else { | 5681 } else { |
5667 ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull()); | 5682 ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull()); |
5668 set_data(value); | 5683 set_data(value); |
5669 } | 5684 } |
5670 } | 5685 } |
5671 | 5686 |
| 5687 RawFunction* Function::converted_closure_function() const { |
| 5688 if (IsClosureFunction() || IsSignatureFunction() || IsFactory()) { |
| 5689 return Function::null(); |
| 5690 } |
| 5691 const Object& obj = Object::Handle(raw_ptr()->data_); |
| 5692 ASSERT(obj.IsNull() || obj.IsFunction()); |
| 5693 if (obj.IsFunction()) { |
| 5694 return Function::Cast(obj).raw(); |
| 5695 } |
| 5696 return Function::null(); |
| 5697 } |
| 5698 |
| 5699 |
| 5700 void Function::set_converted_closure_function(const Function& value) const { |
| 5701 ASSERT(!IsClosureFunction() && !IsSignatureFunction() && !is_native()); |
| 5702 ASSERT((raw_ptr()->data_ == Object::null()) || value.IsNull()); |
| 5703 set_data(value); |
| 5704 } |
| 5705 |
5672 | 5706 |
5673 RawType* Function::ExistingSignatureType() const { | 5707 RawType* Function::ExistingSignatureType() const { |
5674 const Object& obj = Object::Handle(raw_ptr()->data_); | 5708 const Object& obj = Object::Handle(raw_ptr()->data_); |
5675 ASSERT(!obj.IsNull()); | 5709 ASSERT(!obj.IsNull()); |
5676 if (IsSignatureFunction()) { | 5710 if (IsSignatureFunction()) { |
5677 return SignatureData::Cast(obj).signature_type(); | 5711 return SignatureData::Cast(obj).signature_type(); |
5678 } else { | 5712 } else { |
5679 ASSERT(IsClosureFunction()); | 5713 ASSERT(IsClosureFunction() || IsConvertedClosureFunction()); |
5680 return ClosureData::Cast(obj).signature_type(); | 5714 return ClosureData::Cast(obj).signature_type(); |
5681 } | 5715 } |
5682 } | 5716 } |
5683 | 5717 |
5684 | 5718 |
5685 RawType* Function::SignatureType() const { | 5719 RawType* Function::SignatureType() const { |
5686 Type& type = Type::Handle(ExistingSignatureType()); | 5720 Type& type = Type::Handle(ExistingSignatureType()); |
5687 if (type.IsNull()) { | 5721 if (type.IsNull()) { |
5688 // The function type of this function is not yet cached and needs to be | 5722 // The function type of this function is not yet cached and needs to be |
5689 // constructed and cached here. | 5723 // constructed and cached here. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5724 } | 5758 } |
5725 | 5759 |
5726 | 5760 |
5727 void Function::SetSignatureType(const Type& value) const { | 5761 void Function::SetSignatureType(const Type& value) const { |
5728 const Object& obj = Object::Handle(raw_ptr()->data_); | 5762 const Object& obj = Object::Handle(raw_ptr()->data_); |
5729 ASSERT(!obj.IsNull()); | 5763 ASSERT(!obj.IsNull()); |
5730 if (IsSignatureFunction()) { | 5764 if (IsSignatureFunction()) { |
5731 SignatureData::Cast(obj).set_signature_type(value); | 5765 SignatureData::Cast(obj).set_signature_type(value); |
5732 ASSERT(!value.IsCanonical() || (value.signature() == this->raw())); | 5766 ASSERT(!value.IsCanonical() || (value.signature() == this->raw())); |
5733 } else { | 5767 } else { |
5734 ASSERT(IsClosureFunction()); | 5768 ASSERT(IsClosureFunction() || IsConvertedClosureFunction()); |
5735 ClosureData::Cast(obj).set_signature_type(value); | 5769 ClosureData::Cast(obj).set_signature_type(value); |
5736 } | 5770 } |
5737 } | 5771 } |
5738 | 5772 |
5739 | 5773 |
5740 bool Function::IsRedirectingFactory() const { | 5774 bool Function::IsRedirectingFactory() const { |
5741 if (!IsFactory() || !is_redirecting()) { | 5775 if (!IsFactory() || !is_redirecting()) { |
5742 return false; | 5776 return false; |
5743 } | 5777 } |
5744 ASSERT(!IsClosureFunction()); // A factory cannot also be a closure. | 5778 ASSERT(!IsClosureFunction()); // A factory cannot also be a closure. |
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6814 NOT_IN_PRECOMPILED(result.set_deoptimization_counter(0)); | 6848 NOT_IN_PRECOMPILED(result.set_deoptimization_counter(0)); |
6815 NOT_IN_PRECOMPILED(result.set_optimized_instruction_count(0)); | 6849 NOT_IN_PRECOMPILED(result.set_optimized_instruction_count(0)); |
6816 NOT_IN_PRECOMPILED(result.set_optimized_call_site_count(0)); | 6850 NOT_IN_PRECOMPILED(result.set_optimized_call_site_count(0)); |
6817 result.set_kernel_offset(0); | 6851 result.set_kernel_offset(0); |
6818 result.set_is_optimizable(is_native ? false : true); | 6852 result.set_is_optimizable(is_native ? false : true); |
6819 result.set_is_inlinable(true); | 6853 result.set_is_inlinable(true); |
6820 result.set_allows_hoisting_check_class(true); | 6854 result.set_allows_hoisting_check_class(true); |
6821 result.set_allows_bounds_check_generalization(true); | 6855 result.set_allows_bounds_check_generalization(true); |
6822 result.SetInstructionsSafe( | 6856 result.SetInstructionsSafe( |
6823 Code::Handle(StubCode::LazyCompile_entry()->code())); | 6857 Code::Handle(StubCode::LazyCompile_entry()->code())); |
6824 if (kind == RawFunction::kClosureFunction) { | 6858 if (kind == RawFunction::kClosureFunction || |
| 6859 kind == RawFunction::kConvertedClosureFunction) { |
6825 ASSERT(space == Heap::kOld); | 6860 ASSERT(space == Heap::kOld); |
6826 const ClosureData& data = ClosureData::Handle(ClosureData::New()); | 6861 const ClosureData& data = ClosureData::Handle(ClosureData::New()); |
6827 result.set_data(data); | 6862 result.set_data(data); |
6828 } else if (kind == RawFunction::kSignatureFunction) { | 6863 } else if (kind == RawFunction::kSignatureFunction) { |
6829 const SignatureData& data = | 6864 const SignatureData& data = |
6830 SignatureData::Handle(SignatureData::New(space)); | 6865 SignatureData::Handle(SignatureData::New(space)); |
6831 result.set_data(data); | 6866 result.set_data(data); |
6832 } else { | 6867 } else { |
6833 // Functions other than signature functions have no reason to be allocated | 6868 // Functions other than signature functions have no reason to be allocated |
6834 // in new space. | 6869 // in new space. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6900 /* is_static = */ parent.is_static(), | 6935 /* is_static = */ parent.is_static(), |
6901 /* is_const = */ false, | 6936 /* is_const = */ false, |
6902 /* is_abstract = */ false, | 6937 /* is_abstract = */ false, |
6903 /* is_external = */ false, | 6938 /* is_external = */ false, |
6904 /* is_native = */ false, parent_owner, token_pos)); | 6939 /* is_native = */ false, parent_owner, token_pos)); |
6905 result.set_parent_function(parent); | 6940 result.set_parent_function(parent); |
6906 return result.raw(); | 6941 return result.raw(); |
6907 } | 6942 } |
6908 | 6943 |
6909 | 6944 |
| 6945 RawFunction* Function::NewConvertedClosureFunction(const String& name, |
| 6946 const Function& parent, |
| 6947 TokenPosition token_pos) { |
| 6948 ASSERT(!parent.IsNull()); |
| 6949 // Only static top-level functions are allowed to be converted right now. |
| 6950 ASSERT(parent.is_static()); |
| 6951 // Use the owner defining the parent function and not the class containing it. |
| 6952 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_); |
| 6953 ASSERT(!parent_owner.IsNull()); |
| 6954 const Function& result = Function::Handle( |
| 6955 Function::New(name, RawFunction::kConvertedClosureFunction, |
| 6956 /* is_static = */ true, |
| 6957 /* is_const = */ false, |
| 6958 /* is_abstract = */ false, |
| 6959 /* is_external = */ false, |
| 6960 /* is_native = */ false, parent_owner, token_pos)); |
| 6961 result.set_parent_function(parent); |
| 6962 return result.raw(); |
| 6963 } |
| 6964 |
| 6965 |
6910 RawFunction* Function::NewSignatureFunction(const Object& owner, | 6966 RawFunction* Function::NewSignatureFunction(const Object& owner, |
6911 TokenPosition token_pos, | 6967 TokenPosition token_pos, |
6912 Heap::Space space) { | 6968 Heap::Space space) { |
6913 const Function& result = Function::Handle(Function::New( | 6969 const Function& result = Function::Handle(Function::New( |
6914 Symbols::AnonymousSignature(), RawFunction::kSignatureFunction, | 6970 Symbols::AnonymousSignature(), RawFunction::kSignatureFunction, |
6915 /* is_static = */ false, | 6971 /* is_static = */ false, |
6916 /* is_const = */ false, | 6972 /* is_const = */ false, |
6917 /* is_abstract = */ false, | 6973 /* is_abstract = */ false, |
6918 /* is_external = */ false, | 6974 /* is_external = */ false, |
6919 /* is_native = */ false, | 6975 /* is_native = */ false, |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7026 void Function::DropUncompiledImplicitClosureFunction() const { | 7082 void Function::DropUncompiledImplicitClosureFunction() const { |
7027 if (implicit_closure_function() != Function::null()) { | 7083 if (implicit_closure_function() != Function::null()) { |
7028 const Function& func = Function::Handle(implicit_closure_function()); | 7084 const Function& func = Function::Handle(implicit_closure_function()); |
7029 if (!func.HasCode()) { | 7085 if (!func.HasCode()) { |
7030 set_implicit_closure_function(Function::Handle()); | 7086 set_implicit_closure_function(Function::Handle()); |
7031 } | 7087 } |
7032 } | 7088 } |
7033 } | 7089 } |
7034 | 7090 |
7035 | 7091 |
| 7092 // Converted closure functions represent a pair of a top-level function and a |
| 7093 // vector of captured variables. When being invoked, converted clousre |
| 7094 // functions get the vector as the first argument, and the arguments supplied at |
| 7095 // the invocation are passed as the remaining arguments to that function. |
| 7096 // |
| 7097 // Internally, converted closure functins are represented with the same Closure |
| 7098 // class as implicit closure functions (that are used for dealing with |
| 7099 // tear-offs). The Closure class instances have two fields, one for the |
| 7100 // function, and one for the captured context. Implicit closure functions have |
| 7101 // pre-defined shape of the context: it's a single variable that is used as |
| 7102 // 'this'. Converted closure functions use the context field to store the |
| 7103 // vector of captured variables that will be supplied as the first argument |
| 7104 // during invocation. |
| 7105 // |
| 7106 // The top-level functions used in converted closure functions are generated |
| 7107 // during a front-end transformation in Kernel. Those functions have some |
| 7108 // common properties: |
| 7109 // * they expect the captured context to be passed as the first argument, |
| 7110 // * the first argument should be of Vector type (index-based storage), |
| 7111 // * they retrieve the captured variables from Vectors explicitly, so they |
| 7112 // don't need the variables from the context to be put into their current |
| 7113 // scope. |
| 7114 // |
| 7115 // During closure-conversion pass in Kernel, the contexts are generated |
| 7116 // explicitly and are represented as Vectors. Then they are paired together |
| 7117 // with the top-level functions to form a closure. When the closure, created |
| 7118 // this way, is invoked, it should receive the Vector as the first argument, and |
| 7119 // take the rest of the arguments from the invocation. |
| 7120 // |
| 7121 // Converted cosure functions in VM follow same discipline as implicit closure |
| 7122 // functions, because they are similar in many ways. For further deatils, please |
| 7123 // refer to the following methods: |
| 7124 // -> Function::ConvertedClosureFunction |
| 7125 // -> FlowGraphBuilder::BuildGraphOfConvertedClosureFunction |
| 7126 // -> FlowGraphBuilder::BuildGraph (small change that calls |
| 7127 // BuildGraphOfConvertedClosureFunction) |
| 7128 // -> FlowGraphBuilder::VisitClosureCreation (converted closure functions are |
| 7129 // created here) |
| 7130 // |
| 7131 // Function::ConvertedClosureFunction method follows the logic similar to that |
| 7132 // of Function::ImplicitClosureFunction method. |
| 7133 RawFunction* Function::ConvertedClosureFunction() const { |
| 7134 // Return the existing converted closure function if any. |
| 7135 if (converted_closure_function() != Function::null()) { |
| 7136 return converted_closure_function(); |
| 7137 } |
| 7138 ASSERT(!IsSignatureFunction() && !IsClosureFunction()); |
| 7139 Thread* thread = Thread::Current(); |
| 7140 Zone* zone = thread->zone(); |
| 7141 // Create closure function. |
| 7142 const String& closure_name = String::Handle(zone, name()); |
| 7143 const Function& closure_function = Function::Handle( |
| 7144 zone, NewConvertedClosureFunction(closure_name, *this, token_pos())); |
| 7145 |
| 7146 // Currently only static top-level functions are allowed to be converted. |
| 7147 ASSERT(is_static()); |
| 7148 closure_function.set_context_scope(Object::empty_context_scope()); |
| 7149 |
| 7150 // Set closure function's type parameters. |
| 7151 closure_function.set_type_parameters( |
| 7152 TypeArguments::Handle(zone, type_parameters())); |
| 7153 |
| 7154 // Set closure function's result type to this result type. |
| 7155 closure_function.set_result_type(AbstractType::Handle(zone, result_type())); |
| 7156 |
| 7157 // Set closure function's end token to this end token. |
| 7158 closure_function.set_end_token_pos(end_token_pos()); |
| 7159 |
| 7160 // The closurized method stub just calls into the original method and should |
| 7161 // therefore be skipped by the debugger and in stack traces. |
| 7162 closure_function.set_is_debuggable(false); |
| 7163 closure_function.set_is_visible(false); |
| 7164 |
| 7165 // Set closure function's formal parameters to this formal parameters, |
| 7166 // removing the first parameter over which the currying is done, and adding |
| 7167 // the closure class instance as the first parameter. So, the overall number |
| 7168 // of fixed parameters doesn't change. |
| 7169 const int num_fixed_params = num_fixed_parameters(); |
| 7170 const int num_opt_params = NumOptionalParameters(); |
| 7171 const bool has_opt_pos_params = HasOptionalPositionalParameters(); |
| 7172 const int num_params = num_fixed_params + num_opt_params; |
| 7173 closure_function.set_num_fixed_parameters(num_fixed_params); |
| 7174 closure_function.SetNumOptionalParameters(num_opt_params, has_opt_pos_params); |
| 7175 closure_function.set_parameter_types( |
| 7176 Array::Handle(zone, Array::New(num_params, Heap::kOld))); |
| 7177 closure_function.set_parameter_names( |
| 7178 Array::Handle(zone, Array::New(num_params, Heap::kOld))); |
| 7179 AbstractType& param_type = AbstractType::Handle(zone); |
| 7180 String& param_name = String::Handle(zone); |
| 7181 // Add implicit closure object as the first parameter. |
| 7182 param_type = Type::DynamicType(); |
| 7183 closure_function.SetParameterTypeAt(0, param_type); |
| 7184 closure_function.SetParameterNameAt(0, Symbols::ClosureParameter()); |
| 7185 // All the parameters, but the first one, are the same for the top-level |
| 7186 // function being converted, and the method of the closure class that is being |
| 7187 // generated. |
| 7188 for (int i = 1; i < num_params; i++) { |
| 7189 param_type = ParameterTypeAt(i); |
| 7190 closure_function.SetParameterTypeAt(i, param_type); |
| 7191 param_name = ParameterNameAt(i); |
| 7192 closure_function.SetParameterNameAt(i, param_name); |
| 7193 } |
| 7194 closure_function.set_kernel_offset(kernel_offset()); |
| 7195 |
| 7196 const Type& signature_type = |
| 7197 Type::Handle(zone, closure_function.SignatureType()); |
| 7198 if (!signature_type.IsFinalized()) { |
| 7199 ClassFinalizer::FinalizeType(Class::Handle(zone, Owner()), signature_type); |
| 7200 } |
| 7201 set_converted_closure_function(closure_function); |
| 7202 return closure_function.raw(); |
| 7203 } |
| 7204 |
| 7205 |
| 7206 void Function::DropUncompiledConvertedClosureFunction() const { |
| 7207 if (converted_closure_function() != Function::null()) { |
| 7208 const Function& func = Function::Handle(converted_closure_function()); |
| 7209 if (!func.HasCode()) { |
| 7210 set_converted_closure_function(Function::Handle()); |
| 7211 } |
| 7212 } |
| 7213 } |
| 7214 |
| 7215 |
7036 RawString* Function::UserVisibleFormalParameters() const { | 7216 RawString* Function::UserVisibleFormalParameters() const { |
7037 Thread* thread = Thread::Current(); | 7217 Thread* thread = Thread::Current(); |
7038 Zone* zone = thread->zone(); | 7218 Zone* zone = thread->zone(); |
7039 // Typically 3, 5,.. elements in 'pieces', e.g.: | 7219 // Typically 3, 5,.. elements in 'pieces', e.g.: |
7040 // '_LoadRequest', CommaSpace, '_LoadError'. | 7220 // '_LoadRequest', CommaSpace, '_LoadError'. |
7041 GrowableHandlePtrArray<const String> pieces(zone, 5); | 7221 GrowableHandlePtrArray<const String> pieces(zone, 5); |
7042 BuildSignatureParameters(thread, zone, kUserVisibleName, &pieces); | 7222 BuildSignatureParameters(thread, zone, kUserVisibleName, &pieces); |
7043 return Symbols::FromConcatAll(thread, pieces); | 7223 return Symbols::FromConcatAll(thread, pieces); |
7044 } | 7224 } |
7045 | 7225 |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7520 if (IsNull()) { | 7700 if (IsNull()) { |
7521 return "Function: null"; | 7701 return "Function: null"; |
7522 } | 7702 } |
7523 const char* static_str = is_static() ? " static" : ""; | 7703 const char* static_str = is_static() ? " static" : ""; |
7524 const char* abstract_str = is_abstract() ? " abstract" : ""; | 7704 const char* abstract_str = is_abstract() ? " abstract" : ""; |
7525 const char* kind_str = NULL; | 7705 const char* kind_str = NULL; |
7526 const char* const_str = is_const() ? " const" : ""; | 7706 const char* const_str = is_const() ? " const" : ""; |
7527 switch (kind()) { | 7707 switch (kind()) { |
7528 case RawFunction::kRegularFunction: | 7708 case RawFunction::kRegularFunction: |
7529 case RawFunction::kClosureFunction: | 7709 case RawFunction::kClosureFunction: |
| 7710 case RawFunction::kConvertedClosureFunction: |
7530 case RawFunction::kGetterFunction: | 7711 case RawFunction::kGetterFunction: |
7531 case RawFunction::kSetterFunction: | 7712 case RawFunction::kSetterFunction: |
7532 kind_str = ""; | 7713 kind_str = ""; |
7533 break; | 7714 break; |
7534 case RawFunction::kSignatureFunction: | 7715 case RawFunction::kSignatureFunction: |
7535 kind_str = " signature"; | 7716 kind_str = " signature"; |
7536 break; | 7717 break; |
7537 case RawFunction::kConstructor: | 7718 case RawFunction::kConstructor: |
7538 kind_str = is_static() ? " factory" : " constructor"; | 7719 kind_str = is_static() ? " factory" : " constructor"; |
7539 break; | 7720 break; |
(...skipping 15879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
23419 return UserTag::null(); | 23600 return UserTag::null(); |
23420 } | 23601 } |
23421 | 23602 |
23422 | 23603 |
23423 const char* UserTag::ToCString() const { | 23604 const char* UserTag::ToCString() const { |
23424 const String& tag_label = String::Handle(label()); | 23605 const String& tag_label = String::Handle(label()); |
23425 return tag_label.ToCString(); | 23606 return tag_label.ToCString(); |
23426 } | 23607 } |
23427 | 23608 |
23428 } // namespace dart | 23609 } // namespace dart |
OLD | NEW |