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 |