Update to ES2015 == semantics for Symbol/SIMD wrappers
When == is invoked on a Symbol or SIMD vector and an object, the object should be converted to a primitive with ToPrimitive and then compared again. This means, for example, that for a Symbol or SIMD vector s, s == Object(s). This patch makes that change in the implementation of ==. Only the runtime function needed to be changed, as the code stubs and compiler specializations don't operate on Symbols or SIMD vectors, and on these types, a fallback to the runtime function is always used. BUG=v8:3593 LOG=Y R=adamk Review URL: https://codereview.chromium.org/1421413002 Cr-Commit-Position: refs/heads/master@{#31614}
This commit is contained in:
parent
f8465b45f7
commit
b436635ac4
@ -291,8 +291,9 @@ Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) {
|
|||||||
} else if (y->IsString()) {
|
} else if (y->IsString()) {
|
||||||
return Just(NumberEquals(x, String::ToNumber(Handle<String>::cast(y))));
|
return Just(NumberEquals(x, String::ToNumber(Handle<String>::cast(y))));
|
||||||
} else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
|
} else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
|
||||||
if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
|
if (JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y)).ToHandle(&y)) {
|
||||||
.ToHandle(&y)) {
|
continue;
|
||||||
|
} else {
|
||||||
return Nothing<bool>();
|
return Nothing<bool>();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -309,8 +310,9 @@ Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) {
|
|||||||
x = String::ToNumber(Handle<String>::cast(x));
|
x = String::ToNumber(Handle<String>::cast(x));
|
||||||
return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
|
return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
|
||||||
} else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
|
} else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
|
||||||
if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
|
if (JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y)).ToHandle(&y)) {
|
||||||
.ToHandle(&y)) {
|
continue;
|
||||||
|
} else {
|
||||||
return Nothing<bool>();
|
return Nothing<bool>();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -330,25 +332,47 @@ Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) {
|
|||||||
return Nothing<bool>();
|
return Nothing<bool>();
|
||||||
}
|
}
|
||||||
x = Oddball::ToNumber(Handle<Oddball>::cast(x));
|
x = Oddball::ToNumber(Handle<Oddball>::cast(x));
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
return Just(false);
|
return Just(false);
|
||||||
}
|
}
|
||||||
} else if (x->IsSymbol()) {
|
} else if (x->IsSymbol()) {
|
||||||
|
if (y->IsSymbol()) {
|
||||||
return Just(x.is_identical_to(y));
|
return Just(x.is_identical_to(y));
|
||||||
|
} else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
|
||||||
|
if (JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y)).ToHandle(&y)) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return Nothing<bool>();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Just(false);
|
||||||
|
}
|
||||||
} else if (x->IsSimd128Value()) {
|
} else if (x->IsSimd128Value()) {
|
||||||
if (!y->IsSimd128Value()) return Just(false);
|
if (y->IsSimd128Value()) {
|
||||||
return Just(Simd128Value::Equals(Handle<Simd128Value>::cast(x),
|
return Just(Simd128Value::Equals(Handle<Simd128Value>::cast(x),
|
||||||
Handle<Simd128Value>::cast(y)));
|
Handle<Simd128Value>::cast(y)));
|
||||||
|
} else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
|
||||||
|
if (JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y)).ToHandle(&y)) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
return Nothing<bool>();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Just(false);
|
||||||
|
}
|
||||||
} else if (x->IsJSReceiver() && !x->IsUndetectableObject()) {
|
} else if (x->IsJSReceiver() && !x->IsUndetectableObject()) {
|
||||||
if (y->IsJSReceiver()) {
|
if (y->IsJSReceiver()) {
|
||||||
return Just(x.is_identical_to(y));
|
return Just(x.is_identical_to(y));
|
||||||
} else if (y->IsNull() || y->IsSimd128Value() || y->IsSymbol() ||
|
} else if (y->IsNull() || y->IsUndefined()) {
|
||||||
y->IsUndefined()) {
|
|
||||||
return Just(false);
|
return Just(false);
|
||||||
} else if (y->IsBoolean()) {
|
} else if (y->IsBoolean()) {
|
||||||
y = Oddball::ToNumber(Handle<Oddball>::cast(y));
|
y = Oddball::ToNumber(Handle<Oddball>::cast(y));
|
||||||
}
|
continue;
|
||||||
if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(x)).ToHandle(&x)) {
|
} else if (JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(x))
|
||||||
|
.ToHandle(&x)) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
return Nothing<bool>();
|
return Nothing<bool>();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -356,6 +380,7 @@ Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) {
|
|||||||
(x->IsNull() || x->IsUndefined() || x->IsUndetectableObject()) &&
|
(x->IsNull() || x->IsUndefined() || x->IsUndetectableObject()) &&
|
||||||
(y->IsNull() || y->IsUndefined() || y->IsUndetectableObject()));
|
(y->IsNull() || y->IsUndefined() || y->IsUndetectableObject()));
|
||||||
}
|
}
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2366,7 +2366,7 @@ THREADED_TEST(SymbolProperties) {
|
|||||||
CHECK(sym_obj->IsSymbolObject());
|
CHECK(sym_obj->IsSymbolObject());
|
||||||
CHECK(!sym2->IsSymbolObject());
|
CHECK(!sym2->IsSymbolObject());
|
||||||
CHECK(!obj->IsSymbolObject());
|
CHECK(!obj->IsSymbolObject());
|
||||||
CHECK(!sym_obj->Equals(sym2));
|
CHECK(sym_obj->Equals(sym2));
|
||||||
CHECK(!sym_obj->StrictEquals(sym2));
|
CHECK(!sym_obj->StrictEquals(sym2));
|
||||||
CHECK(v8::SymbolObject::Cast(*sym_obj)->Equals(sym_obj));
|
CHECK(v8::SymbolObject::Cast(*sym_obj)->Equals(sym_obj));
|
||||||
CHECK(v8::SymbolObject::Cast(*sym_obj)->ValueOf()->Equals(sym2));
|
CHECK(v8::SymbolObject::Cast(*sym_obj)->ValueOf()->Equals(sym2));
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Flags: --harmony-simd
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test uses assert{True,False}(... == ...) instead of
|
* This test uses assert{True,False}(... == ...) instead of
|
||||||
* assertEquals(..., ...) to not rely on the details of the
|
* assertEquals(..., ...) to not rely on the details of the
|
||||||
@ -234,3 +236,15 @@ function testBadConversion(value) {
|
|||||||
testBadConversion(0);
|
testBadConversion(0);
|
||||||
testBadConversion("string");
|
testBadConversion("string");
|
||||||
testBadConversion(true);
|
testBadConversion(true);
|
||||||
|
|
||||||
|
var s = Symbol();
|
||||||
|
testEqual(s, s);
|
||||||
|
testEqual(Object(s), s);
|
||||||
|
testEqual(new Wrapper(s), s);
|
||||||
|
testNotEqual(Object(s), Object(s));
|
||||||
|
|
||||||
|
var simd = SIMD.Float32x4(1, 2, 3, 4);
|
||||||
|
testEqual(simd, simd);
|
||||||
|
testEqual(Object(simd), simd);
|
||||||
|
testEqual(new Wrapper(simd), simd);
|
||||||
|
testNotEqual(Object(simd), Object(simd));
|
||||||
|
@ -167,8 +167,8 @@ function TestEquality() {
|
|||||||
assertTrue(symbols[i] == symbols[i])
|
assertTrue(symbols[i] == symbols[i])
|
||||||
assertFalse(symbols[i] === Object(symbols[i]))
|
assertFalse(symbols[i] === Object(symbols[i]))
|
||||||
assertFalse(Object(symbols[i]) === symbols[i])
|
assertFalse(Object(symbols[i]) === symbols[i])
|
||||||
assertFalse(symbols[i] == Object(symbols[i]))
|
assertTrue(symbols[i] == Object(symbols[i]))
|
||||||
assertFalse(Object(symbols[i]) == symbols[i])
|
assertTrue(Object(symbols[i]) == symbols[i])
|
||||||
assertTrue(symbols[i] === symbols[i].valueOf())
|
assertTrue(symbols[i] === symbols[i].valueOf())
|
||||||
assertTrue(symbols[i].valueOf() === symbols[i])
|
assertTrue(symbols[i].valueOf() === symbols[i])
|
||||||
assertTrue(symbols[i] == symbols[i].valueOf())
|
assertTrue(symbols[i] == symbols[i].valueOf())
|
||||||
|
@ -132,8 +132,8 @@ function TestEquality() {
|
|||||||
assertTrue(symbols[i] == symbols[i])
|
assertTrue(symbols[i] == symbols[i])
|
||||||
assertFalse(symbols[i] === Object(symbols[i]))
|
assertFalse(symbols[i] === Object(symbols[i]))
|
||||||
assertFalse(Object(symbols[i]) === symbols[i])
|
assertFalse(Object(symbols[i]) === symbols[i])
|
||||||
assertFalse(symbols[i] == Object(symbols[i]))
|
assertTrue(symbols[i] == Object(symbols[i]))
|
||||||
assertFalse(Object(symbols[i]) == symbols[i])
|
assertTrue(Object(symbols[i]) == symbols[i])
|
||||||
assertTrue(symbols[i] === symbols[i].valueOf())
|
assertTrue(symbols[i] === symbols[i].valueOf())
|
||||||
assertTrue(symbols[i].valueOf() === symbols[i])
|
assertTrue(symbols[i].valueOf() === symbols[i])
|
||||||
assertTrue(symbols[i] == symbols[i].valueOf())
|
assertTrue(symbols[i] == symbols[i].valueOf())
|
||||||
|
@ -337,8 +337,8 @@ function TestEquality(type, lanes) {
|
|||||||
assertTrue(instance == instance)
|
assertTrue(instance == instance)
|
||||||
assertFalse(instance === Object(instance))
|
assertFalse(instance === Object(instance))
|
||||||
assertFalse(Object(instance) === instance)
|
assertFalse(Object(instance) === instance)
|
||||||
assertFalse(instance == Object(instance))
|
assertTrue(instance == Object(instance))
|
||||||
assertFalse(Object(instance) == instance)
|
assertTrue(Object(instance) == instance)
|
||||||
assertTrue(instance === instance.valueOf())
|
assertTrue(instance === instance.valueOf())
|
||||||
assertTrue(instance.valueOf() === instance)
|
assertTrue(instance.valueOf() === instance)
|
||||||
assertTrue(instance == instance.valueOf())
|
assertTrue(instance == instance.valueOf())
|
||||||
|
@ -620,9 +620,6 @@
|
|||||||
'intl402/String/prototype/toLocaleUpperCase/special_casing_Lithuanian': [FAIL],
|
'intl402/String/prototype/toLocaleUpperCase/special_casing_Lithuanian': [FAIL],
|
||||||
'intl402/String/prototype/toLocaleUpperCase/special_casing_Turkish': [FAIL],
|
'intl402/String/prototype/toLocaleUpperCase/special_casing_Turkish': [FAIL],
|
||||||
|
|
||||||
# https://code.google.com/p/v8/issues/detail?id=3788
|
|
||||||
'language/expressions/equals/coerce-symbol-to-prim-return-prim': [FAIL],
|
|
||||||
|
|
||||||
######################## NEEDS INVESTIGATION ###########################
|
######################## NEEDS INVESTIGATION ###########################
|
||||||
|
|
||||||
# These test failures are specific to the intl402 suite and need investigation
|
# These test failures are specific to the intl402 suite and need investigation
|
||||||
|
Loading…
Reference in New Issue
Block a user