From: bmeurer Date: Tue, 15 Sep 2015 13:14:36 +0000 (-0700) Subject: [runtime] Replace the EQUALS builtin with proper Object::Equals. X-Git-Tag: upstream/4.7.83~293 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=54bab695f5de5bf5948c5b50b217628a00d60f91;p=platform%2Fupstream%2Fv8.git [runtime] Replace the EQUALS builtin with proper Object::Equals. Move the implementation of the Abstract Equality Comparison to the runtime and thereby remove the EQUALS dispatcher builtin. Also remove the various runtime entry points that were only used to support the EQUALS builtin. Now the Abstract Equality Comparison is also using the correct ToPrimitive implementation, which properly supports @@toPrimitive. CQ_INCLUDE_TRYBOTS=tryserver.v8:v8_linux_layout_dbg,v8_linux_nosnap_dbg R=mstarzinger@chromium.org BUG=v8:4307 LOG=n Review URL: https://codereview.chromium.org/1337993005 Cr-Commit-Position: refs/heads/master@{#30747} --- diff --git a/src/api.cc b/src/api.cc index 8cceb65a2..1b5d428a3 100644 --- a/src/api.cc +++ b/src/api.cc @@ -3365,21 +3365,7 @@ Local Value::ToArrayIndex() const { Maybe Value::Equals(Local context, Local that) const { auto self = Utils::OpenHandle(this); auto other = Utils::OpenHandle(*that); - if (self->IsSmi() && other->IsSmi()) { - return Just(self->Number() == other->Number()); - } - if (self->IsJSObject() && other->IsJSObject()) { - return Just(*self == *other); - } - PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Value::Equals()", bool); - i::Handle args[] = { other }; - i::Handle fun = isolate->equals_builtin(); - i::Handle result; - has_pending_exception = - !i::Execution::Call(isolate, fun, self, arraysize(args), args) - .ToHandle(&result); - RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); - return Just(*result == i::Smi::FromInt(i::EQUAL)); + return i::Object::Equals(self, other); } diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 907bdaced..f6b08bd87 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -681,26 +681,22 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { __ Push(lhs, rhs); // Figure out which native to call and setup the arguments. - if (cc == eq && strict()) { - __ TailCallRuntime(Runtime::kStrictEquals, 2, 1); + if (cc == eq) { + __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals, 2, + 1); } else { - int context_index; - if (cc == eq) { - context_index = Context::EQUALS_BUILTIN_INDEX; + int context_index = is_strong(strength()) + ? Context::COMPARE_STRONG_BUILTIN_INDEX + : Context::COMPARE_BUILTIN_INDEX; + int ncr; // NaN compare result + if (cc == lt || cc == le) { + ncr = GREATER; } else { - context_index = is_strong(strength()) - ? Context::COMPARE_STRONG_BUILTIN_INDEX - : Context::COMPARE_BUILTIN_INDEX; - int ncr; // NaN compare result - if (cc == lt || cc == le) { - ncr = GREATER; - } else { - DCHECK(cc == gt || cc == ge); // remaining cases - ncr = LESS; - } - __ mov(r0, Operand(Smi::FromInt(ncr))); - __ push(r0); + DCHECK(cc == gt || cc == ge); // remaining cases + ncr = LESS; } + __ mov(r0, Operand(Smi::FromInt(ncr))); + __ push(r0); // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) // tagged as a small integer. diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc index 98dbb9cd1..cc198b8cf 100644 --- a/src/arm64/code-stubs-arm64.cc +++ b/src/arm64/code-stubs-arm64.cc @@ -652,26 +652,22 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { __ Push(lhs, rhs); // Figure out which native to call and setup the arguments. - if (cond == eq && strict()) { - __ TailCallRuntime(Runtime::kStrictEquals, 2, 1); + if (cond == eq) { + __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals, 2, + 1); } else { - int context_index; - if (cond == eq) { - context_index = Context::EQUALS_BUILTIN_INDEX; + int context_index = is_strong(strength()) + ? Context::COMPARE_STRONG_BUILTIN_INDEX + : Context::COMPARE_BUILTIN_INDEX; + int ncr; // NaN compare result + if ((cond == lt) || (cond == le)) { + ncr = GREATER; } else { - context_index = is_strong(strength()) - ? Context::COMPARE_STRONG_BUILTIN_INDEX - : Context::COMPARE_BUILTIN_INDEX; - int ncr; // NaN compare result - if ((cond == lt) || (cond == le)) { - ncr = GREATER; - } else { - DCHECK((cond == gt) || (cond == ge)); // remaining cases - ncr = LESS; - } - __ Mov(x10, Smi::FromInt(ncr)); - __ Push(x10); + DCHECK((cond == gt) || (cond == ge)); // remaining cases + ncr = LESS; } + __ Mov(x10, Smi::FromInt(ncr)); + __ Push(x10); // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) // tagged as a small integer. diff --git a/src/contexts.h b/src/contexts.h index dd5e1add8..70e6ccfa6 100644 --- a/src/contexts.h +++ b/src/contexts.h @@ -96,7 +96,6 @@ enum BindingFlags { V(COMPARE_STRONG_BUILTIN_INDEX, JSFunction, compare_strong_builtin) \ V(CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX, JSFunction, \ concat_iterable_to_array_builtin) \ - V(EQUALS_BUILTIN_INDEX, JSFunction, equals_builtin) \ V(REFLECT_APPLY_PREPARE_BUILTIN_INDEX, JSFunction, \ reflect_apply_prepare_builtin) \ V(REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX, JSFunction, \ diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 4fcdabc8c..b9dc33f4e 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -1867,19 +1867,15 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { __ push(eax); // Figure out which native to call and setup the arguments. - if (cc == equal && strict()) { + if (cc == equal) { __ push(ecx); - __ TailCallRuntime(Runtime::kStrictEquals, 2, 1); + __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals, 2, + 1); } else { - int native_context_index; - if (cc == equal) { - native_context_index = Context::EQUALS_BUILTIN_INDEX; - } else { - native_context_index = is_strong(strength()) - ? Context::COMPARE_STRONG_BUILTIN_INDEX - : Context::COMPARE_BUILTIN_INDEX; - __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc)))); - } + int native_context_index = is_strong(strength()) + ? Context::COMPARE_STRONG_BUILTIN_INDEX + : Context::COMPARE_BUILTIN_INDEX; + __ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc)))); // Restore return address on the stack. __ push(ecx); diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 955a87e1c..76a577c79 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -727,26 +727,22 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { // a1 (rhs) second. __ Push(lhs, rhs); // Figure out which native to call and setup the arguments. - if (cc == eq && strict()) { - __ TailCallRuntime(Runtime::kStrictEquals, 2, 1); + if (cc == eq) { + __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals, 2, + 1); } else { - int context_index; - if (cc == eq) { - context_index = Context::EQUALS_BUILTIN_INDEX; + int context_index = is_strong(strength()) + ? Context::COMPARE_STRONG_BUILTIN_INDEX + : Context::COMPARE_BUILTIN_INDEX; + int ncr; // NaN compare result. + if (cc == lt || cc == le) { + ncr = GREATER; } else { - context_index = is_strong(strength()) - ? Context::COMPARE_STRONG_BUILTIN_INDEX - : Context::COMPARE_BUILTIN_INDEX; - int ncr; // NaN compare result. - if (cc == lt || cc == le) { - ncr = GREATER; - } else { - DCHECK(cc == gt || cc == ge); // Remaining cases. - ncr = LESS; - } - __ li(a0, Operand(Smi::FromInt(ncr))); - __ push(a0); + DCHECK(cc == gt || cc == ge); // Remaining cases. + ncr = LESS; } + __ li(a0, Operand(Smi::FromInt(ncr))); + __ push(a0); // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) // tagged as a small integer. diff --git a/src/mips64/code-stubs-mips64.cc b/src/mips64/code-stubs-mips64.cc index f2e751afd..187f91259 100644 --- a/src/mips64/code-stubs-mips64.cc +++ b/src/mips64/code-stubs-mips64.cc @@ -722,26 +722,22 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { // a1 (rhs) second. __ Push(lhs, rhs); // Figure out which native to call and setup the arguments. - if (cc == eq && strict()) { - __ TailCallRuntime(Runtime::kStrictEquals, 2, 1); + if (cc == eq) { + __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals, 2, + 1); } else { - int context_index; - if (cc == eq) { - context_index = Context::EQUALS_BUILTIN_INDEX; + int context_index = is_strong(strength()) + ? Context::COMPARE_STRONG_BUILTIN_INDEX + : Context::COMPARE_BUILTIN_INDEX; + int ncr; // NaN compare result. + if (cc == lt || cc == le) { + ncr = GREATER; } else { - context_index = is_strong(strength()) - ? Context::COMPARE_STRONG_BUILTIN_INDEX - : Context::COMPARE_BUILTIN_INDEX; - int ncr; // NaN compare result. - if (cc == lt || cc == le) { - ncr = GREATER; - } else { - DCHECK(cc == gt || cc == ge); // Remaining cases. - ncr = LESS; - } - __ li(a0, Operand(Smi::FromInt(ncr))); - __ push(a0); + DCHECK(cc == gt || cc == ge); // Remaining cases. + ncr = LESS; } + __ li(a0, Operand(Smi::FromInt(ncr))); + __ push(a0); // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) // tagged as a small integer. diff --git a/src/objects-inl.h b/src/objects-inl.h index f37671bed..979020869 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1082,11 +1082,11 @@ bool Object::IsArgumentsMarker() const { } -double Object::Number() { +double Object::Number() const { DCHECK(IsNumber()); return IsSmi() - ? static_cast(reinterpret_cast(this)->value()) - : reinterpret_cast(this)->value(); + ? static_cast(reinterpret_cast(this)->value()) + : reinterpret_cast(this)->value(); } @@ -1567,6 +1567,12 @@ bool Simd128Value::Equals(Simd128Value* that) { } +// static +bool Simd128Value::Equals(Handle one, Handle two) { + return one->Equals(*two); +} + + #define SIMD128_VALUE_EQUALS(TYPE, Type, type, lane_count, lane_type) \ bool Type::Equals(Type* that) { \ for (int lane = 0; lane < lane_count; ++lane) { \ @@ -2053,6 +2059,12 @@ void Oddball::set_kind(byte value) { } +// static +Handle Oddball::ToNumber(Handle input) { + return handle(input->to_number(), input->GetIsolate()); +} + + ACCESSORS(Cell, value, Object, kValueOffset) ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset) ACCESSORS(PropertyCell, property_details_raw, Object, kDetailsOffset) diff --git a/src/objects.cc b/src/objects.cc index edb7ee259..a642df0d3 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -98,13 +98,13 @@ MaybeHandle Object::ToNumber(Handle input) { if (input->IsNumber()) { return input; } - Isolate* const isolate = Handle::cast(input)->GetIsolate(); - if (input->IsOddball()) { - return handle(Handle::cast(input)->to_number(), isolate); - } if (input->IsString()) { return String::ToNumber(Handle::cast(input)); } + if (input->IsOddball()) { + return Oddball::ToNumber(Handle::cast(input)); + } + Isolate* const isolate = Handle::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 x, Handle y) { + return NumberEquals(*x, *y); +} + +} // namespace + + +// static +Maybe Object::Equals(Handle x, Handle y) { + while (true) { + if (x->IsNumber()) { + if (y->IsNumber()) { + return Just(NumberEquals(x, y)); + } else if (y->IsBoolean()) { + return Just(NumberEquals(*x, Handle::cast(y)->to_number())); + } else if (y->IsString()) { + return Just(NumberEquals(x, String::ToNumber(Handle::cast(y)))); + } else if (y->IsJSReceiver() && !y->IsUndetectableObject()) { + if (!JSReceiver::ToPrimitive(Handle::cast(y)) + .ToHandle(&y)) { + return Nothing(); + } + } else { + return Just(false); + } + } else if (x->IsString()) { + if (y->IsString()) { + return Just( + String::Equals(Handle::cast(x), Handle::cast(y))); + } else if (y->IsNumber()) { + x = String::ToNumber(Handle::cast(x)); + return Just(NumberEquals(x, y)); + } else if (y->IsBoolean()) { + x = String::ToNumber(Handle::cast(x)); + return Just(NumberEquals(*x, Handle::cast(y)->to_number())); + } else if (y->IsJSReceiver() && !y->IsUndetectableObject()) { + if (!JSReceiver::ToPrimitive(Handle::cast(y)) + .ToHandle(&y)) { + return Nothing(); + } + } 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::cast(x)->to_number(), *y)); + } else if (y->IsString()) { + y = String::ToNumber(Handle::cast(y)); + return Just(NumberEquals(Handle::cast(x)->to_number(), *y)); + } else if (y->IsJSReceiver() && !y->IsUndetectableObject()) { + if (!JSReceiver::ToPrimitive(Handle::cast(y)) + .ToHandle(&y)) { + return Nothing(); + } + x = Oddball::ToNumber(Handle::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::cast(x), + Handle::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::cast(y)); + } + if (!JSReceiver::ToPrimitive(Handle::cast(x)).ToHandle(&x)) { + return Nothing(); + } + } 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)); diff --git a/src/objects.h b/src/objects.h index 9797f0427..9e773c036 100644 --- a/src/objects.h +++ b/src/objects.h @@ -1048,7 +1048,7 @@ class Object { INLINE(bool IsFiller() const); // Extract the number. - inline double Number(); + inline double Number() const; INLINE(bool IsNaN() const); INLINE(bool IsMinusZero() const); bool ToInt32(int32_t* value); @@ -1083,6 +1083,9 @@ class Object { bool BooleanValue(); // ECMA-262 9.2. + // ES6 section 7.2.12 Abstract Equality Comparison + MUST_USE_RESULT static Maybe Equals(Handle x, Handle y); + // ES6 section 7.2.13 Strict Equality Comparison bool StrictEquals(Object* that); @@ -1657,6 +1660,7 @@ class Simd128Value : public HeapObject { // Equality operations. inline bool Equals(Simd128Value* that); + static inline bool Equals(Handle one, Handle two); // Checks that another instance is bit-wise equal. bool BitwiseEquals(const Simd128Value* other) const; @@ -9102,6 +9106,9 @@ class Oddball: public HeapObject { inline byte kind() const; inline void set_kind(byte kind); + // ES6 section 7.1.3 ToNumber for Boolean, Null, Undefined. + MUST_USE_RESULT static inline Handle ToNumber(Handle input); + DECLARE_CAST(Oddball) // Dispatched behavior. diff --git a/src/runtime.js b/src/runtime.js index 6df7faa71..fcb9471cd 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -42,68 +42,6 @@ var isConcatSpreadableSymbol = ----------------------------------- */ -// ECMA-262 Section 11.9.3. -function EQUALS(y) { - if (IS_STRING(this) && IS_STRING(y)) return %StringEquals(this, y); - var x = this; - - while (true) { - if (IS_NUMBER(x)) { - while (true) { - if (IS_NUMBER(y)) return %NumberEquals(x, y); - if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal - if (!IS_SPEC_OBJECT(y)) { - if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal - // String or boolean. - return %NumberEquals(x, %to_number_fun(y)); - } - y = %to_primitive(y, NO_HINT); - } - } else if (IS_STRING(x)) { - while (true) { - if (IS_STRING(y)) return %StringEquals(x, y); - if (IS_NUMBER(y)) return %NumberEquals(%to_number_fun(x), y); - if (IS_BOOLEAN(y)) { - return %NumberEquals(%to_number_fun(x), %to_number_fun(y)); - } - if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal - if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal - y = %to_primitive(y, NO_HINT); - } - } else if (IS_SYMBOL(x)) { - if (IS_SYMBOL(y)) return %_ObjectEquals(x, y) ? 0 : 1; - return 1; // not equal - } 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(%to_number_fun(x), y); - if (IS_STRING(y)) { - return %NumberEquals(%to_number_fun(x), %to_number_fun(y)); - } - if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) return 1; // not equal - // y is object. - x = %to_number_fun(x); - y = %to_primitive(y, NO_HINT); - } else if (IS_NULL_OR_UNDEFINED(x)) { - return IS_NULL_OR_UNDEFINED(y) ? 0 : 1; - } else if (IS_SIMD_VALUE(x)) { - if (!IS_SIMD_VALUE(y)) return 1; // not equal - return %SimdEquals(x, y); - } else { - // x is an object. - if (IS_SPEC_OBJECT(y)) return %_ObjectEquals(x, y) ? 0 : 1; - if (IS_NULL_OR_UNDEFINED(y)) return 1; // not equal - if (IS_BOOLEAN(y)) { - y = %to_number_fun(y); - } else if (IS_SYMBOL(y) || IS_SIMD_VALUE(y)) { - return 1; // not equal - } - x = %to_primitive(x, NO_HINT); - } - } -} - - // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as // the result when either (or both) the operands are NaN. function COMPARE(x, ncr) { @@ -498,7 +436,6 @@ $toString = ToString; "compare_builtin", COMPARE, "compare_strong_builtin", COMPARE_STRONG, "concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY, - "equals_builtin", EQUALS, "reflect_apply_prepare_builtin", REFLECT_APPLY_PREPARE, "reflect_construct_prepare_builtin", REFLECT_CONSTRUCT_PREPARE, ]); diff --git a/src/runtime/runtime-numbers.cc b/src/runtime/runtime-numbers.cc index 75c8065cd..bcdd89f14 100644 --- a/src/runtime/runtime-numbers.cc +++ b/src/runtime/runtime-numbers.cc @@ -11,8 +11,7 @@ #ifndef _STLP_VENDOR_CSTD -// STLPort doesn't import fpclassify and isless into the std namespace. -using std::fpclassify; +// STLPort doesn't import isless into the std namespace. using std::isless; #endif @@ -233,25 +232,6 @@ RUNTIME_FUNCTION(Runtime_NumberImul) { } -RUNTIME_FUNCTION(Runtime_NumberEquals) { - SealHandleScope shs(isolate); - DCHECK(args.length() == 2); - - CONVERT_DOUBLE_ARG_CHECKED(x, 0); - CONVERT_DOUBLE_ARG_CHECKED(y, 1); - if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL); - if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL); - if (x == y) return Smi::FromInt(EQUAL); - Object* result; - if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) { - result = Smi::FromInt(EQUAL); - } else { - result = Smi::FromInt(NOT_EQUAL); - } - return result; -} - - RUNTIME_FUNCTION(Runtime_NumberCompare) { SealHandleScope shs(isolate); DCHECK(args.length() == 3); @@ -362,5 +342,6 @@ RUNTIME_FUNCTION(Runtime_GetRootNaN) { DCHECK(args.length() == 0); return isolate->heap()->nan_value(); } + } // namespace internal } // namespace v8 diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc index 75d09a8ee..0c6f81306 100644 --- a/src/runtime/runtime-object.cc +++ b/src/runtime/runtime-object.cc @@ -1478,6 +1478,18 @@ RUNTIME_FUNCTION(Runtime_ToName) { } +RUNTIME_FUNCTION(Runtime_Equals) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, x, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, y, 1); + Maybe result = Object::Equals(x, y); + if (!result.IsJust()) return isolate->heap()->exception(); + // TODO(bmeurer): Change this at some point to return true/false instead. + return Smi::FromInt(result.FromJust() ? EQUAL : NOT_EQUAL); +} + + RUNTIME_FUNCTION(Runtime_StrictEquals) { SealHandleScope scope(isolate); DCHECK_EQ(2, args.length()); diff --git a/src/runtime/runtime-simd.cc b/src/runtime/runtime-simd.cc index 7ec97371c..bed866fac 100644 --- a/src/runtime/runtime-simd.cc +++ b/src/runtime/runtime-simd.cc @@ -172,23 +172,6 @@ RUNTIME_FUNCTION(Runtime_IsSimdValue) { } -RUNTIME_FUNCTION(Runtime_SimdToObject) { - HandleScope scope(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(Simd128Value, value, 0); - return *Object::ToObject(isolate, value).ToHandleChecked(); -} - - -RUNTIME_FUNCTION(Runtime_SimdEquals) { - SealHandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_CHECKED(Simd128Value, x, 0); - CONVERT_ARG_CHECKED(Simd128Value, y, 1); - return Smi::FromInt(x->Equals(y) ? EQUAL : NOT_EQUAL); -} - - RUNTIME_FUNCTION(Runtime_SimdSameValue) { HandleScope scope(isolate); DCHECK(args.length() == 2); diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 2b437da91..4774073d4 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -407,7 +407,6 @@ namespace internal { F(NumberToIntegerMapMinusZero, 1, 1) \ F(NumberToSmi, 1, 1) \ F(NumberImul, 2, 1) \ - F(NumberEquals, 2, 1) \ F(NumberCompare, 3, 1) \ F(SmiLexicographicCompare, 2, 1) \ F(MaxSmi, 0, 1) \ @@ -480,6 +479,7 @@ namespace internal { F(ToNumber, 1, 1) \ F(ToString, 1, 1) \ F(ToName, 1, 1) \ + F(Equals, 2, 1) \ F(StrictEquals, 2, 1) \ F(InstanceOf, 2, 1) \ F(HasInPrototypeChain, 2, 1) \ @@ -576,8 +576,6 @@ namespace internal { #define FOR_EACH_INTRINSIC_SIMD(F) \ F(IsSimdValue, 1, 1) \ - F(SimdToObject, 1, 1) \ - F(SimdEquals, 2, 1) \ F(SimdSameValue, 2, 1) \ F(SimdSameValueZero, 2, 1) \ F(CreateFloat32x4, 4, 1) \ diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index ff8d4be19..7000e1ddc 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -1734,20 +1734,15 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) { __ Push(rax); // Figure out which native to call and setup the arguments. - if (cc == equal && strict()) { + if (cc == equal) { __ PushReturnAddressFrom(rcx); - __ TailCallRuntime(Runtime::kStrictEquals, 2, 1); + __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals, 2, + 1); } else { - int context_index; - if (cc == equal) { - context_index = Context::EQUALS_BUILTIN_INDEX; - } else { - context_index = is_strong(strength()) - ? Context::COMPARE_STRONG_BUILTIN_INDEX - : Context::COMPARE_BUILTIN_INDEX; - __ Push(Smi::FromInt(NegativeComparisonResult(cc))); - } - + int context_index = is_strong(strength()) + ? Context::COMPARE_STRONG_BUILTIN_INDEX + : Context::COMPARE_BUILTIN_INDEX; + __ Push(Smi::FromInt(NegativeComparisonResult(cc))); __ PushReturnAddressFrom(rcx); // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)