diff --git a/ReactCommon/jsi/JSCRuntime.cpp b/ReactCommon/jsi/JSCRuntime.cpp index 9eb578a229eb12..ae907bbd16f373 100644 --- a/ReactCommon/jsi/JSCRuntime.cpp +++ b/ReactCommon/jsi/JSCRuntime.cpp @@ -158,6 +158,13 @@ class JSCRuntime : public jsi::Runtime { std::string symbolToString(const jsi::Symbol &) override; + jsi::BigInt createBigIntFromInt64(int64_t) override; + jsi::BigInt createBigIntFromUint64(uint64_t) override; + bool bigintIsInt64(const jsi::BigInt &) override; + bool bigintIsUint64(const jsi::BigInt &) override; + uint64_t truncate(const jsi::BigInt &) override; + jsi::String bigintToString(const jsi::BigInt &, int) override; + jsi::String createStringFromAscii(const char *str, size_t length) override; jsi::String createStringFromUtf8(const uint8_t *utf8, size_t length) override; std::string utf8(const jsi::String &) override; @@ -686,6 +693,30 @@ std::string JSCRuntime::symbolToString(const jsi::Symbol &sym) { return jsi::Value(*this, sym).toString(*this).utf8(*this); } +jsi::BigInt JSCRuntime::createBigIntFromInt64(int64_t) { + throw std::logic_error("Not implemented"); +} + +jsi::BigInt JSCRuntime::createBigIntFromUint64(uint64_t) { + throw std::logic_error("Not implemented"); +} + +bool JSCRuntime::bigintIsInt64(const jsi::BigInt &) { + throw std::logic_error("Not implemented"); +} + +bool JSCRuntime::bigintIsUint64(const jsi::BigInt &) { + throw std::logic_error("Not implemented"); +} + +uint64_t JSCRuntime::truncate(const jsi::BigInt &) { + throw std::logic_error("Not implemented"); +} + +jsi::String JSCRuntime::bigintToString(const jsi::BigInt &, int) { + throw std::logic_error("Not implemented"); +} + jsi::String JSCRuntime::createStringFromAscii(const char *str, size_t length) { // Yes we end up double casting for semantic reasons (UTF8 contains ASCII, // not the other way around) diff --git a/ReactCommon/jsi/jsi/decorator.h b/ReactCommon/jsi/jsi/decorator.h index 5c4811ac26ba8e..075cb8aa666699 100644 --- a/ReactCommon/jsi/jsi/decorator.h +++ b/ReactCommon/jsi/jsi/decorator.h @@ -193,6 +193,25 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation { return plain_.symbolToString(sym); } + BigInt createBigIntFromInt64(int64_t value) override { + return plain_.createBigIntFromInt64(value); + } + BigInt createBigIntFromUint64(uint64_t value) override { + return plain_.createBigIntFromUint64(value); + } + bool bigintIsInt64(const BigInt& b) override { + return plain_.bigintIsInt64(b); + } + bool bigintIsUint64(const BigInt& b) override { + return plain_.bigintIsUint64(b); + } + uint64_t truncate(const BigInt& b) override { + return plain_.truncate(b); + } + String bigintToString(const BigInt& bigint, int radix) override { + return plain_.bigintToString(bigint, radix); + } + String createStringFromAscii(const char* str, size_t length) override { return plain_.createStringFromAscii(str, length); }; diff --git a/ReactCommon/jsi/jsi/jsi-inl.h b/ReactCommon/jsi/jsi/jsi-inl.h index c3cad4dd8e7fca..a7e51583492668 100644 --- a/ReactCommon/jsi/jsi/jsi-inl.h +++ b/ReactCommon/jsi/jsi/jsi-inl.h @@ -341,5 +341,9 @@ inline Value Function::callAsConstructor(Runtime& runtime, Args&&... args) runtime, {detail::toValue(runtime, std::forward(args))...}); } +String BigInt::toString(Runtime& runtime, int radix) const { + return runtime.bigintToString(*this, radix); +} + } // namespace jsi } // namespace facebook diff --git a/ReactCommon/jsi/jsi/jsi.cpp b/ReactCommon/jsi/jsi/jsi.cpp index c8fe78379eaf67..815189d2443182 100644 --- a/ReactCommon/jsi/jsi/jsi.cpp +++ b/ReactCommon/jsi/jsi/jsi.cpp @@ -381,6 +381,20 @@ String Value::toString(Runtime& runtime) const { return toString.call(runtime, *this).getString(runtime); } +uint64_t BigInt::asUint64(Runtime& runtime) const { + if (!isUint64(runtime)) { + throw JSError(runtime, "Lossy truncation in BigInt64::asUint64"); + } + return getUint64(runtime); +} + +int64_t BigInt::asInt64(Runtime& runtime) const { + if (!isInt64(runtime)) { + throw JSError(runtime, "Lossy truncation in BigInt64::asInt64"); + } + return getInt64(runtime); +} + Array Array::createWithElements( Runtime& rt, std::initializer_list elements) { diff --git a/ReactCommon/jsi/jsi/jsi.h b/ReactCommon/jsi/jsi/jsi.h index 4dc4a8fe5dc0e2..85c0626905c974 100644 --- a/ReactCommon/jsi/jsi/jsi.h +++ b/ReactCommon/jsi/jsi/jsi.h @@ -290,6 +290,13 @@ class JSI_EXPORT Runtime { virtual std::string symbolToString(const Symbol&) = 0; + virtual BigInt createBigIntFromInt64(int64_t) = 0; + virtual BigInt createBigIntFromUint64(uint64_t) = 0; + virtual bool bigintIsInt64(const BigInt&) = 0; + virtual bool bigintIsUint64(const BigInt&) = 0; + virtual uint64_t truncate(const BigInt&) = 0; + virtual String bigintToString(const BigInt&, int) = 0; + virtual String createStringFromAscii(const char* str, size_t length) = 0; virtual String createStringFromUtf8(const uint8_t* utf8, size_t length) = 0; virtual std::string utf8(const String&) = 0; @@ -507,6 +514,53 @@ class JSI_EXPORT BigInt : public Pointer { BigInt(BigInt&& other) = default; BigInt& operator=(BigInt&& other) = default; + /// Create a BigInt representing the signed 64-bit \p value. + static BigInt fromInt64(Runtime& runtime, int64_t value) { + return runtime.createBigIntFromInt64(value); + } + + /// Create a BigInt representing the unsigned 64-bit \p value. + static BigInt fromUint64(Runtime& runtime, uint64_t value) { + return runtime.createBigIntFromUint64(value); + } + + /// \return whether a === b. + static bool strictEquals(Runtime& runtime, const BigInt& a, const BigInt& b) { + return runtime.strictEquals(a, b); + } + + /// \returns This bigint truncated to a signed 64-bit integer. + int64_t getInt64(Runtime& runtime) const { + return runtime.truncate(*this); + } + + /// \returns Whether this bigint can be losslessly converted to int64_t. + bool isInt64(Runtime& runtime) const { + return runtime.bigintIsInt64(*this); + } + + /// \returns This bigint truncated to a signed 64-bit integer. Throws a + /// JSIException if the truncation is lossy. + int64_t asInt64(Runtime& runtime) const; + + /// \returns This bigint truncated to an unsigned 64-bit integer. + uint64_t getUint64(Runtime& runtime) const { + return runtime.truncate(*this); + } + + /// \returns Whether this bigint can be losslessly converted to uint64_t. + bool isUint64(Runtime& runtime) const { + return runtime.bigintIsUint64(*this); + } + + /// \returns This bigint truncated to an unsigned 64-bit integer. Throws a + /// JSIException if the truncation is lossy. + uint64_t asUint64(Runtime& runtime) const; + + /// \returns this BigInt converted to a String in base \p radix. Throws a + /// JSIException if radix is not in the [2, 36] range. + inline String toString(Runtime& runtime, int radix = 10) const; + friend class Runtime; friend class Value; };