diff options
author | 2023-02-13 05:07:18 -0600 | |
---|---|---|
committer | 2023-02-13 03:07:18 -0800 | |
commit | 739de2c9cd19736b6d088a9f127b52709e72909b (patch) | |
tree | f5df3fb866408bb0f8e68c49ddd4412a044c0804 | |
parent | 0db8cdf4e9e79214410454f9225b14f2765bc3c5 (diff) | |
download | bun-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.cpp | 42 | ||||
-rw-r--r-- | src/napi/napi.zig | 1 | ||||
-rw-r--r-- | src/symbols.txt | 1 |
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 |