WebKit Bugzilla
Attachment 339724 Details for
Bug 185379
: [ESNext][BigInt] Implement support for "<" and ">" relational operation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP - Patch
big-int-less.diff (text/plain), 22.03 KB, created by
Caio Lima
on 2018-05-07 08:39:06 PDT
(
hide
)
Description:
WIP - Patch
Filename:
MIME Type:
Creator:
Caio Lima
Created:
2018-05-07 08:39:06 PDT
Size:
22.03 KB
patch
obsolete
>diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index 899e6be..8722be8 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,14 @@ >+2018-04-22 Caio Lima <ticaiolima@gmail.com> >+ >+ [ESNext][BigInt] Implement support for "==" operation >+ https://bugs.webkit.org/show_bug.cgi?id=184474 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/big-int-equals-basic.js: Added. >+ * stress/big-int-equals-to-primitive-precedence.js: Added. >+ * stress/big-int-equals-wrapped-value.js: Added. >+ > 2018-05-05 Caio Lima <ticaiolima@gmail.com> > > [ESNext][BigInt] Implement support for "==" operation >diff --git a/JSTests/stress/big-int-greater-than-general.js b/JSTests/stress/big-int-greater-than-general.js >new file mode 100644 >index 0000000..fbdec33 >--- /dev/null >+++ b/JSTests/stress/big-int-greater-than-general.js >@@ -0,0 +1,45 @@ >+//@ runBigIntEnabled >+ >+// Copyright (C) 2017 Josh Wolfe. All rights reserved. >+// Copyright (C) 2018 Igalia, S.L. All rights reserved. >+// This code is governed by the BSD license found in the LICENSE file. >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+assert(0n > 0n, false, "0n > 0n"); >+assert(1n > 1n, false, "1n > 1n"); >+assert(BigInt("-1") > BigInt("-1"), false, "-1n > -1n"); >+assert(0n > BigInt("-0"), false, "0n > -0n"); >+assert(BigInt("-0") > 0n, false, "-0n > 0n"); >+assert(0n > 1n, false, "0n > 1n"); >+assert(1n > 0n, true, "1n > 0n"); >+assert(0n > BigInt("-1"), true, "0n > -1n"); >+assert(BigInt("-1") > 0n, false, "-1n > 0n"); >+assert(1n > BigInt("-1"), true, "1n > -1n"); >+assert(BigInt("-1") > 1n, false, "-1n > 1n"); >+assert(0x1fffffffffffff01n > 0x1fffffffffffff02n, false, "0x1fffffffffffff01n > 0x1fffffffffffff02n"); >+assert(0x1fffffffffffff02n > 0x1fffffffffffff01n, true, "0x1fffffffffffff02n > 0x1fffffffffffff01n"); >+assert(BigInt("-2305843009213693697") > BigInt("-2305843009213693698"), true, "-2305843009213693697n > -2305843009213693698n"); >+assert(BigInt("-2305843009213693698") > BigInt("-2305843009213693697"), false, "-2305843009213693698n > -2305843009213693697n"); >+assert(0x10000000000000000n > 0n, true, "0x10000000000000000n > 0n"); >+assert(0n > 0x10000000000000000n, false, "0n > 0x10000000000000000n"); >+assert(0x10000000000000000n > 1n, true, "0x10000000000000000n > 1n"); >+assert(1n > 0x10000000000000000n, false, "1n > 0x10000000000000000n"); >+assert(0x10000000000000000n > BigInt("-1"), true, "0x10000000000000000n > -1n"); >+assert(BigInt("-1") > 0x10000000000000000n, false, "-1n > 0x10000000000000000n"); >+assert(0x10000000000000001n > 0n, true, "0x10000000000000001n > 0n"); >+assert(0n > 0x10000000000000001n, false, "0n > 0x10000000000000001n"); >+assert(BigInt("-18446744073709551616") > 0n, false, "-18446744073709551616n > 0n"); >+assert(0n > BigInt("-18446744073709551616"), true, "0n > -18446744073709551616n"); >+assert(BigInt("-18446744073709551616") > 1n, false, "-18446744073709551616n > 1n"); >+assert(1n > BigInt("-18446744073709551616"), true, "1n > -18446744073709551616n"); >+assert(BigInt("-18446744073709551616") > BigInt("-1"), false, "-18446744073709551616n > -1n"); >+assert(BigInt("-1") > BigInt("-18446744073709551616"), true, "-1n > -18446744073709551616n"); >+assert(BigInt("-18446744073709551617") > 0n, false, "-18446744073709551617n > 0n"); >+assert(0n > BigInt("-18446744073709551617"), true, "0n > -18446744073709551617n"); >+assert(0x10000000000000000n > 0x100000000n, true, "0x10000000000000000n > 0x100000000n"); >+assert(0x100000000n > 0x10000000000000000n, false, "0x100000000n > 0x10000000000000000n"); >+ >diff --git a/JSTests/stress/big-int-less-than-general.js b/JSTests/stress/big-int-less-than-general.js >new file mode 100644 >index 0000000..ca75c2a >--- /dev/null >+++ b/JSTests/stress/big-int-less-than-general.js >@@ -0,0 +1,133 @@ >+//@ runBigIntEnabled >+ >+// Copyright (C) 2017 Josh Wolfe. All rights reserved. >+// Copyright (C) 2017 Robin Templeton. All rights reserved. >+// Copyright (C) 2018 Igalia, S.L. All rights reserved. >+// This code is governed by the BSD license found in the LICENSE file. >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+assert(0n < 0n, false, "0n < 0n"); >+assert(1n < 1n, false, "1n < 1n"); >+assert(BigInt("-1") < BigInt("-1"), false, "-1n < -1n"); >+assert(0n < BigInt("-0"), false, "0n < -0n"); >+assert(BigInt("-0") < 0n, false, "-0n < 0n"); >+assert(0n < 1n, true, "0n < 1n"); >+assert(1n < 0n, false, "1n < 0n"); >+assert(0n < BigInt("-1"), false, "0n < -1n"); >+assert(BigInt("-1") < 0n, true, "-1n < 0n"); >+assert(1n < BigInt("-1"), false, "1n < -1n"); >+assert(BigInt("-1") < 1n, true, "-1n < 1n"); >+assert(0x1fffffffffffff01n < 0x1fffffffffffff02n, true, "0x1fffffffffffff01n < 0x1fffffffffffff02n"); >+assert(0x1fffffffffffff02n < 0x1fffffffffffff01n, false, "0x1fffffffffffff02n < 0x1fffffffffffff01n"); >+assert(BigInt("-2305843009213693697") < BigInt("-2305843009213693698"), false, "-2305843009213693697n < -2305843009213693698n"); >+assert(BigInt("-2305843009213693698") < BigInt("-2305843009213693697"), true, "-2305843009213693698n < -2305843009213693697n"); >+assert(0x10000000000000000n < 0n, false, "0x10000000000000000n < 0n"); >+assert(0n < 0x10000000000000000n, true, "0n < 0x10000000000000000n"); >+assert(0x10000000000000000n < 1n, false, "0x10000000000000000n < 1n"); >+assert(1n < 0x10000000000000000n, true, "1n < 0x10000000000000000n"); >+assert(0x10000000000000000n < BigInt("-1"), false, "0x10000000000000000n < -1n"); >+assert(BigInt("-1") < 0x10000000000000000n, true, "-1n < 0x10000000000000000n"); >+assert(0x10000000000000001n < 0n, false, "0x10000000000000001n < 0n"); >+assert(0n < 0x10000000000000001n, true, "0n < 0x10000000000000001n"); >+assert(BigInt("-18446744073709551616") < 0n, true, "-18446744073709551616n < 0n"); >+assert(0n < BigInt("-18446744073709551616"), false, "0n < -18446744073709551616n"); >+assert(BigInt("-18446744073709551616") < 1n, true, "-18446744073709551616n < 1n"); >+assert(1n < BigInt("-18446744073709551616"), false, "1n < -18446744073709551616n"); >+assert(BigInt("-18446744073709551616") < BigInt("-1"), true, "-18446744073709551616n < -1n"); >+assert(BigInt("-1") < BigInt("-18446744073709551616"), false, "-1n < -18446744073709551616n"); >+assert(BigInt("-18446744073709551617") < 0n, true, "-18446744073709551617n < 0n"); >+assert(0n < BigInt("-18446744073709551617"), false, "0n < -18446744073709551617n"); >+assert(0x10000000000000000n < 0x100000000n, false, "0x10000000000000000n < 0x100000000n"); >+assert(0x100000000n < 0x10000000000000000n, true, "0x100000000n < 0x10000000000000000n"); >+ >+// BigInt - String >+ >+assert(0n < "0", false, "0n < '0'"); assert("0" < 0n, false, "'0' < 0n"); >+assert(0n < "1", true, "0n < '1'"); >+assert("0" < 1n, true, "'0' < 1n"); >+assert(1n < "0", false, "1n < '0'"); >+assert("1" < 0n, false, "'1' < 0n"); >+assert(0n < "", false, "0n < ''"); >+assert("" < 0n, false, "'' < 0n"); >+assert(0n < "1", true, "0n < '1'"); >+assert("" < 1n, true, "'' < 1n"); >+assert(1n < "", false, "1n < ''"); >+assert("1" < 0n, false, "'1' < 0n"); >+assert(1n < "1", false, "1n < '1'"); >+assert("1" < 1n, false, "'1' < 1n"); >+assert(1n < "-1", false, "1n < '-1'"); >+assert("1" < BigInt("-1"), false, "'1' < -1n"); >+assert(BigInt("-1") < "1", true, "-1n < '1'"); >+assert("-1" < 1n, true, "'-1' < 1n"); >+assert(BigInt("-1") < "-1", false, "-1n < '-1'"); >+assert("-1" < BigInt("-1"), false, "'-1' < -1n"); >+assert(9007199254740993n < "9007199254740992", false, "9007199254740993n < '9007199254740992'"); >+assert("9007199254740993" < 9007199254740992n, false, "'9007199254740993' < 9007199254740992n"); >+assert(BigInt("-9007199254740992") < "-9007199254740993", false, "-9007199254740992n < '-9007199254740993'"); >+assert("-9007199254740992" < BigInt("-9007199254740992"), false, "'-9007199254740992' < -9007199254740993n"); >+ >+// BigInt - Number >+ >+assert(0n < 0, false, "0n < 0"); >+assert(0 < 0n, false, "0 < 0n"); >+assert(0n < -0, false, "0n < -0"); >+assert(-0 < 0n, false, "-0 < 0n"); >+assert(0n < 0.000000000001, true, "0n < 0.000000000001"); >+assert(0.000000000001 < 0n, false, "0.000000000001 < 0n"); >+assert(0n < 1, true, "0n < 1"); >+assert(1 < 0n, false, "1 < 0n"); >+assert(1n < 0, false, "1n < 0"); >+assert(0 < 1n, true, "0 < 1n"); >+assert(1n < 0.999999999999, false, "1n < 0.999999999999"); >+assert(0.999999999999 < 1n, true, "0.999999999999 < 1n"); >+assert(1n < 1, false, "1n < 1"); >+assert(1 < 1n, false, "1 < 1n"); >+assert(0n < Number.MIN_VALUE, true, "0n < Number.MIN_VALUE"); >+assert(Number.MIN_VALUE < 0n, false, "Number.MIN_VALUE < 0n"); >+assert(0n < -Number.MIN_VALUE, false, "0n < -Number.MIN_VALUE"); >+assert(-Number.MIN_VALUE < 0n, true, "-Number.MIN_VALUE < 0n"); >+assert(BigInt("-10") < Number.MIN_VALUE, true, "-10n < Number.MIN_VALUE"); >+assert(Number.MIN_VALUE < BigInt("-10"), false, "Number.MIN_VALUE < -10n"); >+assert(1n < Number.MAX_VALUE, true, "1n < Number.MAX_VALUE"); >+assert(Number.MAX_VALUE < 1n, false, "Number.MAX_VALUE < 1n"); >+assert(1n < -Number.MAX_VALUE, false, "1n < -Number.MAX_VALUE"); >+assert(-Number.MAX_VALUE < 1n, true, "-Number.MAX_VALUE < 1n"); >+assert(0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn < Number.MAX_VALUE, true, "0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn < Number.MAX_VALUE"); >+assert(Number.MAX_VALUE < 0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn, false, "Number.MAX_VALUE < 0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn"); >+assert(0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n < Number.MAX_VALUE, false, "0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n < Number.MAX_VALUE"); >+assert(Number.MAX_VALUE < 0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n, true, "Number.MAX_VALUE < 0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n"); >+assert(1n < Infinity, true, "1n < Infinity"); >+assert(Infinity < 1n, false, "Infinity < 1n"); >+assert(BigInt("-1") < Infinity, true, "-1n < Infinity"); >+assert(Infinity < BigInt("-1"), false, "Infinity < -1n"); >+assert(1n < -Infinity, false, "1n < -Infinity"); >+assert(-Infinity < 1n, true, "-Infinity < 1n"); >+assert(BigInt("-1") < -Infinity, false, "-1n < -Infinity"); >+assert(-Infinity < BigInt("-1"), true, "-Infinity < -1n"); >+assert(0n < NaN, false, "0n < NaN"); >+assert(NaN < 0n, false, "NaN < 0n"); >+ >+// BigInt - Boolean >+ >+assert(false < 1n, true, "false < 1n"); >+assert(1n < false, false, "1n < false"); >+assert(false < 0n, false, "false < 0n"); >+assert(0n < false, false, "0n < false"); >+assert(true < 1n, false, "true < 1n"); >+assert(1n < true, false, "1n < true"); >+assert(true < 2n, true, "true < 2n"); >+assert(2n < true, false, "2n < true"); >+ >+// BigInt - Symbol >+ >+try { >+ 1n < Symbol("1"); >+ assert(false, true, "Comparison with Symbol shoud throw TypeError, but executed without exception"); >+} catch(e) { >+ assert(e instanceof TypeError, true, "Comparison with Symbol shoud throw TypeError, but throwed something else"); >+} >+ >diff --git a/JSTests/stress/big-int-wrapped-values.js b/JSTests/stress/big-int-wrapped-values.js >new file mode 100644 >index 0000000..dc16b85 >--- /dev/null >+++ b/JSTests/stress/big-int-wrapped-values.js >@@ -0,0 +1,13 @@ >+//@ runBigIntEnabled >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+assert(Object(2n) < 1n, false, "Object(2n) < 1n"); >+assert(1n < Object(2n), true, "1n < Object(2n)"); >+ >+assert(Object(2n) < Object(1n), false, "Object(2n) < Object(1n)"); >+assert(Object(1n) < Object(2n), true, "Object(1n) < Object(2n)"); >+ >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index e18c782..ab8d748 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,25 @@ >+2018-04-22 Caio Lima <ticaiolima@gmail.com> >+ >+ [ESNext][BigInt] Implement support for "==" operation >+ https://bugs.webkit.org/show_bug.cgi?id=184474 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch is implementing support of BigInt for equals operator >+ following the spec semantics[1]. >+ >+ [1] - https://tc39.github.io/proposal-bigint/#sec-abstract-equality-comparison >+ >+ * runtime/JSBigInt.cpp: >+ (JSC::JSBigInt::parseInt): >+ (JSC::JSBigInt::stringToBigInt): >+ (JSC::JSBigInt::setDigit): >+ (JSC::JSBigInt::equalsToNumber): >+ (JSC::JSBigInt::compareToDouble): >+ * runtime/JSBigInt.h: >+ * runtime/JSCJSValueInlines.h: >+ (JSC::JSValue::equalSlowCaseInline): >+ > 2018-05-05 Caio Lima <ticaiolima@gmail.com> > > [ESNext][BigInt] Implement support for "==" operation >diff --git a/Source/JavaScriptCore/runtime/JSBigInt.cpp b/Source/JavaScriptCore/runtime/JSBigInt.cpp >index c36a06a..baceec7 100644 >--- a/Source/JavaScriptCore/runtime/JSBigInt.cpp >+++ b/Source/JavaScriptCore/runtime/JSBigInt.cpp >@@ -478,6 +478,53 @@ bool JSBigInt::equals(JSBigInt* x, JSBigInt* y) > return true; > } > >+// Produces comparison result for {leftNegative} == sign(x) != sign(y). >+JSBigInt::ComparisonResult JSBigInt::unequalSign(bool leftNegative) { >+ return leftNegative ? ComparisonResult::LessThan : ComparisonResult::GreaterThan; >+} >+ >+// Produces result for |x| > |y|, with {bothNegative} == sign(x) == sign(y); >+JSBigInt::ComparisonResult JSBigInt::absoluteGreater(bool bothNegative) { >+ return bothNegative ? ComparisonResult::LessThan : ComparisonResult::GreaterThan; >+} >+ >+// Produces result for |x| < |y|, with {bothNegative} == sign(x) == sign(y). >+JSBigInt::ComparisonResult JSBigInt::absoluteLess(bool bothNegative) { >+ return bothNegative ? ComparisonResult::GreaterThan : ComparisonResult::LessThan; >+} >+ >+JSBigInt::ComparisonResult JSBigInt::compare(JSBigInt* x, JSBigInt* y) >+{ >+ bool xSign = x->sign(); >+ >+ if (xSign != y->sign()) >+ return unequalSign(xSign); >+ >+ int result = absoluteCompare(x, y); >+ if (result > 0) >+ return absoluteGreater(xSign); >+ if (result < 0) >+ return absoluteLess(xSign); >+ >+ return ComparisonResult::Equal; >+} >+ >+int JSBigInt::absoluteCompare(JSBigInt* x, JSBigInt* y) >+{ >+ int diff = x->length() - y->length(); >+ if (diff) >+ return diff; >+ >+ int i = x->length() - 1; >+ while (i >= 0 && x->digit(i) == y->digit(i)) >+ i--; >+ >+ if (i < 0) >+ return 0; >+ >+ return x->digit(i) > y->digit(i) ? 1 : -1; >+} >+ > // Divides {x} by {divisor}, returning the result in {quotient} and {remainder}. > // Mathematically, the contract is: > // quotient = (x - remainder) / divisor, with 0 <= remainder < divisor. >diff --git a/Source/JavaScriptCore/runtime/JSBigInt.h b/Source/JavaScriptCore/runtime/JSBigInt.h >index b9bf751..f7d3968 100644 >--- a/Source/JavaScriptCore/runtime/JSBigInt.h >+++ b/Source/JavaScriptCore/runtime/JSBigInt.h >@@ -85,23 +85,26 @@ public: > std::optional<uint8_t> singleDigitValueForString(); > String toString(ExecState&, unsigned radix); > >+ enum ComparisonResult { >+ Equal, >+ Undefined, >+ GreaterThan, >+ LessThan >+ }; >+ > JS_EXPORT_PRIVATE static bool equals(JSBigInt*, JSBigInt*); > bool equalsToNumber(JSValue); >+ static ComparisonResult compare(JSBigInt* x, JSBigInt* y); > > bool getPrimitiveNumber(ExecState*, double& number, JSValue& result) const; > double toNumber(ExecState*) const; > > JSObject* toObject(ExecState*, JSGlobalObject*) const; > >+ ComparisonResult static compareToDouble(JSBigInt* x, double y); >+ > private: > >- enum ComparisonResult { >- Equal, >- Undefined, >- GreaterThan, >- LessThan >- }; >- > using Digit = uintptr_t; > static constexpr const int bitsPerByte = 8; > static constexpr const int digitBits = sizeof(Digit) * bitsPerByte; >@@ -117,6 +120,11 @@ private: > > static uint64_t calculateMaximumCharactersRequired(int length, int radix, Digit lastDigit, bool sign); > >+ static ComparisonResult unequalSign(bool leftNegative); >+ static ComparisonResult absoluteGreater(bool bothNegative); >+ static ComparisonResult absoluteLess(bool bothNegative); >+ >+ static int absoluteCompare(JSBigInt* x, JSBigInt* y); > static void absoluteDivSmall(ExecState&, JSBigInt* x, Digit divisor, JSBigInt** quotient, Digit& remainder); > static void internalMultiplyAdd(JSBigInt* source, Digit factor, Digit summand, int, JSBigInt* result); > >@@ -131,8 +139,6 @@ private: > > bool isZero(); > >- ComparisonResult static compareToDouble(JSBigInt* x, double y); >- > template <typename CharType> > static JSBigInt* parseInt(ExecState*, CharType* data, unsigned length, ErrorParseMode); > >diff --git a/Source/JavaScriptCore/runtime/JSCJSValueInlines.h b/Source/JavaScriptCore/runtime/JSCJSValueInlines.h >index 23d3b26..3aced06 100644 >--- a/Source/JavaScriptCore/runtime/JSCJSValueInlines.h >+++ b/Source/JavaScriptCore/runtime/JSCJSValueInlines.h >@@ -591,7 +591,7 @@ inline bool JSValue::isSymbol() const > > inline bool JSValue::isPrimitive() const > { >- return !isCell() || asCell()->isString() || asCell()->isSymbol(); >+ return !isCell() || asCell()->isString() || asCell()->isSymbol() || asCell()->isBigInt(); > } > > inline bool JSValue::isGetterSetter() const >diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h >index 1349aec..72e9dff 100644 >--- a/Source/JavaScriptCore/runtime/Operations.h >+++ b/Source/JavaScriptCore/runtime/Operations.h >@@ -23,6 +23,7 @@ > > #include "CallFrame.h" > #include "ExceptionHelpers.h" >+#include "JSBigInt.h" > #include "JSCJSValue.h" > > namespace JSC { >@@ -155,6 +156,42 @@ ALWAYS_INLINE JSValue jsStringFromArguments(ExecState* exec, JSValue thisValue) > return ropeBuilder.release(); > } > >+ALWAYS_INLINE bool bigIntCompareLess(CallFrame* callFrame, JSValue v1, JSValue v2) >+{ >+ ASSERT(v1.isBigInt() || v2.isBigInt()); >+ ASSERT(v1.isPrimitive() && v2.isPrimitive()); >+ >+ VM& vm = callFrame->vm(); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ if (v1.isBigInt() && v2.isBigInt()) >+ return JSBigInt::compare(asBigInt(v1), asBigInt(v2)) == JSBigInt::LessThan; >+ >+ if (v1.isBigInt()) { >+ JSValue primValue = v2; >+ if (primValue.isString()) >+ return JSBigInt::compare(asBigInt(v1), JSBigInt::stringToBigInt(callFrame, asString(primValue)->value(callFrame))) == JSBigInt::LessThan; >+ >+ if (primValue.isBigInt()) >+ return JSBigInt::compare(asBigInt(v1), asBigInt(primValue)) == JSBigInt::LessThan; >+ >+ double numberValue = primValue.toNumber(callFrame); >+ RETURN_IF_EXCEPTION(scope, false); >+ return JSBigInt::compareToDouble(asBigInt(v1), numberValue) == JSBigInt::LessThan; >+ } >+ >+ JSValue primValue = v1; >+ if (primValue.isString()) >+ return JSBigInt::compare(JSBigInt::stringToBigInt(callFrame, asString(primValue)->value(callFrame)), asBigInt(v2)) == JSBigInt::LessThan; >+ >+ if (primValue.isBigInt()) >+ return JSBigInt::compare(asBigInt(primValue), asBigInt(v2)) == JSBigInt::LessThan; >+ >+ double numberValue = primValue.toNumber(callFrame); >+ RETURN_IF_EXCEPTION(scope, false); >+ return JSBigInt::compareToDouble(asBigInt(v2), numberValue) == JSBigInt::GreaterThan; >+} >+ > // See ES5 11.8.1/11.8.2/11.8.5 for definition of leftFirst, this value ensures correct > // evaluation ordering for argument conversions for '<' and '>'. For '<' pass the value > // true, for leftFirst, for '>' pass the value false (and reverse operand order). >@@ -173,6 +210,23 @@ ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2) > if (isJSString(v1) && isJSString(v2)) > return codePointCompareLessThan(asString(v1)->value(callFrame), asString(v2)->value(callFrame)); > >+ if (v1.isBigInt() || v2.isBigInt()) { >+ if (v1.isBigInt()) { >+ JSValue primValue = v2.toPrimitive(callFrame, PreferNumber); >+ RETURN_IF_EXCEPTION(scope, false); >+ bool comparisonResult = bigIntCompareLess(callFrame, v1, primValue); >+ RETURN_IF_EXCEPTION(scope, false); >+ return comparisonResult; >+ >+ } >+ >+ JSValue primValue = v1.toPrimitive(callFrame, PreferNumber); >+ RETURN_IF_EXCEPTION(scope, false); >+ bool comparisonResult = bigIntCompareLess(callFrame, primValue, v2); >+ RETURN_IF_EXCEPTION(scope, false); >+ return comparisonResult; >+ } >+ > double n1; > double n2; > JSValue p1; >@@ -190,8 +244,12 @@ ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2) > } > RETURN_IF_EXCEPTION(scope, false); > >- if (wasNotString1 | wasNotString2) >+ if (wasNotString1 | wasNotString2) { >+ if (p1.isBigInt() || p2.isBigInt()) >+ return bigIntCompareLess(callFrame, p1, p2); >+ > return n1 < n2; >+ } > return codePointCompareLessThan(asString(p1)->value(callFrame), asString(p2)->value(callFrame)); > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185379
:
339724
|
339808
|
340317
|
340392
|
340467
|
340791
|
340792
|
340794
|
340809
|
340818
|
341164
|
341178
|
341504
|
341508