diff options
author | Brian Smith <brian@dbsoft.org> | 2023-07-13 02:40:25 -0500 |
---|---|---|
committer | Brian Smith <brian@dbsoft.org> | 2023-07-13 02:40:25 -0500 |
commit | b2ae4d388529c1a63959cc169f3ec1f7fdce9558 (patch) | |
tree | 83f80a93cb61d769c05e41e3ec59045fa2659f41 /js/src/vm | |
parent | eb7a856c766a508cde0a9ad90a233b272c7a9e54 (diff) | |
download | uxp-b2ae4d388529c1a63959cc169f3ec1f7fdce9558.tar.gz |
Issue #1240 - Part 2 - Define the BigIntObject class for BigInt wrapper objects.
Based on https://bugzilla.mozilla.org/show_bug.cgi?id=1366287 Part 3.
In our Part 3 we will fast forward to the V8 implementation skipping GMP.
Diffstat (limited to 'js/src/vm')
-rw-r--r-- | js/src/vm/BigIntType.cpp | 74 | ||||
-rw-r--r-- | js/src/vm/BigIntType.h | 11 | ||||
-rw-r--r-- | js/src/vm/CommonPropertyNames.h | 1 | ||||
-rw-r--r-- | js/src/vm/GlobalObject.cpp | 1 | ||||
-rw-r--r-- | js/src/vm/StringBuffer.cpp | 2 |
5 files changed, 83 insertions, 6 deletions
diff --git a/js/src/vm/BigIntType.cpp b/js/src/vm/BigIntType.cpp index 394f8f8784..50f92bce49 100644 --- a/js/src/vm/BigIntType.cpp +++ b/js/src/vm/BigIntType.cpp @@ -11,6 +11,7 @@ #include "jsapi.h" #include "jscntxt.h" +#include "builtin/BigInt.h" #include "gc/Allocator.h" #include "gc/Tracer.h" #include "vm/SelfHosting.h" @@ -18,7 +19,7 @@ using namespace js; BigInt* -BigInt::create(js::ExclusiveContext* cx) +BigInt::create(ExclusiveContext* cx) { BigInt* x = Allocate<BigInt>(cx); if (!x) @@ -27,7 +28,51 @@ BigInt::create(js::ExclusiveContext* cx) } BigInt* -BigInt::copy(js::ExclusiveContext* cx, HandleBigInt x) +BigInt::create(ExclusiveContext* cx, double d) +{ + return nullptr; +} + +// BigInt proposal section 5.1.1 +static bool +IsInteger(double d) +{ + // Step 1 is an assertion checked by the caller. + // Step 2. + if (!mozilla::IsFinite(d)) + return false; + + // Step 3. + double i = JS::ToInteger(d); + + // Step 4. + if (i != d) + return false; + + // Step 5. + return true; +} + +// BigInt proposal section 5.1.2 +BigInt* +js::NumberToBigInt(ExclusiveContext* cx, double d) +{ + // Step 1 is an assertion checked by the caller. + // Step 2. + if (!IsInteger(d)) { + if(cx->isJSContext()) { + JS_ReportErrorNumberASCII(cx->asJSContext(), GetErrorMessage, nullptr, + JSMSG_NUMBER_TO_BIGINT); + } + return nullptr; + } + + // Step 3. + return BigInt::create(cx, d); +} + +BigInt* +BigInt::copy(ExclusiveContext* cx, HandleBigInt x) { BigInt* bi = create(cx); if (!bi) @@ -35,8 +80,29 @@ BigInt::copy(js::ExclusiveContext* cx, HandleBigInt x) return bi; } +// BigInt proposal section 7.3 +BigInt* +js::ToBigInt(ExclusiveContext* cx, HandleValue val) +{ + RootedValue v(cx, val); + + if(cx->isJSContext()) { + // Step 1. + if (!ToPrimitive(cx->asJSContext(), JSTYPE_NUMBER, &v)) + return nullptr; + + // Step 2. + // Boolean and string conversions are not yet supported. + if (v.isBigInt()) + return v.toBigInt(); + + JS_ReportErrorNumberASCII(cx->asJSContext(), GetErrorMessage, nullptr, JSMSG_NOT_BIGINT); + } + return nullptr; +} + JSLinearString* -BigInt::toString(ExclusiveContext* cx, BigInt* x) +BigInt::toString(ExclusiveContext* cx, BigInt* x, uint8_t radix) { return nullptr; } @@ -50,7 +116,7 @@ BigInt::finalize(js::FreeOp* fop) JSAtom* js::BigIntToAtom(ExclusiveContext* cx, BigInt* bi) { - JSString* str = BigInt::toString(cx, bi); + JSString* str = BigInt::toString(cx, bi, 10); if (!str) return nullptr; return AtomizeString(cx, str); diff --git a/js/src/vm/BigIntType.h b/js/src/vm/BigIntType.h index 3c5768e818..8d934271a3 100644 --- a/js/src/vm/BigIntType.h +++ b/js/src/vm/BigIntType.h @@ -27,6 +27,8 @@ class BigInt final : public js::gc::TenuredCell // Allocate and initialize a BigInt value static BigInt* create(js::ExclusiveContext* cx); + static BigInt* create(js::ExclusiveContext* cx, double d); + static const JS::TraceKind TraceKind = JS::TraceKind::BigInt; void traceChildren(JSTracer* trc); @@ -37,10 +39,12 @@ class BigInt final : public js::gc::TenuredCell size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; - static JSLinearString* toString(js::ExclusiveContext* cx, BigInt* x); bool toBoolean(); static BigInt* copy(js::ExclusiveContext* cx, Handle<BigInt*> x); + + static JSLinearString* toString(js::ExclusiveContext* cx, BigInt* x, uint8_t radix); + }; static_assert(sizeof(BigInt) >= js::gc::CellSize, @@ -53,6 +57,11 @@ namespace js { extern JSAtom* BigIntToAtom(ExclusiveContext* cx, JS::BigInt* bi); +extern JS::BigInt* +NumberToBigInt(ExclusiveContext* cx, double d); + +extern JS::BigInt* +ToBigInt(ExclusiveContext* cx, JS::Handle<JS::Value> v); } // namespace js #endif diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h index 84582b0ac5..efbd8a5323 100644 --- a/js/src/vm/CommonPropertyNames.h +++ b/js/src/vm/CommonPropertyNames.h @@ -275,6 +275,7 @@ macro(objectArguments, objectArguments, "[object Arguments]") \ macro(objectArray, objectArray, "[object Array]") \ macro(objectBoolean, objectBoolean, "[object Boolean]") \ + macro(objectBigInt, objectBigInt, "[object BigInt]") \ macro(objectDate, objectDate, "[object Date]") \ macro(objectError, objectError, "[object Error]") \ macro(objectFunction, objectFunction, "[object Function]") \ diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 542160ce56..b7d3344b3e 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -15,6 +15,7 @@ #include "jsweakmap.h" #include "builtin/AtomicsObject.h" +#include "builtin/BigInt.h" #include "builtin/Eval.h" #include "builtin/MapObject.h" #include "builtin/ModuleObject.h" diff --git a/js/src/vm/StringBuffer.cpp b/js/src/vm/StringBuffer.cpp index 38f1e74e71..58a3c3e164 100644 --- a/js/src/vm/StringBuffer.cpp +++ b/js/src/vm/StringBuffer.cpp @@ -171,7 +171,7 @@ js::ValueToStringBufferSlow(JSContext* cx, const Value& arg, StringBuffer& sb) return false; } if (v.isBigInt()) { - JSString* str = BigInt::toString(cx, v.toBigInt()); + JSLinearString* str = BigInt::toString(cx, v.toBigInt(), 10); if (!str) return false; return sb.append(str); |