Reviewers: Michael Starzinger, adamk,
Description:
Use SameValueZero for Map and Set
Instead of normalizing the keys we use SameValueZero for the actual
comparison.
BUG=v8:1622
LOG=Y
Please review this at https://codereview.chromium.org/299703004/
SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+33, -28 lines):
M src/collection.js
M src/objects.h
M src/objects.cc
Index: src/collection.js
diff --git a/src/collection.js b/src/collection.js
index
fefc7a0499db3c71ea1585ab2eb5a8767af755f9..94125fb89956caf6c7eb0b3f69060962c20fcb8f
100644
--- a/src/collection.js
+++ b/src/collection.js
@@ -11,25 +11,6 @@
var $Set = global.Set;
var $Map = global.Map;
-// Global sentinel to be used instead of undefined keys, which are not
-// supported internally but required for Harmony sets and maps.
-var undefined_sentinel = {};
-
-
-// Map and Set uses SameValueZero which means that +0 and -0 should be
treated
-// as the same value.
-function NormalizeKey(key) {
- if (IS_UNDEFINED(key)) {
- return undefined_sentinel;
- }
-
- if (key === 0) {
- return 0;
- }
-
- return key;
-}
-
// -------------------------------------------------------------------
// Harmony Set
@@ -48,7 +29,7 @@ function SetAddJS(key) {
throw MakeTypeError('incompatible_method_receiver',
['Set.prototype.add', this]);
}
- return %SetAdd(this, NormalizeKey(key));
+ return %SetAdd(this, key);
}
@@ -57,7 +38,7 @@ function SetHasJS(key) {
throw MakeTypeError('incompatible_method_receiver',
['Set.prototype.has', this]);
}
- return %SetHas(this, NormalizeKey(key));
+ return %SetHas(this, key);
}
@@ -66,7 +47,6 @@ function SetDeleteJS(key) {
throw MakeTypeError('incompatible_method_receiver',
['Set.prototype.delete', this]);
}
- key = NormalizeKey(key);
if (%SetHas(this, key)) {
%SetDelete(this, key);
return true;
@@ -154,7 +134,7 @@ function MapGetJS(key) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.get', this]);
}
- return %MapGet(this, NormalizeKey(key));
+ return %MapGet(this, key);
}
@@ -163,7 +143,7 @@ function MapSetJS(key, value) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.set', this]);
}
- return %MapSet(this, NormalizeKey(key), value);
+ return %MapSet(this, key, value);
}
@@ -172,7 +152,7 @@ function MapHasJS(key) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.has', this]);
}
- return %MapHas(this, NormalizeKey(key));
+ return %MapHas(this, key);
}
@@ -181,7 +161,7 @@ function MapDeleteJS(key) {
throw MakeTypeError('incompatible_method_receiver',
['Map.prototype.delete', this]);
}
- return %MapDelete(this, NormalizeKey(key));
+ return %MapDelete(this, key);
}
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
8e8830a768522103da2f79173b33d174e3150664..a1ca34ead8dc83ec02d448eeb23d0953409df07a
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -975,6 +975,25 @@ bool Object::SameValue(Object* other) {
}
+bool Object::SameValueZero(Object* other) {
+ if (other == this) return true;
+
+ // The object is either a number, a name, an odd-ball,
+ // a real JS object, or a Harmony proxy.
+ if (IsNumber() && other->IsNumber()) {
+ double this_value = Number();
+ double other_value = other->Number();
+ // +0 == -0 is true
+ return this_value == other_value
+ || (std::isnan(this_value) && std::isnan(other_value));
+ }
+ if (IsString() && other->IsString()) {
+ return String::cast(this)->Equals(String::cast(other));
+ }
+ return false;
+}
+
+
void Object::ShortPrint(FILE* out) {
HeapStringAllocator allocator;
StringStream accumulator(&allocator);
@@ -16329,7 +16348,7 @@ int OrderedHashTable<Derived, Iterator,
entrysize>::FindEntry(
entry != kNotFound;
entry = ChainAt(entry)) {
Object* candidate = KeyAt(entry);
- if (candidate->SameValue(*key))
+ if (candidate->SameValueZero(*key))
return entry;
}
return kNotFound;
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
910c25200ee3ec808f632a107078702138ea5d76..80848f882bd5e38dd185a4d6d4f9bf0a474f4a67
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1511,6 +1511,12 @@ class Object {
// to implement the Harmony "egal" function.
bool SameValue(Object* other);
+ // Checks whether this object has the same value as the given one.
+ // +0 and -0 are treated equal. Everything else is the same as SameValue.
+ // This function is implemented according to ES6, section 7.2.4 and is
used
+ // by ES6 Map and Set.
+ bool SameValueZero(Object* other);
+
// Tries to convert an object to an array index. Returns true and sets
// the output parameter if it succeeds.
inline bool ToArrayIndex(uint32_t* index);
@@ -4142,7 +4148,7 @@ class ObjectHashTable: public
HashTable<ObjectHashTable,
// insertion order. There are Map and Set interfaces (OrderedHashMap
// and OrderedHashTable, below). It is meant to be used by JSMap/JSSet.
//
-// Only Object* keys are supported, with Object::SameValue() used as the
+// Only Object* keys are supported, with Object::SameValueZero() used as
the
// equality operator and Object::GetHash() for the hash function.
//
// Based on the "Deterministic Hash Table" as described by Jason Orendorff
at
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.