Chromium Code Reviews| Index: runtime/vm/object.cc |
| =================================================================== |
| --- runtime/vm/object.cc (revision 23886) |
| +++ runtime/vm/object.cc (working copy) |
| @@ -9090,13 +9090,41 @@ |
| } |
| -RawInstance* Instance::Canonicalize() const { |
| +RawInstance* Instance::CheckAndCanonicalize(const char** error_str) const { |
| ASSERT(!IsNull()); |
| if (this->IsCanonical()) { |
| return this->raw(); |
| } |
| Instance& result = Instance::Handle(); |
| const Class& cls = Class::Handle(this->clazz()); |
| + if ((cls.id() >= kNumPredefinedCids) || cls.IsArray()) { |
|
Ivan Posva
2013/06/12 15:22:15
Why are you checking for kNumPredefinedCids here?
srdjan
2013/06/12 16:04:19
Because I cannot iterate over content of object's
|
| + // Iterate over all fields, canonicalize numbers and strings, expect all |
|
srdjan
2013/06/12 21:27:28
Added a TODO(srdjan): Check that predefined classe
|
| + // other instances to be canonical otherwise report error (return |
| + // Instance::null()). |
| + Object& obj = Object::Handle(); |
| + const intptr_t end_field_offset = cls.instance_size() - kWordSize; |
| + for (intptr_t field_offset = 0; |
| + field_offset <= end_field_offset; |
| + field_offset += kWordSize) { |
| + obj = *this->FieldAddrAtOffset(field_offset); |
| + if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { |
| + if (obj.IsNumber() || obj.IsString()) { |
| + obj = Instance::Cast(obj).CheckAndCanonicalize(NULL); |
| + ASSERT(!obj.IsNull()); |
| + this->SetFieldAtOffset(field_offset, obj); |
| + } else { |
| + ASSERT(error_str != NULL); |
| + const char* kFormat = "field: %s\n"; |
| + const intptr_t len = |
| + OS::SNPrint(NULL, 0, kFormat, obj.ToCString()) + 1; |
| + char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| + OS::SNPrint(chars, len, kFormat, obj.ToCString()); |
| + *error_str = chars; |
| + return Instance::null(); |
| + } |
| + } |
| + } |
| + } |
| Array& constants = Array::Handle(cls.constants()); |
| const intptr_t constants_len = constants.Length(); |
| // Linear search to see whether this value is already present in the |
| @@ -11444,7 +11472,7 @@ |
| } |
| -RawInstance* String::Canonicalize() const { |
| +RawInstance* String::CheckAndCanonicalize(const char** error_str) const { |
| if (IsCanonical()) { |
| return this->raw(); |
| } |