Bug 722260 - Properly handle NaN values as keys in Map objects. r=luke

This commit is contained in:
Jeff Walden 2012-01-31 16:49:27 -08:00
parent ea987f7685
commit 29b6689cf7
14 changed files with 124 additions and 7 deletions

View File

@ -90,14 +90,10 @@ HashableValue::setValue(JSContext *cx, const Value &v)
if (JSDOUBLE_IS_INT32(d, &i)) {
/* Normalize int32-valued doubles to int32 for faster hashing and testing. */
value = Int32Value(i);
} else if (JSDOUBLE_IS_NaN(d)) {
/* NaNs with different bits must hash and test identically. */
value = DoubleValue(js_NaN);
} else {
#ifdef DEBUG
/* All NaN values are the same. The bit-pattern must reflect this. */
jsval_layout a, b;
a.asDouble = d;
b.asDouble = JS_CANONICALIZE_NAN(d);
JS_ASSERT(a.asBits == b.asBits);
#endif
value = v;
}
} else {

View File

@ -59,6 +59,7 @@ TEST_FILES = \
ecma_3/ \
ecma_3_1/ \
ecma_5/ \
ecma_6/ \
js1_1/ \
js1_2/ \
js1_3/ \

View File

@ -0,0 +1,55 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
//-----------------------------------------------------------------------------
var BUGNUMBER = 722260;
var summary = 'All NaNs must be treated as identical keys for Map';
print(BUGNUMBER + ": " + summary);
/**************
* BEGIN TEST *
**************/
/* Avoid constant-folding that would happen were |undefined| to be used. */
var key = -/a/g.missingProperty;
var m = new Map();
m.set(key, 17);
assertEq(m.get(key), 17);
assertEq(m.get(-key), 17);
assertEq(m.get(NaN), 17);
m.delete(-key);
assertEq(m.has(key), false);
assertEq(m.has(-key), false);
assertEq(m.has(NaN), false);
m.set(-key, 17);
assertEq(m.get(key), 17);
assertEq(m.get(-key), 17);
assertEq(m.get(NaN), 17);
m.delete(NaN);
assertEq(m.has(key), false);
assertEq(m.has(-key), false);
assertEq(m.has(NaN), false);
m.set(NaN, 17);
assertEq(m.get(key), 17);
assertEq(m.get(-key), 17);
assertEq(m.get(NaN), 17);
m.delete(key);
assertEq(m.has(key), false);
assertEq(m.has(-key), false);
assertEq(m.has(NaN), false);
/******************************************************************************/
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");

View File

View File

@ -0,0 +1,2 @@
url-prefix ../../jsreftest.html?test=ecma_6/Map/
script NaN-as-key.js

View File

View File

@ -0,0 +1,56 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
//-----------------------------------------------------------------------------
var BUGNUMBER = 722260;
var summary = 'All NaNs must be treated as identical keys for Set';
print(BUGNUMBER + ": " + summary);
/**************
* BEGIN TEST *
**************/
/* Avoid constant-folding that would happen were |undefined| to be used. */
var key = -/a/g.missingProperty;
var s = new Set();
s.add(key, 17);
assertEq(s.has(key), true);
assertEq(s.has(-key), true);
assertEq(s.has(NaN), true);
s.delete(-key);
assertEq(s.has(key), false);
assertEq(s.has(-key), false);
assertEq(s.has(NaN), false);
s.add(-key, 17);
assertEq(s.has(key), true);
assertEq(s.has(-key), true);
assertEq(s.has(NaN), true);
s.delete(NaN);
assertEq(s.has(key), false);
assertEq(s.has(-key), false);
assertEq(s.has(NaN), false);
s.add(NaN, 17);
assertEq(s.has(key), true);
assertEq(s.has(-key), true);
assertEq(s.has(NaN), true);
s.delete(key);
assertEq(s.has(key), false);
assertEq(s.has(-key), false);
assertEq(s.has(NaN), false);
/******************************************************************************/
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");

View File

View File

@ -0,0 +1,2 @@
url-prefix ../../jsreftest.html?test=ecma_6/Set/
script NaN-as-key.js

View File

View File

View File

@ -0,0 +1,2 @@
include Map/jstests.list
include Set/jstests.list

View File

View File

@ -1,9 +1,12 @@
# If you add a new test subdirectory here, you *must* add it to Makefile.in as
# well, or tinderbox will go up in flames. YOU HAVE BEEN WARNED.
include e4x/jstests.list
include ecma/jstests.list
include ecma_2/jstests.list
include ecma_3/jstests.list
include ecma_3_1/jstests.list
include ecma_5/jstests.list
include ecma_6/jstests.list
include js1_1/jstests.list
include js1_2/jstests.list
include js1_3/jstests.list