Skip to content

Commit

Permalink
Add methods for creating and interacting with BigInt
Browse files Browse the repository at this point in the history
Summary:
This change adds the following methods to jsi::BigInt

  * [static] fromInt64(value): creates a jsi::BigInt from a signed 64-bit value
  * [static] fromUint64(value): creates a jsi::BigInt from an unsigned 64-bit value
  * [static] strictEquals(a, b): return a === b, a and b are BigInts
  * asInt64(): truncates the BigInt to a single signed 64-bit integer; throws a JSIException if the truncation is lossy.
  * getInt64(): truncates the BigInt to a single signed 64-bit integer
  * isInt64(): returns true if the BigInt can be truncated losslessly to an int64_t
  * asUint64(): truncates the BigInt to a single unsigned 64-bit integer; throws a JSIException if the truncation is lossy.
  * getUint64(): truncates the BigInt to a single unsigned 64-bit integer
  * isUint64(): returns true if the BigInt can be truncated losslessly to an uint64_t
  * toString(radix): converts the BigInt to a string representing the number in the given radix.

 A lossy truncation is one that yields a result from which the BigInt cannot be reconstructed from, i.e.,
* BigInt::fromInt64(b.toInt64()) !== b
* BigInt::fromUint64(b.toUint64()) !== b

Changelog: [Internal]

Reviewed By: kodafb

Differential Revision: D37909139

fbshipit-source-id: 172848024f8367aed73cc602f38cde22f03cac8f
  • Loading branch information
jpporto authored and facebook-github-bot committed Jul 29, 2022
1 parent 086714b commit a21a1f8
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 0 deletions.
31 changes: 31 additions & 0 deletions ReactCommon/jsi/JSCRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
19 changes: 19 additions & 0 deletions ReactCommon/jsi/jsi/decorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
Expand Down
4 changes: 4 additions & 0 deletions ReactCommon/jsi/jsi/jsi-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,5 +341,9 @@ inline Value Function::callAsConstructor(Runtime& runtime, Args&&... args)
runtime, {detail::toValue(runtime, std::forward<Args>(args))...});
}

String BigInt::toString(Runtime& runtime, int radix) const {
return runtime.bigintToString(*this, radix);
}

} // namespace jsi
} // namespace facebook
14 changes: 14 additions & 0 deletions ReactCommon/jsi/jsi/jsi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Value> elements) {
Expand Down
54 changes: 54 additions & 0 deletions ReactCommon/jsi/jsi/jsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
};
Expand Down

0 comments on commit a21a1f8

Please sign in to comment.