1 #include <node_api.h>
2 #include <assert.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 
CallWithString(napi_env env, napi_callback_info info)7 static napi_value CallWithString(napi_env env, napi_callback_info info) {
8   napi_status status;
9 
10   size_t argc = 1;
11   napi_value args[1];
12   status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
13   assert(status == napi_ok);
14 
15   napi_valuetype types[1];
16   status = napi_typeof(env, args[0], types);
17   assert(status == napi_ok);
18 
19   assert(types[0] == napi_string);
20   if (types[0] == napi_string) {
21     size_t len = 0;
22     // Get the length
23     status = napi_get_value_string_utf8(env, args[0], NULL, 0, &len);
24     assert(status == napi_ok);
25     char* buf = (char*)malloc(len + 1);
26     status = napi_get_value_string_utf8(env, args[0], buf, len + 1, &len);
27     assert(status == napi_ok);
28     free(buf);
29   }
30 
31   return NULL;
32 }
33 
CallWithArray(napi_env env, napi_callback_info info)34 static napi_value CallWithArray(napi_env env, napi_callback_info info) {
35   napi_status status;
36 
37   size_t argc = 1;
38   napi_value args[1];
39   status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
40   assert(status == napi_ok);
41 
42   napi_value array = args[0];
43   bool is_array = false;
44   status = napi_is_array(env, array, &is_array);
45   assert(status == napi_ok);
46 
47   assert(is_array);
48   if (is_array) {
49     uint32_t length;
50     status = napi_get_array_length(env, array, &length);
51     assert(status == napi_ok);
52 
53     uint32_t i;
54     for (i = 0; i < length; ++i) {
55       napi_value v;
56       status = napi_get_element(env, array, i, &v);
57       assert(status == napi_ok);
58     }
59   }
60 
61   return NULL;
62 }
63 
CallWithNumber(napi_env env, napi_callback_info info)64 static napi_value CallWithNumber(napi_env env, napi_callback_info info) {
65   napi_status status;
66 
67   size_t argc = 1;
68   napi_value args[1];
69   status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
70   assert(status == napi_ok);
71 
72   napi_valuetype types[1];
73   status = napi_typeof(env, args[0], types);
74   assert(status == napi_ok);
75 
76   assert(types[0] == napi_number);
77   if (types[0] == napi_number) {
78     double value = 0.0;
79     status = napi_get_value_double(env, args[0], &value);
80     assert(status == napi_ok);
81   }
82 
83   return NULL;
84 }
85 
CallWithObject(napi_env env, napi_callback_info info)86 static napi_value CallWithObject(napi_env env, napi_callback_info info) {
87   napi_status status;
88 
89   size_t argc = 1;
90   napi_value args[1];
91   status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
92   assert(status == napi_ok);
93 
94   napi_valuetype types[1];
95   status = napi_typeof(env, args[0], types);
96   assert(status == napi_ok);
97 
98   assert(argc == 1 && types[0] == napi_object);
99   if (argc == 1 && types[0] == napi_object) {
100     napi_value value;
101 
102     status = napi_get_named_property(env, args[0], "map", &value);
103     assert(status == napi_ok);
104 
105     status = napi_get_named_property(env, args[0], "operand", &value);
106     assert(status == napi_ok);
107 
108     status = napi_get_named_property(env, args[0], "data", &value);
109     assert(status == napi_ok);
110 
111     status = napi_get_named_property(env, args[0], "reduce", &value);
112     assert(status == napi_ok);
113   }
114 
115   return NULL;
116 }
117 
CallWithTypedarray(napi_env env, napi_callback_info info)118 static napi_value CallWithTypedarray(napi_env env, napi_callback_info info) {
119   napi_status status;
120 
121   size_t argc = 1;
122   napi_value args[1];
123   status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
124   assert(status == napi_ok);
125 
126   bool is_typedarray = false;
127   status = napi_is_typedarray(env, args[0], &is_typedarray);
128   assert(status == napi_ok);
129 
130   assert(is_typedarray);
131   if (is_typedarray) {
132     napi_typedarray_type type;
133     napi_value input_buffer;
134     size_t byte_offset = 0;
135     size_t length = 0;
136     status = napi_get_typedarray_info(env, args[0], &type, &length,
137         NULL, &input_buffer, &byte_offset);
138     assert(status == napi_ok);
139     assert(length > 0);
140 
141     void* data = NULL;
142     size_t byte_length = 0;
143     status = napi_get_arraybuffer_info(env,
144         input_buffer, &data, &byte_length);
145     assert(status == napi_ok);
146 
147     uint32_t* input_integers = (uint32_t*)((uint8_t*)(data) + byte_offset);
148     assert(input_integers);
149   }
150 
151   return NULL;
152 }
153 
CallWithArguments(napi_env env, napi_callback_info info)154 static napi_value CallWithArguments(napi_env env, napi_callback_info info) {
155   napi_status status;
156 
157   size_t argc = 1;
158   napi_value args[1000];
159   // Get the length
160   status = napi_get_cb_info(env, info, &argc, NULL, NULL, NULL);
161   assert(status == napi_ok);
162 
163   status = napi_get_cb_info(env, info, &argc, args, NULL, NULL);
164   assert(status == napi_ok);
165   assert(argc <= 1000);
166 
167   napi_valuetype types[1];
168   status = napi_typeof(env, args[0], types);
169   assert(status == napi_ok);
170 
171   assert(argc > 1 && types[0] == napi_number);
172   if (argc > 1 && types[0] == napi_number) {
173     uint32_t loop = 0;
174     status = napi_get_value_uint32(env, args[0], &loop);
175     assert(status == napi_ok);
176 
177     uint32_t i;
178     for (i = 1; i < loop; ++i) {
179       assert(i < argc);
180       status = napi_typeof(env, args[i], types);
181       assert(status == napi_ok);
182       assert(types[0] == napi_number);
183 
184       uint32_t value = 0;
185       status = napi_get_value_uint32(env, args[i], &value);
186       assert(status == napi_ok);
187     }
188   }
189 
190   return NULL;
191 }
192 
193 
194 #define EXPORT_FUNC(env, exports, name, func)       \
195   do {                                              \
196     napi_status status;                             \
197     napi_value js_func;                             \
198     status = napi_create_function((env),            \
199                                   (name),           \
200                                   NAPI_AUTO_LENGTH, \
201                                   (func),           \
202                                   NULL,             \
203                                   &js_func);        \
204     assert(status == napi_ok);                      \
205     status = napi_set_named_property((env),         \
206                                      (exports),     \
207                                      (name),        \
208                                      js_func);      \
209     assert(status == napi_ok);                      \
210   } while (0);
211 
212 
NAPI_MODULE_INITnull213 NAPI_MODULE_INIT() {
214   EXPORT_FUNC(env, exports, "callWithString", CallWithString);
215   EXPORT_FUNC(env, exports, "callWithLongString", CallWithString);
216 
217   EXPORT_FUNC(env, exports, "callWithArray", CallWithArray);
218   EXPORT_FUNC(env, exports, "callWithLargeArray", CallWithArray);
219   EXPORT_FUNC(env, exports, "callWithHugeArray", CallWithArray);
220 
221   EXPORT_FUNC(env, exports, "callWithNumber", CallWithNumber);
222 
223   EXPORT_FUNC(env, exports, "callWithObject", CallWithObject);
224   EXPORT_FUNC(env, exports, "callWithTypedarray", CallWithTypedarray);
225 
226   EXPORT_FUNC(env, exports, "callWith10Numbers", CallWithArguments);
227   EXPORT_FUNC(env, exports, "callWith100Numbers", CallWithArguments);
228   EXPORT_FUNC(env, exports, "callWith1000Numbers", CallWithArguments);
229 
230   return exports;
231 }
232