1 #include <limits.h>
2 #include <inttypes.h>
3 #include <stdio.h>
4 #include <js_native_api.h>
5 #include "../common.h"
6
IsLossless(napi_env env,napi_callback_info info)7 static napi_value IsLossless(napi_env env, napi_callback_info info) {
8 size_t argc = 2;
9 napi_value args[2];
10 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
11
12 bool is_signed;
13 NAPI_CALL(env, napi_get_value_bool(env, args[1], &is_signed));
14
15 bool lossless;
16
17 if (is_signed) {
18 int64_t input;
19 NAPI_CALL(env, napi_get_value_bigint_int64(env, args[0], &input, &lossless));
20 } else {
21 uint64_t input;
22 NAPI_CALL(env, napi_get_value_bigint_uint64(env, args[0], &input, &lossless));
23 }
24
25 napi_value output;
26 NAPI_CALL(env, napi_get_boolean(env, lossless, &output));
27
28 return output;
29 }
30
TestInt64(napi_env env,napi_callback_info info)31 static napi_value TestInt64(napi_env env, napi_callback_info info) {
32 size_t argc = 1;
33 napi_value args[1];
34 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
35
36 NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
37
38 napi_valuetype valuetype0;
39 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
40
41 NAPI_ASSERT(env, valuetype0 == napi_bigint,
42 "Wrong type of arguments. Expects a bigint as first argument.");
43
44 int64_t input;
45 bool lossless;
46 NAPI_CALL(env, napi_get_value_bigint_int64(env, args[0], &input, &lossless));
47
48 napi_value output;
49 NAPI_CALL(env, napi_create_bigint_int64(env, input, &output));
50
51 return output;
52 }
53
TestUint64(napi_env env,napi_callback_info info)54 static napi_value TestUint64(napi_env env, napi_callback_info info) {
55 size_t argc = 1;
56 napi_value args[1];
57 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
58
59 NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
60
61 napi_valuetype valuetype0;
62 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
63
64 NAPI_ASSERT(env, valuetype0 == napi_bigint,
65 "Wrong type of arguments. Expects a bigint as first argument.");
66
67 uint64_t input;
68 bool lossless;
69 NAPI_CALL(env, napi_get_value_bigint_uint64(
70 env, args[0], &input, &lossless));
71
72 napi_value output;
73 NAPI_CALL(env, napi_create_bigint_uint64(env, input, &output));
74
75 return output;
76 }
77
TestWords(napi_env env,napi_callback_info info)78 static napi_value TestWords(napi_env env, napi_callback_info info) {
79 size_t argc = 1;
80 napi_value args[1];
81 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
82
83 NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
84
85 napi_valuetype valuetype0;
86 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
87
88 NAPI_ASSERT(env, valuetype0 == napi_bigint,
89 "Wrong type of arguments. Expects a bigint as first argument.");
90
91 size_t expected_word_count;
92 NAPI_CALL(env, napi_get_value_bigint_words(
93 env, args[0], NULL, &expected_word_count, NULL));
94
95 int sign_bit;
96 size_t word_count = 10;
97 uint64_t words[10];
98
99 NAPI_CALL(env, napi_get_value_bigint_words(
100 env, args[0], &sign_bit, &word_count, words));
101
102 NAPI_ASSERT(env, word_count == expected_word_count,
103 "word counts do not match");
104
105 napi_value output;
106 NAPI_CALL(env, napi_create_bigint_words(
107 env, sign_bit, word_count, words, &output));
108
109 return output;
110 }
111
112 // throws RangeError
CreateTooBigBigInt(napi_env env,napi_callback_info info)113 static napi_value CreateTooBigBigInt(napi_env env, napi_callback_info info) {
114 int sign_bit = 0;
115 size_t word_count = SIZE_MAX;
116 uint64_t words[10];
117
118 napi_value output;
119
120 NAPI_CALL(env, napi_create_bigint_words(
121 env, sign_bit, word_count, words, &output));
122
123 return output;
124 }
125
126 // Test that we correctly forward exceptions from the engine.
MakeBigIntWordsThrow(napi_env env,napi_callback_info info)127 static napi_value MakeBigIntWordsThrow(napi_env env, napi_callback_info info) {
128 uint64_t words[10];
129 napi_value output;
130
131 napi_status status = napi_create_bigint_words(env,
132 0,
133 INT_MAX,
134 words,
135 &output);
136 if (status != napi_pending_exception)
137 napi_throw_error(env, NULL, "Expected status `napi_pending_exception`");
138
139 return NULL;
140 }
141
142 EXTERN_C_START
Init(napi_env env,napi_value exports)143 napi_value Init(napi_env env, napi_value exports) {
144 napi_property_descriptor descriptors[] = {
145 DECLARE_NAPI_PROPERTY("IsLossless", IsLossless),
146 DECLARE_NAPI_PROPERTY("TestInt64", TestInt64),
147 DECLARE_NAPI_PROPERTY("TestUint64", TestUint64),
148 DECLARE_NAPI_PROPERTY("TestWords", TestWords),
149 DECLARE_NAPI_PROPERTY("CreateTooBigBigInt", CreateTooBigBigInt),
150 DECLARE_NAPI_PROPERTY("MakeBigIntWordsThrow", MakeBigIntWordsThrow),
151 };
152
153 NAPI_CALL(env, napi_define_properties(
154 env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
155
156 return exports;
157 }
158 EXTERN_C_END
159