aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Derrick Farris <mr.dcfarris@gmail.com> 2023-02-13 05:07:18 -0600
committerGravatar GitHub <noreply@github.com> 2023-02-13 03:07:18 -0800
commit739de2c9cd19736b6d088a9f127b52709e72909b (patch)
treef5df3fb866408bb0f8e68c49ddd4412a044c0804
parent0db8cdf4e9e79214410454f9225b14f2765bc3c5 (diff)
downloadbun-739de2c9cd19736b6d088a9f127b52709e72909b.tar.gz
bun-739de2c9cd19736b6d088a9f127b52709e72909b.tar.zst
bun-739de2c9cd19736b6d088a9f127b52709e72909b.zip
feat(napi): add `napi_get_value_bigint_words` (#2061)
* feat(napi): add `napi_get_value_bigint_words` * fix(napi): handle `napi_get_value_bigint_words` arr too small
-rw-r--r--src/bun.js/bindings/napi.cpp42
-rw-r--r--src/napi/napi.zig1
-rw-r--r--src/symbols.txt1
3 files changed, 44 insertions, 0 deletions
diff --git a/src/bun.js/bindings/napi.cpp b/src/bun.js/bindings/napi.cpp
index 574224939..ecae69427 100644
--- a/src/bun.js/bindings/napi.cpp
+++ b/src/bun.js/bindings/napi.cpp
@@ -1568,6 +1568,48 @@ extern "C" napi_status napi_typeof(napi_env env, napi_value val,
return napi_generic_failure;
}
+extern "C" napi_status napi_get_value_bigint_words(napi_env env,
+ napi_value value,
+ int* sign_bit,
+ size_t* word_count,
+ uint64_t* words)
+{
+ Zig::GlobalObject* globalObject = toJS(env);
+
+ JSC::JSValue jsValue = toJS(value);
+ if (UNLIKELY(!jsValue.isBigInt()))
+ return napi_invalid_arg;
+
+ JSC::JSBigInt* bigInt = jsValue.asHeapBigInt();
+ if (UNLIKELY(!bigInt))
+ return napi_invalid_arg;
+
+ if (UNLIKELY(word_count == nullptr))
+ return napi_invalid_arg;
+
+ size_t available_words = *word_count;
+ *word_count = bigInt->length();
+
+ // If both sign_bit and words are nullptr, we're just querying the word count
+ // Return ok in this case
+ if (sign_bit == nullptr) {
+ // However, if one of them is nullptr, we have an invalid argument
+ if (UNLIKELY(words != nullptr))
+ return napi_invalid_arg;
+
+ return napi_ok;
+ } else if (UNLIKELY(words == nullptr))
+ return napi_invalid_arg; // If sign_bit is not nullptr, words must not be nullptr
+
+ *sign_bit = (int)bigInt->sign();
+
+ size_t len = *word_count;
+ for (size_t i = 0; i < available_words && i < len; i++)
+ words[i] = bigInt->digit(i);
+
+ return napi_ok;
+}
+
extern "C" napi_status napi_get_value_external(napi_env env, napi_value value,
void** result)
{
diff --git a/src/napi/napi.zig b/src/napi/napi.zig
index 73a633025..ba5040ca8 100644
--- a/src/napi/napi.zig
+++ b/src/napi/napi.zig
@@ -1504,6 +1504,7 @@ pub fn fixDeadCodeElimination() void {
std.mem.doNotOptimizeAway(&napi_create_bigint_uint64);
std.mem.doNotOptimizeAway(&napi_get_value_bigint_int64);
std.mem.doNotOptimizeAway(&napi_get_value_bigint_uint64);
+ std.mem.doNotOptimizeAway(&napi_get_value_bigint_words);
std.mem.doNotOptimizeAway(&napi_fatal_error);
std.mem.doNotOptimizeAway(&napi_fatal_exception);
std.mem.doNotOptimizeAway(&napi_create_buffer);
diff --git a/src/symbols.txt b/src/symbols.txt
index 72f24291d..16125adb3 100644
--- a/src/symbols.txt
+++ b/src/symbols.txt
@@ -81,6 +81,7 @@ _napi_get_undefined
_napi_get_uv_event_loop
_napi_get_value_bigint_int64
_napi_get_value_bigint_uint64
+_napi_get_value_bigint_words
_napi_get_value_bool
_napi_get_value_double
_napi_get_value_external