Commit 50f5a795 authored by adamk@chromium.org's avatar adamk@chromium.org

Use SameValueZero for Map and Set

Instead of normalizing the keys we use SameValueZero for the actual
comparison.

BUG=v8:1622
LOG=Y
R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/299703004

Patch from Erik Arvidsson <arv@chromium.org>.

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21400 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6717ac65
......@@ -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);
}
......
......@@ -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;
......
......@@ -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
......
......@@ -51,7 +51,7 @@ EXPECTED_FUNCTION_COUNT = 359
EXPECTED_FUZZABLE_COUNT = 326
EXPECTED_CCTEST_COUNT = 6
EXPECTED_UNKNOWN_COUNT = 5
EXPECTED_BUILTINS_COUNT = 824
EXPECTED_BUILTINS_COUNT = 823
# Don't call these at all.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment