Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(753)

Unified Diff: src/objects.cc

Issue 1337993005: [runtime] Replace the EQUALS builtin with proper Object::Equals. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address Michi's nit. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index a7c3d7610c42ad192c2396cba4dedea79370ec67..91aa2ae250360535fb89e37dcd6f79f394cc4f3f 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -98,13 +98,13 @@ MaybeHandle<Object> Object::ToNumber(Handle<Object> input) {
if (input->IsNumber()) {
return input;
}
- Isolate* const isolate = Handle<HeapObject>::cast(input)->GetIsolate();
- if (input->IsOddball()) {
- return handle(Handle<Oddball>::cast(input)->to_number(), isolate);
- }
if (input->IsString()) {
return String::ToNumber(Handle<String>::cast(input));
}
+ if (input->IsOddball()) {
+ return Oddball::ToNumber(Handle<Oddball>::cast(input));
+ }
+ Isolate* const isolate = Handle<HeapObject>::cast(input)->GetIsolate();
if (input->IsSymbol()) {
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber),
Object);
@@ -159,13 +159,114 @@ bool Object::BooleanValue() {
}
+namespace {
+
+// TODO(bmeurer): Maybe we should introduce a marker interface Number,
+// where we put all these methods at some point?
+bool NumberEquals(double x, double y) {
+ // Must check explicitly for NaN's on Windows, but -0 works fine.
+ if (std::isnan(x)) return false;
+ if (std::isnan(y)) return false;
+ return x == y;
+}
+
+
+bool NumberEquals(const Object* x, const Object* y) {
+ return NumberEquals(x->Number(), y->Number());
+}
+
+
+bool NumberEquals(Handle<Object> x, Handle<Object> y) {
+ return NumberEquals(*x, *y);
+}
+
+} // namespace
+
+
+// static
+Maybe<bool> Object::Equals(Handle<Object> x, Handle<Object> y) {
+ while (true) {
+ if (x->IsNumber()) {
+ if (y->IsNumber()) {
+ return Just(NumberEquals(x, y));
+ } else if (y->IsBoolean()) {
+ return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
+ } else if (y->IsString()) {
+ return Just(NumberEquals(x, String::ToNumber(Handle<String>::cast(y))));
+ } else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
+ if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
+ .ToHandle(&y)) {
+ return Nothing<bool>();
+ }
+ } else {
+ return Just(false);
+ }
+ } else if (x->IsString()) {
+ if (y->IsString()) {
+ return Just(
+ String::Equals(Handle<String>::cast(x), Handle<String>::cast(y)));
+ } else if (y->IsNumber()) {
+ x = String::ToNumber(Handle<String>::cast(x));
+ return Just(NumberEquals(x, y));
+ } else if (y->IsBoolean()) {
+ x = String::ToNumber(Handle<String>::cast(x));
+ return Just(NumberEquals(*x, Handle<Oddball>::cast(y)->to_number()));
+ } else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
+ if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
+ .ToHandle(&y)) {
+ return Nothing<bool>();
+ }
+ } else {
+ return Just(false);
+ }
+ } else if (x->IsBoolean()) {
+ if (y->IsOddball()) {
+ return Just(x.is_identical_to(y));
+ } else if (y->IsNumber()) {
+ return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
+ } else if (y->IsString()) {
+ y = String::ToNumber(Handle<String>::cast(y));
+ return Just(NumberEquals(Handle<Oddball>::cast(x)->to_number(), *y));
+ } else if (y->IsJSReceiver() && !y->IsUndetectableObject()) {
+ if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y))
+ .ToHandle(&y)) {
+ return Nothing<bool>();
+ }
+ x = Oddball::ToNumber(Handle<Oddball>::cast(x));
+ } else {
+ return Just(false);
+ }
+ } else if (x->IsSymbol()) {
+ return Just(x.is_identical_to(y));
+ } else if (x->IsSimd128Value()) {
+ if (!y->IsSimd128Value()) return Just(false);
+ return Just(Simd128Value::Equals(Handle<Simd128Value>::cast(x),
+ Handle<Simd128Value>::cast(y)));
+ } else if (x->IsJSReceiver() && !x->IsUndetectableObject()) {
+ if (y->IsJSReceiver()) {
+ return Just(x.is_identical_to(y));
+ } else if (y->IsNull() || y->IsSimd128Value() || y->IsSymbol() ||
+ y->IsUndefined()) {
+ return Just(false);
+ } else if (y->IsBoolean()) {
+ y = Oddball::ToNumber(Handle<Oddball>::cast(y));
+ }
+ if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(x)).ToHandle(&x)) {
+ return Nothing<bool>();
+ }
+ } else {
+ return Just(
+ (x->IsNull() || x->IsUndefined() || x->IsUndetectableObject()) &&
+ (y->IsNull() || y->IsUndefined() || y->IsUndetectableObject()));
+ }
+ }
+}
+
+
bool Object::StrictEquals(Object* that) {
if (this->IsNumber()) {
if (!that->IsNumber()) return false;
- double const x = this->Number();
- double const y = that->Number();
- // Must check explicitly for NaN:s on Windows, but -0 works fine.
- return x == y && !std::isnan(x) && !std::isnan(y);
+ return NumberEquals(this, that);
} else if (this->IsString()) {
if (!that->IsString()) return false;
return String::cast(this)->Equals(String::cast(that));
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698