Chromium Code Reviews| 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/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 2827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2838 } | 2838 } |
| 2839 | 2839 |
| 2840 | 2840 |
| 2841 // Apply the members from the patch class to the original class. | 2841 // Apply the members from the patch class to the original class. |
| 2842 bool Class::ApplyPatch(const Class& patch, Error* error) const { | 2842 bool Class::ApplyPatch(const Class& patch, Error* error) const { |
| 2843 ASSERT(error != NULL); | 2843 ASSERT(error != NULL); |
| 2844 ASSERT(!is_finalized()); | 2844 ASSERT(!is_finalized()); |
| 2845 // Shared handles used during the iteration. | 2845 // Shared handles used during the iteration. |
| 2846 String& member_name = String::Handle(); | 2846 String& member_name = String::Handle(); |
| 2847 | 2847 |
| 2848 const PatchClass& patch_class = | 2848 const PatchClass& patch_class = PatchClass::Handle( |
| 2849 PatchClass::Handle(PatchClass::New(*this, patch)); | 2849 PatchClass::New(*this, Script::Handle(patch.script()))); |
| 2850 | 2850 |
| 2851 Array& orig_list = Array::Handle(functions()); | 2851 Array& orig_list = Array::Handle(functions()); |
| 2852 intptr_t orig_len = orig_list.Length(); | 2852 intptr_t orig_len = orig_list.Length(); |
| 2853 Array& patch_list = Array::Handle(patch.functions()); | 2853 Array& patch_list = Array::Handle(patch.functions()); |
| 2854 intptr_t patch_len = patch_list.Length(); | 2854 intptr_t patch_len = patch_list.Length(); |
| 2855 | 2855 |
| 2856 // TODO(iposva): Verify that only patching existing methods and adding only | 2856 // TODO(iposva): Verify that only patching existing methods and adding only |
| 2857 // new private methods. | 2857 // new private methods. |
| 2858 Function& func = Function::Handle(); | 2858 Function& func = Function::Handle(); |
| 2859 Function& orig_func = Function::Handle(); | 2859 Function& orig_func = Function::Handle(); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2941 } | 2941 } |
| 2942 new_list.SetAt(i, field); | 2942 new_list.SetAt(i, field); |
| 2943 } | 2943 } |
| 2944 for (intptr_t i = 0; i < orig_len; i++) { | 2944 for (intptr_t i = 0; i < orig_len; i++) { |
| 2945 field ^= orig_list.At(i); | 2945 field ^= orig_list.At(i); |
| 2946 new_list.SetAt(patch_len + i, field); | 2946 new_list.SetAt(patch_len + i, field); |
| 2947 } | 2947 } |
| 2948 SetFields(new_list); | 2948 SetFields(new_list); |
| 2949 | 2949 |
| 2950 // The functions and fields in the patch class are no longer needed. | 2950 // The functions and fields in the patch class are no longer needed. |
| 2951 // The patch class itself is also no longer needed. | |
| 2951 patch.SetFunctions(Object::empty_array()); | 2952 patch.SetFunctions(Object::empty_array()); |
| 2952 patch.SetFields(Object::empty_array()); | 2953 patch.SetFields(Object::empty_array()); |
| 2954 Library::Handle(patch.library()).RemovePatchClass(patch); | |
| 2953 return true; | 2955 return true; |
| 2954 } | 2956 } |
| 2955 | 2957 |
| 2956 | 2958 |
| 2957 static RawString* BuildClosureSource(const Array& formal_params, | 2959 static RawString* BuildClosureSource(const Array& formal_params, |
| 2958 const String& expr) { | 2960 const String& expr) { |
| 2959 const GrowableObjectArray& src_pieces = | 2961 const GrowableObjectArray& src_pieces = |
| 2960 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 2962 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 2961 String& piece = String::Handle(); | 2963 String& piece = String::Handle(); |
| 2962 src_pieces.Add(Symbols::LParen()); | 2964 src_pieces.Add(Symbols::LParen()); |
| (...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3572 ASSERT(!value.IsNull()); | 3574 ASSERT(!value.IsNull()); |
| 3573 StorePointer(&raw_ptr()->mixin_, value.raw()); | 3575 StorePointer(&raw_ptr()->mixin_, value.raw()); |
| 3574 } | 3576 } |
| 3575 | 3577 |
| 3576 | 3578 |
| 3577 bool Class::IsMixinApplication() const { | 3579 bool Class::IsMixinApplication() const { |
| 3578 return mixin() != Type::null(); | 3580 return mixin() != Type::null(); |
| 3579 } | 3581 } |
| 3580 | 3582 |
| 3581 | 3583 |
| 3582 void Class::SetPatchClass(const Class& cls) const { | |
| 3583 ASSERT(GetPatchClass() == Class::null()); | |
| 3584 const GrowableObjectArray& patch_classes = | |
| 3585 GrowableObjectArray::Handle(Library::Handle(library()).patch_classes()); | |
| 3586 patch_classes.Add(cls); | |
| 3587 } | |
| 3588 | |
| 3589 | |
| 3590 RawClass* Class::GetPatchClass() const { | 3584 RawClass* Class::GetPatchClass() const { |
| 3591 const GrowableObjectArray& patch_classes = | 3585 const Library& lib = Library::Handle(library()); |
| 3592 GrowableObjectArray::Handle(Library::Handle(library()).patch_classes()); | 3586 return lib.GetPatchClass(String::Handle(Name())); |
| 3593 Class& pc = Class::Handle(); | |
| 3594 for (intptr_t i = 0; i < patch_classes.Length(); i++) { | |
| 3595 pc ^= patch_classes.At(i); | |
| 3596 if (pc.Name() == this->Name()) { // Names are canonicalized. | |
| 3597 return pc.raw(); | |
| 3598 } | |
| 3599 } | |
| 3600 return Class::null(); | |
| 3601 } | 3587 } |
| 3602 | 3588 |
| 3603 | 3589 |
| 3604 void Class::AddDirectSubclass(const Class& subclass) const { | 3590 void Class::AddDirectSubclass(const Class& subclass) const { |
| 3605 ASSERT(!subclass.IsNull()); | 3591 ASSERT(!subclass.IsNull()); |
| 3606 ASSERT(subclass.SuperClass() == raw()); | 3592 ASSERT(subclass.SuperClass() == raw()); |
| 3607 // Do not keep track of the direct subclasses of class Object. | 3593 // Do not keep track of the direct subclasses of class Object. |
| 3608 ASSERT(!IsObjectClass()); | 3594 ASSERT(!IsObjectClass()); |
| 3609 GrowableObjectArray& direct_subclasses = | 3595 GrowableObjectArray& direct_subclasses = |
| 3610 GrowableObjectArray::Handle(raw_ptr()->direct_subclasses_); | 3596 GrowableObjectArray::Handle(raw_ptr()->direct_subclasses_); |
| (...skipping 5727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9338 lib = ImportLibraryAt(i); | 9324 lib = ImportLibraryAt(i); |
| 9339 error = lib.TransitiveLoadError(); | 9325 error = lib.TransitiveLoadError(); |
| 9340 if (!error.IsNull()) { | 9326 if (!error.IsNull()) { |
| 9341 break; | 9327 break; |
| 9342 } | 9328 } |
| 9343 } | 9329 } |
| 9344 return error.raw(); | 9330 return error.raw(); |
| 9345 } | 9331 } |
| 9346 | 9332 |
| 9347 | 9333 |
| 9334 void Library::AddPatchClass(const Class& cls) const { | |
| 9335 ASSERT(cls.is_patch()); | |
| 9336 ASSERT(GetPatchClass(String::Handle(cls.Name())) == Class::null()); | |
| 9337 const GrowableObjectArray& patch_classes = | |
| 9338 GrowableObjectArray::Handle(this->patch_classes()); | |
| 9339 patch_classes.Add(cls); | |
| 9340 } | |
| 9341 | |
| 9342 | |
| 9343 RawClass* Library::GetPatchClass(const String& name) const { | |
| 9344 const GrowableObjectArray& patch_classes = | |
| 9345 GrowableObjectArray::Handle(this->patch_classes()); | |
| 9346 Object& obj = Object::Handle(); | |
| 9347 for (intptr_t i = 0; i < patch_classes.Length(); i++) { | |
| 9348 obj = patch_classes.At(i); | |
| 9349 if (obj.IsClass() && | |
| 9350 (Class::Cast(obj).Name() == name.raw())) { // Names are canonicalized. | |
| 9351 return Class::RawCast(obj.raw()); | |
| 9352 } | |
| 9353 } | |
| 9354 return Class::null(); | |
| 9355 } | |
| 9356 | |
| 9357 | |
| 9358 void Library::RemovePatchClass(const Class& cls) const { | |
| 9359 ASSERT(cls.is_patch()); | |
| 9360 const GrowableObjectArray& patch_classes = | |
| 9361 GrowableObjectArray::Handle(this->patch_classes()); | |
| 9362 const intptr_t num_classes = patch_classes.Length(); | |
| 9363 intptr_t i = 0; | |
| 9364 while (i < num_classes) { | |
| 9365 if (cls.raw() == patch_classes.At(i)) break; | |
| 9366 i++; | |
| 9367 } | |
| 9368 if (i == num_classes) return; | |
| 9369 // Replace the entry with the script. We keep the script so that | |
| 9370 // Library::LoadedScripts() can find it without having to iterate | |
| 9371 // over the members of each class. | |
| 9372 ASSERT(i < num_classes); // We must have found a class. | |
| 9373 Class& pc = Class::Handle(); | |
| 9374 pc ^= patch_classes.At(i); | |
| 9375 const Script& patch_script = Script::Handle(pc.script()); | |
|
Ivan Posva
2015/12/08 09:11:14
Why is this not just
Script::Handle(cls.script());
hausner
2015/12/08 17:00:15
D'uh! I changed this code a few times and apparent
| |
| 9376 patch_classes.SetAt(i, patch_script); | |
| 9377 } | |
| 9378 | |
| 9379 | |
| 9348 static RawString* MakeClassMetaName(const Class& cls) { | 9380 static RawString* MakeClassMetaName(const Class& cls) { |
| 9349 return Symbols::FromConcat(Symbols::At(), String::Handle(cls.Name())); | 9381 return Symbols::FromConcat(Symbols::At(), String::Handle(cls.Name())); |
| 9350 } | 9382 } |
| 9351 | 9383 |
| 9352 | 9384 |
| 9353 static RawString* MakeFieldMetaName(const Field& field) { | 9385 static RawString* MakeFieldMetaName(const Field& field) { |
| 9354 const String& cname = | 9386 const String& cname = |
| 9355 String::Handle(MakeClassMetaName(Class::Handle(field.origin()))); | 9387 String::Handle(MakeClassMetaName(Class::Handle(field.origin()))); |
| 9356 GrowableHandlePtrArray<const String> pieces(Thread::Current()->zone(), 3); | 9388 GrowableHandlePtrArray<const String> pieces(Thread::Current()->zone(), 3); |
| 9357 pieces.Add(cname); | 9389 pieces.Add(cname); |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9772 owner_script = Field::Cast(entry).script(); | 9804 owner_script = Field::Cast(entry).script(); |
| 9773 } else { | 9805 } else { |
| 9774 continue; | 9806 continue; |
| 9775 } | 9807 } |
| 9776 AddScriptIfUnique(scripts, owner_script); | 9808 AddScriptIfUnique(scripts, owner_script); |
| 9777 } | 9809 } |
| 9778 | 9810 |
| 9779 // Add all scripts from patch classes. | 9811 // Add all scripts from patch classes. |
| 9780 GrowableObjectArray& patches = GrowableObjectArray::Handle(patch_classes()); | 9812 GrowableObjectArray& patches = GrowableObjectArray::Handle(patch_classes()); |
| 9781 for (intptr_t i = 0; i < patches.Length(); i++) { | 9813 for (intptr_t i = 0; i < patches.Length(); i++) { |
| 9782 cls ^= patches.At(i); | 9814 entry = patches.At(i); |
| 9783 owner_script = cls.script(); | 9815 if (entry.IsClass()) { |
| 9816 owner_script = Class::Cast(entry).script(); | |
| 9817 } else { | |
| 9818 ASSERT(entry.IsScript()); | |
| 9819 owner_script ^= Script::Cast(entry).raw(); | |
|
Ivan Posva
2015/12/08 09:11:14
Why is the ^= operator needed here?
hausner
2015/12/08 17:00:15
Good catch. Will remove.
| |
| 9820 } | |
| 9784 AddScriptIfUnique(scripts, owner_script); | 9821 AddScriptIfUnique(scripts, owner_script); |
| 9785 } | 9822 } |
| 9786 | 9823 |
| 9787 cls ^= toplevel_class(); | 9824 cls ^= toplevel_class(); |
| 9788 if (!cls.IsNull()) { | 9825 if (!cls.IsNull()) { |
| 9789 owner_script = cls.script(); | 9826 owner_script = cls.script(); |
| 9790 AddScriptIfUnique(scripts, owner_script); | 9827 AddScriptIfUnique(scripts, owner_script); |
| 9791 // Special case: Scripts that only contain external top-level functions | 9828 // Special case: Scripts that only contain external top-level functions |
| 9792 // are not included above, but can be referenced through a library's | 9829 // are not included above, but can be referenced through a library's |
| 9793 // anonymous classes. Example: dart-core:identical.dart. | 9830 // anonymous classes. Example: dart-core:identical.dart. |
| (...skipping 12125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 21919 return tag_label.ToCString(); | 21956 return tag_label.ToCString(); |
| 21920 } | 21957 } |
| 21921 | 21958 |
| 21922 | 21959 |
| 21923 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 21960 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 21924 Instance::PrintJSONImpl(stream, ref); | 21961 Instance::PrintJSONImpl(stream, ref); |
| 21925 } | 21962 } |
| 21926 | 21963 |
| 21927 | 21964 |
| 21928 } // namespace dart | 21965 } // namespace dart |
| OLD | NEW |