| 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 12690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12701 param = param_values.At(i); | 12701 param = param_values.At(i); |
| 12702 args.SetAt(i + 1, param); | 12702 args.SetAt(i + 1, param); |
| 12703 } | 12703 } |
| 12704 const Object& result = | 12704 const Object& result = |
| 12705 Object::Handle(DartEntry::InvokeFunction(eval_func, args)); | 12705 Object::Handle(DartEntry::InvokeFunction(eval_func, args)); |
| 12706 return result.raw(); | 12706 return result.raw(); |
| 12707 } | 12707 } |
| 12708 | 12708 |
| 12709 | 12709 |
| 12710 | 12710 |
| 12711 bool Instance::Equals(const Instance& other) const { | 12711 bool Instance::CanonicalizeEquals(const Instance& other) const { |
| 12712 if (this->raw() == other.raw()) { | 12712 if (this->raw() == other.raw()) { |
| 12713 return true; // "===". | 12713 return true; // "===". |
| 12714 } | 12714 } |
| 12715 | 12715 |
| 12716 if (other.IsNull() || (this->clazz() != other.clazz())) { | 12716 if (other.IsNull() || (this->clazz() != other.clazz())) { |
| 12717 return false; | 12717 return false; |
| 12718 } | 12718 } |
| 12719 | 12719 |
| 12720 { | 12720 { |
| 12721 NoGCScope no_gc; | 12721 NoGCScope no_gc; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12812 Array& constants = Array::Handle(cls.constants()); | 12812 Array& constants = Array::Handle(cls.constants()); |
| 12813 const intptr_t constants_len = constants.Length(); | 12813 const intptr_t constants_len = constants.Length(); |
| 12814 // Linear search to see whether this value is already present in the | 12814 // Linear search to see whether this value is already present in the |
| 12815 // list of canonicalized constants. | 12815 // list of canonicalized constants. |
| 12816 intptr_t index = 0; | 12816 intptr_t index = 0; |
| 12817 while (index < constants_len) { | 12817 while (index < constants_len) { |
| 12818 result ^= constants.At(index); | 12818 result ^= constants.At(index); |
| 12819 if (result.IsNull()) { | 12819 if (result.IsNull()) { |
| 12820 break; | 12820 break; |
| 12821 } | 12821 } |
| 12822 if (this->Equals(result)) { | 12822 if (this->CanonicalizeEquals(result)) { |
| 12823 return result.raw(); | 12823 return result.raw(); |
| 12824 } | 12824 } |
| 12825 index++; | 12825 index++; |
| 12826 } | 12826 } |
| 12827 // The value needs to be added to the list. Grow the list if | 12827 // The value needs to be added to the list. Grow the list if |
| 12828 // it is full. | 12828 // it is full. |
| 12829 result ^= this->raw(); | 12829 result ^= this->raw(); |
| 12830 if (result.IsNew()) { | 12830 if (result.IsNew()) { |
| 12831 // Create a canonical object in old space. | 12831 // Create a canonical object in old space. |
| 12832 result ^= Object::Clone(result, Heap::kOld); | 12832 result ^= Object::Clone(result, Heap::kOld); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12918 other_type_arguments = instantiated_other.arguments(); | 12918 other_type_arguments = instantiated_other.arguments(); |
| 12919 } else { | 12919 } else { |
| 12920 other_class = other.type_class(); | 12920 other_class = other.type_class(); |
| 12921 other_type_arguments = other.arguments(); | 12921 other_type_arguments = other.arguments(); |
| 12922 } | 12922 } |
| 12923 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, | 12923 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, |
| 12924 bound_error); | 12924 bound_error); |
| 12925 } | 12925 } |
| 12926 | 12926 |
| 12927 | 12927 |
| 12928 bool Instance::OperatorEquals(const Instance& other) const { |
| 12929 // TODO(koda): Optimize for all builtin classes and all classes |
| 12930 // that do not override operator==. |
| 12931 const Object& result = |
| 12932 Object::Handle(DartLibraryCalls::Equals(*this, other)); |
| 12933 return result.raw() == Object::bool_true().raw(); |
| 12934 } |
| 12935 |
| 12936 |
| 12928 bool Instance::IsIdenticalTo(const Instance& other) const { | 12937 bool Instance::IsIdenticalTo(const Instance& other) const { |
| 12929 if (raw() == other.raw()) return true; | 12938 if (raw() == other.raw()) return true; |
| 12930 if (IsInteger() && other.IsInteger()) { | 12939 if (IsInteger() && other.IsInteger()) { |
| 12931 return Equals(other); | 12940 return Integer::Cast(*this).Equals(other); |
| 12932 } | 12941 } |
| 12933 if (IsDouble() && other.IsDouble()) { | 12942 if (IsDouble() && other.IsDouble()) { |
| 12934 if (Equals(other)) return true; | 12943 if (Double::Cast(*this).CanonicalizeEquals(other)) return true; |
| 12935 // Check for NaN. | 12944 // Check for NaN. |
| 12936 const Double& a_double = Double::Cast(*this); | 12945 const Double& a_double = Double::Cast(*this); |
| 12937 const Double& b_double = Double::Cast(other); | 12946 const Double& b_double = Double::Cast(other); |
| 12938 if (isnan(a_double.value()) && isnan(b_double.value())) { | 12947 if (isnan(a_double.value()) && isnan(b_double.value())) { |
| 12939 return true; | 12948 return true; |
| 12940 } | 12949 } |
| 12941 } | 12950 } |
| 12942 return false; | 12951 return false; |
| 12943 } | 12952 } |
| 12944 | 12953 |
| (...skipping 2505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15450 void Mint::PrintJSONImpl(JSONStream* stream, bool ref) const { | 15459 void Mint::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 15451 Number::PrintJSONImpl(stream, ref); | 15460 Number::PrintJSONImpl(stream, ref); |
| 15452 } | 15461 } |
| 15453 | 15462 |
| 15454 | 15463 |
| 15455 void Double::set_value(double value) const { | 15464 void Double::set_value(double value) const { |
| 15456 raw_ptr()->value_ = value; | 15465 raw_ptr()->value_ = value; |
| 15457 } | 15466 } |
| 15458 | 15467 |
| 15459 | 15468 |
| 15460 bool Double::EqualsToDouble(double value) const { | 15469 bool Double::BitwiseEqualsToDouble(double value) const { |
| 15461 intptr_t value_offset = Double::value_offset(); | 15470 intptr_t value_offset = Double::value_offset(); |
| 15462 void* this_addr = reinterpret_cast<void*>( | 15471 void* this_addr = reinterpret_cast<void*>( |
| 15463 reinterpret_cast<uword>(this->raw_ptr()) + value_offset); | 15472 reinterpret_cast<uword>(this->raw_ptr()) + value_offset); |
| 15464 void* other_addr = reinterpret_cast<void*>(&value); | 15473 void* other_addr = reinterpret_cast<void*>(&value); |
| 15465 return (memcmp(this_addr, other_addr, sizeof(value)) == 0); | 15474 return (memcmp(this_addr, other_addr, sizeof(value)) == 0); |
| 15466 } | 15475 } |
| 15467 | 15476 |
| 15468 | 15477 |
| 15469 bool Double::Equals(const Instance& other) const { | 15478 bool Double::OperatorEquals(const Instance& other) const { |
| 15479 if (this->IsNull() || other.IsNull()) { |
| 15480 return (this->IsNull() && other.IsNull()); |
| 15481 } |
| 15482 if (!other.IsDouble()) { |
| 15483 return false; |
| 15484 } |
| 15485 return this->value() == Double::Cast(other).value(); |
| 15486 } |
| 15487 |
| 15488 |
| 15489 bool Double::CanonicalizeEquals(const Instance& other) const { |
| 15470 if (this->raw() == other.raw()) { | 15490 if (this->raw() == other.raw()) { |
| 15471 return true; // "===". | 15491 return true; // "===". |
| 15472 } | 15492 } |
| 15473 if (other.IsNull() || !other.IsDouble()) { | 15493 if (other.IsNull() || !other.IsDouble()) { |
| 15474 return false; | 15494 return false; |
| 15475 } | 15495 } |
| 15476 return EqualsToDouble(Double::Cast(other).value()); | 15496 return BitwiseEqualsToDouble(Double::Cast(other).value()); |
| 15477 } | 15497 } |
| 15478 | 15498 |
| 15479 | 15499 |
| 15480 RawDouble* Double::New(double d, Heap::Space space) { | 15500 RawDouble* Double::New(double d, Heap::Space space) { |
| 15481 ASSERT(Isolate::Current()->object_store()->double_class() != Class::null()); | 15501 ASSERT(Isolate::Current()->object_store()->double_class() != Class::null()); |
| 15482 Double& result = Double::Handle(); | 15502 Double& result = Double::Handle(); |
| 15483 { | 15503 { |
| 15484 RawObject* raw = Object::Allocate(Double::kClassId, | 15504 RawObject* raw = Object::Allocate(Double::kClassId, |
| 15485 Double::InstanceSize(), | 15505 Double::InstanceSize(), |
| 15486 space); | 15506 space); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 15508 const intptr_t constants_len = constants.Length(); | 15528 const intptr_t constants_len = constants.Length(); |
| 15509 // Linear search to see whether this value is already present in the | 15529 // Linear search to see whether this value is already present in the |
| 15510 // list of canonicalized constants. | 15530 // list of canonicalized constants. |
| 15511 Double& canonical_value = Double::Handle(); | 15531 Double& canonical_value = Double::Handle(); |
| 15512 intptr_t index = 0; | 15532 intptr_t index = 0; |
| 15513 while (index < constants_len) { | 15533 while (index < constants_len) { |
| 15514 canonical_value ^= constants.At(index); | 15534 canonical_value ^= constants.At(index); |
| 15515 if (canonical_value.IsNull()) { | 15535 if (canonical_value.IsNull()) { |
| 15516 break; | 15536 break; |
| 15517 } | 15537 } |
| 15518 if (canonical_value.EqualsToDouble(value)) { | 15538 if (canonical_value.BitwiseEqualsToDouble(value)) { |
| 15519 return canonical_value.raw(); | 15539 return canonical_value.raw(); |
| 15520 } | 15540 } |
| 15521 index++; | 15541 index++; |
| 15522 } | 15542 } |
| 15523 // The value needs to be added to the constants list. Grow the list if | 15543 // The value needs to be added to the constants list. Grow the list if |
| 15524 // it is full. | 15544 // it is full. |
| 15525 canonical_value = Double::New(value, Heap::kOld); | 15545 canonical_value = Double::New(value, Heap::kOld); |
| 15526 cls.InsertCanonicalConstant(index, canonical_value); | 15546 cls.InsertCanonicalConstant(index, canonical_value); |
| 15527 canonical_value.SetCanonical(); | 15547 canonical_value.SetCanonical(); |
| 15528 return canonical_value.raw(); | 15548 return canonical_value.raw(); |
| (...skipping 1880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17409 const char* str = ToCString(); | 17429 const char* str = ToCString(); |
| 17410 JSONObject jsobj(stream); | 17430 JSONObject jsobj(stream); |
| 17411 jsobj.AddProperty("type", JSONType(ref)); | 17431 jsobj.AddProperty("type", JSONType(ref)); |
| 17412 jsobj.AddPropertyF("id", "objects/bool-%s", str); | 17432 jsobj.AddPropertyF("id", "objects/bool-%s", str); |
| 17413 class Class& cls = Class::Handle(this->clazz()); | 17433 class Class& cls = Class::Handle(this->clazz()); |
| 17414 jsobj.AddProperty("class", cls); | 17434 jsobj.AddProperty("class", cls); |
| 17415 jsobj.AddPropertyF("valueAsString", "%s", str); | 17435 jsobj.AddPropertyF("valueAsString", "%s", str); |
| 17416 } | 17436 } |
| 17417 | 17437 |
| 17418 | 17438 |
| 17419 bool Array::Equals(const Instance& other) const { | 17439 bool Array::CanonicalizeEquals(const Instance& other) const { |
| 17420 if (this->raw() == other.raw()) { | 17440 if (this->raw() == other.raw()) { |
| 17421 // Both handles point to the same raw instance. | 17441 // Both handles point to the same raw instance. |
| 17422 return true; | 17442 return true; |
| 17423 } | 17443 } |
| 17424 | 17444 |
| 17425 // An Array may be compared to an ImmutableArray. | 17445 // An Array may be compared to an ImmutableArray. |
| 17426 if (!other.IsArray() || other.IsNull()) { | 17446 if (!other.IsArray() || other.IsNull()) { |
| 17427 return false; | 17447 return false; |
| 17428 } | 17448 } |
| 17429 | 17449 |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17649 ASSERT(Length() > 0); | 17669 ASSERT(Length() > 0); |
| 17650 intptr_t index = Length() - 1; | 17670 intptr_t index = Length() - 1; |
| 17651 const Array& contents = Array::Handle(data()); | 17671 const Array& contents = Array::Handle(data()); |
| 17652 const Object& obj = Object::Handle(contents.At(index)); | 17672 const Object& obj = Object::Handle(contents.At(index)); |
| 17653 contents.SetAt(index, Object::null_object()); | 17673 contents.SetAt(index, Object::null_object()); |
| 17654 SetLength(index); | 17674 SetLength(index); |
| 17655 return obj.raw(); | 17675 return obj.raw(); |
| 17656 } | 17676 } |
| 17657 | 17677 |
| 17658 | 17678 |
| 17659 bool GrowableObjectArray::Equals(const Instance& other) const { | 17679 bool GrowableObjectArray::CanonicalizeEquals(const Instance& other) const { |
| 17660 // If both handles point to the same raw instance they are equal. | 17680 // If both handles point to the same raw instance they are equal. |
| 17661 if (this->raw() == other.raw()) { | 17681 if (this->raw() == other.raw()) { |
| 17662 return true; | 17682 return true; |
| 17663 } | 17683 } |
| 17664 | 17684 |
| 17665 // Other instance must be non null and a GrowableObjectArray. | 17685 // Other instance must be non null and a GrowableObjectArray. |
| 17666 if (!other.IsGrowableObjectArray() || other.IsNull()) { | 17686 if (!other.IsGrowableObjectArray() || other.IsNull()) { |
| 17667 return false; | 17687 return false; |
| 17668 } | 17688 } |
| 17669 | 17689 |
| (...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18559 case kGlobal | kMultiLine : | 18579 case kGlobal | kMultiLine : |
| 18560 case kMultiLine: | 18580 case kMultiLine: |
| 18561 return "m"; | 18581 return "m"; |
| 18562 default: | 18582 default: |
| 18563 break; | 18583 break; |
| 18564 } | 18584 } |
| 18565 return ""; | 18585 return ""; |
| 18566 } | 18586 } |
| 18567 | 18587 |
| 18568 | 18588 |
| 18569 bool JSRegExp::Equals(const Instance& other) const { | 18589 bool JSRegExp::CanonicalizeEquals(const Instance& other) const { |
| 18570 if (this->raw() == other.raw()) { | 18590 if (this->raw() == other.raw()) { |
| 18571 return true; // "===". | 18591 return true; // "===". |
| 18572 } | 18592 } |
| 18573 if (other.IsNull() || !other.IsJSRegExp()) { | 18593 if (other.IsNull() || !other.IsJSRegExp()) { |
| 18574 return false; | 18594 return false; |
| 18575 } | 18595 } |
| 18576 const JSRegExp& other_js = JSRegExp::Cast(other); | 18596 const JSRegExp& other_js = JSRegExp::Cast(other); |
| 18577 // Match the pattern. | 18597 // Match the pattern. |
| 18578 const String& str1 = String::Handle(pattern()); | 18598 const String& str1 = String::Handle(pattern()); |
| 18579 const String& str2 = String::Handle(other_js.pattern()); | 18599 const String& str2 = String::Handle(other_js.pattern()); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18813 return tag_label.ToCString(); | 18833 return tag_label.ToCString(); |
| 18814 } | 18834 } |
| 18815 | 18835 |
| 18816 | 18836 |
| 18817 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 18837 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 18818 Instance::PrintJSONImpl(stream, ref); | 18838 Instance::PrintJSONImpl(stream, ref); |
| 18819 } | 18839 } |
| 18820 | 18840 |
| 18821 | 18841 |
| 18822 } // namespace dart | 18842 } // namespace dart |
| OLD | NEW |