• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef NAPI_EXPERIMENTAL
16 #define NAPI_EXPERIMENTAL
17 #endif
18 
19 #include "native_api_internal.h"
20 #include "native_engine/native_property.h"
21 #include "native_engine/native_value.h"
22 #include "securec.h"
23 #include "utils/log.h"
24 
napi_get_last_error_info(napi_env env,const napi_extended_error_info ** result)25 NAPI_EXTERN napi_status napi_get_last_error_info(napi_env env, const napi_extended_error_info** result)
26 {
27     CHECK_ENV(env);
28     CHECK_ARG(env, result);
29 
30     auto engine = reinterpret_cast<NativeEngine*>(env);
31 
32     *result = reinterpret_cast<napi_extended_error_info*>(engine->GetLastError());
33     if ((*result)->error_code == napi_ok) {
34         napi_clear_last_error(env);
35     }
36     return napi_ok;
37 }
38 
39 // Getters for defined singletons
napi_get_undefined(napi_env env,napi_value * result)40 NAPI_EXTERN napi_status napi_get_undefined(napi_env env, napi_value* result)
41 {
42     CHECK_ENV(env);
43     CHECK_ARG(env, result);
44 
45     auto engine = reinterpret_cast<NativeEngine*>(env);
46     auto resultValue = engine->CreateUndefined();
47 
48     *result = reinterpret_cast<napi_value>(resultValue);
49     return napi_clear_last_error(env);
50 }
51 
napi_get_null(napi_env env,napi_value * result)52 NAPI_EXTERN napi_status napi_get_null(napi_env env, napi_value* result)
53 {
54     CHECK_ENV(env);
55     CHECK_ARG(env, result);
56 
57     auto engine = reinterpret_cast<NativeEngine*>(env);
58     auto resultValue = engine->CreateNull();
59 
60     *result = reinterpret_cast<napi_value>(resultValue);
61     return napi_clear_last_error(env);
62 }
63 
napi_get_global(napi_env env,napi_value * result)64 NAPI_EXTERN napi_status napi_get_global(napi_env env, napi_value* result)
65 {
66     CHECK_ENV(env);
67     CHECK_ARG(env, result);
68 
69     auto engine = reinterpret_cast<NativeEngine*>(env);
70     auto resultValue = engine->GetGlobal();
71 
72     *result = reinterpret_cast<napi_value>(resultValue);
73     return napi_clear_last_error(env);
74 }
75 
napi_get_boolean(napi_env env,bool value,napi_value * result)76 NAPI_EXTERN napi_status napi_get_boolean(napi_env env, bool value, napi_value* result)
77 {
78     CHECK_ENV(env);
79     CHECK_ARG(env, result);
80 
81     auto engine = reinterpret_cast<NativeEngine*>(env);
82     auto resultValue = engine->CreateBoolean(value);
83 
84     *result = reinterpret_cast<napi_value>(resultValue);
85     return napi_clear_last_error(env);
86 }
87 
88 // Methods to create Primitive types/Objects
napi_create_object(napi_env env,napi_value * result)89 NAPI_EXTERN napi_status napi_create_object(napi_env env, napi_value* result)
90 {
91     CHECK_ENV(env);
92     CHECK_ARG(env, result);
93 
94     auto engine = reinterpret_cast<NativeEngine*>(env);
95     auto resultValue = engine->CreateObject();
96 
97     *result = reinterpret_cast<napi_value>(resultValue);
98     return napi_clear_last_error(env);
99 }
100 
napi_create_array(napi_env env,napi_value * result)101 NAPI_EXTERN napi_status napi_create_array(napi_env env, napi_value* result)
102 {
103     CHECK_ENV(env);
104     CHECK_ARG(env, result);
105 
106     auto engine = reinterpret_cast<NativeEngine*>(env);
107     auto resultValue = engine->CreateArray(0);
108 
109     *result = reinterpret_cast<napi_value>(resultValue);
110     return napi_clear_last_error(env);
111 }
112 
napi_create_array_with_length(napi_env env,size_t length,napi_value * result)113 NAPI_EXTERN napi_status napi_create_array_with_length(napi_env env, size_t length, napi_value* result)
114 {
115     CHECK_ENV(env);
116     CHECK_ARG(env, result);
117 
118     auto engine = reinterpret_cast<NativeEngine*>(env);
119     auto resultValue = engine->CreateArray(length);
120 
121     *result = reinterpret_cast<napi_value>(resultValue);
122     return napi_clear_last_error(env);
123 }
124 
napi_create_double(napi_env env,double value,napi_value * result)125 NAPI_EXTERN napi_status napi_create_double(napi_env env, double value, napi_value* result)
126 {
127     CHECK_ENV(env);
128     CHECK_ARG(env, result);
129 
130     auto engine = reinterpret_cast<NativeEngine*>(env);
131     auto resultValue = engine->CreateNumber(value);
132 
133     *result = reinterpret_cast<napi_value>(resultValue);
134     return napi_clear_last_error(env);
135 }
136 
napi_create_int32(napi_env env,int32_t value,napi_value * result)137 NAPI_EXTERN napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)
138 {
139     CHECK_ENV(env);
140     CHECK_ARG(env, result);
141 
142     auto engine = reinterpret_cast<NativeEngine*>(env);
143     auto resultValue = engine->CreateNumber(value);
144 
145     *result = reinterpret_cast<napi_value>(resultValue);
146     return napi_clear_last_error(env);
147 }
148 
napi_create_uint32(napi_env env,uint32_t value,napi_value * result)149 NAPI_EXTERN napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)
150 {
151     CHECK_ENV(env);
152     CHECK_ARG(env, result);
153 
154     auto engine = reinterpret_cast<NativeEngine*>(env);
155     auto resultValue = engine->CreateNumber(value);
156 
157     *result = reinterpret_cast<napi_value>(resultValue);
158     return napi_clear_last_error(env);
159 }
160 
napi_create_int64(napi_env env,int64_t value,napi_value * result)161 NAPI_EXTERN napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)
162 {
163     CHECK_ENV(env);
164     CHECK_ARG(env, result);
165 
166     auto engine = reinterpret_cast<NativeEngine*>(env);
167     auto resultValue = engine->CreateNumber(value);
168 
169     *result = reinterpret_cast<napi_value>(resultValue);
170     return napi_clear_last_error(env);
171 }
172 
napi_create_string_latin1(napi_env env,const char * str,size_t length,napi_value * result)173 NAPI_EXTERN napi_status napi_create_string_latin1(napi_env env, const char* str, size_t length, napi_value* result)
174 {
175     CHECK_ENV(env);
176     CHECK_ARG(env, str);
177     CHECK_ARG(env, result);
178 
179     auto engine = reinterpret_cast<NativeEngine*>(env);
180     auto resultValue = engine->CreateString(str, (length == NAPI_AUTO_LENGTH) ? strlen(str) : length);
181 
182     *result = reinterpret_cast<napi_value>(resultValue);
183     return napi_clear_last_error(env);
184 }
185 
napi_create_string_utf8(napi_env env,const char * str,size_t length,napi_value * result)186 NAPI_EXTERN napi_status napi_create_string_utf8(napi_env env, const char* str, size_t length, napi_value* result)
187 {
188     CHECK_ENV(env);
189     CHECK_ARG(env, str);
190     CHECK_ARG(env, result);
191 
192     auto engine = reinterpret_cast<NativeEngine*>(env);
193     auto resultValue = engine->CreateString(str, (length == NAPI_AUTO_LENGTH) ? strlen(str) : length);
194 
195     *result = reinterpret_cast<napi_value>(resultValue);
196     return napi_clear_last_error(env);
197 }
198 
napi_create_string_utf16(napi_env env,const char16_t * str,size_t length,napi_value * result)199 NAPI_EXTERN napi_status napi_create_string_utf16(
200     napi_env env, const char16_t* str, size_t length, napi_value* result)
201 {
202     CHECK_ENV(env);
203     CHECK_ARG(env, str);
204     CHECK_ARG(env, result);
205     RETURN_STATUS_IF_FALSE(env, (length == NAPI_AUTO_LENGTH) || (length <= INT_MAX && length >= 0), napi_invalid_arg);
206     auto engine = reinterpret_cast<NativeEngine*>(env);
207     int char16Length = static_cast<int>(std::char_traits<char16_t>::length(str));
208     auto resultValue = engine->CreateString16(str, (length == NAPI_AUTO_LENGTH) ? char16Length : length);
209 
210     *result = reinterpret_cast<napi_value>(resultValue);
211     return napi_clear_last_error(env);
212 }
213 
napi_create_symbol(napi_env env,napi_value description,napi_value * result)214 NAPI_EXTERN napi_status napi_create_symbol(napi_env env, napi_value description, napi_value* result)
215 {
216     CHECK_ENV(env);
217     CHECK_ARG(env, result);
218 
219     auto engine = reinterpret_cast<NativeEngine*>(env);
220     auto descriptionValue = reinterpret_cast<NativeValue*>(description);
221     if (description == nullptr) {
222         const char* str = "";
223         descriptionValue = engine->CreateString(str, 0);
224     }
225     RETURN_STATUS_IF_FALSE(env, (descriptionValue->TypeOf() == NATIVE_STRING), napi_invalid_arg);
226     auto resultValue = engine->CreateSymbol(descriptionValue);
227     *result = reinterpret_cast<napi_value>(resultValue);
228     return napi_clear_last_error(env);
229 }
230 
napi_create_function(napi_env env,const char * utf8name,size_t length,napi_callback cb,void * data,napi_value * result)231 NAPI_EXTERN napi_status napi_create_function(napi_env env,
232                                              const char* utf8name,
233                                              size_t length,
234                                              napi_callback cb,
235                                              void* data,
236                                              napi_value* result)
237 {
238     CHECK_ENV(env);
239     CHECK_ARG(env, cb);
240     CHECK_ARG(env, result);
241 
242     auto engine = reinterpret_cast<NativeEngine*>(env);
243     auto callback = reinterpret_cast<NativeCallback>(cb);
244     NativeValue* resultValue = nullptr;
245     if (utf8name != nullptr) {
246         resultValue = engine->CreateFunction(utf8name,
247             (length == NAPI_AUTO_LENGTH) ? strlen(utf8name) : length, callback, data);
248     } else {
249         const char* name = "defaultName";
250         resultValue = engine->CreateFunction(name,
251             (length == NAPI_AUTO_LENGTH) ? strlen(name) : length, callback, data);
252     }
253 
254     *result = reinterpret_cast<napi_value>(resultValue);
255     return napi_clear_last_error(env);
256 }
257 
napi_create_error(napi_env env,napi_value code,napi_value msg,napi_value * result)258 NAPI_EXTERN napi_status napi_create_error(napi_env env, napi_value code, napi_value msg, napi_value* result)
259 {
260     CHECK_ENV(env);
261     CHECK_ARG(env, msg);
262     CHECK_ARG(env, result);
263 
264     auto engine = reinterpret_cast<NativeEngine*>(env);
265     auto codeValue = reinterpret_cast<NativeValue*>(code);
266     auto msgValue = reinterpret_cast<NativeValue*>(msg);
267 
268     if (codeValue != nullptr) {
269         RETURN_STATUS_IF_FALSE(env, codeValue->TypeOf() == NATIVE_STRING, napi_invalid_arg);
270     }
271     RETURN_STATUS_IF_FALSE(env, msgValue->TypeOf() == NATIVE_STRING, napi_invalid_arg);
272 
273     auto resultValue = engine->CreateError(codeValue, msgValue);
274 
275     *result = reinterpret_cast<napi_value>(resultValue);
276     return napi_clear_last_error(env);
277 }
278 
napi_create_type_error(napi_env env,napi_value code,napi_value msg,napi_value * result)279 NAPI_EXTERN napi_status napi_create_type_error(napi_env env, napi_value code, napi_value msg, napi_value* result)
280 {
281     CHECK_ENV(env);
282     CHECK_ARG(env, msg);
283     CHECK_ARG(env, result);
284 
285     auto engine = reinterpret_cast<NativeEngine*>(env);
286     auto codeValue = reinterpret_cast<NativeValue*>(code);
287     auto msgValue = reinterpret_cast<NativeValue*>(msg);
288 
289     if (codeValue != nullptr) {
290         RETURN_STATUS_IF_FALSE(env, codeValue->TypeOf() == NATIVE_STRING, napi_invalid_arg);
291     }
292     RETURN_STATUS_IF_FALSE(env, msgValue->TypeOf() == NATIVE_STRING, napi_invalid_arg);
293 
294     auto resultValue = engine->CreateError(codeValue, msgValue);
295 
296     *result = reinterpret_cast<napi_value>(resultValue);
297     return napi_clear_last_error(env);
298 }
299 
napi_create_range_error(napi_env env,napi_value code,napi_value msg,napi_value * result)300 NAPI_EXTERN napi_status napi_create_range_error(napi_env env, napi_value code, napi_value msg, napi_value* result)
301 {
302     CHECK_ENV(env);
303     CHECK_ARG(env, msg);
304     CHECK_ARG(env, result);
305 
306     auto engine = reinterpret_cast<NativeEngine*>(env);
307     auto codeValue = reinterpret_cast<NativeValue*>(code);
308     auto msgValue = reinterpret_cast<NativeValue*>(msg);
309 
310     if (codeValue != nullptr) {
311         RETURN_STATUS_IF_FALSE(env, codeValue->TypeOf() == NATIVE_STRING, napi_invalid_arg);
312     }
313     RETURN_STATUS_IF_FALSE(env, msgValue->TypeOf() == NATIVE_STRING, napi_invalid_arg);
314 
315     auto resultValue = engine->CreateError(codeValue, msgValue);
316 
317     *result = reinterpret_cast<napi_value>(resultValue);
318     return napi_clear_last_error(env);
319 }
320 
321 // Methods to get the native napi_value from Primitive type
napi_typeof(napi_env env,napi_value value,napi_valuetype * result)322 NAPI_EXTERN napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result)
323 {
324     CHECK_ENV(env);
325     CHECK_ARG(env, value);
326     CHECK_ARG(env, result);
327 
328     auto nativeValue = reinterpret_cast<NativeValue*>(value);
329 
330     *result = (napi_valuetype)nativeValue->TypeOf();
331     return napi_clear_last_error(env);
332 }
333 
napi_get_value_double(napi_env env,napi_value value,double * result)334 NAPI_EXTERN napi_status napi_get_value_double(napi_env env, napi_value value, double* result)
335 {
336     CHECK_ENV(env);
337     CHECK_ARG(env, value);
338     CHECK_ARG(env, result);
339 
340     auto nativeValue = reinterpret_cast<NativeValue*>(value);
341 
342     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_NUMBER, napi_number_expected);
343 
344     *result = *reinterpret_cast<NativeNumber*>(nativeValue->GetInterface(NativeNumber::INTERFACE_ID));
345     return napi_clear_last_error(env);
346 }
347 
napi_get_value_int32(napi_env env,napi_value value,int32_t * result)348 NAPI_EXTERN napi_status napi_get_value_int32(napi_env env, napi_value value, int32_t* result)
349 {
350     CHECK_ENV(env);
351     CHECK_ARG(env, value);
352     CHECK_ARG(env, result);
353 
354     auto nativeValue = reinterpret_cast<NativeValue*>(value);
355 
356     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_NUMBER, napi_number_expected);
357 
358     *result = *reinterpret_cast<NativeNumber*>(nativeValue->GetInterface(NativeNumber::INTERFACE_ID));
359     return napi_clear_last_error(env);
360 }
361 
napi_get_value_uint32(napi_env env,napi_value value,uint32_t * result)362 NAPI_EXTERN napi_status napi_get_value_uint32(napi_env env, napi_value value, uint32_t* result)
363 {
364     CHECK_ENV(env);
365     CHECK_ARG(env, value);
366     CHECK_ARG(env, result);
367 
368     auto nativeValue = reinterpret_cast<NativeValue*>(value);
369 
370     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_NUMBER, napi_number_expected);
371 
372     *result = *reinterpret_cast<NativeNumber*>(nativeValue->GetInterface(NativeNumber::INTERFACE_ID));
373     return napi_clear_last_error(env);
374 }
375 
napi_get_value_int64(napi_env env,napi_value value,int64_t * result)376 NAPI_EXTERN napi_status napi_get_value_int64(napi_env env, napi_value value, int64_t* result)
377 {
378     CHECK_ENV(env);
379     CHECK_ARG(env, value);
380     CHECK_ARG(env, result);
381 
382     auto nativeValue = reinterpret_cast<NativeValue*>(value);
383 
384     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_NUMBER, napi_number_expected);
385 
386     *result = *reinterpret_cast<NativeNumber*>(nativeValue->GetInterface(NativeNumber::INTERFACE_ID));
387     return napi_clear_last_error(env);
388 }
389 
napi_get_value_bool(napi_env env,napi_value value,bool * result)390 NAPI_EXTERN napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result)
391 {
392     CHECK_ENV(env);
393     CHECK_ARG(env, value);
394     CHECK_ARG(env, result);
395 
396     auto nativeValue = reinterpret_cast<NativeValue*>(value);
397 
398     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_BOOLEAN, napi_boolean_expected);
399 
400     *result = *reinterpret_cast<NativeBoolean*>(nativeValue->GetInterface(NativeBoolean::INTERFACE_ID));
401     return napi_clear_last_error(env);
402 }
403 
404 // Copies LATIN-1 encoded bytes from a string into a buffer.
napi_get_value_string_latin1(napi_env env,napi_value value,char * buf,size_t bufsize,size_t * result)405 NAPI_EXTERN napi_status napi_get_value_string_latin1(
406     napi_env env, napi_value value, char* buf, size_t bufsize, size_t* result)
407 {
408     CHECK_ENV(env);
409     CHECK_ARG(env, value);
410     CHECK_ARG(env, result);
411 
412     auto nativeValue = reinterpret_cast<NativeValue*>(value);
413 
414     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_STRING, napi_string_expected);
415 
416     auto nativeString = reinterpret_cast<NativeString*>(nativeValue->GetInterface(NativeString::INTERFACE_ID));
417 
418     nativeString->GetCStringLatin1(buf, bufsize, result);
419     return napi_clear_last_error(env);
420 }
421 
422 // Copies UTF-8 encoded bytes from a string into a buffer.
napi_get_value_string_utf8(napi_env env,napi_value value,char * buf,size_t bufsize,size_t * result)423 NAPI_EXTERN napi_status napi_get_value_string_utf8(
424     napi_env env, napi_value value, char* buf, size_t bufsize, size_t* result)
425 {
426     CHECK_ENV(env);
427     CHECK_ARG(env, value);
428     CHECK_ARG(env, result);
429 
430     auto nativeValue = reinterpret_cast<NativeValue*>(value);
431 
432     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_STRING, napi_string_expected);
433 
434     auto nativeString = reinterpret_cast<NativeString*>(nativeValue->GetInterface(NativeString::INTERFACE_ID));
435 
436     nativeString->GetCString(buf, bufsize, result);
437     return napi_clear_last_error(env);
438 }
439 
napi_get_value_string_utf16(napi_env env,napi_value value,char16_t * buf,size_t bufsize,size_t * result)440 NAPI_EXTERN napi_status napi_get_value_string_utf16(
441     napi_env env, napi_value value, char16_t* buf, size_t bufsize, size_t* result)
442 {
443     CHECK_ENV(env);
444     CHECK_ARG(env, value);
445     CHECK_ARG(env, result);
446 
447     auto nativeValue = reinterpret_cast<NativeValue*>(value);
448 
449     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_STRING, napi_string_expected);
450 
451     auto nativeString = reinterpret_cast<NativeString*>(nativeValue->GetInterface(NativeString::INTERFACE_ID));
452 
453     nativeString->GetCString16(buf, bufsize, result);
454     return napi_clear_last_error(env);
455 }
456 
457 // Methods to coerce values
458 // These APIs may execute user scripts
napi_coerce_to_bool(napi_env env,napi_value value,napi_value * result)459 NAPI_EXTERN napi_status napi_coerce_to_bool(napi_env env, napi_value value, napi_value* result)
460 {
461     CHECK_ENV(env);
462     CHECK_ARG(env, value);
463     CHECK_ARG(env, result);
464 
465     auto nativeValue = reinterpret_cast<NativeValue*>(value);
466 
467     auto resultValue = nativeValue->ToBoolean();
468 
469     *result = reinterpret_cast<napi_value>(resultValue);
470     return napi_clear_last_error(env);
471 }
472 
napi_coerce_to_number(napi_env env,napi_value value,napi_value * result)473 NAPI_EXTERN napi_status napi_coerce_to_number(napi_env env, napi_value value, napi_value* result)
474 {
475     CHECK_ENV(env);
476     CHECK_ARG(env, value);
477     CHECK_ARG(env, result);
478 
479     auto nativeValue = reinterpret_cast<NativeValue*>(value);
480 
481     auto resultValue = nativeValue->ToNumber();
482 
483     *result = reinterpret_cast<napi_value>(resultValue);
484     return napi_clear_last_error(env);
485 }
486 
napi_coerce_to_object(napi_env env,napi_value value,napi_value * result)487 NAPI_EXTERN napi_status napi_coerce_to_object(napi_env env, napi_value value, napi_value* result)
488 {
489     CHECK_ENV(env);
490     CHECK_ARG(env, value);
491     CHECK_ARG(env, result);
492 
493     auto nativeValue = reinterpret_cast<NativeValue*>(value);
494 
495     auto resultValue = nativeValue->ToObject();
496 
497     *result = reinterpret_cast<napi_value>(resultValue);
498     return napi_clear_last_error(env);
499 }
500 
napi_coerce_to_string(napi_env env,napi_value value,napi_value * result)501 NAPI_EXTERN napi_status napi_coerce_to_string(napi_env env, napi_value value, napi_value* result)
502 {
503     CHECK_ENV(env);
504     CHECK_ARG(env, value);
505     CHECK_ARG(env, result);
506 
507     auto nativeValue = reinterpret_cast<NativeValue*>(value);
508 
509     auto resultValue = nativeValue->ToString();
510 
511     *result = reinterpret_cast<napi_value>(resultValue);
512     return napi_clear_last_error(env);
513 }
514 
515 // Methods to work with Objects
napi_get_prototype(napi_env env,napi_value object,napi_value * result)516 NAPI_EXTERN napi_status napi_get_prototype(napi_env env, napi_value object, napi_value* result)
517 {
518     CHECK_ENV(env);
519     CHECK_ARG(env, object);
520     CHECK_ARG(env, result);
521 
522     auto nativeValue = reinterpret_cast<NativeValue*>(object);
523 
524     NativeValueType type = nativeValue->TypeOf();
525     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION, napi_object_expected);
526 
527     NativeValue* resultValue = nullptr;
528     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
529     resultValue = nativeObject->GetPrototype();
530 
531     *result = reinterpret_cast<napi_value>(resultValue);
532     return napi_clear_last_error(env);
533 }
534 
napi_get_property_names(napi_env env,napi_value object,napi_value * result)535 NAPI_EXTERN napi_status napi_get_property_names(napi_env env, napi_value object, napi_value* result)
536 {
537     CHECK_ENV(env);
538     CHECK_ARG(env, object);
539     CHECK_ARG(env, result);
540 
541     auto nativeValue = reinterpret_cast<NativeValue*>(object);
542 
543     NativeValueType type = nativeValue->TypeOf();
544     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
545         napi_object_expected);
546 
547     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
548 
549     auto resultValue = nativeObject->GetPropertyNames();
550 
551     *result = reinterpret_cast<napi_value>(resultValue);
552     return napi_clear_last_error(env);
553 }
554 
napi_set_property(napi_env env,napi_value object,napi_value key,napi_value value)555 NAPI_EXTERN napi_status napi_set_property(napi_env env, napi_value object, napi_value key, napi_value value)
556 {
557     CHECK_ENV(env);
558     CHECK_ARG(env, object);
559     CHECK_ARG(env, key);
560     CHECK_ARG(env, value);
561 
562     auto nativeValue = reinterpret_cast<NativeValue*>(object);
563     auto propKey = reinterpret_cast<NativeValue*>(key);
564     auto propValue = reinterpret_cast<NativeValue*>(value);
565 
566     NativeValueType type = nativeValue->TypeOf();
567     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
568         napi_object_expected);
569 
570     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
571 
572     nativeObject->SetProperty(propKey, propValue);
573     return napi_clear_last_error(env);
574 }
575 
napi_has_property(napi_env env,napi_value object,napi_value key,bool * result)576 NAPI_EXTERN napi_status napi_has_property(napi_env env, napi_value object, napi_value key, bool* result)
577 {
578     CHECK_ENV(env);
579     CHECK_ARG(env, object);
580     CHECK_ARG(env, key);
581     CHECK_ARG(env, result);
582 
583     auto nativeValue = reinterpret_cast<NativeValue*>(object);
584     auto propKey = reinterpret_cast<NativeValue*>(key);
585 
586     NativeValueType type = nativeValue->TypeOf();
587     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
588         napi_object_expected);
589 
590     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
591 
592     *result = nativeObject->HasProperty(propKey);
593     return napi_clear_last_error(env);
594 }
595 
napi_get_property(napi_env env,napi_value object,napi_value key,napi_value * result)596 NAPI_EXTERN napi_status napi_get_property(napi_env env, napi_value object, napi_value key, napi_value* result)
597 {
598     CHECK_ENV(env);
599     CHECK_ARG(env, object);
600     CHECK_ARG(env, key);
601     CHECK_ARG(env, result);
602 
603     auto nativeValue = reinterpret_cast<NativeValue*>(object);
604 
605     NativeValueType type = nativeValue->TypeOf();
606     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
607         napi_object_expected);
608 
609     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
610 
611     auto resultValue = nativeObject->GetProperty((NativeValue*)key);
612 
613     *result = reinterpret_cast<napi_value>(resultValue);
614     return napi_clear_last_error(env);
615 }
616 
napi_delete_property(napi_env env,napi_value object,napi_value key,bool * result)617 NAPI_EXTERN napi_status napi_delete_property(napi_env env, napi_value object, napi_value key, bool* result)
618 {
619     CHECK_ENV(env);
620     CHECK_ARG(env, object);
621     CHECK_ARG(env, key);
622 
623     auto nativeValue = reinterpret_cast<NativeValue*>(object);
624     auto propKey = reinterpret_cast<NativeValue*>(key);
625 
626     NativeValueType type = nativeValue->TypeOf();
627     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
628         napi_object_expected);
629 
630     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
631 
632     bool deleteResult = nativeObject->DeleteProperty(propKey);
633     if (result) {
634         *result = deleteResult;
635     }
636 
637     return napi_clear_last_error(env);
638 }
639 
napi_has_own_property(napi_env env,napi_value object,napi_value key,bool * result)640 NAPI_EXTERN napi_status napi_has_own_property(napi_env env, napi_value object, napi_value key, bool* result)
641 {
642     CHECK_ENV(env);
643     CHECK_ARG(env, object);
644     CHECK_ARG(env, key);
645     CHECK_ARG(env, result);
646 
647     auto nativeValue = reinterpret_cast<NativeValue*>(object);
648     auto propKey = reinterpret_cast<NativeValue*>(key);
649 
650     NativeValueType type = nativeValue->TypeOf();
651     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
652         napi_object_expected);
653 
654     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
655 
656     *result = nativeObject->HasProperty(propKey);
657     return napi_clear_last_error(env);
658 }
659 
napi_set_named_property(napi_env env,napi_value object,const char * utf8name,napi_value value)660 NAPI_EXTERN napi_status napi_set_named_property(napi_env env, napi_value object, const char* utf8name, napi_value value)
661 {
662     CHECK_ENV(env);
663     CHECK_ARG(env, object);
664     CHECK_ARG(env, utf8name);
665     CHECK_ARG(env, value);
666 
667     auto nativeValue = reinterpret_cast<NativeValue*>(object);
668     auto propValue = reinterpret_cast<NativeValue*>(value);
669 
670     NativeValueType type = nativeValue->TypeOf();
671     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
672         napi_object_expected);
673 
674     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
675 
676     nativeObject->SetProperty(utf8name, propValue);
677     return napi_clear_last_error(env);
678 }
679 
napi_has_named_property(napi_env env,napi_value object,const char * utf8name,bool * result)680 NAPI_EXTERN napi_status napi_has_named_property(napi_env env, napi_value object, const char* utf8name, bool* result)
681 {
682     CHECK_ENV(env);
683     CHECK_ARG(env, object);
684     CHECK_ARG(env, utf8name);
685     CHECK_ARG(env, result);
686 
687     auto nativeValue = reinterpret_cast<NativeValue*>(object);
688 
689     NativeValueType type = nativeValue->TypeOf();
690     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
691         napi_object_expected);
692 
693     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
694 
695     *result = nativeObject->HasProperty(utf8name);
696     return napi_clear_last_error(env);
697 }
698 
napi_get_named_property(napi_env env,napi_value object,const char * utf8name,napi_value * result)699 NAPI_EXTERN napi_status napi_get_named_property(napi_env env,
700                                                 napi_value object,
701                                                 const char* utf8name,
702                                                 napi_value* result)
703 {
704     CHECK_ENV(env);
705     CHECK_ARG(env, object);
706     CHECK_ARG(env, utf8name);
707     CHECK_ARG(env, result);
708 
709     auto nativeValue = reinterpret_cast<NativeValue*>(object);
710 
711     NativeValueType type = nativeValue->TypeOf();
712     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
713         napi_object_expected);
714 
715     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
716 
717     auto resultValue = nativeObject->GetProperty(utf8name);
718 
719     *result = reinterpret_cast<napi_value>(resultValue);
720     return napi_clear_last_error(env);
721 }
722 
napi_get_own_property_descriptor(napi_env env,napi_value object,const char * utf8name,napi_value * result)723 NAPI_EXTERN napi_status napi_get_own_property_descriptor(napi_env env,
724                                                          napi_value object,
725                                                          const char* utf8name,
726                                                          napi_value* result)
727 {
728     CHECK_ENV(env);
729     CHECK_ARG(env, object);
730     CHECK_ARG(env, utf8name);
731     CHECK_ARG(env, result);
732 
733     auto nativeValue = reinterpret_cast<NativeValue*>(object);
734 
735     NativeValueType type = nativeValue->TypeOf();
736     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
737         napi_object_expected);
738 
739     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
740 
741     auto resultValue = nativeObject->GetOwnProperty(utf8name);
742 
743     *result = reinterpret_cast<napi_value>(resultValue);
744     return napi_clear_last_error(env);
745 }
746 
napi_set_element(napi_env env,napi_value object,uint32_t index,napi_value value)747 NAPI_EXTERN napi_status napi_set_element(napi_env env, napi_value object, uint32_t index, napi_value value)
748 {
749     CHECK_ENV(env);
750     CHECK_ARG(env, object);
751     CHECK_ARG(env, value);
752 
753     NativeValue* nativeValue = reinterpret_cast<NativeValue*>(object);
754     NativeValue* elementValue = reinterpret_cast<NativeValue*>(value);
755 
756     NativeValueType type = nativeValue->TypeOf();
757     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
758         napi_object_expected);
759 
760     NativeObject* nativeObject =
761         reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
762 
763     nativeObject->SetElement(index, elementValue);
764     return napi_clear_last_error(env);
765 }
766 
napi_has_element(napi_env env,napi_value object,uint32_t index,bool * result)767 NAPI_EXTERN napi_status napi_has_element(napi_env env, napi_value object, uint32_t index, bool* result)
768 {
769     CHECK_ENV(env);
770     CHECK_ARG(env, object);
771     CHECK_ARG(env, result);
772 
773     NativeValue* nativeValue = reinterpret_cast<NativeValue*>(object);
774 
775     NativeValueType type = nativeValue->TypeOf();
776     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
777         napi_object_expected);
778 
779     NativeObject* nativeObject =
780         reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
781 
782     *result = nativeObject->HasElement(index);
783     return napi_clear_last_error(env);
784 }
785 
napi_get_element(napi_env env,napi_value object,uint32_t index,napi_value * result)786 NAPI_EXTERN napi_status napi_get_element(napi_env env, napi_value object, uint32_t index, napi_value* result)
787 {
788     CHECK_ENV(env);
789     CHECK_ARG(env, object);
790     CHECK_ARG(env, result);
791 
792     NativeValue* nativeValue = reinterpret_cast<NativeValue*>(object);
793 
794     NativeValueType type = nativeValue->TypeOf();
795     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
796         napi_object_expected);
797 
798     NativeObject* nativeObject =
799         reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
800 
801     NativeValue* resultValue = nativeObject->GetElement(index);
802 
803     *result = reinterpret_cast<napi_value>(resultValue);
804     return napi_clear_last_error(env);
805 }
806 
napi_delete_element(napi_env env,napi_value object,uint32_t index,bool * result)807 NAPI_EXTERN napi_status napi_delete_element(napi_env env, napi_value object, uint32_t index, bool* result)
808 {
809     CHECK_ENV(env);
810     CHECK_ARG(env, object);
811 
812     NativeValue* nativeValue = reinterpret_cast<NativeValue*>(object);
813 
814     NativeValueType type = nativeValue->TypeOf();
815     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
816         napi_object_expected);
817 
818     NativeObject* nativeObject =
819         reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
820 
821     bool deleteResult = nativeObject->DeleteElement(index);
822     if (result) {
823         *result = deleteResult;
824     }
825     return napi_clear_last_error(env);
826 }
827 
napi_define_properties(napi_env env,napi_value object,size_t property_count,const napi_property_descriptor * properties)828 NAPI_EXTERN napi_status napi_define_properties(napi_env env,
829                                                napi_value object,
830                                                size_t property_count,
831                                                const napi_property_descriptor* properties)
832 {
833     CHECK_ENV(env);
834     CHECK_ARG(env, object);
835     CHECK_ARG(env, properties);
836 
837     auto nativeValue = reinterpret_cast<NativeValue*>(object);
838 
839     NativeValueType type = nativeValue->TypeOf();
840     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
841         napi_object_expected);
842 
843     NativeObject* nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
844 
845     for (size_t i = 0; i < property_count; i++) {
846         NativePropertyDescriptor property;
847 
848         property.utf8name = properties[i].utf8name;
849         property.name = reinterpret_cast<NativeValue*>(properties[i].name);
850         property.method = reinterpret_cast<NativeCallback>(properties[i].method);
851         property.getter = reinterpret_cast<NativeCallback>(properties[i].getter);
852         property.setter = reinterpret_cast<NativeCallback>(properties[i].setter);
853         property.value = reinterpret_cast<NativeValue*>(properties[i].value);
854         property.attributes = (uint32_t)properties[i].attributes;
855         property.data = properties[i].data;
856 
857         nativeObject->DefineProperty(property);
858     }
859 
860     return napi_clear_last_error(env);
861 }
862 
863 // Methods to work with Arrays
napi_is_array(napi_env env,napi_value value,bool * result)864 NAPI_EXTERN napi_status napi_is_array(napi_env env, napi_value value, bool* result)
865 {
866     CHECK_ENV(env);
867     CHECK_ARG(env, value);
868     CHECK_ARG(env, result);
869 
870     auto nativeValue = reinterpret_cast<NativeValue*>(value);
871 
872     *result = nativeValue->IsArray();
873     return napi_clear_last_error(env);
874 }
875 
napi_get_array_length(napi_env env,napi_value value,uint32_t * result)876 NAPI_EXTERN napi_status napi_get_array_length(napi_env env, napi_value value, uint32_t* result)
877 {
878     CHECK_ENV(env);
879     CHECK_ARG(env, value);
880     CHECK_ARG(env, result);
881 
882     auto nativeValue = reinterpret_cast<NativeValue*>(value);
883 
884     RETURN_STATUS_IF_FALSE(env, nativeValue->IsArray(), napi_array_expected);
885 
886     auto nativeArray = reinterpret_cast<NativeArray*>(nativeValue->GetInterface(NativeArray::INTERFACE_ID));
887 
888     *result = nativeArray->GetLength();
889 
890     return napi_clear_last_error(env);
891 }
892 
893 // Methods to compare values
napi_strict_equals(napi_env env,napi_value lhs,napi_value rhs,bool * result)894 NAPI_EXTERN napi_status napi_strict_equals(napi_env env, napi_value lhs, napi_value rhs, bool* result)
895 {
896     CHECK_ENV(env);
897     CHECK_ARG(env, lhs);
898     CHECK_ARG(env, rhs);
899     CHECK_ARG(env, result);
900 
901     auto nativeLhs = reinterpret_cast<NativeValue*>(lhs);
902     auto nativeRhs = reinterpret_cast<NativeValue*>(rhs);
903 
904     *result = nativeLhs->StrictEquals(nativeRhs);
905     return napi_clear_last_error(env);
906 }
907 
908 // Methods to work with Functions
napi_call_function(napi_env env,napi_value recv,napi_value func,size_t argc,const napi_value * argv,napi_value * result)909 NAPI_EXTERN napi_status napi_call_function(napi_env env,
910                                            napi_value recv,
911                                            napi_value func,
912                                            size_t argc,
913                                            const napi_value* argv,
914                                            napi_value* result)
915 {
916     CHECK_ENV(env);
917     CHECK_ARG(env, func);
918     if (argc > 0) {
919         CHECK_ARG(env, argv);
920     }
921 
922     auto engine = reinterpret_cast<NativeEngine*>(env);
923     auto nativeRecv = reinterpret_cast<NativeValue*>(recv);
924     auto nativeFunc = reinterpret_cast<NativeValue*>(func);
925     auto nativeArgv = reinterpret_cast<NativeValue* const*>(argv);
926 
927     RETURN_STATUS_IF_FALSE(env, nativeFunc->TypeOf() == NATIVE_FUNCTION, napi_function_expected);
928 
929     auto resultValue = engine->CallFunction(nativeRecv, nativeFunc, nativeArgv, argc);
930 
931     RETURN_STATUS_IF_FALSE(env, resultValue != nullptr, napi_pending_exception);
932     if (result) {
933         *result = reinterpret_cast<napi_value>(resultValue);
934     }
935     return napi_clear_last_error(env);
936 }
937 
napi_new_instance(napi_env env,napi_value constructor,size_t argc,const napi_value * argv,napi_value * result)938 NAPI_EXTERN napi_status napi_new_instance(
939     napi_env env, napi_value constructor, size_t argc, const napi_value* argv, napi_value* result)
940 {
941     CHECK_ENV(env);
942     CHECK_ARG(env, constructor);
943     if (argc > 0) {
944         CHECK_ARG(env, argv);
945     }
946     CHECK_ARG(env, result);
947 
948     auto engine = reinterpret_cast<NativeEngine*>(env);
949     auto nativeConstructor = reinterpret_cast<NativeValue*>(constructor);
950     auto nativeArgv = reinterpret_cast<NativeValue* const*>(argv);
951 
952     RETURN_STATUS_IF_FALSE(env, nativeConstructor->TypeOf() == NATIVE_FUNCTION, napi_function_expected);
953 
954     auto resultValue = engine->CreateInstance(nativeConstructor, nativeArgv, argc);
955 
956     *result = reinterpret_cast<napi_value>(resultValue);
957     return napi_clear_last_error(env);
958 }
959 
napi_instanceof(napi_env env,napi_value object,napi_value constructor,bool * result)960 NAPI_EXTERN napi_status napi_instanceof(napi_env env, napi_value object, napi_value constructor, bool* result)
961 {
962     CHECK_ENV(env);
963     CHECK_ARG(env, object);
964     CHECK_ARG(env, constructor);
965     CHECK_ARG(env, result);
966 
967     auto nativeValue = reinterpret_cast<NativeValue*>(object);
968     auto nativeConstructor = reinterpret_cast<NativeValue*>(constructor);
969 
970     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_OBJECT, napi_object_expected);
971 
972     RETURN_STATUS_IF_FALSE(env, nativeConstructor->TypeOf() == NATIVE_FUNCTION, napi_function_expected);
973 
974     *result = nativeValue->InstanceOf(nativeConstructor);
975     return napi_clear_last_error(env);
976 }
977 
978 // Methods to work with napi_callbacks
979 // Gets all callback info in a single call. (Ugly, but faster.)
napi_get_cb_info(napi_env env,napi_callback_info cbinfo,size_t * argc,napi_value * argv,napi_value * this_arg,void ** data)980 NAPI_EXTERN napi_status napi_get_cb_info(napi_env env,              // [in] NAPI environment handle
981                                          napi_callback_info cbinfo, // [in] Opaque callback-info handle
982                                          size_t* argc,         // [in-out] Specifies the size of the provided argv array
983                                                                // and receives the actual count of args.
984                                          napi_value* argv,     // [out] Array of values
985                                          napi_value* this_arg, // [out] Receives the JS 'this' arg for the call
986                                          void** data)          // [out] Receives the data pointer for the callback.
987 {
988     CHECK_ENV(env);
989     CHECK_ARG(env, cbinfo);
990 
991     auto info = reinterpret_cast<NativeCallbackInfo*>(cbinfo);
992 
993     if ((argc != nullptr) && (argv != nullptr)) {
994         size_t i = 0;
995         for (i = 0; (i < *argc) && (i < info->argc); i++) {
996             argv[i] = reinterpret_cast<napi_value>(info->argv[i]);
997         }
998         *argc = i;
999     }
1000 
1001     if (argc != nullptr) {
1002         *argc = info->argc;
1003     }
1004 
1005     if (this_arg != nullptr) {
1006         *this_arg = reinterpret_cast<napi_value>(info->thisVar);
1007     }
1008 
1009     if (data != nullptr && info->functionInfo != nullptr) {
1010         *data = info->functionInfo->data;
1011     }
1012 
1013     return napi_clear_last_error(env);
1014 }
1015 
napi_get_new_target(napi_env env,napi_callback_info cbinfo,napi_value * result)1016 NAPI_EXTERN napi_status napi_get_new_target(napi_env env, napi_callback_info cbinfo, napi_value* result)
1017 {
1018     CHECK_ENV(env);
1019     CHECK_ARG(env, cbinfo);
1020     CHECK_ARG(env, result);
1021 
1022     auto info = reinterpret_cast<NativeCallbackInfo*>(cbinfo);
1023 
1024     if (info->thisVar->InstanceOf(info->function)) {
1025         *result = reinterpret_cast<napi_value>(info->function);
1026     } else {
1027         *result = nullptr;
1028     }
1029 
1030     return napi_clear_last_error(env);
1031 }
1032 
napi_define_class(napi_env env,const char * utf8name,size_t length,napi_callback constructor,void * data,size_t property_count,const napi_property_descriptor * properties,napi_value * result)1033 NAPI_EXTERN napi_status napi_define_class(napi_env env,
1034                                           const char* utf8name,
1035                                           size_t length,
1036                                           napi_callback constructor,
1037                                           void* data,
1038                                           size_t property_count,
1039                                           const napi_property_descriptor* properties,
1040                                           napi_value* result)
1041 {
1042     CHECK_ENV(env);
1043     CHECK_ARG(env, utf8name);
1044     RETURN_STATUS_IF_FALSE(env, length == NAPI_AUTO_LENGTH || length <= INT_MAX, napi_object_expected);
1045     CHECK_ARG(env, constructor);
1046     if (property_count > 0) {
1047         CHECK_ARG(env, properties);
1048     }
1049     CHECK_ARG(env, result);
1050 
1051     auto engine = reinterpret_cast<NativeEngine*>(env);
1052     auto callback = reinterpret_cast<NativeCallback>(constructor);
1053     auto nativeProperties = reinterpret_cast<const NativePropertyDescriptor*>(properties);
1054 
1055     size_t nameLength = std::min(length, strlen(utf8name));
1056     char newName[nameLength + 1];
1057     if (strncpy_s(newName, nameLength + 1, utf8name, nameLength) != EOK) {
1058         HILOG_ERROR("napi_define_class strncpy_s failed");
1059         *result = nullptr;
1060     } else {
1061         auto resultValue = engine->DefineClass(newName, callback, data, nativeProperties, property_count);
1062         *result = reinterpret_cast<napi_value>(resultValue);
1063     }
1064 
1065     return napi_clear_last_error(env);
1066 }
1067 
1068 // Methods to work with external data objects
napi_wrap(napi_env env,napi_value js_object,void * native_object,napi_finalize finalize_cb,void * finalize_hint,napi_ref * result)1069 NAPI_EXTERN napi_status napi_wrap(napi_env env,
1070                                   napi_value js_object,
1071                                   void* native_object,
1072                                   napi_finalize finalize_cb,
1073                                   void* finalize_hint,
1074                                   napi_ref* result)
1075 {
1076     CHECK_ENV(env);
1077     CHECK_ARG(env, js_object);
1078     CHECK_ARG(env, native_object);
1079     CHECK_ARG(env, finalize_cb);
1080 
1081     auto nativeValue = reinterpret_cast<NativeValue*>(js_object);
1082     auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
1083 
1084     NativeValueType type = nativeValue->TypeOf();
1085     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
1086         napi_object_expected);
1087 
1088     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
1089     if (result != nullptr) {
1090         nativeObject->SetNativePointer(
1091             native_object, callback, finalize_hint, reinterpret_cast<NativeReference**>(result));
1092     } else {
1093         nativeObject->SetNativePointer(native_object, callback, finalize_hint);
1094     }
1095     return napi_clear_last_error(env);
1096 }
1097 
1098 // Methods to work with external data objects
napi_wrap_with_size(napi_env env,napi_value js_object,void * native_object,napi_finalize finalize_cb,void * finalize_hint,napi_ref * result,size_t native_binding_size)1099 NAPI_EXTERN napi_status napi_wrap_with_size(napi_env env,
1100                                             napi_value js_object,
1101                                             void* native_object,
1102                                             napi_finalize finalize_cb,
1103                                             void* finalize_hint,
1104                                             napi_ref* result,
1105                                             size_t native_binding_size)
1106 {
1107     CHECK_ENV(env);
1108     CHECK_ARG(env, js_object);
1109     CHECK_ARG(env, native_object);
1110     CHECK_ARG(env, finalize_cb);
1111 
1112     auto nativeValue = reinterpret_cast<NativeValue*>(js_object);
1113     auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
1114 
1115     NativeValueType type = nativeValue->TypeOf();
1116     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
1117         napi_object_expected);
1118 
1119     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
1120 
1121     if (result != nullptr) {
1122         nativeObject->SetNativePointer(
1123             native_object, callback, finalize_hint, reinterpret_cast<NativeReference**>(result), native_binding_size);
1124     } else {
1125         nativeObject->SetNativePointer(native_object, callback, finalize_hint, nullptr, native_binding_size);
1126     }
1127     return napi_clear_last_error(env);
1128 }
1129 
napi_unwrap(napi_env env,napi_value js_object,void ** result)1130 NAPI_EXTERN napi_status napi_unwrap(napi_env env, napi_value js_object, void** result)
1131 {
1132     CHECK_ENV(env);
1133     CHECK_ARG(env, js_object);
1134     CHECK_ARG(env, result);
1135 
1136     auto nativeValue = reinterpret_cast<NativeValue*>(js_object);
1137 
1138     NativeValueType type = nativeValue->TypeOf();
1139     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
1140         napi_object_expected);
1141 
1142     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
1143 
1144     *result = nativeObject->GetNativePointer();
1145 
1146     return napi_clear_last_error(env);
1147 }
1148 
napi_remove_wrap(napi_env env,napi_value js_object,void ** result)1149 NAPI_EXTERN napi_status napi_remove_wrap(napi_env env, napi_value js_object, void** result)
1150 {
1151     CHECK_ENV(env);
1152     CHECK_ARG(env, js_object);
1153     CHECK_ARG(env, result);
1154 
1155     auto nativeValue = reinterpret_cast<NativeValue*>(js_object);
1156 
1157     NativeValueType type = nativeValue->TypeOf();
1158     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
1159         napi_object_expected);
1160 
1161     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
1162 
1163     *result = nativeObject->GetNativePointer();
1164     nativeObject->SetNativePointer(nullptr, nullptr, nullptr);
1165 
1166     return napi_clear_last_error(env);
1167 }
1168 
napi_create_external(napi_env env,void * data,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)1169 NAPI_EXTERN napi_status napi_create_external(
1170     napi_env env, void* data, napi_finalize finalize_cb, void* finalize_hint, napi_value* result)
1171 {
1172     CHECK_ENV(env);
1173     CHECK_ARG(env, result);
1174 
1175     auto engine = reinterpret_cast<NativeEngine*>(env);
1176     auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
1177 
1178     auto resultValue = engine->CreateExternal(data, callback, finalize_hint);
1179 
1180     *result = reinterpret_cast<napi_value>(resultValue);
1181     return napi_clear_last_error(env);
1182 }
1183 
napi_create_external_with_size(napi_env env,void * data,napi_finalize finalize_cb,void * finalize_hint,napi_value * result,size_t native_binding_size)1184 NAPI_EXTERN napi_status napi_create_external_with_size(napi_env env, void* data, napi_finalize finalize_cb,
1185     void* finalize_hint, napi_value* result, size_t native_binding_size)
1186 {
1187     CHECK_ENV(env);
1188     CHECK_ARG(env, result);
1189 
1190     auto engine = reinterpret_cast<NativeEngine*>(env);
1191     auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
1192 
1193     auto resultValue = engine->CreateExternal(data, callback, finalize_hint, native_binding_size);
1194 
1195     *result = reinterpret_cast<napi_value>(resultValue);
1196     return napi_clear_last_error(env);
1197 }
1198 
napi_get_value_external(napi_env env,napi_value value,void ** result)1199 NAPI_EXTERN napi_status napi_get_value_external(napi_env env, napi_value value, void** result)
1200 {
1201     CHECK_ENV(env);
1202     CHECK_ARG(env, value);
1203     CHECK_ARG(env, result);
1204 
1205     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1206 
1207     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_EXTERNAL, napi_object_expected);
1208 
1209     auto external = reinterpret_cast<NativeExternal*>(nativeValue->GetInterface(NativeExternal::INTERFACE_ID));
1210 
1211     *result = *external;
1212     return napi_clear_last_error(env);
1213 }
1214 
1215 // Methods to control object lifespan
1216 // Set initial_refcount to 0 for a weak reference, >0 for a strong reference.
napi_create_reference(napi_env env,napi_value value,uint32_t initial_refcount,napi_ref * result)1217 NAPI_EXTERN napi_status napi_create_reference(napi_env env,
1218                                               napi_value value,
1219                                               uint32_t initial_refcount,
1220                                               napi_ref* result)
1221 {
1222     CHECK_ENV(env);
1223     CHECK_ARG(env, value);
1224     CHECK_ARG(env, result);
1225     auto engine = reinterpret_cast<NativeEngine*>(env);
1226     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1227     auto reference = engine->CreateReference(nativeValue, initial_refcount);
1228 
1229     *result = reinterpret_cast<napi_ref>(reference);
1230     return napi_clear_last_error(env);
1231 }
1232 
1233 // Deletes a reference. The referenced value is released, and may
1234 // be GC'd unless there are other references to it.
napi_delete_reference(napi_env env,napi_ref ref)1235 NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref)
1236 {
1237     CHECK_ENV(env);
1238     CHECK_ARG(env, ref);
1239 
1240     auto reference = reinterpret_cast<NativeReference*>(ref);
1241     uint32_t refCount = reference->GetRefCount();
1242     if (refCount > 0 || reference->GetFinalRun()) {
1243         delete reference;
1244         reference = nullptr;
1245     } else {
1246         reference->SetDeleteSelf();
1247     }
1248 
1249     return napi_clear_last_error(env);
1250 }
1251 
1252 // Increments the reference count, optionally returning the resulting count.
1253 // After this call the  reference will be a strong reference because its
1254 // refcount is >0, and the referenced object is effectively "pinned".
1255 // Calling this when the refcount is 0 and the object is unavailable
1256 // results in an error.
napi_reference_ref(napi_env env,napi_ref ref,uint32_t * result)1257 NAPI_EXTERN napi_status napi_reference_ref(napi_env env, napi_ref ref, uint32_t* result)
1258 {
1259     CHECK_ENV(env);
1260     CHECK_ARG(env, ref);
1261 
1262     auto reference = reinterpret_cast<NativeReference*>(ref);
1263     uint32_t refCount = reference->Ref();
1264 
1265     if (result) {
1266         *result = refCount;
1267     }
1268 
1269     return napi_clear_last_error(env);
1270 }
1271 
1272 // Decrements the reference count, optionally returning the resulting count.
1273 // If the result is 0 the reference is now weak and the object may be GC'd
1274 // at any time if there are no other references. Calling this when the
1275 // refcount is already 0 results in an error.
napi_reference_unref(napi_env env,napi_ref ref,uint32_t * result)1276 NAPI_EXTERN napi_status napi_reference_unref(napi_env env, napi_ref ref, uint32_t* result)
1277 {
1278     CHECK_ENV(env);
1279     CHECK_ARG(env, ref);
1280 
1281     auto reference = reinterpret_cast<NativeReference*>(ref);
1282     uint32_t unrefCount = reference->Unref();
1283 
1284     if (result) {
1285         *result = unrefCount;
1286     }
1287 
1288     return napi_clear_last_error(env);
1289 }
1290 
1291 // Attempts to get a referenced value. If the reference is weak,
1292 // the value might no longer be available, in that case the call
1293 // is still successful but the result is nullptr.
napi_get_reference_value(napi_env env,napi_ref ref,napi_value * result)1294 NAPI_EXTERN napi_status napi_get_reference_value(napi_env env, napi_ref ref, napi_value* result)
1295 {
1296     CHECK_ENV(env);
1297     CHECK_ARG(env, ref);
1298     CHECK_ARG(env, result);
1299 
1300     auto reference = reinterpret_cast<NativeReference*>(ref);
1301 
1302     auto resultValue = reference->Get();
1303 
1304     *result = reinterpret_cast<napi_value>(resultValue);
1305     return napi_clear_last_error(env);
1306 }
1307 
napi_open_handle_scope(napi_env env,napi_handle_scope * result)1308 NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env, napi_handle_scope* result)
1309 {
1310     CHECK_ENV(env);
1311     CHECK_ARG(env, result);
1312 
1313     auto engine = reinterpret_cast<NativeEngine*>(env);
1314 
1315     auto scopeManager = engine->GetScopeManager();
1316     if (scopeManager == nullptr) {
1317         return napi_set_last_error(env, napi_generic_failure);
1318     }
1319     *result = reinterpret_cast<napi_handle_scope>(scopeManager->Open());
1320     return napi_clear_last_error(env);
1321 }
1322 
napi_close_handle_scope(napi_env env,napi_handle_scope scope)1323 NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env, napi_handle_scope scope)
1324 {
1325     CHECK_ENV(env);
1326     CHECK_ARG(env, scope);
1327 
1328     auto engine = reinterpret_cast<NativeEngine*>(env);
1329     auto nativeScope = reinterpret_cast<NativeScope*>(scope);
1330 
1331     auto scopeManager = engine->GetScopeManager();
1332     if (scopeManager == nullptr) {
1333         return napi_set_last_error(env, napi_generic_failure);
1334     }
1335     scopeManager->Close(nativeScope);
1336     return napi_clear_last_error(env);
1337 }
1338 
napi_open_escapable_handle_scope(napi_env env,napi_escapable_handle_scope * result)1339 NAPI_EXTERN napi_status napi_open_escapable_handle_scope(napi_env env, napi_escapable_handle_scope* result)
1340 {
1341     CHECK_ENV(env);
1342     CHECK_ARG(env, result);
1343 
1344     auto engine = reinterpret_cast<NativeEngine*>(env);
1345     auto scopeManager = engine->GetScopeManager();
1346 
1347     if (scopeManager == nullptr) {
1348         return napi_set_last_error(env, napi_generic_failure);
1349     }
1350 
1351     auto NativeScope = scopeManager->OpenEscape();
1352 
1353     *result = reinterpret_cast<napi_escapable_handle_scope>(NativeScope);
1354     return napi_clear_last_error(env);
1355 }
1356 
napi_close_escapable_handle_scope(napi_env env,napi_escapable_handle_scope scope)1357 NAPI_EXTERN napi_status napi_close_escapable_handle_scope(napi_env env, napi_escapable_handle_scope scope)
1358 {
1359     CHECK_ENV(env);
1360     CHECK_ARG(env, scope);
1361 
1362     auto engine = reinterpret_cast<NativeEngine*>(env);
1363     auto nativeScope = reinterpret_cast<NativeScope*>(scope);
1364 
1365     auto scopeManager = engine->GetScopeManager();
1366     if (scopeManager == nullptr) {
1367         return napi_set_last_error(env, napi_generic_failure);
1368     }
1369     scopeManager->CloseEscape(nativeScope);
1370     return napi_clear_last_error(env);
1371 }
1372 
napi_escape_handle(napi_env env,napi_escapable_handle_scope scope,napi_value escapee,napi_value * result)1373 NAPI_EXTERN napi_status napi_escape_handle(napi_env env,
1374                                            napi_escapable_handle_scope scope,
1375                                            napi_value escapee,
1376                                            napi_value* result)
1377 {
1378     CHECK_ENV(env);
1379     CHECK_ARG(env, scope);
1380     CHECK_ARG(env, escapee);
1381     CHECK_ARG(env, result);
1382 
1383     auto engine = reinterpret_cast<NativeEngine*>(env);
1384     auto nativeScope = reinterpret_cast<NativeScope*>(scope);
1385     auto escapeeValue = reinterpret_cast<NativeValue*>(escapee);
1386 
1387     auto scopeManager = engine->GetScopeManager();
1388     if (scopeManager == nullptr) {
1389         return napi_set_last_error(env, napi_generic_failure);
1390     }
1391 
1392     if (!nativeScope->escapeCalled) {
1393         auto resultValue = scopeManager->Escape(nativeScope, escapeeValue);
1394         *result = reinterpret_cast<napi_value>(resultValue);
1395         nativeScope->escapeCalled = true;
1396         return napi_clear_last_error(env);
1397     }
1398     return napi_set_last_error(env, napi_escape_called_twice);
1399 }
1400 
1401 // Methods to support error handling
napi_throw(napi_env env,napi_value error)1402 NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error)
1403 {
1404     CHECK_ENV(env);
1405     CHECK_ARG(env, error);
1406 
1407     auto engine = reinterpret_cast<NativeEngine*>(env);
1408     auto nativeValue = reinterpret_cast<NativeValue*>(error);
1409 
1410     RETURN_STATUS_IF_FALSE(env, nativeValue->IsError(), napi_invalid_arg);
1411 
1412     engine->Throw(nativeValue);
1413     return napi_clear_last_error(env);
1414 }
1415 
napi_throw_error(napi_env env,const char * code,const char * msg)1416 NAPI_EXTERN napi_status napi_throw_error(napi_env env, const char* code, const char* msg)
1417 {
1418     CHECK_ENV(env);
1419     CHECK_ARG(env, msg);
1420 
1421     auto engine = reinterpret_cast<NativeEngine*>(env);
1422 
1423     engine->Throw(NativeErrorType::NATIVE_COMMON_ERROR, code, msg);
1424     return napi_clear_last_error(env);
1425 }
1426 
napi_throw_type_error(napi_env env,const char * code,const char * msg)1427 NAPI_EXTERN napi_status napi_throw_type_error(napi_env env, const char* code, const char* msg)
1428 {
1429     CHECK_ENV(env);
1430     CHECK_ARG(env, msg);
1431 
1432     auto engine = reinterpret_cast<NativeEngine*>(env);
1433 
1434     engine->Throw(NativeErrorType::NATIVE_TYPE_ERROR, code, msg);
1435     return napi_generic_failure;
1436 }
1437 
napi_throw_range_error(napi_env env,const char * code,const char * msg)1438 NAPI_EXTERN napi_status napi_throw_range_error(napi_env env, const char* code, const char* msg)
1439 {
1440     CHECK_ENV(env);
1441     CHECK_ARG(env, msg);
1442 
1443     auto engine = reinterpret_cast<NativeEngine*>(env);
1444 
1445     engine->Throw(NativeErrorType::NATIVE_RANGE_ERROR, code, msg);
1446     return napi_generic_failure;
1447 }
1448 
napi_is_error(napi_env env,napi_value value,bool * result)1449 NAPI_EXTERN napi_status napi_is_error(napi_env env, napi_value value, bool* result)
1450 {
1451     CHECK_ENV(env);
1452     CHECK_ARG(env, value);
1453     CHECK_ARG(env, result);
1454 
1455     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1456 
1457     *result = nativeValue->IsError();
1458     return napi_clear_last_error(env);
1459 }
1460 
1461 // Methods to support catching exceptions
napi_is_exception_pending(napi_env env,bool * result)1462 NAPI_EXTERN napi_status napi_is_exception_pending(napi_env env, bool* result)
1463 {
1464     CHECK_ENV(env);
1465     CHECK_ARG(env, result);
1466 
1467     auto engine = reinterpret_cast<NativeEngine*>(env);
1468 
1469     *result = engine->IsExceptionPending();
1470     return napi_clear_last_error(env);
1471 }
1472 
napi_get_and_clear_last_exception(napi_env env,napi_value * result)1473 NAPI_EXTERN napi_status napi_get_and_clear_last_exception(napi_env env, napi_value* result)
1474 {
1475     CHECK_ENV(env);
1476     CHECK_ARG(env, result);
1477 
1478     auto engine = reinterpret_cast<NativeEngine*>(env);
1479 
1480     auto resultValue = engine->GetAndClearLastException();
1481 
1482     *result = reinterpret_cast<napi_value>(resultValue);
1483     return napi_clear_last_error(env);
1484 }
1485 
1486 // Methods to work with array buffers and typed arrays
napi_is_arraybuffer(napi_env env,napi_value value,bool * result)1487 NAPI_EXTERN napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result)
1488 {
1489     CHECK_ENV(env);
1490     CHECK_ARG(env, value);
1491     CHECK_ARG(env, result);
1492 
1493     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1494 
1495     *result = nativeValue->IsArrayBuffer();
1496     return napi_clear_last_error(env);
1497 }
1498 
napi_create_arraybuffer(napi_env env,size_t byte_length,void ** data,napi_value * result)1499 NAPI_EXTERN napi_status napi_create_arraybuffer(napi_env env, size_t byte_length, void** data, napi_value* result)
1500 {
1501     CHECK_ENV(env);
1502     CHECK_ARG(env, data);
1503     CHECK_ARG(env, result);
1504 
1505     auto engine = reinterpret_cast<NativeEngine*>(env);
1506 
1507     auto resultValue = engine->CreateArrayBuffer(data, byte_length);
1508 
1509     *result = reinterpret_cast<napi_value>(resultValue);
1510     return napi_clear_last_error(env);
1511 }
1512 
napi_create_external_arraybuffer(napi_env env,void * external_data,size_t byte_length,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)1513 NAPI_EXTERN napi_status napi_create_external_arraybuffer(napi_env env,
1514                                                          void* external_data,
1515                                                          size_t byte_length,
1516                                                          napi_finalize finalize_cb,
1517                                                          void* finalize_hint,
1518                                                          napi_value* result)
1519 {
1520     CHECK_ENV(env);
1521     CHECK_ARG(env, external_data);
1522     CHECK_ARG(env, finalize_cb);
1523     CHECK_ARG(env, result);
1524 
1525     auto engine = reinterpret_cast<NativeEngine*>(env);
1526     auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
1527 
1528     auto resultValue = engine->CreateArrayBufferExternal(external_data, byte_length, callback, finalize_hint);
1529 
1530     *result = reinterpret_cast<napi_value>(resultValue);
1531     return napi_clear_last_error(env);
1532 }
1533 
napi_get_arraybuffer_info(napi_env env,napi_value arraybuffer,void ** data,size_t * byte_length)1534 NAPI_EXTERN napi_status napi_get_arraybuffer_info(napi_env env,
1535                                                   napi_value arraybuffer,
1536                                                   void** data,
1537                                                   size_t* byte_length)
1538 {
1539     CHECK_ENV(env);
1540     CHECK_ARG(env, arraybuffer);
1541     CHECK_ARG(env, data);
1542     CHECK_ARG(env, byte_length);
1543 
1544     auto nativeValue = reinterpret_cast<NativeValue*>(arraybuffer);
1545 
1546     RETURN_STATUS_IF_FALSE(env, nativeValue->IsArrayBuffer(), napi_status::napi_arraybuffer_expected);
1547 
1548     auto nativeArrayBuffer =
1549         reinterpret_cast<NativeArrayBuffer*>(nativeValue->GetInterface(NativeArrayBuffer::INTERFACE_ID));
1550 
1551     *data = nativeArrayBuffer->GetBuffer();
1552     *byte_length = nativeArrayBuffer->GetLength();
1553     return napi_clear_last_error(env);
1554 }
1555 
napi_is_typedarray(napi_env env,napi_value value,bool * result)1556 NAPI_EXTERN napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result)
1557 {
1558     CHECK_ENV(env);
1559     CHECK_ARG(env, value);
1560 
1561     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1562 
1563     *result = nativeValue->IsTypedArray();
1564 
1565     return napi_clear_last_error(env);
1566 }
1567 
1568 EXTERN_C_START
napi_is_buffer(napi_env env,napi_value value,bool * result)1569 NAPI_EXTERN napi_status napi_is_buffer(napi_env env, napi_value value, bool* result)
1570 {
1571     CHECK_ENV(env);
1572     CHECK_ARG(env, value);
1573     CHECK_ARG(env, result);
1574 
1575     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1576     *result = nativeValue->IsBuffer();
1577     return napi_clear_last_error(env);
1578 }
1579 
napi_create_buffer(napi_env env,size_t size,void ** data,napi_value * result)1580 NAPI_EXTERN napi_status napi_create_buffer(napi_env env, size_t size, void** data, napi_value* result)
1581 {
1582     CHECK_ENV(env);
1583     CHECK_ARG(env, data);
1584     CHECK_ARG(env, result);
1585 
1586     RETURN_STATUS_IF_FALSE(env, size > 0, napi_invalid_arg);
1587 
1588     auto engine = reinterpret_cast<NativeEngine*>(env);
1589 
1590     auto resultValue = engine->CreateBuffer(data, size);
1591 
1592     CHECK_ARG(env, resultValue);
1593     CHECK_ARG(env, *data);
1594 
1595     auto nativeBuffer = reinterpret_cast<NativeBuffer*>(resultValue->GetInterface(NativeBuffer::INTERFACE_ID));
1596     void* ptr = nativeBuffer->GetBuffer();
1597     CHECK_ARG(env, ptr);
1598 
1599     *result = reinterpret_cast<napi_value>(resultValue);
1600     return napi_clear_last_error(env);
1601 }
1602 
napi_create_buffer_copy(napi_env env,size_t length,const void * data,void ** result_data,napi_value * result)1603 NAPI_EXTERN napi_status napi_create_buffer_copy(
1604     napi_env env, size_t length, const void* data, void** result_data, napi_value* result)
1605 {
1606     CHECK_ENV(env);
1607     CHECK_ARG(env, data);
1608     CHECK_ARG(env, result_data);
1609     CHECK_ARG(env, result);
1610     RETURN_STATUS_IF_FALSE(env, length > 0, napi_invalid_arg);
1611 
1612     auto engine = reinterpret_cast<NativeEngine*>(env);
1613     auto resultValue = engine->CreateBufferCopy(result_data, length, data);
1614     if (resultValue == nullptr) {
1615         HILOG_INFO("engine create buffer_copy failed!");
1616     }
1617     CHECK_ARG(env, resultValue);
1618 
1619     auto nativeBuffer = reinterpret_cast<NativeBuffer*>(resultValue->GetInterface(NativeBuffer::INTERFACE_ID));
1620     void* ptr = nativeBuffer->GetBuffer();
1621     CHECK_ARG(env, ptr);
1622 
1623     *result = reinterpret_cast<napi_value>(resultValue);
1624     return napi_clear_last_error(env);
1625 }
1626 
napi_create_external_buffer(napi_env env,size_t length,void * data,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)1627 NAPI_EXTERN napi_status napi_create_external_buffer(
1628     napi_env env, size_t length, void* data, napi_finalize finalize_cb, void* finalize_hint, napi_value* result)
1629 {
1630     CHECK_ENV(env);
1631     CHECK_ARG(env, result);
1632     CHECK_ARG(env, data);
1633     RETURN_STATUS_IF_FALSE(env, length > 0, napi_invalid_arg);
1634 
1635     auto engine = reinterpret_cast<NativeEngine*>(env);
1636     auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
1637     auto resultValue = engine->CreateBufferExternal(data, length, callback, finalize_hint);
1638     CHECK_ARG(env, resultValue);
1639 
1640     auto nativeBuffer = reinterpret_cast<NativeBuffer*>(resultValue->GetInterface(NativeBuffer::INTERFACE_ID));
1641     void* ptr = nativeBuffer->GetBuffer();
1642     CHECK_ARG(env, ptr);
1643 
1644     *result = reinterpret_cast<napi_value>(resultValue);
1645     return napi_clear_last_error(env);
1646 }
1647 
napi_get_buffer_info(napi_env env,napi_value value,void ** data,size_t * length)1648 NAPI_EXTERN napi_status napi_get_buffer_info(napi_env env, napi_value value, void** data, size_t* length)
1649 {
1650     CHECK_ENV(env);
1651     CHECK_ARG(env, value);
1652 
1653     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1654     RETURN_STATUS_IF_FALSE(env, nativeValue->IsArrayBuffer(), napi_status::napi_arraybuffer_expected);
1655 
1656     auto nativeArrayBuffer =
1657         reinterpret_cast<NativeArrayBuffer*>(nativeValue->GetInterface(NativeArrayBuffer::INTERFACE_ID));
1658 
1659     *data = nativeArrayBuffer->GetBuffer();
1660     *length = nativeArrayBuffer->GetLength();
1661     return napi_clear_last_error(env);
1662 }
1663 
napi_object_freeze(napi_env env,napi_value object)1664 NAPI_EXTERN napi_status napi_object_freeze(napi_env env, napi_value object)
1665 {
1666     CHECK_ENV(env);
1667     CHECK_ARG(env, object);
1668 
1669     auto nativeValue = reinterpret_cast<NativeValue*>(object);
1670     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_OBJECT, napi_object_expected);
1671     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
1672 
1673     nativeObject->Freeze();
1674 
1675     return napi_clear_last_error(env);
1676 }
1677 
napi_object_seal(napi_env env,napi_value object)1678 NAPI_EXTERN napi_status napi_object_seal(napi_env env, napi_value object)
1679 {
1680     CHECK_ENV(env);
1681     CHECK_ARG(env, object);
1682 
1683     auto nativeValue = reinterpret_cast<NativeValue*>(object);
1684     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_OBJECT, napi_object_expected);
1685     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
1686 
1687     nativeObject->Seal();
1688 
1689     return napi_clear_last_error(env);
1690 }
1691 
1692 EXTERN_C_END
1693 
napi_create_typedarray(napi_env env,napi_typedarray_type type,size_t length,napi_value arraybuffer,size_t byte_offset,napi_value * result)1694 NAPI_EXTERN napi_status napi_create_typedarray(napi_env env,
1695                                                napi_typedarray_type type,
1696                                                size_t length,
1697                                                napi_value arraybuffer,
1698                                                size_t byte_offset,
1699                                                napi_value* result)
1700 {
1701     CHECK_ENV(env);
1702     CHECK_ARG(env, arraybuffer);
1703     CHECK_ARG(env, result);
1704 
1705     auto engine = reinterpret_cast<NativeEngine*>(env);
1706     auto value = reinterpret_cast<NativeValue*>(arraybuffer);
1707     auto typedArrayType = (NativeTypedArrayType)type;
1708 
1709     RETURN_STATUS_IF_FALSE(env, value->IsArrayBuffer(), napi_status::napi_arraybuffer_expected);
1710 
1711     auto resultValue = engine->CreateTypedArray(typedArrayType, value, length, byte_offset);
1712 
1713     *result = reinterpret_cast<napi_value>(resultValue);
1714     return napi_clear_last_error(env);
1715 }
1716 
napi_get_typedarray_info(napi_env env,napi_value typedarray,napi_typedarray_type * type,size_t * length,void ** data,napi_value * arraybuffer,size_t * byte_offset)1717 NAPI_EXTERN napi_status napi_get_typedarray_info(napi_env env,
1718                                                  napi_value typedarray,
1719                                                  napi_typedarray_type* type,
1720                                                  size_t* length,
1721                                                  void** data,
1722                                                  napi_value* arraybuffer,
1723                                                  size_t* byte_offset)
1724 {
1725     CHECK_ENV(env);
1726     CHECK_ARG(env, typedarray);
1727 
1728     auto value = reinterpret_cast<NativeValue*>(typedarray);
1729 
1730     RETURN_STATUS_IF_FALSE(env, value->IsTypedArray(), napi_status::napi_invalid_arg);
1731 
1732     auto nativeTypedArray = reinterpret_cast<NativeTypedArray*>(value->GetInterface(NativeTypedArray::INTERFACE_ID));
1733 
1734     if (type != nullptr) {
1735         *type = (napi_typedarray_type)nativeTypedArray->GetTypedArrayType();
1736     }
1737     if (length != nullptr) {
1738         *length = nativeTypedArray->GetLength();
1739     }
1740     if (data != nullptr) {
1741         *data = static_cast<uint8_t*>(nativeTypedArray->GetData()) + nativeTypedArray->GetOffset();
1742     }
1743     if (arraybuffer != nullptr) {
1744         *arraybuffer = reinterpret_cast<napi_value>(nativeTypedArray->GetArrayBuffer());
1745     }
1746     if (byte_offset != nullptr) {
1747         *byte_offset = nativeTypedArray->GetOffset();
1748     }
1749 
1750     return napi_clear_last_error(env);
1751 }
1752 
napi_create_dataview(napi_env env,size_t length,napi_value arraybuffer,size_t byte_offset,napi_value * result)1753 NAPI_EXTERN napi_status napi_create_dataview(
1754     napi_env env, size_t length, napi_value arraybuffer, size_t byte_offset, napi_value* result)
1755 {
1756     CHECK_ENV(env);
1757     CHECK_ARG(env, arraybuffer);
1758     CHECK_ARG(env, result);
1759 
1760     auto engine = reinterpret_cast<NativeEngine*>(env);
1761     auto arrayBufferValue = reinterpret_cast<NativeValue*>(arraybuffer);
1762 
1763     RETURN_STATUS_IF_FALSE(env, arrayBufferValue->IsArrayBuffer(), napi_status::napi_arraybuffer_expected);
1764 
1765     auto nativeArrayBuffer =
1766         reinterpret_cast<NativeArrayBuffer*>(arrayBufferValue->GetInterface(NativeArrayBuffer::INTERFACE_ID));
1767     if (length + byte_offset > nativeArrayBuffer->GetLength()) {
1768         napi_throw_range_error(
1769             env,
1770             "ERR_NAPI_INVALID_DATAVIEW_ARGS",
1771             "byte_offset + byte_length should be less than or "
1772             "equal to the size in bytes of the array passed in");
1773         return napi_set_last_error(env, napi_pending_exception);
1774     }
1775 
1776     auto resultValue = engine->CreateDataView(arrayBufferValue, length, byte_offset);
1777 
1778     *result = reinterpret_cast<napi_value>(resultValue);
1779     return napi_clear_last_error(env);
1780 }
1781 
napi_is_dataview(napi_env env,napi_value value,bool * result)1782 NAPI_EXTERN napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
1783 {
1784     CHECK_ENV(env);
1785     CHECK_ARG(env, value);
1786     CHECK_ARG(env, result);
1787 
1788     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1789 
1790     *result = nativeValue->IsDataView();
1791     return napi_clear_last_error(env);
1792 }
1793 
napi_get_dataview_info(napi_env env,napi_value dataview,size_t * bytelength,void ** data,napi_value * arraybuffer,size_t * byte_offset)1794 NAPI_EXTERN napi_status napi_get_dataview_info(napi_env env,
1795                                                napi_value dataview,
1796                                                size_t* bytelength,
1797                                                void** data,
1798                                                napi_value* arraybuffer,
1799                                                size_t* byte_offset)
1800 {
1801     CHECK_ENV(env);
1802     CHECK_ARG(env, dataview);
1803 
1804     auto nativeValue = reinterpret_cast<NativeValue*>(dataview);
1805 
1806     RETURN_STATUS_IF_FALSE(env, nativeValue->IsDataView(), napi_status::napi_invalid_arg);
1807 
1808     auto nativeDataView = reinterpret_cast<NativeDataView*>(nativeValue->GetInterface(NativeDataView::INTERFACE_ID));
1809 
1810     if (bytelength != nullptr) {
1811         *bytelength = nativeDataView->GetLength();
1812     }
1813     if (data != nullptr) {
1814         *data = nativeDataView->GetBuffer();
1815     }
1816     if (arraybuffer != nullptr) {
1817         *arraybuffer = reinterpret_cast<napi_value>(nativeDataView->GetArrayBuffer());
1818     }
1819     if (byte_offset != nullptr) {
1820         *byte_offset = nativeDataView->GetOffset();
1821     }
1822     return napi_clear_last_error(env);
1823 }
1824 
1825 // version management
napi_get_version(napi_env env,uint32_t * result)1826 NAPI_EXTERN napi_status napi_get_version(napi_env env, uint32_t* result)
1827 {
1828     CHECK_ENV(env);
1829     CHECK_ARG(env, result);
1830 
1831     *result = NAPI_VERSION;
1832     return napi_clear_last_error(env);
1833 }
1834 
1835 // Promises
napi_create_promise(napi_env env,napi_deferred * deferred,napi_value * promise)1836 NAPI_EXTERN napi_status napi_create_promise(napi_env env, napi_deferred* deferred, napi_value* promise)
1837 {
1838     CHECK_ENV(env);
1839     CHECK_ARG(env, deferred);
1840     CHECK_ARG(env, promise);
1841 
1842     auto engine = reinterpret_cast<NativeEngine*>(env);
1843     auto resultValue = engine->CreatePromise(reinterpret_cast<NativeDeferred**>(deferred));
1844 
1845     *promise = reinterpret_cast<napi_value>(resultValue);
1846     return napi_clear_last_error(env);
1847 }
1848 
napi_resolve_deferred(napi_env env,napi_deferred deferred,napi_value resolution)1849 NAPI_EXTERN napi_status napi_resolve_deferred(napi_env env, napi_deferred deferred, napi_value resolution)
1850 {
1851     CHECK_ENV(env);
1852     CHECK_ARG(env, deferred);
1853     CHECK_ARG(env, resolution);
1854 
1855     auto nativeDeferred = reinterpret_cast<NativeDeferred*>(deferred);
1856     auto resolutionValue = reinterpret_cast<NativeValue*>(resolution);
1857 
1858     nativeDeferred->Resolve(resolutionValue);
1859     delete nativeDeferred;
1860     return napi_clear_last_error(env);
1861 }
1862 
napi_reject_deferred(napi_env env,napi_deferred deferred,napi_value rejection)1863 NAPI_EXTERN napi_status napi_reject_deferred(napi_env env, napi_deferred deferred, napi_value rejection)
1864 {
1865     CHECK_ENV(env);
1866     CHECK_ARG(env, deferred);
1867     CHECK_ARG(env, rejection);
1868 
1869     auto nativeDeferred = reinterpret_cast<NativeDeferred*>(deferred);
1870     auto rejectionValue = reinterpret_cast<NativeValue*>(rejection);
1871 
1872     nativeDeferred->Reject(rejectionValue);
1873     delete nativeDeferred;
1874     return napi_clear_last_error(env);
1875 }
1876 
napi_is_promise(napi_env env,napi_value value,bool * is_promise)1877 NAPI_EXTERN napi_status napi_is_promise(napi_env env, napi_value value, bool* is_promise)
1878 {
1879     CHECK_ENV(env);
1880     CHECK_ARG(env, value);
1881     CHECK_ARG(env, is_promise);
1882 
1883     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1884 
1885     *is_promise = nativeValue->IsPromise();
1886     return napi_clear_last_error(env);
1887 }
1888 
1889 // promise reject events
napi_set_promise_rejection_callback(napi_env env,napi_ref ref,napi_ref checkRef)1890 NAPI_EXTERN napi_status napi_set_promise_rejection_callback(napi_env env, napi_ref ref, napi_ref checkRef)
1891 {
1892     CHECK_ENV(env);
1893     CHECK_ARG(env, ref);
1894     CHECK_ARG(env, checkRef);
1895 
1896     auto engine = reinterpret_cast<NativeEngine*>(env);
1897     auto rejectCallbackRef = reinterpret_cast<NativeReference*>(ref);
1898     auto checkCallbackRef = reinterpret_cast<NativeReference*>(checkRef);
1899 
1900     engine->SetPromiseRejectCallback(rejectCallbackRef, checkCallbackRef);
1901     return napi_clear_last_error(env);
1902 }
1903 
1904 // Running a script
napi_run_script(napi_env env,napi_value script,napi_value * result)1905 NAPI_EXTERN napi_status napi_run_script(napi_env env, napi_value script, napi_value* result)
1906 {
1907     CHECK_ENV(env);
1908     CHECK_ARG(env, script);
1909     CHECK_ARG(env, result);
1910 
1911     auto engine = reinterpret_cast<NativeEngine*>(env);
1912     auto scriptValue = reinterpret_cast<NativeValue*>(script);
1913     RETURN_STATUS_IF_FALSE(env, scriptValue->TypeOf() == NATIVE_STRING, napi_status::napi_string_expected);
1914     auto resultValue = engine->RunScript(scriptValue);
1915     *result = reinterpret_cast<napi_value>(resultValue);
1916     return napi_clear_last_error(env);
1917 }
1918 
1919 // Runnint a buffer script, only used in ark
napi_run_buffer_script(napi_env env,std::vector<uint8_t> & buffer,napi_value * result)1920 NAPI_EXTERN napi_status napi_run_buffer_script(napi_env env, std::vector<uint8_t>& buffer, napi_value* result)
1921 {
1922     CHECK_ENV(env);
1923     CHECK_ARG(env, result);
1924 
1925     auto engine = reinterpret_cast<NativeEngine*>(env);
1926     NativeValue* resultValue = engine->RunBufferScript(buffer);
1927     *result = reinterpret_cast<napi_value>(resultValue);
1928     return napi_clear_last_error(env);
1929 }
1930 
napi_run_actor(napi_env env,std::vector<uint8_t> & buffer,const char * descriptor,napi_value * result)1931 NAPI_EXTERN napi_status napi_run_actor(napi_env env, std::vector<uint8_t>& buffer,
1932                                        const char* descriptor, napi_value* result)
1933 {
1934     CHECK_ENV(env);
1935     CHECK_ARG(env, result);
1936     auto engine = reinterpret_cast<NativeEngine*>(env);
1937     auto resultValue = engine->RunActor(buffer, descriptor);
1938     *result = reinterpret_cast<napi_value>(resultValue);
1939     return napi_clear_last_error(env);
1940 }
1941 
1942 // Memory management
napi_adjust_external_memory(napi_env env,int64_t change_in_bytes,int64_t * adjusted_value)1943 NAPI_INNER_EXTERN napi_status napi_adjust_external_memory(
1944     napi_env env, int64_t change_in_bytes, int64_t* adjusted_value)
1945 {
1946     CHECK_ENV(env);
1947     CHECK_ARG(env, adjusted_value);
1948 
1949     auto engine = reinterpret_cast<NativeEngine*>(env);
1950     engine->AdjustExternalMemory(change_in_bytes, adjusted_value);
1951 
1952     return napi_clear_last_error(env);
1953 }
1954 
napi_is_callable(napi_env env,napi_value value,bool * result)1955 NAPI_EXTERN napi_status napi_is_callable(napi_env env, napi_value value, bool* result)
1956 {
1957     CHECK_ENV(env);
1958     CHECK_ARG(env, value);
1959     CHECK_ARG(env, result);
1960 
1961     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1962 
1963     *result = nativeValue->IsCallable();
1964     return napi_clear_last_error(env);
1965 }
1966 
napi_is_arguments_object(napi_env env,napi_value value,bool * result)1967 NAPI_EXTERN napi_status napi_is_arguments_object(napi_env env, napi_value value, bool* result)
1968 {
1969     CHECK_ENV(env);
1970     CHECK_ARG(env, value);
1971     CHECK_ARG(env, result);
1972 
1973     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1974 
1975     *result = nativeValue->IsArgumentsObject();
1976     return napi_clear_last_error(env);
1977 }
1978 
napi_is_async_function(napi_env env,napi_value value,bool * result)1979 NAPI_EXTERN napi_status napi_is_async_function(napi_env env, napi_value value, bool* result)
1980 {
1981     CHECK_ENV(env);
1982     CHECK_ARG(env, value);
1983     CHECK_ARG(env, result);
1984 
1985     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1986 
1987     *result = nativeValue->IsAsyncFunction();
1988     return napi_clear_last_error(env);
1989 }
1990 
napi_is_boolean_object(napi_env env,napi_value value,bool * result)1991 NAPI_EXTERN napi_status napi_is_boolean_object(napi_env env, napi_value value, bool* result)
1992 {
1993     CHECK_ENV(env);
1994     CHECK_ARG(env, value);
1995     CHECK_ARG(env, result);
1996 
1997     auto nativeValue = reinterpret_cast<NativeValue*>(value);
1998 
1999     *result = nativeValue->IsBooleanObject();
2000     return napi_clear_last_error(env);
2001 }
2002 
napi_is_generator_function(napi_env env,napi_value value,bool * result)2003 NAPI_EXTERN napi_status napi_is_generator_function(napi_env env, napi_value value, bool* result)
2004 {
2005     CHECK_ENV(env);
2006     CHECK_ARG(env, value);
2007     CHECK_ARG(env, result);
2008 
2009     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2010 
2011     *result = nativeValue->IsGeneratorFunction();
2012     return napi_clear_last_error(env);
2013 }
2014 
napi_is_map_iterator(napi_env env,napi_value value,bool * result)2015 NAPI_EXTERN napi_status napi_is_map_iterator(napi_env env, napi_value value, bool* result)
2016 {
2017     CHECK_ENV(env);
2018     CHECK_ARG(env, value);
2019     CHECK_ARG(env, result);
2020 
2021     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2022 
2023     *result = nativeValue->IsMapIterator();
2024     return napi_clear_last_error(env);
2025 }
2026 
napi_is_set_iterator(napi_env env,napi_value value,bool * result)2027 NAPI_EXTERN napi_status napi_is_set_iterator(napi_env env, napi_value value, bool* result)
2028 {
2029     CHECK_ENV(env);
2030     CHECK_ARG(env, value);
2031     CHECK_ARG(env, result);
2032 
2033     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2034 
2035     *result = nativeValue->IsSetIterator();
2036     return napi_clear_last_error(env);
2037 }
2038 
napi_is_generator_object(napi_env env,napi_value value,bool * result)2039 NAPI_EXTERN napi_status napi_is_generator_object(napi_env env, napi_value value, bool* result)
2040 {
2041     CHECK_ENV(env);
2042     CHECK_ARG(env, value);
2043     CHECK_ARG(env, result);
2044 
2045     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2046 
2047     *result = nativeValue->IsGeneratorObject();
2048     return napi_clear_last_error(env);
2049 }
2050 
napi_is_module_namespace_object(napi_env env,napi_value value,bool * result)2051 NAPI_EXTERN napi_status napi_is_module_namespace_object(napi_env env, napi_value value, bool* result)
2052 {
2053     CHECK_ENV(env);
2054     CHECK_ARG(env, value);
2055     CHECK_ARG(env, result);
2056 
2057     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2058 
2059     *result = nativeValue->IsModuleNamespaceObject();
2060     return napi_clear_last_error(env);
2061 }
2062 
napi_is_proxy(napi_env env,napi_value value,bool * result)2063 NAPI_EXTERN napi_status napi_is_proxy(napi_env env, napi_value value, bool* result)
2064 {
2065     CHECK_ENV(env);
2066     CHECK_ARG(env, value);
2067     CHECK_ARG(env, result);
2068 
2069     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2070 
2071     *result = nativeValue->IsProxy();
2072     return napi_clear_last_error(env);
2073 }
2074 
napi_is_reg_exp(napi_env env,napi_value value,bool * result)2075 NAPI_EXTERN napi_status napi_is_reg_exp(napi_env env, napi_value value, bool* result)
2076 {
2077     CHECK_ENV(env);
2078     CHECK_ARG(env, value);
2079     CHECK_ARG(env, result);
2080 
2081     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2082 
2083     *result = nativeValue->IsRegExp();
2084     return napi_clear_last_error(env);
2085 }
2086 
napi_is_number_object(napi_env env,napi_value value,bool * result)2087 NAPI_EXTERN napi_status napi_is_number_object(napi_env env, napi_value value, bool* result)
2088 {
2089     CHECK_ENV(env);
2090     CHECK_ARG(env, value);
2091     CHECK_ARG(env, result);
2092 
2093     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2094 
2095     *result = nativeValue->IsNumberObject();
2096     return napi_clear_last_error(env);
2097 }
2098 
napi_is_map(napi_env env,napi_value value,bool * result)2099 NAPI_EXTERN napi_status napi_is_map(napi_env env, napi_value value, bool* result)
2100 {
2101     CHECK_ENV(env);
2102     CHECK_ARG(env, value);
2103     CHECK_ARG(env, result);
2104 
2105     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2106 
2107     *result = nativeValue->IsMap();
2108     return napi_clear_last_error(env);
2109 }
2110 
napi_is_set(napi_env env,napi_value value,bool * result)2111 NAPI_EXTERN napi_status napi_is_set(napi_env env, napi_value value, bool* result)
2112 {
2113     CHECK_ENV(env);
2114     CHECK_ARG(env, value);
2115     CHECK_ARG(env, result);
2116 
2117     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2118 
2119     *result = nativeValue->IsSet();
2120     return napi_clear_last_error(env);
2121 }
2122 
napi_is_string_object(napi_env env,napi_value value,bool * result)2123 NAPI_EXTERN napi_status napi_is_string_object(napi_env env, napi_value value, bool* result)
2124 {
2125     CHECK_ENV(env);
2126     CHECK_ARG(env, value);
2127     CHECK_ARG(env, result);
2128 
2129     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2130 
2131     *result = nativeValue->IsStringObject();
2132     return napi_clear_last_error(env);
2133 }
2134 
napi_is_symbol_object(napi_env env,napi_value value,bool * result)2135 NAPI_EXTERN napi_status napi_is_symbol_object(napi_env env, napi_value value, bool* result)
2136 {
2137     CHECK_ENV(env);
2138     CHECK_ARG(env, value);
2139     CHECK_ARG(env, result);
2140 
2141     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2142 
2143     *result = nativeValue->IsSymbolObject();
2144     return napi_clear_last_error(env);
2145 }
2146 
napi_is_weak_map(napi_env env,napi_value value,bool * result)2147 NAPI_EXTERN napi_status napi_is_weak_map(napi_env env, napi_value value, bool* result)
2148 {
2149     CHECK_ENV(env);
2150     CHECK_ARG(env, value);
2151     CHECK_ARG(env, result);
2152 
2153     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2154 
2155     *result = nativeValue->IsWeakMap();
2156     return napi_clear_last_error(env);
2157 }
2158 
napi_is_weak_set(napi_env env,napi_value value,bool * result)2159 NAPI_EXTERN napi_status napi_is_weak_set(napi_env env, napi_value value, bool* result)
2160 {
2161     CHECK_ENV(env);
2162     CHECK_ARG(env, value);
2163     CHECK_ARG(env, result);
2164 
2165     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2166 
2167     *result = nativeValue->IsWeakSet();
2168     return napi_clear_last_error(env);
2169 }
2170 
napi_create_runtime(napi_env env,napi_env * result_env)2171 NAPI_EXTERN napi_status napi_create_runtime(napi_env env, napi_env* result_env)
2172 {
2173     CHECK_ENV(env);
2174     CHECK_ARG(env, result_env);
2175 
2176     auto engine = reinterpret_cast<NativeEngine*>(env);
2177 
2178     auto result = engine->CreateRuntime();
2179     *result_env = reinterpret_cast<napi_env>(result);
2180 
2181     return napi_clear_last_error(env);
2182 }
2183 
napi_serialize(napi_env env,napi_value object,napi_value transfer_list,napi_value * result)2184 NAPI_EXTERN napi_status napi_serialize(napi_env env, napi_value object, napi_value transfer_list, napi_value* result)
2185 {
2186     CHECK_ENV(env);
2187     CHECK_ARG(env, object);
2188     CHECK_ARG(env, transfer_list);
2189     CHECK_ARG(env, result);
2190 
2191     auto engine = reinterpret_cast<NativeEngine*>(env);
2192     auto nativeValue = reinterpret_cast<NativeValue*>(object);
2193     auto transferList = reinterpret_cast<NativeValue*>(transfer_list);
2194 
2195     auto resultValue = engine->Serialize(engine, nativeValue, transferList);
2196     *result = reinterpret_cast<napi_value>(resultValue);
2197 
2198     return napi_clear_last_error(env);
2199 }
2200 
napi_deserialize(napi_env env,napi_value recorder,napi_value * object)2201 NAPI_EXTERN napi_status napi_deserialize(napi_env env, napi_value recorder, napi_value* object)
2202 {
2203     CHECK_ENV(env);
2204     CHECK_ARG(env, recorder);
2205     CHECK_ARG(env, object);
2206 
2207     auto engine = reinterpret_cast<NativeEngine*>(env);
2208     auto recorderValue = reinterpret_cast<NativeValue*>(recorder);
2209 
2210     auto result = engine->Deserialize(engine, recorderValue);
2211     *object = reinterpret_cast<napi_value>(result);
2212 
2213     return napi_clear_last_error(env);
2214 }
2215 
napi_delete_serialization_data(napi_env env,napi_value value)2216 NAPI_EXTERN napi_status napi_delete_serialization_data(napi_env env, napi_value value)
2217 {
2218     CHECK_ENV(env);
2219     CHECK_ARG(env, value);
2220 
2221     auto engine = reinterpret_cast<NativeEngine*>(env);
2222     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2223     engine->DeleteSerializationData(nativeValue);
2224 
2225     return napi_clear_last_error(env);
2226 }
2227 
napi_create_bigint_int64(napi_env env,int64_t value,napi_value * result)2228 NAPI_EXTERN napi_status napi_create_bigint_int64(napi_env env, int64_t value, napi_value* result)
2229 {
2230     CHECK_ENV(env);
2231     CHECK_ARG(env, result);
2232 
2233     auto engine = reinterpret_cast<NativeEngine*>(env);
2234     auto resultValue = engine->CreateBigInt(value);
2235 
2236     *result = reinterpret_cast<napi_value>(resultValue);
2237     return napi_clear_last_error(env);
2238 }
2239 
napi_create_bigint_uint64(napi_env env,uint64_t value,napi_value * result)2240 NAPI_EXTERN napi_status napi_create_bigint_uint64(napi_env env, uint64_t value, napi_value* result)
2241 {
2242     CHECK_ENV(env);
2243     CHECK_ARG(env, result);
2244 
2245     auto engine = reinterpret_cast<NativeEngine*>(env);
2246     auto resultValue = engine->CreateBigInt(value);
2247 
2248     *result = reinterpret_cast<napi_value>(resultValue);
2249     return napi_clear_last_error(env);
2250 }
2251 
napi_get_value_bigint_int64(napi_env env,napi_value value,int64_t * result,bool * lossless)2252 NAPI_EXTERN napi_status napi_get_value_bigint_int64(
2253     napi_env env, napi_value value, int64_t* result, bool* lossless)
2254 {
2255     CHECK_ENV(env);
2256     CHECK_ARG(env, value);
2257     CHECK_ARG(env, result);
2258     CHECK_ARG(env, lossless);
2259 
2260     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2261     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_BIGINT, napi_bigint_expected);
2262 
2263     auto nativeBigint = reinterpret_cast<NativeBigint*>(nativeValue->GetInterface(NativeBigint::INTERFACE_ID));
2264     nativeBigint->Int64Value(result, lossless);
2265     return napi_clear_last_error(env);
2266 }
2267 
napi_get_value_bigint_uint64(napi_env env,napi_value value,uint64_t * result,bool * lossless)2268 NAPI_EXTERN napi_status napi_get_value_bigint_uint64(
2269     napi_env env, napi_value value, uint64_t* result, bool* lossless)
2270 {
2271     CHECK_ENV(env);
2272     CHECK_ARG(env, value);
2273     CHECK_ARG(env, result);
2274     CHECK_ARG(env, lossless);
2275 
2276     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2277     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_BIGINT, napi_bigint_expected);
2278     auto nativeBigint = reinterpret_cast<NativeBigint*>(nativeValue->GetInterface(NativeBigint::INTERFACE_ID));
2279     nativeBigint->Uint64Value(result, lossless);
2280     return napi_clear_last_error(env);
2281 }
2282 
napi_is_date(napi_env env,napi_value value,bool * result)2283 NAPI_EXTERN napi_status napi_is_date(napi_env env, napi_value value, bool* result)
2284 {
2285     CHECK_ENV(env);
2286     CHECK_ARG(env, value);
2287     CHECK_ARG(env, result);
2288 
2289     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2290 
2291     *result = nativeValue->IsDate();
2292     return napi_clear_last_error(env);
2293 }
2294 
napi_is_detached_arraybuffer(napi_env env,napi_value arraybuffer,bool * result)2295 NAPI_EXTERN napi_status napi_is_detached_arraybuffer(napi_env env, napi_value arraybuffer, bool* result)
2296 {
2297     CHECK_ENV(env);
2298     CHECK_ARG(env, arraybuffer);
2299     CHECK_ARG(env, result);
2300 
2301     auto nativeValue = reinterpret_cast<NativeValue*>(arraybuffer);
2302     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_OBJECT, napi_object_expected);
2303     auto ArrayBuffer_result = nativeValue->IsArrayBuffer();
2304     if (ArrayBuffer_result) {
2305         auto nativeArrayBuffer =
2306             reinterpret_cast<NativeArrayBuffer*>(nativeValue->GetInterface(NativeArrayBuffer::INTERFACE_ID));
2307         *result = nativeArrayBuffer->IsDetachedArrayBuffer();
2308     } else {
2309         return napi_set_last_error(env, napi_invalid_arg);
2310     }
2311     return napi_clear_last_error(env);
2312 }
2313 
napi_get_all_property_names(napi_env env,napi_value object,napi_key_collection_mode key_mode,napi_key_filter key_filter,napi_key_conversion key_conversion,napi_value * result)2314 NAPI_EXTERN napi_status napi_get_all_property_names(
2315     napi_env env, napi_value object, napi_key_collection_mode key_mode,
2316     napi_key_filter key_filter, napi_key_conversion key_conversion, napi_value* result)
2317 {
2318     CHECK_ENV(env);
2319     CHECK_ARG(env, object);
2320     CHECK_ARG(env, result);
2321 
2322     auto nativeValue = reinterpret_cast<NativeValue*>(object);
2323 
2324     NativeValueType type = nativeValue->TypeOf();
2325     RETURN_STATUS_IF_FALSE(env, type == NATIVE_OBJECT || type == NATIVE_FUNCTION,
2326         napi_object_expected);
2327 
2328     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
2329 
2330     auto resultValue = nativeObject->GetAllPropertyNames(key_mode, key_filter, key_conversion);
2331     *result = reinterpret_cast<napi_value>(resultValue);
2332     return napi_clear_last_error(env);
2333 }
2334 
napi_detach_arraybuffer(napi_env env,napi_value arraybuffer)2335 NAPI_EXTERN napi_status napi_detach_arraybuffer(napi_env env, napi_value arraybuffer)
2336 {
2337     CHECK_ENV(env);
2338     CHECK_ARG(env, arraybuffer);
2339 
2340     auto nativeValue = reinterpret_cast<NativeValue*>(arraybuffer);
2341     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_OBJECT, napi_object_expected);
2342 
2343     auto ArrayBuffer_result = nativeValue->IsArrayBuffer();
2344     if (ArrayBuffer_result) {
2345         auto nativeArrayBuffer =
2346             reinterpret_cast<NativeArrayBuffer*>(nativeValue->GetInterface(NativeArrayBuffer::INTERFACE_ID));
2347 
2348         auto ret = nativeArrayBuffer->DetachArrayBuffer();
2349         if (!ret) {
2350             return napi_set_last_error(env, napi_detachable_arraybuffer_expected);
2351         }
2352     } else {
2353         return napi_set_last_error(env, napi_invalid_arg);
2354     }
2355     return napi_clear_last_error(env);
2356 }
2357 
napi_type_tag_object(napi_env env,napi_value js_object,const napi_type_tag * type_tag)2358 NAPI_EXTERN napi_status napi_type_tag_object(napi_env env, napi_value js_object, const napi_type_tag* type_tag)
2359 {
2360     CHECK_ENV(env);
2361     CHECK_ARG(env, js_object);
2362     CHECK_ARG(env, type_tag);
2363     bool result = true;
2364 
2365     auto nativeValue = reinterpret_cast<NativeValue*>(js_object);
2366 
2367     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_OBJECT, napi_object_expected);
2368 
2369     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
2370 
2371     result = nativeObject->AssociateTypeTag((NapiTypeTag*)type_tag);
2372 
2373     if (!result) {
2374         return napi_set_last_error(env, napi_invalid_arg);
2375     }
2376 
2377     return napi_clear_last_error(env);
2378 }
2379 
napi_check_object_type_tag(napi_env env,napi_value js_object,const napi_type_tag * type_tag,bool * result)2380 NAPI_EXTERN napi_status napi_check_object_type_tag(
2381     napi_env env, napi_value js_object, const napi_type_tag* type_tag, bool* result)
2382 {
2383     CHECK_ENV(env);
2384     CHECK_ARG(env, js_object);
2385     CHECK_ARG(env, type_tag);
2386     CHECK_ARG(env, result);
2387 
2388     auto nativeValue = reinterpret_cast<NativeValue*>(js_object);
2389 
2390     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_OBJECT, napi_object_expected);
2391 
2392     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
2393     *result = nativeObject->CheckTypeTag((NapiTypeTag*)type_tag);
2394     return napi_clear_last_error(env);
2395 }
2396 
napi_create_date(napi_env env,double time,napi_value * result)2397 NAPI_EXTERN napi_status napi_create_date(napi_env env, double time, napi_value* result)
2398 {
2399     CHECK_ENV(env);
2400     CHECK_ARG(env, result);
2401 
2402     auto engine = reinterpret_cast<NativeEngine*>(env);
2403     auto resultValue = engine->CreateDate(time);
2404     *result = reinterpret_cast<napi_value>(resultValue);
2405     return napi_clear_last_error(env);
2406 }
2407 
napi_get_date_value(napi_env env,napi_value value,double * result)2408 NAPI_EXTERN napi_status napi_get_date_value(napi_env env, napi_value value, double* result)
2409 {
2410     CHECK_ENV(env);
2411     CHECK_ARG(env, value);
2412     CHECK_ARG(env, result);
2413 
2414     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2415     auto IsDate_result = nativeValue->IsDate();
2416     if (IsDate_result) {
2417         auto nativeDate = reinterpret_cast<NativeDate*>(nativeValue->GetInterface(NativeDate::INTERFACE_ID));
2418         *result = nativeDate->GetTime();
2419     } else {
2420         return napi_set_last_error(env, napi_date_expected);
2421     }
2422 
2423     return napi_clear_last_error(env);
2424 }
2425 
napi_add_finalizer(napi_env env,napi_value js_object,void * native_object,napi_finalize finalize_cb,void * finalize_hint,napi_ref * result)2426 NAPI_INNER_EXTERN napi_status napi_add_finalizer(napi_env env, napi_value js_object, void* native_object,
2427     napi_finalize finalize_cb, void* finalize_hint, napi_ref* result)
2428 {
2429     CHECK_ENV(env);
2430     CHECK_ARG(env, js_object);
2431     CHECK_ARG(env, finalize_cb);
2432 
2433     auto nativeValue = reinterpret_cast<NativeValue*>(js_object);
2434     auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
2435     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_OBJECT, napi_object_expected);
2436     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
2437     nativeObject->AddFinalizer(native_object, callback, finalize_hint);
2438     if (result != nullptr) {
2439         auto engine = reinterpret_cast<NativeEngine*>(env);
2440         auto reference = engine->CreateReference(nativeValue, 1, callback, native_object, finalize_hint);
2441         *result = reinterpret_cast<napi_ref>(reference);
2442     }
2443     return napi_clear_last_error(env);
2444 }
2445 
napi_create_bigint_words(napi_env env,int sign_bit,size_t word_count,const uint64_t * words,napi_value * result)2446 NAPI_EXTERN napi_status napi_create_bigint_words(
2447     napi_env env, int sign_bit, size_t word_count, const uint64_t* words, napi_value* result)
2448 {
2449     CHECK_ENV(env);
2450     CHECK_ARG(env, words);
2451     CHECK_ARG(env, result);
2452     auto engine = reinterpret_cast<NativeEngine*>(env);
2453     RETURN_STATUS_IF_FALSE(env, word_count <= INT_MAX, napi_invalid_arg);
2454     auto resultValue = engine->CreateBigWords(sign_bit, word_count, words);
2455     if (engine->HasPendingException()) {
2456         return napi_set_last_error(env, napi_pending_exception);
2457     }
2458     *result = reinterpret_cast<napi_value>(resultValue);
2459     return napi_clear_last_error(env);
2460 }
2461 
napi_get_value_bigint_words(napi_env env,napi_value value,int * sign_bit,size_t * word_count,uint64_t * words)2462 NAPI_EXTERN napi_status napi_get_value_bigint_words(
2463     napi_env env, napi_value value, int* sign_bit, size_t* word_count, uint64_t* words)
2464 {
2465     CHECK_ENV(env);
2466     CHECK_ARG(env, value);
2467     CHECK_ARG(env, word_count);
2468 
2469     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2470 
2471     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_BIGINT, napi_object_expected);
2472 
2473     auto nativeBigint = reinterpret_cast<NativeBigint*>(nativeValue->GetInterface(NativeBigint::INTERFACE_ID));
2474 
2475     auto resultValue = nativeBigint->GetWordsArray(sign_bit, word_count, words);
2476 
2477     if (resultValue == false) {
2478         return napi_set_last_error(env, napi_invalid_arg);
2479     }
2480 
2481     return napi_clear_last_error(env);
2482 }
2483 
napi_run_script_path(napi_env env,const char * path,napi_value * result)2484 NAPI_EXTERN napi_status napi_run_script_path(napi_env env, const char* path, napi_value* result)
2485 {
2486     CHECK_ENV(env);
2487     CHECK_ARG(env, result);
2488     auto engine = reinterpret_cast<NativeEngine*>(env);
2489     NativeValue* resultValue = nullptr;
2490     resultValue = engine->RunScript(path);
2491     *result = reinterpret_cast<napi_value>(resultValue);
2492     return napi_clear_last_error(env);
2493 }
2494 
napi_is_big_int64_array(napi_env env,napi_value value,bool * result)2495 NAPI_EXTERN napi_status napi_is_big_int64_array(napi_env env, napi_value value, bool* result)
2496 {
2497     CHECK_ENV(env);
2498     CHECK_ARG(env, value);
2499     CHECK_ARG(env, result);
2500 
2501     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2502 
2503     *result = nativeValue->IsBigInt64Array();
2504     return napi_clear_last_error(env);
2505 }
2506 
napi_is_big_uint64_array(napi_env env,napi_value value,bool * result)2507 NAPI_EXTERN napi_status napi_is_big_uint64_array(napi_env env, napi_value value, bool* result)
2508 {
2509     CHECK_ENV(env);
2510     CHECK_ARG(env, value);
2511     CHECK_ARG(env, result);
2512 
2513     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2514 
2515     *result = nativeValue->IsBigUint64Array();
2516     return napi_clear_last_error(env);
2517 }
2518 
napi_is_shared_array_buffer(napi_env env,napi_value value,bool * result)2519 NAPI_EXTERN napi_status napi_is_shared_array_buffer(napi_env env, napi_value value, bool* result)
2520 {
2521     CHECK_ENV(env);
2522     CHECK_ARG(env, value);
2523     CHECK_ARG(env, result);
2524 
2525     auto nativeValue = reinterpret_cast<NativeValue*>(value);
2526 
2527     *result = nativeValue->IsSharedArrayBuffer();
2528     return napi_clear_last_error(env);
2529 }
2530 
napi_get_stack_trace(napi_env env,std::string & stack)2531 NAPI_EXTERN napi_status napi_get_stack_trace(napi_env env, std::string& stack)
2532 {
2533     CHECK_ENV(env);
2534 
2535     auto engine = reinterpret_cast<NativeEngine*>(env);
2536     std::string rawStack;
2537     bool getStackSuccess = engine->BuildJsStackTrace(rawStack);
2538     if (!getStackSuccess) {
2539         HILOG_ERROR("GetStacktrace env get stack failed");
2540     }
2541     stack = engine->ExecuteTranslateBySourceMap(rawStack);
2542     return napi_clear_last_error(env);
2543 }
2544 
napi_object_get_keys(napi_env env,napi_value data,napi_value * result)2545 NAPI_EXTERN napi_status napi_object_get_keys(napi_env env, napi_value data, napi_value* result)
2546 {
2547     CHECK_ENV(env);
2548 
2549     auto nativeValue = reinterpret_cast<NativeValue*>(data);
2550 
2551     RETURN_STATUS_IF_FALSE(env, nativeValue->TypeOf() == NATIVE_OBJECT, napi_object_expected);
2552 
2553     auto nativeObject = reinterpret_cast<NativeObject*>(nativeValue->GetInterface(NativeObject::INTERFACE_ID));
2554 
2555     auto resultValue = nativeObject->GetEnumerablePropertyNames();
2556 
2557     *result = reinterpret_cast<napi_value>(resultValue);
2558     return napi_clear_last_error(env);
2559 }
2560 
napi_queue_async_work_with_qos(napi_env env,napi_async_work work,napi_qos_t qos)2561 NAPI_EXTERN napi_status napi_queue_async_work_with_qos(napi_env env, napi_async_work work, napi_qos_t qos)
2562 {
2563     CHECK_ENV(env);
2564     CHECK_ARG(env, work);
2565 
2566     auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work);
2567 
2568     asyncWork->QueueWithQos(qos);
2569     return napi_status::napi_ok;
2570 }