-
Notifications
You must be signed in to change notification settings - Fork 462
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #292 from devsnek/feature/bigint
bigint support
- Loading branch information
Showing
10 changed files
with
426 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# BigInt | ||
|
||
A JavaScript BigInt value. | ||
|
||
## Methods | ||
|
||
### New | ||
|
||
```cpp | ||
static BigInt New(Napi::Env env, int64_t value); | ||
static BigInt New(Napi::Env env, uint64_t value); | ||
``` | ||
- `[in] env`: The environment in which to construct the `BigInt` object. | ||
- `[in] value`: The value the JavaScript `BigInt` will contain | ||
These APIs convert the C `int64_t` and `uint64_t` types to the JavaScript | ||
`BigInt` type. | ||
```cpp | ||
static BigInt New(Napi::Env env, | ||
int sign_bit, | ||
size_t word_count, | ||
const uint64_t* words); | ||
``` | ||
|
||
- `[in] env`: The environment in which to construct the `BigInt` object. | ||
- `[in] sign_bit`: Determines if the resulting `BigInt` will be positive or negative. | ||
- `[in] word_count`: The length of the words array. | ||
- `[in] words`: An array of `uint64_t` little-endian 64-bit words. | ||
|
||
This API converts an array of unsigned 64-bit words into a single `BigInt` | ||
value. | ||
|
||
The resulting `BigInt` is calculated as: (–1)<sup>`sign_bit`</sup> (`words[0]` | ||
× (2<sup>64</sup>)<sup>0</sup> + `words[1]` × (2<sup>64</sup>)<sup>1</sup> + …) | ||
|
||
Returns a new JavaScript `BigInt`. | ||
|
||
### Constructor | ||
|
||
```cpp | ||
Napi::BigInt(); | ||
``` | ||
|
||
Returns a new empty JavaScript `BigInt`. | ||
|
||
### Int64Value | ||
|
||
```cpp | ||
int64_t Int64Value(bool* lossless) const; | ||
``` | ||
- `[out] lossless`: Indicates whether the `BigInt` value was converted | ||
losslessly. | ||
Returns the C `int64_t` primitive equivalent of the given JavaScript | ||
`BigInt`. If needed it will truncate the value, setting lossless to false. | ||
### Uint64Value | ||
```cpp | ||
uint64_t Uint64Value(bool* lossless) const; | ||
``` | ||
|
||
- `[out] lossless`: Indicates whether the `BigInt` value was converted | ||
losslessly. | ||
|
||
Returns the C `uint64_t` primitive equivalent of the given JavaScript | ||
`BigInt`. If needed it will truncate the value, setting lossless to false. | ||
|
||
### WordCount | ||
|
||
```cpp | ||
size_t WordCount() const; | ||
``` | ||
|
||
Returns the number of words needed to store this `BigInt` value. | ||
|
||
### ToWords | ||
|
||
```cpp | ||
void ToWords(size_t* word_count, int* sign_bit, uint64_t* words); | ||
``` | ||
- `[out] sign_bit`: Integer representing if the JavaScript `BigInt` is positive | ||
or negative. | ||
- `[in/out] word_count`: Must be initialized to the length of the words array. | ||
Upon return, it will be set to the actual number of words that would be | ||
needed to store this `BigInt`. | ||
- `[out] words`: Pointer to a pre-allocated 64-bit word array. | ||
Returns a single `BigInt` value into a sign bit, 64-bit little-endian array, | ||
and the number of elements in the array. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#define NAPI_EXPERIMENTAL | ||
#include "napi.h" | ||
|
||
using namespace Napi; | ||
|
||
namespace { | ||
|
||
Value IsLossless(const CallbackInfo& info) { | ||
Env env = info.Env(); | ||
|
||
BigInt big = info[0].As<BigInt>(); | ||
bool is_signed = info[1].ToBoolean().Value(); | ||
|
||
bool lossless; | ||
if (is_signed) { | ||
big.Int64Value(&lossless); | ||
} else { | ||
big.Uint64Value(&lossless); | ||
} | ||
|
||
return Boolean::New(env, lossless); | ||
} | ||
|
||
Value TestInt64(const CallbackInfo& info) { | ||
bool lossless; | ||
int64_t input = info[0].As<BigInt>().Int64Value(&lossless); | ||
|
||
return BigInt::New(info.Env(), input); | ||
} | ||
|
||
Value TestUint64(const CallbackInfo& info) { | ||
bool lossless; | ||
uint64_t input = info[0].As<BigInt>().Uint64Value(&lossless); | ||
|
||
return BigInt::New(info.Env(), input); | ||
} | ||
|
||
Value TestWords(const CallbackInfo& info) { | ||
BigInt big = info[0].As<BigInt>(); | ||
|
||
size_t expected_word_count = big.WordCount(); | ||
|
||
int sign_bit; | ||
size_t word_count = 10; | ||
uint64_t words[10]; | ||
|
||
big.ToWords(&sign_bit, &word_count, words); | ||
|
||
if (word_count != expected_word_count) { | ||
Error::New(info.Env(), "word count did not match").ThrowAsJavaScriptException(); | ||
return BigInt(); | ||
} | ||
|
||
return BigInt::New(info.Env(), sign_bit, word_count, words); | ||
} | ||
|
||
Value TestTooBigBigInt(const CallbackInfo& info) { | ||
int sign_bit = 0; | ||
size_t word_count = SIZE_MAX; | ||
uint64_t words[10]; | ||
|
||
return BigInt::New(info.Env(), sign_bit, word_count, words); | ||
} | ||
|
||
} // anonymous namespace | ||
|
||
Object InitBigInt(Env env) { | ||
Object exports = Object::New(env); | ||
exports["IsLossless"] = Function::New(env, IsLossless); | ||
exports["TestInt64"] = Function::New(env, TestInt64); | ||
exports["TestUint64"] = Function::New(env, TestUint64); | ||
exports["TestWords"] = Function::New(env, TestWords); | ||
exports["TestTooBigBigInt"] = Function::New(env, TestTooBigBigInt); | ||
|
||
return exports; | ||
} |
Oops, something went wrong.