WebKit Bugzilla
Attachment 340809 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]
Patch
bug-185379-20180520201338.patch (text/plain), 35.95 KB, created by
Caio Lima
on 2018-05-20 16:13:41 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Caio Lima
Created:
2018-05-20 16:13:41 PDT
Size:
35.95 KB
patch
obsolete
>Subversion Revision: 232001 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 8228176e72b5a333221358c4f3bea8410ceaf0da..983ab2059885571f0157bc436ecf32418327c92d 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,32 @@ >+2018-05-20 Caio Lima <ticaiolima@gmail.com> >+ >+ [ESNext][BigInt] Implement support for "<" and ">" relational operation >+ https://bugs.webkit.org/show_bug.cgi?id=185379 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch is changing the ``jsLess``` operation to follow the >+ semantics of Abstract Relational Comparison[1] that supports BigInt. >+ For that, we create 2 new helper functions ```bigIntCompareLess``` and >+ ```toPrimitiveNumeric``` that considers BigInt as a valid type to be >+ compared. >+ >+ [1] - https://tc39.github.io/proposal-bigint/#sec-abstract-relational-comparison >+ >+ * runtime/JSBigInt.cpp: >+ (JSC::JSBigInt::unequalSign): >+ (JSC::JSBigInt::absoluteGreater): >+ (JSC::JSBigInt::absoluteLess): >+ (JSC::JSBigInt::compare): >+ (JSC::JSBigInt::absoluteCompare): >+ * runtime/JSBigInt.h: >+ * runtime/JSCJSValueInlines.h: >+ (JSC::JSValue::isPrimitive const): >+ * runtime/Operations.h: >+ (JSC::bigIntCompareLess): >+ (JSC::toPrimitiveNumeric): >+ (JSC::jsLess): >+ > 2018-05-18 Filip Pizlo <fpizlo@apple.com> > > DFG should inline InstanceOf ICs >diff --git a/Source/JavaScriptCore/runtime/JSBigInt.cpp b/Source/JavaScriptCore/runtime/JSBigInt.cpp >index 460775d248b998bc3e8b827b8b22757fd9d2dbc8..b5cc09cde6ab964fd1fa5d28d89ce01a054b67fe 100644 >--- a/Source/JavaScriptCore/runtime/JSBigInt.cpp >+++ b/Source/JavaScriptCore/runtime/JSBigInt.cpp >@@ -575,10 +575,26 @@ bool JSBigInt::equals(JSBigInt* x, JSBigInt* y) > return true; > } > >+JSBigInt::ComparisonResult JSBigInt::compare(JSBigInt* x, JSBigInt* y) >+{ >+ bool xSign = x->sign(); >+ >+ if (xSign != y->sign()) >+ return xSign ? ComparisonResult::LessThan : ComparisonResult::GreaterThan; >+ >+ ComparisonResult result = absoluteCompare(x, y); >+ if (result == ComparisonResult::GreaterThan) >+ return xSign ? ComparisonResult::LessThan : ComparisonResult::GreaterThan; >+ if (result == ComparisonResult::LessThan) >+ return xSign ? ComparisonResult::GreaterThan : ComparisonResult::LessThan; >+ >+ return ComparisonResult::Equal; >+} >+ > inline JSBigInt::ComparisonResult JSBigInt::absoluteCompare(JSBigInt* x, JSBigInt* y) > { >- ASSERT(!x->length() || x->digit(0)); >- ASSERT(!y->length() || y->digit(0)); >+ ASSERT(!x->length() || x->digit(x->length() - 1)); >+ ASSERT(!y->length() || y->digit(y->length() - 1)); > > int diff = x->length() - y->length(); > if (diff) >diff --git a/Source/JavaScriptCore/runtime/JSBigInt.h b/Source/JavaScriptCore/runtime/JSBigInt.h >index 67650fc2f368b58fdee550c677e2c628476b7200..3cb1ddf4adb7f8a07b6082bc0d9e4b054203f0c6 100644 >--- a/Source/JavaScriptCore/runtime/JSBigInt.h >+++ b/Source/JavaScriptCore/runtime/JSBigInt.h >@@ -84,8 +84,16 @@ public: > std::optional<uint8_t> singleDigitValueForString(); > String toString(ExecState*, unsigned radix); > >+ enum class 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; >@@ -94,18 +102,13 @@ public: > > static JSBigInt* multiply(ExecState*, JSBigInt* x, JSBigInt* y); > >+ ComparisonResult static compareToDouble(JSBigInt* x, double y); >+ > static JSBigInt* divide(ExecState*, JSBigInt* x, JSBigInt* y); > static JSBigInt* unaryMinus(VM&, JSBigInt* x); > > private: > >- enum class ComparisonResult { >- Equal, >- Undefined, >- GreaterThan, >- LessThan >- }; >- > using Digit = uintptr_t; > static constexpr const unsigned bitsPerByte = 8; > static constexpr const unsigned digitBits = sizeof(Digit) * bitsPerByte; >@@ -150,8 +153,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 55b1218eaf3a7a99df13873a913feac81d17fc8a..3c7f70d1343687511ae71ee2981f84e4666905d9 100644 >--- a/Source/JavaScriptCore/runtime/JSCJSValueInlines.h >+++ b/Source/JavaScriptCore/runtime/JSCJSValueInlines.h >@@ -592,7 +592,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 495590bb886ea0af3ba5d81ef20ffd745500a75e..f69d9ca315f44a10dafc402063e9f826e89455a8 100644 >--- a/Source/JavaScriptCore/runtime/Operations.h >+++ b/Source/JavaScriptCore/runtime/Operations.h >@@ -157,6 +157,69 @@ 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::ComparisonResult::LessThan; >+ >+ if (v1.isBigInt()) { >+ JSValue primValue = v2; >+ if (primValue.isString()) { >+ JSBigInt* bigIntValue = JSBigInt::stringToBigInt(callFrame, asString(primValue)->value(callFrame)); >+ RETURN_IF_EXCEPTION(scope, false); >+ if (!bigIntValue) >+ return false; >+ >+ return JSBigInt::compare(asBigInt(v1), bigIntValue) == JSBigInt::ComparisonResult::LessThan; >+ } >+ >+ if (primValue.isBigInt()) >+ return JSBigInt::compare(asBigInt(v1), asBigInt(primValue)) == JSBigInt::ComparisonResult::LessThan; >+ >+ double numberValue = primValue.toNumber(callFrame); >+ RETURN_IF_EXCEPTION(scope, false); >+ return JSBigInt::compareToDouble(asBigInt(v1), numberValue) == JSBigInt::ComparisonResult::LessThan; >+ } >+ >+ JSValue primValue = v1; >+ if (primValue.isString()) { >+ JSBigInt* bigIntValue = JSBigInt::stringToBigInt(callFrame, asString(primValue)->value(callFrame)); >+ RETURN_IF_EXCEPTION(scope, false); >+ if (!bigIntValue) >+ return false; >+ >+ return JSBigInt::compare(bigIntValue, asBigInt(v2)) == JSBigInt::ComparisonResult::LessThan; >+ } >+ >+ if (primValue.isBigInt()) >+ return JSBigInt::compare(asBigInt(primValue), asBigInt(v2)) == JSBigInt::ComparisonResult::LessThan; >+ >+ double numberValue = primValue.toNumber(callFrame); >+ RETURN_IF_EXCEPTION(scope, false); >+ return JSBigInt::compareToDouble(asBigInt(v2), numberValue) == JSBigInt::ComparisonResult::GreaterThan; >+} >+ >+ALWAYS_INLINE bool toPrimitiveNumeric(CallFrame* callFrame, JSValue v, JSValue& p, double& n) >+{ >+ VM& vm = callFrame->vm(); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ p = v.toPrimitive(callFrame, PreferNumber); >+ RETURN_IF_EXCEPTION(scope, false); >+ if (p.isBigInt()) >+ return true; >+ >+ n = p.toNumber(callFrame); >+ RETURN_IF_EXCEPTION(scope, false); >+ return !p.isString(); >+} >+ > // 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). >@@ -182,18 +245,25 @@ ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2) > bool wasNotString1; > bool wasNotString2; > if (leftFirst) { >- wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1); >+ wasNotString1 = toPrimitiveNumeric(callFrame, v1, p1, n1); > RETURN_IF_EXCEPTION(scope, false); >- wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2); >+ wasNotString2 = toPrimitiveNumeric(callFrame, v2, p2, n2); > } else { >- wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2); >+ wasNotString2 = toPrimitiveNumeric(callFrame, v2, p2, n2); > RETURN_IF_EXCEPTION(scope, false); >- wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1); >+ wasNotString1 = toPrimitiveNumeric(callFrame, v1, p1, n1); > } > RETURN_IF_EXCEPTION(scope, false); > >- if (wasNotString1 | wasNotString2) >+ if (wasNotString1 | wasNotString2) { >+ if (p1.isBigInt() || p2.isBigInt()) { >+ bool result = bigIntCompareLess(callFrame, p1, p2); >+ RETURN_IF_EXCEPTION(scope, false); >+ return result; >+ } >+ > return n1 < n2; >+ } > return codePointCompareLessThan(asString(p1)->value(callFrame), asString(p2)->value(callFrame)); > } > >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index 72f9954fad476b4d3cd7c2a0def5544fcfe4b577..be21210e564abfdfa8fd36a9a09efe1a655ea0a2 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,19 @@ >+2018-05-20 Caio Lima <ticaiolima@gmail.com> >+ >+ [ESNext][BigInt] Implement support for "<" and ">" relational operation >+ https://bugs.webkit.org/show_bug.cgi?id=185379 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/big-int-greater-than-general.js: Added. >+ * stress/big-int-greater-than-jit.js: Added. >+ * stress/big-int-greater-than-order-of-evaluation.js: Added. >+ * stress/big-int-greater-than-wrapped-values.js: Added. >+ * stress/big-int-less-than-general.js: Added. >+ * stress/big-int-less-than-jit.js: Added. >+ * stress/big-int-less-than-order-of-evaluation.js: Added. >+ * stress/big-int-less-than-wrapped-values.js: Added. >+ > 2018-05-19 Yusuke Suzuki <utatane.tea@gmail.com> > > [JSC] JSC should have consistent InById IC >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 0000000000000000000000000000000000000000..5776beb34ef567711862043e9e00e0e145b31f46 >--- /dev/null >+++ b/JSTests/stress/big-int-greater-than-general.js >@@ -0,0 +1,140 @@ >+//@ 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"); >+ >+// BigInt - String >+ >+assert(0n > "0", false, "0n > '0'"); >+assert("0" > 0n, false, "'0' > 0n"); >+assert(0n > "1", false, "0n > '1'"); >+assert("0" > 1n, false, "'0' > 1n"); >+assert(1n > "0", true, "1n > '0'"); >+assert("1" > 0n, true, "'1' > 0n"); >+assert(0n > "", false, "0n > ''"); >+assert("" > 0n, false, "'' > 0n"); >+assert(0n > "1", false, "0n > '1'"); >+assert("" > 1n, false, "'' > 1n"); >+assert(1n > "", true, "1n > ''"); >+assert(1n > "1", false, "1n > '1'"); >+assert("1" > 1n, false, "'1' > 1n"); >+assert(1n > "-1", true, "1n > '-1'"); >+assert("1" > BigInt("-1"), true, "'1' > -1n"); >+assert(BigInt("-1") > "1", false, "-1n > '1'"); >+assert("-1" > 1n, false, "'-1' > 1n"); >+assert(BigInt("-1") > "-1", false, "-1n > '-1'"); >+assert("-1" > BigInt("-1"), false, "'-1' > -1n"); >+assert(9007199254740993n > "9007199254740992", true, "9007199254740993n > '9007199254740992'"); >+assert("9007199254740993" > 9007199254740992n, true, "'9007199254740993' > 9007199254740992n"); >+assert(BigInt("-9007199254740992") > "-9007199254740993", true, "-9007199254740992n > '-9007199254740993'"); >+assert("-9007199254740992" > BigInt("-9007199254740992"), false, "'-9007199254740992' > -9007199254740993n"); >+assert("0x10" > 14n, true, "'0x10' > 3n"); >+assert("0b10" > 2n, false, "'0b10' > 2n"); >+assert("0b10" > 1n, true, "'0x10' > 1n"); >+ >+// Invalid String >+ >+assert("b10" > 2n, false, "'b10' > 2n"); >+assert("bbb10" > 2n, false, "'bbb10' > 2n"); >+ >+// 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, false, "0n > 0.000000000001"); >+assert(0.000000000001 > 0n, true, "0.000000000001 > 0n"); >+assert(0n > 1, false, "0n > 1"); >+assert(1 > 0n, true, "1 > 0n"); >+assert(1n > 0, true, "1n > 0"); >+assert(0 > 1n, false, "0 > 1n"); >+assert(1n > 0.999999999999, true, "1n > 0.999999999999"); >+assert(0.999999999999 > 1n, false, "0.999999999999 > 1n"); >+assert(1n > 1, false, "1n > 1"); >+assert(1 > 1n, false, "1 > 1n"); >+assert(0n > Number.MIN_VALUE, false, "0n > Number.MIN_VALUE"); >+assert(Number.MIN_VALUE > 0n, true, "Number.MIN_VALUE > 0n"); >+assert(0n > -Number.MIN_VALUE, true, "0n > -Number.MIN_VALUE"); >+assert(-Number.MIN_VALUE > 0n, false, "-Number.MIN_VALUE > 0n"); >+assert(BigInt("-10") > Number.MIN_VALUE, false, "-10n > Number.MIN_VALUE"); >+assert(Number.MIN_VALUE > BigInt("-10"), true, "Number.MIN_VALUE > -10n"); >+assert(1n > Number.MAX_VALUE, false, "1n > Number.MAX_VALUE"); >+assert(Number.MAX_VALUE > 1n, true, "Number.MAX_VALUE > 1n"); >+assert(1n > -Number.MAX_VALUE, true, "1n > -Number.MAX_VALUE"); >+assert(-Number.MAX_VALUE > 1n, false, "-Number.MAX_VALUE > 1n"); >+assert(0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn > Number.MAX_VALUE, false, "0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn > Number.MAX_VALUE"); >+assert(Number.MAX_VALUE > 0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn, true, "Number.MAX_VALUE > 0xfffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn"); >+assert(0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n > Number.MAX_VALUE, true, "0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n > Number.MAX_VALUE"); >+assert(Number.MAX_VALUE > 0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n, false, "Number.MAX_VALUE > 0xfffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n"); >+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(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(0n > NaN, false, "0n > NaN"); >+assert(NaN > 0n, false, "NaN > 0n"); >+ >+// BigInt - Boolean >+ >+assert(false > 1n, false, "false > 1n"); >+assert(1n > false, true, "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, flase, "true > 2n"); >+assert(2n > true, true, "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-greater-than-jit.js b/JSTests/stress/big-int-greater-than-jit.js >new file mode 100644 >index 0000000000000000000000000000000000000000..f03ada2bd9a6c49ee3b0859c8fa0cac71d86ece0 >--- /dev/null >+++ b/JSTests/stress/big-int-greater-than-jit.js >@@ -0,0 +1,24 @@ >+//@ runBigIntEnabled >+ >+function assert(a) { >+ if (!a) >+ throw new Error("Bad assertion"); >+} >+ >+function greaterThanTest(a, b) { >+ return a > b; >+} >+noInline(greaterThanTest); >+ >+for (let i = 0; i < 100000; i++) { >+ assert(greaterThanTest(3n, 4) === false); >+} >+ >+for (let i = 0; i < 100000; i++) { >+ assert(greaterThanTest(3n, 4n) === false); >+} >+ >+for (let i = 0; i < 100000; i++) { >+ assert(greaterThanTest(3n, "4") === false); >+} >+ >diff --git a/JSTests/stress/big-int-greater-than-order-of-evaluation.js b/JSTests/stress/big-int-greater-than-order-of-evaluation.js >new file mode 100644 >index 0000000000000000000000000000000000000000..b961ba5c45e899b6055a58b07e4dfc27947179b9 >--- /dev/null >+++ b/JSTests/stress/big-int-greater-than-order-of-evaluation.js >@@ -0,0 +1,55 @@ >+//@ runBigIntEnabled >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+let o = { >+ [Symbol.toPrimitive]: function() { >+ throw new Error("Calling @toPrimitive"); >+ } >+} >+ >+try { >+ o > Symbol(2); >+ assert(true, false, "") >+} catch(e) { >+ assert(e.message, "Calling @toPrimitive", "Bad Exception when object is left operand"); >+} >+ >+try { >+ Symbol(2) > o; >+ assert(true, false, "") >+} catch(e) { >+ assert(e instanceof TypeError, true, "Bad Exception when Symbol is left operand"); >+} >+ >+o = { >+ [Symbol.toPrimitive]: function() { >+ return 2n; >+ }, >+ >+ toString: function() { >+ throw new Error("Should never call toString"); >+ }, >+ >+ valueOf: function() { >+ throw new Error("Should never call valueOf"); >+ } >+} >+ >+assert(o > 3n, false, "ToPrimitive(2n) > 3n"); >+ >+o = { >+ toString: function() { >+ throw new Error("Should never call toString"); >+ }, >+ >+ valueOf: function() { >+ return 2n; >+ } >+} >+ >+assert(o > 3n, false, "valueOf(2n) > 3n"); >+ >diff --git a/JSTests/stress/big-int-greater-than-wrapped-values.js b/JSTests/stress/big-int-greater-than-wrapped-values.js >new file mode 100644 >index 0000000000000000000000000000000000000000..4f45f1f229eb6f31803ff715c02e7090006830cc >--- /dev/null >+++ b/JSTests/stress/big-int-greater-than-wrapped-values.js >@@ -0,0 +1,63 @@ >+//@ runBigIntEnabled >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+assert(Object(2n) > 1n, true, "Object(2n) > 1n"); >+assert(1n > Object(2n), false, "1n > Object(2n)"); >+assert(Object(2n) > Object(1n), true, "Object(2n) > Object(1n)"); >+assert(Object(1n) > Object(2n), false, "Object(1n) > Object(2n)"); >+ >+let o = { >+ [Symbol.toPrimitive]: function() { >+ return 2n; >+ } >+} >+ >+let o2 = { >+ [Symbol.toPrimitive]: function() { >+ return 1n; >+ } >+} >+ >+assert(o > 1n, true, "ToPrimitive(2n) > 1n"); >+assert(1n > o, false, "1n > ToPrimitive(2n)"); >+assert(o > o2, true, "ToPrimitive(2n) > ToPrimitive(1n)"); >+assert(o2 > o, false, "ToPrimitive(1n) > ToPrimitive(2n)"); >+ >+o = { >+ valueOf: function() { >+ return 2n; >+ } >+} >+ >+o2 = { >+ valueOf: function() { >+ return 1n; >+ } >+} >+ >+assert(o > 1n, true, "valueOf(2n) > 1n"); >+assert(1n > o, false, "1n > valueOf(2n)"); >+assert(o > o2, true, "valueOf(2n) > valueOf(1n)"); >+assert(o2 > o, false, "valueOf(1n) > valueOf(2n)"); >+ >+o = { >+ toString: function() { >+ return 2n; >+ } >+} >+ >+o2 = { >+ toString: function() { >+ return 1n; >+ } >+} >+ >+assert(o > 1n, true, "toString(2n) > 1n"); >+assert(1n > o, false, "1n > ToPrimitive(2n)"); >+assert(o > o2, true, "toString(2n) < toString(1n)"); >+assert(o2 > o, false, "toString(1n) < toString(2n)"); >+ >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 0000000000000000000000000000000000000000..357c2aae13b07bd73a000ce6d4a063b72ee13ff8 >--- /dev/null >+++ b/JSTests/stress/big-int-less-than-general.js >@@ -0,0 +1,142 @@ >+//@ 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"); >+assert("0x10" < 3n, false, "'0x10' < 3n"); >+assert("0x10" < 2n, false, "'0x10' < 2n"); >+assert("0x10" < 1n, false, "'0x10' < 1n"); >+ >+// Invalid String >+ >+assert("b10" < 2n, false, "'b10' > 2n"); >+assert("bbb10" < 2n, false, "'bbb10' > 2n"); >+ >+// 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-less-than-jit.js b/JSTests/stress/big-int-less-than-jit.js >new file mode 100644 >index 0000000000000000000000000000000000000000..0e80addc11e08bcd4a3a74bb1148161153bcb74f >--- /dev/null >+++ b/JSTests/stress/big-int-less-than-jit.js >@@ -0,0 +1,24 @@ >+//@ runBigIntEnabled >+ >+function assert(a) { >+ if (!a) >+ throw new Error("Bad assertion"); >+} >+ >+function lessThanTest(a, b) { >+ return a < b; >+} >+noInline(lessThanTest); >+ >+for (let i = 0; i < 100000; i++) { >+ assert(lessThanTest(3n, 4) === true); >+} >+ >+for (let i = 0; i < 100000; i++) { >+ assert(lessThanTest(3n, 4n) === true); >+} >+ >+for (let i = 0; i < 100000; i++) { >+ assert(lessThanTest(3n, "4") === true); >+} >+ >diff --git a/JSTests/stress/big-int-less-than-order-of-evaluation.js b/JSTests/stress/big-int-less-than-order-of-evaluation.js >new file mode 100644 >index 0000000000000000000000000000000000000000..b7efe433ef6df2efd6f648563699c927765ad75c >--- /dev/null >+++ b/JSTests/stress/big-int-less-than-order-of-evaluation.js >@@ -0,0 +1,55 @@ >+//@ runBigIntEnabled >+ >+function assert(v, e, m) { >+ if (v !== e) >+ throw new Error(m); >+} >+ >+let o = { >+ [Symbol.toPrimitive]: function() { >+ throw new Error("Calling @toPrimitive"); >+ } >+} >+ >+try { >+ o < Symbol(2); >+ assert(true, false, "") >+} catch(e) { >+ assert(e.message, "Calling @toPrimitive", "Bad Exception when object is left operand"); >+} >+ >+try { >+ Symbol(2) < o; >+ assert(true, false, "") >+} catch(e) { >+ assert(e instanceof TypeError, true, "Bad Exception when Symbol is left operand"); >+} >+ >+o = { >+ [Symbol.toPrimitive]: function() { >+ return 2n; >+ }, >+ >+ toString: function() { >+ throw new Error("Should never call toString"); >+ }, >+ >+ valueOf: function() { >+ throw new Error("Should never call valueOf"); >+ } >+} >+ >+assert(o < 3n, true, "ToPrimitive(2n) < 3n"); >+ >+o = { >+ toString: function() { >+ throw new Error("Should never call toString"); >+ }, >+ >+ valueOf: function() { >+ return 2n; >+ } >+} >+ >+assert(o < 3n, true, "valueOf(2n) < 3n"); >+ >diff --git a/JSTests/stress/big-int-less-than-wrapped-values.js b/JSTests/stress/big-int-less-than-wrapped-values.js >new file mode 100644 >index 0000000000000000000000000000000000000000..67a2e0ba87162281f0f9c8296c49784f53633665 >--- /dev/null >+++ b/JSTests/stress/big-int-less-than-wrapped-values.js >@@ -0,0 +1,63 @@ >+//@ 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)"); >+ >+let o = { >+ [Symbol.toPrimitive]: function() { >+ return 2n; >+ } >+} >+ >+let o2 = { >+ [Symbol.toPrimitive]: function() { >+ return 1n; >+ } >+} >+ >+assert(o < 1n, false, "ToPrimitive(2n) < 1n"); >+assert(1n < o, true, "1n < ToPrimitive(2n)"); >+assert(o < o2, false, "ToPrimitive(2n) < ToPrimitive(1n)"); >+assert(o2 < o, true, "ToPrimitive(1n) < ToPrimitive(2n)"); >+ >+o = { >+ valueOf: function() { >+ return 2n; >+ } >+} >+ >+o2 = { >+ valueOf: function() { >+ return 1n; >+ } >+} >+ >+assert(o < 1n, false, "ToPrimitive(2n) < 1n"); >+assert(1n < o, true, "1n < ToPrimitive(2n)"); >+assert(o < o2, false, "ToPrimitive(2n) < ToPrimitive(1n)"); >+assert(o2 < o, true, "ToPrimitive(1n) < ToPrimitive(2n)"); >+ >+o = { >+ toString: function() { >+ return 2n; >+ } >+} >+ >+o2 = { >+ toString: function() { >+ return 1n; >+ } >+} >+ >+assert(o < 1n, false, "ToPrimitive(2n) < 1n"); >+assert(1n < o, true, "1n < ToPrimitive(2n)"); >+assert(o < o2, false, "ToPrimitive(2n) < ToPrimitive(1n)"); >+assert(o2 < o, true, "ToPrimitive(1n) < ToPrimitive(2n)"); >+
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