| 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 |