Commit b449691d authored by rossberg@chromium.org's avatar rossberg@chromium.org

ES6 symbols: fix corner cases of equality operators

R=mstarzinger@chromium.org
BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14128 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a172a5e8
......@@ -2508,7 +2508,10 @@ void Name::set_hash_field(uint32_t value) {
bool Name::Equals(Name* other) {
if (other == this) return true;
if (this->IsUniqueName() && other->IsUniqueName()) return false;
if (this->IsSymbol() || other->IsSymbol() ||
(this->IsInternalizedString() && other->IsInternalizedString())) {
return false;
}
return String::cast(this)->SlowEquals(String::cast(other));
}
......
......@@ -98,6 +98,10 @@ MaybeObject* Object::ToObject() {
Isolate* isolate = HeapObject::cast(this)->GetIsolate();
Context* native_context = isolate->context()->native_context();
return CreateJSValue(native_context->string_function(), this);
} else if (IsSymbol()) {
Isolate* isolate = HeapObject::cast(this)->GetIsolate();
Context* native_context = isolate->context()->native_context();
return CreateJSValue(native_context->symbol_function(), this);
}
// Throw a type error.
......
......@@ -69,16 +69,24 @@ function EQUALS(y) {
} else if (IS_STRING(x)) {
while (true) {
if (IS_STRING(y)) return %StringEquals(x, y);
if (IS_SYMBOL(y)) return 1; // not equal
if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
if (IS_BOOLEAN(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal
y = %ToPrimitive(y, NO_HINT);
}
} else if (IS_SYMBOL(x)) {
while (true) {
if (IS_SYMBOL(y)) return %_ObjectEquals(x, y) ? 0 : 1;
if (!IS_SPEC_OBJECT(y)) return 1; // not equal
y = %ToPrimitive(y, NO_HINT);
}
} else if (IS_BOOLEAN(x)) {
if (IS_BOOLEAN(y)) return %_ObjectEquals(x, y) ? 0 : 1;
if (IS_NULL_OR_UNDEFINED(y)) return 1;
if (IS_NUMBER(y)) return %NumberEquals(%ToNumber(x), y);
if (IS_STRING(y)) return %NumberEquals(%ToNumber(x), %ToNumber(y));
if (IS_SYMBOL(y)) return 1; // not equal
// y is object.
x = %ToNumber(x);
y = %ToPrimitive(y, NO_HINT);
......@@ -508,6 +516,7 @@ function ToPrimitive(x, hint) {
if (IS_STRING(x)) return x;
// Normal behavior.
if (!IS_SPEC_OBJECT(x)) return x;
if (IS_SYMBOL_WRAPPER(x)) return %_ValueOf(x);
if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT;
return (hint == NUMBER_HINT) ? %DefaultNumber(x) : %DefaultString(x);
}
......
......@@ -131,13 +131,17 @@ TestToNumber()
function TestEquality() {
// Every symbol should equal itself.
// Every symbol should equal itself, and non-strictly equal its wrapper.
for (var i in symbols) {
assertSame(symbols[i], symbols[i])
assertEquals(symbols[i], symbols[i])
assertTrue(Object.is(symbols[i], symbols[i]))
assertTrue(symbols[i] === symbols[i])
assertTrue(symbols[i] == symbols[i])
assertFalse(symbols[i] === new Symbol(symbols[i]))
assertFalse(new Symbol(symbols[i]) === symbols[i])
assertTrue(symbols[i] == new Symbol(symbols[i]))
assertTrue(new Symbol(symbols[i]) == symbols[i])
}
// All symbols should be distinct.
......@@ -148,6 +152,17 @@ function TestEquality() {
assertFalse(symbols[i] == symbols[j])
}
}
// Symbols should not be equal to any other value (and the test terminates).
var values = [347, 1.275, NaN, "string", null, undefined, {}, function() {}]
for (var i in symbols) {
for (var j in values) {
assertFalse(symbols[i] === values[j])
assertFalse(values[j] === symbols[i])
assertFalse(symbols[i] == values[j])
assertFalse(values[j] == symbols[i])
}
}
}
TestEquality()
......
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