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 #ifdef ENABLE_HITRACE
20 #include <sys/prctl.h>
21 #endif
22
23 #include "ecmascript/napi/include/jsnapi.h"
24 #include "native_api_internal.h"
25 #include "native_engine/impl/ark/ark_native_engine.h"
26 #include "native_engine/impl/ark/ark_native_reference.h"
27 #include "native_engine/native_property.h"
28 #include "native_engine/native_utils.h"
29 #include "native_engine/native_value.h"
30 #include "securec.h"
31 #include "utils/log.h"
32 #ifdef ENABLE_HITRACE
33 #include "hitrace_meter.h"
34 #endif
35
36 using panda::ArrayRef;
37 using panda::ArrayBufferRef;
38 using panda::BigIntRef;
39 using panda::BooleanRef;
40 using panda::BufferRef;
41 using panda::DateRef;
42 using panda::DataViewRef;
43 using panda::EscapeLocalScope;
44 using panda::FunctionRef;
45 using panda::Global;
46 using panda::IntegerRef;
47 using panda::JSNApi;
48 using panda::JsiRuntimeCallInfo;
49 using panda::Local;
50 using panda::LocalScope;
51 using panda::NativePointerRef;
52 using panda::NumberRef;
53 using panda::ObjectRef;
54 using panda::PrimitiveRef;
55 using panda::PromiseCapabilityRef;
56 using panda::PromiseRef;
57 using panda::PropertyAttribute;
58 using panda::StringRef;
59 using panda::SymbolRef;
60 using panda::TypedArrayRef;
61 using panda::ecmascript::EcmaVM;
62
63 static constexpr size_t MAX_BYTE_LENGTH = 2097152;
64 static constexpr size_t ONEMIB_BYTE_SIZE = 1048576;
65 static constexpr auto PANDA_MAIN_FUNCTION = "_GLOBAL::func_main_0";
66
67 class HandleScopeWrapper {
68 public:
HandleScopeWrapper(NativeEngine * engine)69 explicit HandleScopeWrapper(NativeEngine* engine) : scope_(engine->GetEcmaVm()) {}
70
71 private:
72 LocalScope scope_;
73 };
74
75 class EscapableHandleScopeWrapper {
76 public:
EscapableHandleScopeWrapper(NativeEngine * engine)77 explicit EscapableHandleScopeWrapper(NativeEngine* engine)
78 : scope_(engine->GetEcmaVm()), escapeCalled_(false) {}
79
IsEscapeCalled() const80 bool IsEscapeCalled() const
81 {
82 return escapeCalled_;
83 }
84
85 template<typename T>
Escape(Local<T> value)86 Local<T> Escape(Local<T> value)
87 {
88 escapeCalled_ = true;
89 return scope_.Escape(value);
90 }
91
92 private:
93 EscapeLocalScope scope_;
94 bool escapeCalled_;
95 };
96
HandleScopeToNapiHandleScope(HandleScopeWrapper * s)97 inline napi_handle_scope HandleScopeToNapiHandleScope(HandleScopeWrapper* s)
98 {
99 return reinterpret_cast<napi_handle_scope>(s);
100 }
101
NapiHandleScopeToHandleScope(napi_handle_scope s)102 inline HandleScopeWrapper* NapiHandleScopeToHandleScope(napi_handle_scope s)
103 {
104 return reinterpret_cast<HandleScopeWrapper*>(s);
105 }
106
EscapableHandleScopeToNapiEscapableHandleScope(EscapableHandleScopeWrapper * s)107 inline napi_escapable_handle_scope EscapableHandleScopeToNapiEscapableHandleScope(EscapableHandleScopeWrapper* s)
108 {
109 return reinterpret_cast<napi_escapable_handle_scope>(s);
110 }
111
NapiEscapableHandleScopeToEscapableHandleScope(napi_escapable_handle_scope s)112 inline EscapableHandleScopeWrapper* NapiEscapableHandleScopeToEscapableHandleScope(napi_escapable_handle_scope s)
113 {
114 return reinterpret_cast<EscapableHandleScopeWrapper*>(s);
115 }
116
napi_get_last_error_info(napi_env env,const napi_extended_error_info ** result)117 NAPI_EXTERN napi_status napi_get_last_error_info(napi_env env, const napi_extended_error_info** result)
118 {
119 CHECK_ENV(env);
120 CHECK_ARG(env, result);
121
122 *result = reinterpret_cast<napi_extended_error_info*>(reinterpret_cast<NativeEngine*>(env)->GetLastError());
123 if ((*result)->error_code == napi_ok) {
124 napi_clear_last_error(env);
125 }
126
127 return napi_ok;
128 }
129
130 // Getters for defined singletons
napi_get_undefined(napi_env env,napi_value * result)131 NAPI_EXTERN napi_status napi_get_undefined(napi_env env, napi_value* result)
132 {
133 CHECK_ENV(env);
134 CHECK_ARG(env, result);
135
136 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
137 Local<panda::PrimitiveRef> value = panda::JSValueRef::Undefined(vm);
138 *result = JsValueFromLocalValue(value);
139
140 return napi_clear_last_error(env);
141 }
142
napi_get_null(napi_env env,napi_value * result)143 NAPI_EXTERN napi_status napi_get_null(napi_env env, napi_value* result)
144 {
145 CHECK_ENV(env);
146 CHECK_ARG(env, result);
147
148 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
149 Local<panda::PrimitiveRef> value = panda::JSValueRef::Null(vm);
150 *result = JsValueFromLocalValue(value);
151
152 return napi_clear_last_error(env);
153 }
154
napi_get_global(napi_env env,napi_value * result)155 NAPI_EXTERN napi_status napi_get_global(napi_env env, napi_value* result)
156 {
157 CHECK_ENV(env);
158 CHECK_ARG(env, result);
159
160 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
161 Local<panda::ObjectRef> value = panda::JSNApi::GetGlobalObject(vm);
162 *result = JsValueFromLocalValue(value);
163
164 return napi_clear_last_error(env);
165 }
166
napi_get_boolean(napi_env env,bool value,napi_value * result)167 NAPI_EXTERN napi_status napi_get_boolean(napi_env env, bool value, napi_value* result)
168 {
169 CHECK_ENV(env);
170 CHECK_ARG(env, result);
171
172 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
173 if (value) {
174 *result = JsValueFromLocalValue(panda::JSValueRef::True(vm));
175 } else {
176 *result = JsValueFromLocalValue(panda::JSValueRef::False(vm));
177 }
178
179 return napi_clear_last_error(env);
180 }
181
182 // Methods to create Primitive types/Objects
napi_create_object(napi_env env,napi_value * result)183 NAPI_EXTERN napi_status napi_create_object(napi_env env, napi_value* result)
184 {
185 CHECK_ENV(env);
186 CHECK_ARG(env, result);
187
188 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
189 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
190 *result = JsValueFromLocalValue(object);
191
192 return napi_clear_last_error(env);
193 }
194
195 // Create JSObject with initial properties given by descriptors, note that property key must be String, and
196 // must can not convert to element_index, also all keys must not duplicate.
napi_create_object_with_properties(napi_env env,napi_value * result,size_t property_count,const napi_property_descriptor * properties)197 NAPI_EXTERN napi_status napi_create_object_with_properties(napi_env env, napi_value* result, size_t property_count,
198 const napi_property_descriptor* properties)
199 {
200 CHECK_ENV(env);
201 CHECK_ARG(env, result);
202
203 Local<panda::ObjectRef> object;
204 if (property_count <= panda::ObjectRef::MAX_PROPERTIES_ON_STACK) {
205 char attrs[sizeof(PropertyAttribute) * panda::ObjectRef::MAX_PROPERTIES_ON_STACK];
206 char keys[sizeof(Local<panda::JSValueRef>) * panda::ObjectRef::MAX_PROPERTIES_ON_STACK];
207 object = NapiCreateObjectWithProperties(env, property_count, properties,
208 reinterpret_cast<Local<panda::JSValueRef> *>(keys),
209 reinterpret_cast<PropertyAttribute *>(attrs));
210 } else {
211 void *attrs = malloc(sizeof(PropertyAttribute) * property_count);
212 void *keys = malloc(sizeof(Local<panda::JSValueRef>) * property_count);
213 if (attrs != nullptr && keys != nullptr) {
214 object = NapiCreateObjectWithProperties(env, property_count, properties,
215 reinterpret_cast<Local<panda::JSValueRef> *>(keys),
216 reinterpret_cast<PropertyAttribute *>(attrs));
217 } else {
218 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
219 object = panda::JSValueRef::Undefined(vm);
220 napi_throw_error(env, nullptr, "malloc failed in napi_create_object_with_properties");
221 }
222 if (attrs != nullptr) {
223 free(attrs);
224 }
225 if (keys != nullptr) {
226 free(keys);
227 }
228 }
229 *result = JsValueFromLocalValue(object);
230
231 return napi_clear_last_error(env);
232 }
233
234 // Create JSObject with initial properties given by keys and values, note that property key must be String, and
235 // must can not convert to element_index, also all keys must not duplicate.
napi_create_object_with_named_properties(napi_env env,napi_value * result,size_t property_count,const char ** keys,const napi_value * values)236 NAPI_EXTERN napi_status napi_create_object_with_named_properties(napi_env env, napi_value* result,
237 size_t property_count, const char** keys,
238 const napi_value* values)
239 {
240 CHECK_ENV(env);
241 CHECK_ARG(env, result);
242
243 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
244 Local<panda::ObjectRef> object = panda::ObjectRef::NewWithNamedProperties(vm, property_count, keys,
245 reinterpret_cast<const Local<JSValueRef> *>(values));
246 *result = JsValueFromLocalValue(object);
247
248 return napi_clear_last_error(env);
249 }
250
napi_create_array(napi_env env,napi_value * result)251 NAPI_EXTERN napi_status napi_create_array(napi_env env, napi_value* result)
252 {
253 CHECK_ENV(env);
254 CHECK_ARG(env, result);
255
256 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
257 Local<panda::ArrayRef> object = panda::ArrayRef::New(vm, 0);
258 *result = JsValueFromLocalValue(object);
259
260 return napi_clear_last_error(env);
261 }
262
napi_create_array_with_length(napi_env env,size_t length,napi_value * result)263 NAPI_EXTERN napi_status napi_create_array_with_length(napi_env env, size_t length, napi_value* result)
264 {
265 CHECK_ENV(env);
266 CHECK_ARG(env, result);
267
268 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
269 Local<panda::ArrayRef> object = panda::ArrayRef::New(vm, length);
270 *result = JsValueFromLocalValue(object);
271
272 return napi_clear_last_error(env);
273 }
274
napi_create_double(napi_env env,double value,napi_value * result)275 NAPI_EXTERN napi_status napi_create_double(napi_env env, double value, napi_value* result)
276 {
277 CHECK_ENV(env);
278 CHECK_ARG(env, result);
279
280 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
281 Local<panda::NumberRef> object = panda::NumberRef::New(vm, value);
282 *result = JsValueFromLocalValue(object);
283
284 return napi_clear_last_error(env);
285 }
286
napi_create_int32(napi_env env,int32_t value,napi_value * result)287 NAPI_EXTERN napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)
288 {
289 CHECK_ENV(env);
290 CHECK_ARG(env, result);
291
292 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
293 Local<panda::NumberRef> object = panda::NumberRef::New(vm, value);
294 *result = JsValueFromLocalValue(object);
295
296 return napi_clear_last_error(env);
297 }
298
napi_create_uint32(napi_env env,uint32_t value,napi_value * result)299 NAPI_EXTERN napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)
300 {
301 CHECK_ENV(env);
302 CHECK_ARG(env, result);
303
304 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
305 Local<panda::NumberRef> object = panda::NumberRef::New(vm, value);
306 *result = JsValueFromLocalValue(object);
307
308 return napi_clear_last_error(env);
309 }
310
napi_create_int64(napi_env env,int64_t value,napi_value * result)311 NAPI_EXTERN napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)
312 {
313 CHECK_ENV(env);
314 CHECK_ARG(env, result);
315
316 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
317 Local<panda::NumberRef> object = panda::NumberRef::New(vm, value);
318 *result = JsValueFromLocalValue(object);
319
320 return napi_clear_last_error(env);
321 }
322
napi_create_string_latin1(napi_env env,const char * str,size_t length,napi_value * result)323 NAPI_EXTERN napi_status napi_create_string_latin1(napi_env env, const char* str, size_t length, napi_value* result)
324 {
325 CHECK_ENV(env);
326 CHECK_ARG(env, str);
327 CHECK_ARG(env, result);
328
329 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
330 Local<panda::StringRef> object = panda::StringRef::NewFromUtf8(
331 vm, str, (length == NAPI_AUTO_LENGTH) ? strlen(str) : length);
332 *result = JsValueFromLocalValue(object);
333
334 return napi_clear_last_error(env);
335 }
336
napi_create_string_utf8(napi_env env,const char * str,size_t length,napi_value * result)337 NAPI_EXTERN napi_status napi_create_string_utf8(napi_env env, const char* str, size_t length, napi_value* result)
338 {
339 CHECK_ENV(env);
340 CHECK_ARG(env, str);
341 CHECK_ARG(env, result);
342
343 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
344 Local<panda::StringRef> object = panda::StringRef::NewFromUtf8(
345 vm, str, (length == NAPI_AUTO_LENGTH) ? strlen(str) : length);
346 *result = JsValueFromLocalValue(object);
347
348 return napi_clear_last_error(env);
349 }
350
napi_create_string_utf16(napi_env env,const char16_t * str,size_t length,napi_value * result)351 NAPI_EXTERN napi_status napi_create_string_utf16(
352 napi_env env, const char16_t* str, size_t length, napi_value* result)
353 {
354 CHECK_ENV(env);
355 CHECK_ARG(env, str);
356 CHECK_ARG(env, result);
357 RETURN_STATUS_IF_FALSE(env, (length == NAPI_AUTO_LENGTH) || (length <= INT_MAX && length >= 0), napi_invalid_arg);
358
359 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
360 int char16Length = static_cast<int>(std::char_traits<char16_t>::length(str));
361 Local<panda::StringRef> object = panda::StringRef::NewFromUtf16(
362 vm, str, (length == NAPI_AUTO_LENGTH) ? char16Length : length);
363 *result = JsValueFromLocalValue(object);
364
365 return napi_clear_last_error(env);
366 }
367
napi_create_symbol(napi_env env,napi_value description,napi_value * result)368 NAPI_EXTERN napi_status napi_create_symbol(napi_env env, napi_value description, napi_value* result)
369 {
370 CHECK_ENV(env);
371 CHECK_ARG(env, result);
372
373 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
374 panda::Local<panda::JSValueRef> object = panda::JSValueRef::Undefined(vm);
375 if (description == nullptr) {
376 const char* str = "";
377 object = panda::StringRef::NewFromUtf8(vm, str, 0);
378 } else {
379 object = LocalValueFromJsValue(description);
380 }
381 RETURN_STATUS_IF_FALSE(env, object->IsString(), napi_invalid_arg);
382 Local<panda::SymbolRef> symbol = panda::SymbolRef::New(vm, object);
383 *result = JsValueFromLocalValue(symbol);
384
385 return napi_clear_last_error(env);
386 }
387
napi_create_function(napi_env env,const char * utf8name,size_t length,napi_callback cb,void * data,napi_value * result)388 NAPI_EXTERN napi_status napi_create_function(napi_env env,
389 const char* utf8name,
390 size_t length,
391 napi_callback cb,
392 void* data,
393 napi_value* result)
394 {
395 NAPI_PREAMBLE(env);
396 CHECK_ARG(env, cb);
397 CHECK_ARG(env, result);
398
399 auto vm = const_cast<EcmaVM*>(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm());
400 EscapeLocalScope scope(vm);
401 auto callback = reinterpret_cast<NapiNativeCallback>(cb);
402 const char* name = "defaultName";
403 NapiFunctionInfo* funcInfo = NapiFunctionInfo::CreateNewInstance();
404 if (funcInfo == nullptr) {
405 HILOG_ERROR("funcInfo is nullptr");
406 return napi_set_last_error(env, napi_invalid_arg);
407 }
408 funcInfo->env = env;
409 funcInfo->callback = callback;
410 funcInfo->data = data;
411
412 Local<panda::FunctionRef> fn = panda::FunctionRef::New(vm, ArkNativeFunctionCallBack,
413 [](void* externalPointer, void* data) {
414 auto info = reinterpret_cast<NapiFunctionInfo*>(data);
415 if (info != nullptr) {
416 delete info;
417 }
418 },
419 reinterpret_cast<void*>(funcInfo), true);
420 Local<panda::StringRef> fnName = panda::StringRef::NewFromUtf8(vm, utf8name != nullptr ? utf8name : name);
421 fn->SetName(vm, fnName);
422 *result = JsValueFromLocalValue(scope.Escape(fn));
423 return GET_RETURN_STATUS(env);
424 }
425
napi_create_error(napi_env env,napi_value code,napi_value msg,napi_value * result)426 NAPI_EXTERN napi_status napi_create_error(napi_env env, napi_value code, napi_value msg, napi_value* result)
427 {
428 CHECK_ENV(env);
429 CHECK_ARG(env, msg);
430 CHECK_ARG(env, result);
431
432 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
433 Local<panda::JSValueRef> codeValue = panda::JSValueRef::Undefined(vm);
434 if (code != nullptr) {
435 codeValue = LocalValueFromJsValue(code);
436 RETURN_STATUS_IF_FALSE(env, codeValue->IsString() || codeValue->IsNumber(), napi_invalid_arg);
437 }
438
439 auto msgValue = LocalValueFromJsValue(msg);
440 RETURN_STATUS_IF_FALSE(env, msgValue->IsString(), napi_invalid_arg);
441
442 Local<panda::JSValueRef> errorVal = panda::Exception::Error(vm, msgValue);
443 if (code != nullptr) {
444 Local<panda::StringRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
445 Local<panda::ObjectRef> errorObj(errorVal);
446 errorObj->Set(vm, codeKey, codeValue);
447 }
448 *result = JsValueFromLocalValue(errorVal);
449
450 return napi_clear_last_error(env);
451 }
452
napi_create_type_error(napi_env env,napi_value code,napi_value msg,napi_value * result)453 NAPI_EXTERN napi_status napi_create_type_error(napi_env env, napi_value code, napi_value msg, napi_value* result)
454 {
455 CHECK_ENV(env);
456 CHECK_ARG(env, msg);
457 CHECK_ARG(env, result);
458
459 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
460 Local<panda::JSValueRef> codeValue = panda::JSValueRef::Undefined(vm);
461 if (code != nullptr) {
462 codeValue = LocalValueFromJsValue(code);
463 RETURN_STATUS_IF_FALSE(env, codeValue->IsString() || codeValue->IsNumber(), napi_invalid_arg);
464 }
465 auto msgValue = LocalValueFromJsValue(msg);
466 RETURN_STATUS_IF_FALSE(env, msgValue->IsString(), napi_invalid_arg);
467
468 Local<panda::JSValueRef> errorVal = panda::Exception::Error(vm, msgValue);
469 if (code != nullptr) {
470 Local<panda::StringRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
471 Local<panda::ObjectRef> errorObj(errorVal);
472 errorObj->Set(vm, codeKey, codeValue);
473 }
474 *result = JsValueFromLocalValue(errorVal);
475
476 return napi_clear_last_error(env);
477 }
478
napi_create_range_error(napi_env env,napi_value code,napi_value msg,napi_value * result)479 NAPI_EXTERN napi_status napi_create_range_error(napi_env env, napi_value code, napi_value msg, napi_value* result)
480 {
481 CHECK_ENV(env);
482 CHECK_ARG(env, msg);
483 CHECK_ARG(env, result);
484
485 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
486 Local<panda::JSValueRef> codeValue = panda::JSValueRef::Undefined(vm);
487
488 if (code != nullptr) {
489 codeValue = LocalValueFromJsValue(code);
490 RETURN_STATUS_IF_FALSE(env, codeValue->IsString() || codeValue->IsNumber(), napi_invalid_arg);
491 }
492 auto msgValue = LocalValueFromJsValue(msg);
493 RETURN_STATUS_IF_FALSE(env, msgValue->IsString(), napi_invalid_arg);
494
495 Local<panda::JSValueRef> errorVal = panda::Exception::Error(vm, msgValue);
496 if (code != nullptr) {
497 Local<panda::StringRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
498 Local<panda::ObjectRef> errorObj(errorVal);
499 errorObj->Set(vm, codeKey, codeValue);
500 }
501 *result = JsValueFromLocalValue(errorVal);
502
503 return napi_clear_last_error(env);
504 }
505
506 // Methods to get the native napi_value from Primitive type
napi_typeof(napi_env env,napi_value value,napi_valuetype * result)507 NAPI_EXTERN napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result)
508 {
509 CHECK_ENV(env);
510 CHECK_ARG(env, value);
511 CHECK_ARG(env, result);
512
513 auto valueObj = LocalValueFromJsValue(value);
514 napi_valuetype resultType;
515 if (valueObj->IsNumber()) {
516 resultType = napi_number;
517 } else if (valueObj->IsString()) {
518 resultType = napi_string;
519 } else if (valueObj->IsFunction()) {
520 resultType = napi_function;
521 } else if (valueObj->IsNativePointer()) {
522 resultType = napi_external;
523 } else if (valueObj->IsNull()) {
524 resultType = napi_null;
525 } else if (valueObj->IsBoolean()) {
526 resultType = napi_boolean;
527 } else if (valueObj->IsUndefined()) {
528 resultType = napi_undefined;
529 } else if (valueObj->IsSymbol()) {
530 resultType = napi_symbol;
531 } else if (valueObj->IsBigInt()) {
532 resultType = napi_bigint;
533 } else if (valueObj->IsObject()) {
534 resultType = napi_object;
535 } else {
536 resultType = napi_undefined;
537 }
538 *result = resultType;
539 return napi_clear_last_error(env);
540 }
541
napi_get_value_double(napi_env env,napi_value value,double * result)542 NAPI_EXTERN napi_status napi_get_value_double(napi_env env, napi_value value, double* result)
543 {
544 CHECK_ENV(env);
545 CHECK_ARG(env, value);
546 CHECK_ARG(env, result);
547
548 auto nativeValue = LocalValueFromJsValue(value);
549 RETURN_STATUS_IF_FALSE(env, nativeValue->IsNumber(), napi_number_expected);
550 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
551 Local<panda::NumberRef> NumberVal = nativeValue->ToNumber(vm);
552 *result = NumberVal->Value();
553 return napi_clear_last_error(env);
554 }
555
napi_get_value_int32(napi_env env,napi_value value,int32_t * result)556 NAPI_EXTERN napi_status napi_get_value_int32(napi_env env, napi_value value, int32_t* result)
557 {
558 CHECK_ENV(env);
559 CHECK_ARG(env, value);
560 CHECK_ARG(env, result);
561
562 auto nativeValue = LocalValueFromJsValue(value);
563 RETURN_STATUS_IF_FALSE(env, nativeValue->IsNumber(), napi_number_expected);
564 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
565 *result = nativeValue->Int32Value(vm);
566
567 return napi_clear_last_error(env);
568 }
569
napi_get_value_uint32(napi_env env,napi_value value,uint32_t * result)570 NAPI_EXTERN napi_status napi_get_value_uint32(napi_env env, napi_value value, uint32_t* result)
571 {
572 CHECK_ENV(env);
573 CHECK_ARG(env, value);
574 CHECK_ARG(env, result);
575
576 auto nativeValue = LocalValueFromJsValue(value);
577 RETURN_STATUS_IF_FALSE(env, nativeValue->IsNumber(), napi_number_expected);
578 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
579 *result = nativeValue->Uint32Value(vm);
580 return napi_clear_last_error(env);
581 }
582
napi_get_value_int64(napi_env env,napi_value value,int64_t * result)583 NAPI_EXTERN napi_status napi_get_value_int64(napi_env env, napi_value value, int64_t* result)
584 {
585 CHECK_ENV(env);
586 CHECK_ARG(env, value);
587 CHECK_ARG(env, result);
588
589 auto nativeValue = LocalValueFromJsValue(value);
590 RETURN_STATUS_IF_FALSE(env, nativeValue->IsNumber(), napi_number_expected);
591 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
592 *result = nativeValue->IntegerValue(vm);
593 return napi_clear_last_error(env);
594 }
595
napi_get_value_bool(napi_env env,napi_value value,bool * result)596 NAPI_EXTERN napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result)
597 {
598 CHECK_ENV(env);
599 CHECK_ARG(env, value);
600 CHECK_ARG(env, result);
601
602 Local<panda::JSValueRef> val = LocalValueFromJsValue(value);
603 RETURN_STATUS_IF_FALSE(env, val->IsBoolean(), napi_boolean_expected);
604 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
605 Local<panda::BooleanRef> boolVal = val->ToBoolean(vm);
606 *result = boolVal->Value();
607 return napi_clear_last_error(env);
608 }
609
610 // 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)611 NAPI_EXTERN napi_status napi_get_value_string_latin1(napi_env env,
612 napi_value value,
613 char* buf,
614 size_t bufsize,
615 size_t* result)
616 {
617 CHECK_ENV(env);
618 CHECK_ARG(env, value);
619 CHECK_ARG(env, result);
620
621 auto nativeValue = LocalValueFromJsValue(value);
622 RETURN_STATUS_IF_FALSE(env, nativeValue->IsString(), napi_string_expected);
623 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
624 Local<panda::StringRef> stringVal = nativeValue->ToString(vm);
625 if (buf == nullptr) {
626 *result = stringVal->Length();
627 } else if (bufsize != 0) {
628 int copied = stringVal->WriteLatin1(buf, bufsize);
629 buf[copied] = '\0';
630 *result = copied;
631 } else {
632 *result = 0;
633 }
634
635 return napi_clear_last_error(env);
636 }
637
638 // 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)639 NAPI_EXTERN napi_status napi_get_value_string_utf8(napi_env env,
640 napi_value value,
641 char* buf,
642 size_t bufsize,
643 size_t* result)
644 {
645 CHECK_ENV(env);
646 CHECK_ARG(env, value);
647 CHECK_ARG(env, result);
648
649 auto nativeValue = LocalValueFromJsValue(value);
650 RETURN_STATUS_IF_FALSE(env, nativeValue->IsString(), napi_string_expected);
651 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
652 Local<panda::StringRef> stringVal = nativeValue->ToString(vm);
653 if (buf == nullptr) {
654 *result = stringVal->Utf8Length(vm) - 1;
655 } else if (bufsize != 0) {
656 int copied = stringVal->WriteUtf8(buf, bufsize - 1, true) - 1;
657 buf[copied] = '\0';
658 *result = copied;
659 } else {
660 *result = 0;
661 }
662
663 return napi_clear_last_error(env);
664 }
665
napi_get_value_string_utf16(napi_env env,napi_value value,char16_t * buf,size_t bufsize,size_t * result)666 NAPI_EXTERN napi_status napi_get_value_string_utf16(napi_env env,
667 napi_value value,
668 char16_t* buf,
669 size_t bufsize,
670 size_t* result)
671 {
672 CHECK_ENV(env);
673 CHECK_ARG(env, value);
674 CHECK_ARG(env, result);
675
676 auto nativeValue = LocalValueFromJsValue(value);
677 RETURN_STATUS_IF_FALSE(env, nativeValue->IsString(), napi_string_expected);
678 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
679 Local<panda::StringRef> stringVal = nativeValue->ToString(vm);
680 if (buf == nullptr) {
681 *result = stringVal->Length();
682 } else if (bufsize == 1) {
683 buf[0] = '\0';
684 *result = 0;
685 } else if (bufsize != 0) {
686 int copied = stringVal->WriteUtf16(buf, bufsize - 1); // bufsize - 1 : reserve the position of buf "\0"
687 buf[copied] = '\0';
688 *result = copied;
689 } else {
690 *result = 0;
691 }
692
693 return napi_clear_last_error(env);
694 }
695
696 // Methods to coerce values
697 // These APIs may execute user scripts
napi_coerce_to_bool(napi_env env,napi_value value,napi_value * result)698 NAPI_EXTERN napi_status napi_coerce_to_bool(napi_env env, napi_value value, napi_value* result)
699 {
700 NAPI_PREAMBLE(env);
701 CHECK_ARG(env, value);
702 CHECK_ARG(env, result);
703
704 Local<panda::JSValueRef> val = LocalValueFromJsValue(value);
705 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
706 Local<panda::BooleanRef> boolVal = val->ToBoolean(vm);
707 *result = JsValueFromLocalValue(boolVal);
708
709 return napi_clear_last_error(env);
710 }
711
napi_coerce_to_number(napi_env env,napi_value value,napi_value * result)712 NAPI_EXTERN napi_status napi_coerce_to_number(napi_env env, napi_value value, napi_value* result)
713 {
714 CHECK_ENV(env);
715 CHECK_ARG(env, value);
716 CHECK_ARG(env, result);
717
718 auto nativeValue = LocalValueFromJsValue(value);
719 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
720 *result = JsValueFromLocalValue(nativeValue->ToNumber(vm));
721
722 return napi_clear_last_error(env);
723 }
724
napi_coerce_to_object(napi_env env,napi_value value,napi_value * result)725 NAPI_EXTERN napi_status napi_coerce_to_object(napi_env env, napi_value value, napi_value* result)
726 {
727 CHECK_ENV(env);
728 CHECK_ARG(env, value);
729 CHECK_ARG(env, result);
730
731 auto nativeValue = LocalValueFromJsValue(value);
732 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
733 *result = JsValueFromLocalValue(nativeValue->ToObject(vm));
734
735 return napi_clear_last_error(env);
736 }
737
napi_coerce_to_string(napi_env env,napi_value value,napi_value * result)738 NAPI_EXTERN napi_status napi_coerce_to_string(napi_env env, napi_value value, napi_value* result)
739 {
740 CHECK_ENV(env);
741 CHECK_ARG(env, value);
742 CHECK_ARG(env, result);
743
744 auto nativeValue = LocalValueFromJsValue(value);
745 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
746 *result = JsValueFromLocalValue(nativeValue->ToString(vm));
747
748 return napi_clear_last_error(env);
749 }
750
751 // Methods to work with Objects
napi_get_prototype(napi_env env,napi_value object,napi_value * result)752 NAPI_EXTERN napi_status napi_get_prototype(napi_env env, napi_value object, napi_value* result)
753 {
754 NAPI_PREAMBLE(env);
755 CHECK_ARG(env, object);
756 CHECK_ARG(env, result);
757
758 auto nativeValue = LocalValueFromJsValue(object);
759 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
760 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
761 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
762 Local<panda::JSValueRef> val = obj->GetPrototype(vm);
763 *result = JsValueFromLocalValue(val);
764
765 return GET_RETURN_STATUS(env);
766 }
767
napi_get_property_names(napi_env env,napi_value object,napi_value * result)768 NAPI_EXTERN napi_status napi_get_property_names(napi_env env, napi_value object, napi_value* result)
769 {
770 CHECK_ENV(env);
771 CHECK_ARG(env, object);
772 CHECK_ARG(env, result);
773
774 auto napiVal = LocalValueFromJsValue(object);
775 RETURN_STATUS_IF_FALSE(env, napiVal->IsObject() || napiVal->IsFunction(), napi_object_expected);
776 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
777 auto obj = napiVal->ToObject(vm);
778 Local<panda::ArrayRef> arrayVal = obj->GetOwnPropertyNames(vm);
779 *result = JsValueFromLocalValue(arrayVal);
780 return napi_clear_last_error(env);
781 }
782
napi_set_property(napi_env env,napi_value object,napi_value key,napi_value value)783 NAPI_EXTERN napi_status napi_set_property(napi_env env, napi_value object, napi_value key, napi_value value)
784 {
785 NAPI_PREAMBLE(env);
786 CHECK_ARG(env, object);
787 CHECK_ARG(env, key);
788 CHECK_ARG(env, value);
789
790 auto nativeValue = LocalValueFromJsValue(object);
791 auto propKey = LocalValueFromJsValue(key);
792 auto propValue = LocalValueFromJsValue(value);
793 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
794 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
795 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
796 obj->Set(vm, propKey, propValue);
797
798 return GET_RETURN_STATUS(env);
799 }
800
napi_has_property(napi_env env,napi_value object,napi_value key,bool * result)801 NAPI_EXTERN napi_status napi_has_property(napi_env env, napi_value object, napi_value key, bool* result)
802 {
803 NAPI_PREAMBLE(env);
804 CHECK_ARG(env, object);
805 CHECK_ARG(env, key);
806 CHECK_ARG(env, result);
807
808 auto nativeValue = LocalValueFromJsValue(object);
809 auto propKey = LocalValueFromJsValue(key);
810 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
811 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
812 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
813 *result = obj->Has(vm, propKey);
814
815 return GET_RETURN_STATUS(env);
816 }
817
napi_get_property(napi_env env,napi_value object,napi_value key,napi_value * result)818 NAPI_EXTERN napi_status napi_get_property(napi_env env, napi_value object, napi_value key, napi_value* result)
819 {
820 NAPI_PREAMBLE(env);
821 CHECK_ARG(env, object);
822 CHECK_ARG(env, key);
823 CHECK_ARG(env, result);
824
825 auto nativeValue = LocalValueFromJsValue(object);
826 auto propKey = LocalValueFromJsValue(key);
827 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
828 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
829 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
830 Local<panda::JSValueRef> value = obj->Get(vm, propKey);
831 if (value->IsFunction()) {
832 FunctionSetContainerId(vm, value);
833 }
834 *result = JsValueFromLocalValue(value);
835
836 return GET_RETURN_STATUS(env);
837 }
838
napi_delete_property(napi_env env,napi_value object,napi_value key,bool * result)839 NAPI_EXTERN napi_status napi_delete_property(napi_env env, napi_value object, napi_value key, bool* result)
840 {
841 NAPI_PREAMBLE(env);
842 CHECK_ARG(env, object);
843 CHECK_ARG(env, key);
844
845 auto nativeValue = LocalValueFromJsValue(object);
846 auto propKey = LocalValueFromJsValue(key);
847 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
848 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
849 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
850 bool deleteResult = obj->Delete(vm, propKey);
851 if (result) {
852 *result = deleteResult;
853 }
854
855 return GET_RETURN_STATUS(env);
856 }
857
napi_has_own_property(napi_env env,napi_value object,napi_value key,bool * result)858 NAPI_EXTERN napi_status napi_has_own_property(napi_env env, napi_value object, napi_value key, bool* result)
859 {
860 NAPI_PREAMBLE(env);
861 CHECK_ARG(env, object);
862 CHECK_ARG(env, key);
863 CHECK_ARG(env, result);
864
865 auto nativeValue = LocalValueFromJsValue(object);
866 auto propKey = LocalValueFromJsValue(key);
867 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
868 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
869 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
870 bool hasResult = obj->Has(vm, propKey);
871 if (result) {
872 *result = hasResult;
873 }
874
875 return GET_RETURN_STATUS(env);
876 }
877
napi_set_named_property(napi_env env,napi_value object,const char * utf8name,napi_value value)878 NAPI_EXTERN napi_status napi_set_named_property(napi_env env, napi_value object, const char* utf8name, napi_value value)
879 {
880 NAPI_PREAMBLE(env);
881 CHECK_ARG(env, object);
882 CHECK_ARG(env, utf8name);
883 CHECK_ARG(env, value);
884
885 auto nativeValue = LocalValueFromJsValue(object);
886 auto propKey = LocalValueFromJsValue(value);
887 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
888 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
889 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, utf8name);
890 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
891 obj->Set(vm, key, propKey);
892
893 return GET_RETURN_STATUS(env);
894 }
895
napi_has_named_property(napi_env env,napi_value object,const char * utf8name,bool * result)896 NAPI_EXTERN napi_status napi_has_named_property(napi_env env, napi_value object, const char* utf8name, bool* result)
897 {
898 NAPI_PREAMBLE(env);
899 CHECK_ARG(env, object);
900 CHECK_ARG(env, utf8name);
901 CHECK_ARG(env, result);
902
903 auto nativeValue = LocalValueFromJsValue(object);
904 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
905 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
906 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, utf8name);
907 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
908 *result = obj->Has(vm, key);
909
910 return GET_RETURN_STATUS(env);
911 }
912
napi_get_named_property(napi_env env,napi_value object,const char * utf8name,napi_value * result)913 NAPI_EXTERN napi_status napi_get_named_property(napi_env env,
914 napi_value object,
915 const char* utf8name,
916 napi_value* result)
917 {
918 NAPI_PREAMBLE(env);
919 CHECK_ARG(env, object);
920 CHECK_ARG(env, utf8name);
921 CHECK_ARG(env, result);
922
923 auto nativeValue = LocalValueFromJsValue(object);
924 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
925 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
926 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, utf8name);
927 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
928 Local<panda::JSValueRef> value = obj->Get(vm, key);
929 if (value->IsFunction()) {
930 FunctionSetContainerId(vm, value);
931 }
932 *result = JsValueFromLocalValue(value);
933
934 return GET_RETURN_STATUS(env);
935 }
936
napi_get_own_property_descriptor(napi_env env,napi_value object,const char * utf8name,napi_value * result)937 NAPI_EXTERN napi_status napi_get_own_property_descriptor(napi_env env,
938 napi_value object,
939 const char* utf8name,
940 napi_value* result)
941 {
942 CHECK_ENV(env);
943 CHECK_ARG(env, object);
944 CHECK_ARG(env, utf8name);
945 CHECK_ARG(env, result);
946
947 auto nativeValue = LocalValueFromJsValue(object);
948 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
949 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
950 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
951 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, utf8name);
952 panda::PropertyAttribute property;
953 obj->GetOwnProperty(vm, key, property);
954 *result = JsValueFromLocalValue(property.GetValue(vm));
955 return napi_clear_last_error(env);
956 }
957
napi_set_element(napi_env env,napi_value object,uint32_t index,napi_value value)958 NAPI_EXTERN napi_status napi_set_element(napi_env env, napi_value object, uint32_t index, napi_value value)
959 {
960 NAPI_PREAMBLE(env);
961 CHECK_ARG(env, object);
962 CHECK_ARG(env, value);
963
964 auto nativeValue = LocalValueFromJsValue(object);
965 auto elementValue = LocalValueFromJsValue(value);
966 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
967 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
968 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
969 obj->Set(vm, index, elementValue);
970
971 return GET_RETURN_STATUS(env);
972 }
973
napi_has_element(napi_env env,napi_value object,uint32_t index,bool * result)974 NAPI_EXTERN napi_status napi_has_element(napi_env env, napi_value object, uint32_t index, bool* result)
975 {
976 NAPI_PREAMBLE(env);
977 CHECK_ARG(env, object);
978 CHECK_ARG(env, result);
979
980 auto nativeValue = LocalValueFromJsValue(object);
981 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
982 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
983 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
984 *result = obj->Has(vm, index);
985
986 return GET_RETURN_STATUS(env);
987 }
988
napi_get_element(napi_env env,napi_value object,uint32_t index,napi_value * result)989 NAPI_EXTERN napi_status napi_get_element(napi_env env, napi_value object, uint32_t index, napi_value* result)
990 {
991 NAPI_PREAMBLE(env);
992 CHECK_ARG(env, object);
993 CHECK_ARG(env, result);
994
995 auto nativeValue = LocalValueFromJsValue(object);
996 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
997 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
998 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
999 Local<panda::JSValueRef> value = obj->Get(vm, index);
1000 if (value->IsFunction()) {
1001 FunctionSetContainerId(vm, value);
1002 }
1003 *result = JsValueFromLocalValue(value);
1004
1005 return GET_RETURN_STATUS(env);
1006 }
1007
napi_delete_element(napi_env env,napi_value object,uint32_t index,bool * result)1008 NAPI_EXTERN napi_status napi_delete_element(napi_env env, napi_value object, uint32_t index, bool* result)
1009 {
1010 NAPI_PREAMBLE(env);
1011 CHECK_ARG(env, object);
1012
1013 auto nativeValue = LocalValueFromJsValue(object);
1014 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
1015 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1016 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
1017 bool deleteResult = obj->Delete(vm, index);
1018 if (result) {
1019 *result = deleteResult;
1020 }
1021
1022 return GET_RETURN_STATUS(env);
1023 }
1024
napi_define_properties(napi_env env,napi_value object,size_t property_count,const napi_property_descriptor * properties)1025 NAPI_EXTERN napi_status napi_define_properties(napi_env env,
1026 napi_value object,
1027 size_t property_count,
1028 const napi_property_descriptor* properties)
1029 {
1030 NAPI_PREAMBLE(env);
1031 CHECK_ARG(env, object);
1032 CHECK_ARG(env, properties);
1033
1034 auto nativeValue = LocalValueFromJsValue(object);
1035 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(),
1036 napi_object_expected);
1037 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1038 Local<panda::ObjectRef> nativeObject = nativeValue->ToObject(vm);
1039
1040 auto nativeProperties = reinterpret_cast<const NapiPropertyDescriptor*>(properties);
1041 for (size_t i = 0; i < property_count; i++) {
1042 if (nativeProperties[i].utf8name == nullptr) {
1043 auto name = LocalValueFromJsValue(nativeProperties[i].name);
1044 RETURN_STATUS_IF_FALSE(env, !name.IsEmpty() && (name->IsString() || name->IsSymbol()), napi_name_expected);
1045 }
1046 NapiDefineProperty(env, nativeObject, nativeProperties[i]);
1047 }
1048 return GET_RETURN_STATUS(env);
1049 }
1050
1051 // Methods to work with Arrays
napi_is_array(napi_env env,napi_value value,bool * result)1052 NAPI_EXTERN napi_status napi_is_array(napi_env env, napi_value value, bool* result)
1053 {
1054 CHECK_ENV(env);
1055 CHECK_ARG(env, value);
1056 CHECK_ARG(env, result);
1057
1058 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1059 auto nativeValue = LocalValueFromJsValue(value);
1060 *result = nativeValue->IsJSArray(vm);
1061 return napi_clear_last_error(env);
1062 }
1063
napi_get_array_length(napi_env env,napi_value value,uint32_t * result)1064 NAPI_EXTERN napi_status napi_get_array_length(napi_env env, napi_value value, uint32_t* result)
1065 {
1066 NAPI_PREAMBLE(env);
1067 CHECK_ARG(env, value);
1068 CHECK_ARG(env, result);
1069
1070 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1071 auto nativeValue = LocalValueFromJsValue(value);
1072 RETURN_STATUS_IF_FALSE(env, nativeValue->IsArray(vm), napi_array_expected);
1073 Local<panda::ArrayRef> arr(nativeValue);
1074 *result = arr->Length(vm);
1075
1076 return GET_RETURN_STATUS(env);
1077 }
1078
napi_is_sendable_object(napi_env env,napi_value value,bool * result)1079 NAPI_EXTERN napi_status napi_is_sendable_object(napi_env env, napi_value value, bool* result)
1080 {
1081 CHECK_ENV(env);
1082 CHECK_ARG(env, value);
1083 CHECK_ARG(env, result);
1084
1085 auto nativeValue = LocalValueFromJsValue(value);
1086 *result = nativeValue->IsSharedObject();
1087 return napi_clear_last_error(env);
1088 }
1089
1090 // Methods to compare values
napi_strict_equals(napi_env env,napi_value lhs,napi_value rhs,bool * result)1091 NAPI_EXTERN napi_status napi_strict_equals(napi_env env, napi_value lhs, napi_value rhs, bool* result)
1092 {
1093 CHECK_ENV(env);
1094 CHECK_ARG(env, lhs);
1095 CHECK_ARG(env, rhs);
1096 CHECK_ARG(env, result);
1097
1098 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1099 auto nativeLhs = LocalValueFromJsValue(lhs);
1100 auto nativeRhs = LocalValueFromJsValue(rhs);
1101 *result = nativeLhs->IsStrictEquals(vm, nativeRhs);
1102 return napi_clear_last_error(env);
1103 }
1104
1105 // 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)1106 NAPI_EXTERN napi_status napi_call_function(napi_env env,
1107 napi_value recv,
1108 napi_value func,
1109 size_t argc,
1110 const napi_value* argv,
1111 napi_value* result)
1112 {
1113 NAPI_PREAMBLE(env);
1114 CHECK_ARG(env, func);
1115 if (argc > 0) {
1116 CHECK_ARG(env, argv);
1117 }
1118
1119 RETURN_STATUS_IF_FALSE(env, reinterpret_cast<panda::JSValueRef *>(func)->IsFunction(), napi_function_expected);
1120 auto vm = reinterpret_cast<NativeEngine *>(env)->GetEcmaVm();
1121 panda::JSValueRef* thisObj = reinterpret_cast<panda::JSValueRef *>(recv);
1122 panda::FunctionRef* function = reinterpret_cast<panda::FunctionRef *>(func);
1123 #ifdef ENABLE_CONTAINER_SCOPE
1124 int32_t scopeId = OHOS::Ace::ContainerScope::CurrentId();
1125 auto funcInfo = reinterpret_cast<NapiFunctionInfo *>(function->GetData(vm));
1126 if (funcInfo != nullptr) {
1127 scopeId = funcInfo->scopeId;
1128 }
1129 OHOS::Ace::ContainerScope containerScope(scopeId);
1130 #endif
1131 panda::JSValueRef* value =
1132 function->CallForNapi(vm, thisObj, reinterpret_cast<panda::JSValueRef *const*>(argv), argc);
1133 if (tryCatch.HasCaught()) {
1134 HILOG_ERROR("pending exception when js function called, print exception info: ");
1135 panda::JSNApi::PrintExceptionInfo(vm);
1136 result = nullptr;
1137 return napi_set_last_error(env, napi_pending_exception);
1138 }
1139 if (result) {
1140 *result = reinterpret_cast<napi_value>(value);
1141 }
1142 return napi_clear_last_error(env);
1143 }
1144
napi_new_instance(napi_env env,napi_value constructor,size_t argc,const napi_value * argv,napi_value * result)1145 NAPI_EXTERN napi_status napi_new_instance(napi_env env,
1146 napi_value constructor,
1147 size_t argc,
1148 const napi_value* argv,
1149 napi_value* result)
1150 {
1151 NAPI_PREAMBLE(env);
1152 CHECK_ARG(env, constructor);
1153 if (argc > 0) {
1154 CHECK_ARG(env, argv);
1155 }
1156 CHECK_ARG(env, result);
1157 RETURN_STATUS_IF_FALSE(env, reinterpret_cast<panda::JSValueRef*>(constructor)->IsFunction(), napi_function_expected);
1158 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1159 panda::FunctionRef* constructorVal = reinterpret_cast<panda::FunctionRef*>(constructor);
1160 panda::JSValueRef* instance = constructorVal->ConstructorOptimize(vm,
1161 reinterpret_cast<panda::JSValueRef**>(const_cast<napi_value*>(argv)), argc);
1162 if (tryCatch.HasCaught()) {
1163 HILOG_ERROR("CreateInstance occur Exception");
1164 *result = nullptr;
1165 } else {
1166 *result = reinterpret_cast<napi_value>(instance);
1167 }
1168 return GET_RETURN_STATUS(env);
1169 }
1170
napi_instanceof(napi_env env,napi_value object,napi_value constructor,bool * result)1171 NAPI_EXTERN napi_status napi_instanceof(napi_env env, napi_value object, napi_value constructor, bool* result)
1172 {
1173 NAPI_PREAMBLE(env);
1174 CHECK_ARG(env, object);
1175 CHECK_ARG(env, constructor);
1176 CHECK_ARG(env, result);
1177
1178 auto nativeValue = LocalValueFromJsValue(object);
1179 auto nativeConstructor = LocalValueFromJsValue(constructor);
1180 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(), napi_object_expected);
1181 RETURN_STATUS_IF_FALSE(env, nativeConstructor->IsFunction(), napi_function_expected);
1182 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1183 *result = nativeValue->InstanceOf(vm, nativeConstructor);
1184
1185 return GET_RETURN_STATUS(env);
1186 }
1187
1188 // Methods to work with napi_callbacks
1189 // 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)1190 NAPI_EXTERN napi_status napi_get_cb_info(napi_env env, // [in] NAPI environment handle
1191 napi_callback_info cbinfo, // [in] Opaque callback-info handle
1192 size_t* argc, // [in-out] Specifies the size of the provided argv array
1193 // and receives the actual count of args.
1194 napi_value* argv, // [out] Array of values
1195 napi_value* this_arg, // [out] Receives the JS 'this' arg for the call
1196 void** data) // [out] Receives the data pointer for the callback.
1197 {
1198 CHECK_ENV(env);
1199 CHECK_ARG(env, cbinfo);
1200
1201 auto info = reinterpret_cast<NapiNativeCallbackInfo*>(cbinfo);
1202 if ((argc != nullptr) && (argv != nullptr)) {
1203 size_t i = info->GetArgv(argv, *argc);
1204 if (i < *argc) {
1205 napi_value undefined = JsValueFromLocalValue(
1206 panda::JSValueRef::Undefined(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm()));
1207 for (; i < *argc; i++) {
1208 argv[i] = undefined;
1209 }
1210 }
1211 }
1212 if (argc != nullptr) {
1213 *argc = info->GetArgc();
1214 }
1215 if (this_arg != nullptr) {
1216 *this_arg = info->GetThisVar();
1217 }
1218 if (data != nullptr && info->GetFunctionInfo() != nullptr) {
1219 *data = info->GetFunctionInfo()->data;
1220 }
1221
1222 return napi_clear_last_error(env);
1223 }
1224
napi_get_new_target(napi_env env,napi_callback_info cbinfo,napi_value * result)1225 NAPI_EXTERN napi_status napi_get_new_target(napi_env env, napi_callback_info cbinfo, napi_value* result)
1226 {
1227 NAPI_PREAMBLE(env);
1228 CHECK_ARG(env, cbinfo);
1229 CHECK_ARG(env, result);
1230
1231 auto info = reinterpret_cast<NapiNativeCallbackInfo*>(cbinfo);
1232 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1233 auto thisVarObj = LocalValueFromJsValue(info->GetThisVar());
1234 auto functionVal = LocalValueFromJsValue(info->GetFunction());
1235 if (thisVarObj->InstanceOf(vm, functionVal)) {
1236 *result = info->GetFunction();
1237 } else {
1238 *result = nullptr;
1239 }
1240
1241 return GET_RETURN_STATUS(env);
1242 }
1243
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)1244 NAPI_EXTERN napi_status napi_define_class(napi_env env,
1245 const char* utf8name,
1246 size_t length,
1247 napi_callback constructor,
1248 void* data,
1249 size_t property_count,
1250 const napi_property_descriptor* properties,
1251 napi_value* result)
1252 {
1253 NAPI_PREAMBLE(env);
1254 CHECK_ARG(env, utf8name);
1255 RETURN_STATUS_IF_FALSE(env, length == NAPI_AUTO_LENGTH || length <= INT_MAX, napi_object_expected);
1256 CHECK_ARG(env, constructor);
1257 if (property_count > 0) {
1258 CHECK_ARG(env, properties);
1259 }
1260 CHECK_ARG(env, result);
1261
1262 auto callback = reinterpret_cast<NapiNativeCallback>(constructor);
1263 auto nativeProperties = reinterpret_cast<const NapiPropertyDescriptor*>(properties);
1264
1265 size_t nameLength = std::min(length, strlen(utf8name));
1266 char newName[nameLength + 1];
1267 if (strncpy_s(newName, nameLength + 1, utf8name, nameLength) != EOK) {
1268 HILOG_ERROR("napi_define_class strncpy_s failed");
1269 *result = nullptr;
1270 } else {
1271 EscapeLocalScope scope(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm());
1272 auto resultValue = NapiDefineClass(env, newName, callback, data, nativeProperties, property_count);
1273 *result = JsValueFromLocalValue(scope.Escape(resultValue));
1274 }
1275
1276 return GET_RETURN_STATUS(env);
1277 }
1278
1279 // 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)1280 NAPI_EXTERN napi_status napi_wrap(napi_env env,
1281 napi_value js_object,
1282 void* native_object,
1283 napi_finalize finalize_cb,
1284 void* finalize_hint,
1285 napi_ref* result)
1286 {
1287 NAPI_PREAMBLE(env);
1288 CHECK_ARG(env, js_object);
1289 CHECK_ARG(env, native_object);
1290 CHECK_ARG(env, finalize_cb);
1291
1292 auto nativeValue = LocalValueFromJsValue(js_object);
1293 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
1294 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
1295 auto engine = reinterpret_cast<NativeEngine*>(env);
1296 auto vm = engine->GetEcmaVm();
1297 auto nativeObject = nativeValue->ToObject(vm);
1298 size_t nativeBindingSize = 0;
1299 auto reference = reinterpret_cast<NativeReference**>(result);
1300 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1301 if (native_object == nullptr && nativeObject->Has(vm, key)) {
1302 Local<panda::ObjectRef> wrapper = nativeObject->Get(vm, key);
1303 auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(0));
1304 // Try to remove native pointer from ArrayDataList
1305 wrapper->SetNativePointerField(vm, 0, nullptr, nullptr, nullptr, nativeBindingSize);
1306 nativeObject->Delete(vm, key);
1307 delete ref;
1308 } else {
1309 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
1310 NativeReference* ref = nullptr;
1311 if (reference != nullptr) {
1312 ref = engine->CreateReference(js_object, 1, false, callback, native_object, finalize_hint);
1313 *reference = ref;
1314 } else {
1315 ref = engine->CreateReference(js_object, 0, true, callback, native_object, finalize_hint);
1316 }
1317 object->SetNativePointerFieldCount(vm, 1);
1318 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, nativeBindingSize);
1319 PropertyAttribute attr(object, true, false, true);
1320 nativeObject->DefineProperty(vm, key, attr);
1321 }
1322 return GET_RETURN_STATUS(env);
1323 }
1324
1325 // 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)1326 NAPI_EXTERN napi_status napi_wrap_with_size(napi_env env,
1327 napi_value js_object,
1328 void* native_object,
1329 napi_finalize finalize_cb,
1330 void* finalize_hint,
1331 napi_ref* result,
1332 size_t native_binding_size)
1333 {
1334 NAPI_PREAMBLE(env);
1335 CHECK_ARG(env, js_object);
1336 CHECK_ARG(env, native_object);
1337 CHECK_ARG(env, finalize_cb);
1338
1339 auto nativeValue = LocalValueFromJsValue(js_object);
1340 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
1341 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
1342 auto engine = reinterpret_cast<NativeEngine*>(env);
1343 auto vm = engine->GetEcmaVm();
1344 auto nativeObject = nativeValue->ToObject(vm);
1345 auto reference = reinterpret_cast<NativeReference**>(result);
1346 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1347 if (native_object == nullptr && nativeObject->Has(vm, key)) {
1348 Local<panda::ObjectRef> wrapper = nativeObject->Get(vm, key);
1349 auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(0));
1350 // Try to remove native pointer from ArrayDataList
1351 wrapper->SetNativePointerField(vm, 0, nullptr, nullptr, nullptr, native_binding_size);
1352 nativeObject->Delete(vm, key);
1353 delete ref;
1354 } else {
1355 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
1356 NativeReference* ref = nullptr;
1357 if (reference != nullptr) {
1358 ref = engine->CreateReference(js_object, 1, false, callback, native_object, finalize_hint);
1359 *reference = ref;
1360 } else {
1361 ref = engine->CreateReference(js_object, 0, true, callback, native_object, finalize_hint);
1362 }
1363 object->SetNativePointerFieldCount(vm, 1);
1364 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, native_binding_size);
1365 PropertyAttribute attr(object, true, false, true);
1366 nativeObject->DefineProperty(vm, key, attr);
1367 }
1368
1369 return GET_RETURN_STATUS(env);
1370 }
1371
napi_unwrap(napi_env env,napi_value js_object,void ** result)1372 NAPI_EXTERN napi_status napi_unwrap(napi_env env, napi_value js_object, void** result)
1373 {
1374 NAPI_PREAMBLE(env);
1375 CHECK_ARG(env, js_object);
1376 CHECK_ARG(env, result);
1377
1378 auto nativeValue = LocalValueFromJsValue(js_object);
1379 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
1380 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1381 auto nativeObject = nativeValue->ToObject(vm);
1382 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1383 Local<panda::JSValueRef> val = nativeObject->Get(vm, key);
1384 *result = nullptr;
1385 if (val->IsObject()) {
1386 Local<panda::ObjectRef> ext(val);
1387 auto ref = reinterpret_cast<NativeReference*>(ext->GetNativePointerField(0));
1388 *result = ref != nullptr ? ref->GetData() : nullptr;
1389 }
1390
1391 return GET_RETURN_STATUS(env);
1392 }
1393
napi_remove_wrap(napi_env env,napi_value js_object,void ** result)1394 NAPI_EXTERN napi_status napi_remove_wrap(napi_env env, napi_value js_object, void** result)
1395 {
1396 NAPI_PREAMBLE(env);
1397 CHECK_ARG(env, js_object);
1398 CHECK_ARG(env, result);
1399
1400 auto nativeValue = LocalValueFromJsValue(js_object);
1401 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
1402 auto engine = reinterpret_cast<NativeEngine*>(env);
1403 auto vm = engine->GetEcmaVm();
1404 auto nativeObject = nativeValue->ToObject(vm);
1405 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1406 Local<panda::JSValueRef> val = nativeObject->Get(vm, key);
1407 *result = nullptr;
1408 if (val->IsObject()) {
1409 Local<panda::ObjectRef> ext(val);
1410 auto ref = reinterpret_cast<NativeReference*>(ext->GetNativePointerField(0));
1411 *result = ref != nullptr ? ref->GetData() : nullptr;
1412 }
1413
1414 size_t nativeBindingSize = 0;
1415 if (nativeObject->Has(vm, key)) {
1416 Local<panda::ObjectRef> wrapper = val;
1417 auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(0));
1418 // Try to remove native pointer from ArrayDataList
1419 wrapper->SetNativePointerField(vm, 0, nullptr, nullptr, nullptr, nativeBindingSize);
1420 nativeObject->Delete(vm, key);
1421 delete ref;
1422 } else {
1423 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
1424 NativeReference* ref = nullptr;
1425 ref = engine->CreateReference(js_object, 0, true, nullptr, nullptr, nullptr);
1426 object->SetNativePointerFieldCount(vm, 1);
1427 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, nativeBindingSize);
1428 PropertyAttribute attr(object, true, false, true);
1429 nativeObject->DefineProperty(vm, key, attr);
1430 }
1431
1432 return GET_RETURN_STATUS(env);
1433 }
1434
napi_create_external(napi_env env,void * data,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)1435 NAPI_EXTERN napi_status napi_create_external(
1436 napi_env env, void* data, napi_finalize finalize_cb, void* finalize_hint, napi_value* result)
1437 {
1438 NAPI_PREAMBLE(env);
1439 CHECK_ARG(env, result);
1440
1441 auto engine = reinterpret_cast<NativeEngine*>(env);
1442 auto vm = engine->GetEcmaVm();
1443 auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
1444 NativeObjectInfo* info = NativeObjectInfo::CreateNewInstance();
1445 if (info == nullptr) {
1446 HILOG_ERROR("info is nullptr");
1447 return napi_set_last_error(env, napi_invalid_arg);
1448 }
1449 info->engine = engine;
1450 info->callback = callback;
1451 info->hint = finalize_hint;
1452 Local<panda::NativePointerRef> object = panda::NativePointerRef::New(vm, data,
1453 [](void* data, void* info) {
1454 auto externalInfo = reinterpret_cast<NativeObjectInfo*>(info);
1455 auto engine = externalInfo->engine;
1456 auto callback = externalInfo->callback;
1457 auto hint = externalInfo->hint;
1458 if (callback != nullptr) {
1459 callback(engine, data, hint);
1460 }
1461 delete externalInfo;
1462 }, info, 0);
1463
1464 *result = JsValueFromLocalValue(object);
1465 return napi_clear_last_error(env);
1466 }
1467
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)1468 NAPI_EXTERN napi_status napi_create_external_with_size(napi_env env,
1469 void* data,
1470 napi_finalize finalize_cb,
1471 void* finalize_hint,
1472 napi_value* result,
1473 size_t native_binding_size)
1474 {
1475 CHECK_ENV(env);
1476 CHECK_ARG(env, result);
1477
1478 auto engine = reinterpret_cast<NativeEngine*>(env);
1479 auto vm = engine->GetEcmaVm();
1480 auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
1481 NativeObjectInfo* info = NativeObjectInfo::CreateNewInstance();
1482 if (info == nullptr) {
1483 HILOG_ERROR("info is nullptr");
1484 return napi_set_last_error(env, napi_function_expected);
1485 }
1486 info->engine = engine;
1487 info->nativeObject = nullptr;
1488 info->callback = callback;
1489 info->hint = finalize_hint;
1490 Local<panda::NativePointerRef> object = panda::NativePointerRef::New(vm, data,
1491 [](void* data, void* info) {
1492 auto externalInfo = reinterpret_cast<NativeObjectInfo*>(info);
1493 auto engine = externalInfo->engine;
1494 auto callback = externalInfo->callback;
1495 auto hint = externalInfo->hint;
1496 if (callback != nullptr) {
1497 callback(engine, data, hint);
1498 }
1499 delete externalInfo;
1500 }, info, native_binding_size);
1501
1502 *result = JsValueFromLocalValue(object);
1503 return napi_clear_last_error(env);
1504 }
1505
napi_get_value_external(napi_env env,napi_value value,void ** result)1506 NAPI_EXTERN napi_status napi_get_value_external(napi_env env, napi_value value, void** result)
1507 {
1508 CHECK_ENV(env);
1509 CHECK_ARG(env, value);
1510 CHECK_ARG(env, result);
1511
1512 auto nativeValue = LocalValueFromJsValue(value);
1513 RETURN_STATUS_IF_FALSE(env, nativeValue->IsNativePointer(), napi_object_expected);
1514 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1515 Local<panda::NativePointerRef> object = nativeValue->ToNativePointer(vm);
1516 *result = object->Value();
1517 return napi_clear_last_error(env);
1518 }
1519
1520 // Methods to control object lifespan
1521 // 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)1522 NAPI_EXTERN napi_status napi_create_reference(napi_env env,
1523 napi_value value,
1524 uint32_t initial_refcount,
1525 napi_ref* result)
1526 {
1527 CHECK_ENV(env);
1528 CHECK_ARG(env, value);
1529 CHECK_ARG(env, result);
1530 auto engine = reinterpret_cast<ArkNativeEngine*>(env);
1531 auto ref = new ArkNativeReference(engine, engine->GetEcmaVm(), value, initial_refcount);
1532
1533 *result = reinterpret_cast<napi_ref>(ref);
1534 return napi_clear_last_error(env);
1535 }
1536
1537 // Deletes a reference. The referenced value is released, and may
1538 // be GC'd unless there are other references to it.
napi_delete_reference(napi_env env,napi_ref ref)1539 NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref)
1540 {
1541 CHECK_ENV(env);
1542 CHECK_ARG(env, ref);
1543
1544 auto reference = reinterpret_cast<NativeReference*>(ref);
1545 uint32_t refCount = reference->GetRefCount();
1546 if (refCount > 0 || reference->GetFinalRun()) {
1547 delete reference;
1548 reference = nullptr;
1549 } else {
1550 reference->SetDeleteSelf();
1551 }
1552
1553 return napi_clear_last_error(env);
1554 }
1555
1556 // Increments the reference count, optionally returning the resulting count.
1557 // After this call the reference will be a strong reference because its
1558 // refcount is >0, and the referenced object is effectively "pinned".
1559 // Calling this when the refcount is 0 and the object is unavailable
1560 // results in an error.
napi_reference_ref(napi_env env,napi_ref ref,uint32_t * result)1561 NAPI_EXTERN napi_status napi_reference_ref(napi_env env, napi_ref ref, uint32_t* result)
1562 {
1563 CHECK_ENV(env);
1564 CHECK_ARG(env, ref);
1565
1566 auto reference = reinterpret_cast<NativeReference*>(ref);
1567 uint32_t refCount = reference->Ref();
1568
1569 if (result) {
1570 *result = refCount;
1571 }
1572
1573 return napi_clear_last_error(env);
1574 }
1575
1576 // Decrements the reference count, optionally returning the resulting count.
1577 // If the result is 0 the reference is now weak and the object may be GC'd
1578 // at any time if there are no other references. Calling this when the
1579 // refcount is already 0 results in an error.
napi_reference_unref(napi_env env,napi_ref ref,uint32_t * result)1580 NAPI_EXTERN napi_status napi_reference_unref(napi_env env, napi_ref ref, uint32_t* result)
1581 {
1582 CHECK_ENV(env);
1583 CHECK_ARG(env, ref);
1584
1585 auto reference = reinterpret_cast<NativeReference*>(ref);
1586 uint32_t unrefCount = reference->Unref();
1587
1588 if (result) {
1589 *result = unrefCount;
1590 }
1591
1592 return napi_clear_last_error(env);
1593 }
1594
1595 // Attempts to get a referenced value. If the reference is weak,
1596 // the value might no longer be available, in that case the call
1597 // is still successful but the result is nullptr.
napi_get_reference_value(napi_env env,napi_ref ref,napi_value * result)1598 NAPI_EXTERN napi_status napi_get_reference_value(napi_env env, napi_ref ref, napi_value* result)
1599 {
1600 CHECK_ENV(env);
1601 CHECK_ARG(env, ref);
1602 CHECK_ARG(env, result);
1603
1604 auto reference = reinterpret_cast<NativeReference*>(ref);
1605
1606 *result = reference->Get();
1607 return napi_clear_last_error(env);
1608 }
1609
napi_open_handle_scope(napi_env env,napi_handle_scope * result)1610 NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env, napi_handle_scope* result)
1611 {
1612 CHECK_ENV(env);
1613 CHECK_ARG(env, result);
1614
1615 auto engine = reinterpret_cast<NativeEngine*>(env);
1616 *result = HandleScopeToNapiHandleScope(new HandleScopeWrapper(engine));
1617 engine->openHandleScopes_++;
1618 return napi_clear_last_error(env);
1619 }
1620
napi_close_handle_scope(napi_env env,napi_handle_scope scope)1621 NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env, napi_handle_scope scope)
1622 {
1623 CHECK_ENV(env);
1624 CHECK_ARG(env, scope);
1625
1626 auto engine = reinterpret_cast<NativeEngine*>(env);
1627 if (engine->openHandleScopes_ == 0) {
1628 return napi_handle_scope_mismatch;
1629 }
1630
1631 engine->openHandleScopes_--;
1632 delete NapiHandleScopeToHandleScope(scope);
1633 return napi_clear_last_error(env);
1634 }
1635
napi_open_escapable_handle_scope(napi_env env,napi_escapable_handle_scope * result)1636 NAPI_EXTERN napi_status napi_open_escapable_handle_scope(napi_env env, napi_escapable_handle_scope* result)
1637 {
1638 CHECK_ENV(env);
1639 CHECK_ARG(env, result);
1640
1641 auto engine = reinterpret_cast<NativeEngine*>(env);
1642 *result = EscapableHandleScopeToNapiEscapableHandleScope(new EscapableHandleScopeWrapper(engine));
1643 engine->openHandleScopes_++;
1644 return napi_clear_last_error(env);
1645 }
1646
napi_close_escapable_handle_scope(napi_env env,napi_escapable_handle_scope scope)1647 NAPI_EXTERN napi_status napi_close_escapable_handle_scope(napi_env env, napi_escapable_handle_scope scope)
1648 {
1649 CHECK_ENV(env);
1650 CHECK_ARG(env, scope);
1651
1652 auto engine = reinterpret_cast<NativeEngine*>(env);
1653 if (engine->openHandleScopes_ == 0) {
1654 return napi_handle_scope_mismatch;
1655 }
1656
1657 engine->openHandleScopes_--;
1658 delete NapiEscapableHandleScopeToEscapableHandleScope(scope);
1659 return napi_clear_last_error(env);
1660 }
1661
napi_escape_handle(napi_env env,napi_escapable_handle_scope scope,napi_value escapee,napi_value * result)1662 NAPI_EXTERN napi_status napi_escape_handle(napi_env env,
1663 napi_escapable_handle_scope scope,
1664 napi_value escapee,
1665 napi_value* result)
1666 {
1667 CHECK_ENV(env);
1668 CHECK_ARG(env, scope);
1669 CHECK_ARG(env, escapee);
1670 CHECK_ARG(env, result);
1671
1672 auto s = NapiEscapableHandleScopeToEscapableHandleScope(scope);
1673 if (!s->IsEscapeCalled()) {
1674 *result = JsValueFromLocalValue(s->Escape(LocalValueFromJsValue(escapee)));
1675 return napi_clear_last_error(env);
1676 }
1677 return napi_set_last_error(env, napi_escape_called_twice);
1678 }
1679
1680 // Methods to support error handling
napi_throw(napi_env env,napi_value error)1681 NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error)
1682 {
1683 CHECK_ENV(env);
1684 CHECK_ARG(env, error);
1685
1686 auto nativeValue = LocalValueFromJsValue(error);
1687 RETURN_STATUS_IF_FALSE(env, nativeValue->IsError(), napi_invalid_arg);
1688 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1689 panda::JSNApi::ThrowException(vm, nativeValue);
1690 return napi_clear_last_error(env);
1691 }
1692
napi_throw_error(napi_env env,const char * code,const char * msg)1693 NAPI_EXTERN napi_status napi_throw_error(napi_env env, const char* code, const char* msg)
1694 {
1695 CHECK_ENV(env);
1696 CHECK_ARG(env, msg);
1697
1698 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1699 Local<panda::JSValueRef> error(panda::JSValueRef::Undefined(vm));
1700 error = panda::Exception::Error(vm, StringRef::NewFromUtf8(vm, msg));
1701 if (code != nullptr) {
1702 Local<panda::JSValueRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
1703 Local<panda::JSValueRef> codeValue = panda::StringRef::NewFromUtf8(vm, code);
1704 Local<panda::ObjectRef> errorObj(error);
1705 errorObj->Set(vm, codeKey, codeValue);
1706 }
1707 panda::JSNApi::ThrowException(vm, error);
1708 return napi_clear_last_error(env);
1709 }
1710
napi_throw_type_error(napi_env env,const char * code,const char * msg)1711 NAPI_EXTERN napi_status napi_throw_type_error(napi_env env, const char* code, const char* msg)
1712 {
1713 CHECK_ENV(env);
1714 CHECK_ARG(env, msg);
1715
1716 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1717 Local<panda::JSValueRef> error(panda::JSValueRef::Undefined(vm));
1718 error = panda::Exception::TypeError(vm, StringRef::NewFromUtf8(vm, msg));
1719 if (code != nullptr) {
1720 Local<panda::JSValueRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
1721 Local<panda::JSValueRef> codeValue = panda::StringRef::NewFromUtf8(vm, code);
1722 Local<panda::ObjectRef> errorObj(error);
1723 errorObj->Set(vm, codeKey, codeValue);
1724 }
1725 panda::JSNApi::ThrowException(vm, error);
1726 return napi_clear_last_error(env);
1727 }
1728
napi_throw_range_error(napi_env env,const char * code,const char * msg)1729 NAPI_EXTERN napi_status napi_throw_range_error(napi_env env, const char* code, const char* msg)
1730 {
1731 CHECK_ENV(env);
1732 CHECK_ARG(env, msg);
1733
1734 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1735 Local<panda::JSValueRef> error(panda::JSValueRef::Undefined(vm));
1736 error = panda::Exception::RangeError(vm, StringRef::NewFromUtf8(vm, msg));
1737 if (code != nullptr) {
1738 Local<panda::JSValueRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
1739 Local<panda::JSValueRef> codeValue = panda::StringRef::NewFromUtf8(vm, code);
1740 Local<panda::ObjectRef> errorObj(error);
1741 errorObj->Set(vm, codeKey, codeValue);
1742 }
1743 panda::JSNApi::ThrowException(vm, error);
1744 return napi_clear_last_error(env);
1745 }
1746
napi_is_error(napi_env env,napi_value value,bool * result)1747 NAPI_EXTERN napi_status napi_is_error(napi_env env, napi_value value, bool* result)
1748 {
1749 CHECK_ENV(env);
1750 CHECK_ARG(env, value);
1751 CHECK_ARG(env, result);
1752
1753 auto nativeValue = LocalValueFromJsValue(value);
1754 *result = nativeValue->IsError();
1755
1756 return napi_clear_last_error(env);
1757 }
1758
1759 // Methods to support catching exceptions
napi_is_exception_pending(napi_env env,bool * result)1760 NAPI_EXTERN napi_status napi_is_exception_pending(napi_env env, bool* result)
1761 {
1762 CHECK_ENV(env);
1763 CHECK_ARG(env, result);
1764
1765 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1766 *result = panda::JSNApi::HasPendingException(vm);
1767 return napi_clear_last_error(env);
1768 }
1769
napi_get_and_clear_last_exception(napi_env env,napi_value * result)1770 NAPI_EXTERN napi_status napi_get_and_clear_last_exception(napi_env env, napi_value* result)
1771 {
1772 CHECK_ENV(env);
1773 CHECK_ARG(env, result);
1774
1775 auto engine = reinterpret_cast<NativeEngine*>(env);
1776 auto vm = engine->GetEcmaVm();
1777 engine->lastException_.Empty();
1778 Local<panda::ObjectRef> exception = panda::JSNApi::GetAndClearUncaughtException(vm);
1779 if (!exception.IsNull()) {
1780 *result = JsValueFromLocalValue(exception);
1781 }
1782
1783 return napi_clear_last_error(env);
1784 }
1785
1786 // Methods to work with array buffers and typed arrays
napi_is_arraybuffer(napi_env env,napi_value value,bool * result)1787 NAPI_EXTERN napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result)
1788 {
1789 CHECK_ENV(env);
1790 CHECK_ARG(env, value);
1791 CHECK_ARG(env, result);
1792
1793 auto nativeValue = LocalValueFromJsValue(value);
1794 *result = nativeValue->IsArrayBuffer();
1795
1796 return napi_clear_last_error(env);
1797 }
1798
napi_create_arraybuffer(napi_env env,size_t byte_length,void ** data,napi_value * result)1799 NAPI_EXTERN napi_status napi_create_arraybuffer(napi_env env, size_t byte_length, void** data, napi_value* result)
1800 {
1801 NAPI_PREAMBLE(env);
1802 CHECK_ARG(env, data);
1803 CHECK_ARG(env, result);
1804
1805 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1806 uint8_t** values = (uint8_t**)(data);
1807 Local<panda::ArrayBufferRef> res = panda::ArrayBufferRef::New(vm, byte_length);
1808 if (values != nullptr) {
1809 *values = reinterpret_cast<uint8_t*>(res->GetBuffer());
1810 }
1811 *result = JsValueFromLocalValue(res);
1812
1813 return GET_RETURN_STATUS(env);
1814 }
1815
napi_create_external_arraybuffer(napi_env env,void * external_data,size_t byte_length,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)1816 NAPI_EXTERN napi_status napi_create_external_arraybuffer(napi_env env,
1817 void* external_data,
1818 size_t byte_length,
1819 napi_finalize finalize_cb,
1820 void* finalize_hint,
1821 napi_value* result)
1822 {
1823 NAPI_PREAMBLE(env);
1824 CHECK_ARG(env, external_data);
1825 CHECK_ARG(env, finalize_cb);
1826 CHECK_ARG(env, result);
1827
1828 auto engine = reinterpret_cast<NativeEngine*>(env);
1829 auto vm = engine->GetEcmaVm();
1830 auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
1831 uint8_t* value = (uint8_t*)external_data;
1832 NativeObjectInfo* cbinfo = NativeObjectInfo::CreateNewInstance();
1833 if (cbinfo == nullptr) {
1834 HILOG_ERROR("cbinfo is nullptr");
1835 return napi_set_last_error(env, napi_function_expected);
1836 }
1837 cbinfo->engine = engine;
1838 cbinfo->callback = callback;
1839 cbinfo->hint = finalize_hint;
1840
1841 Local<panda::ArrayBufferRef> object = panda::ArrayBufferRef::New(vm, value, byte_length,
1842 [](void* data, void* info) {
1843 auto externalInfo = reinterpret_cast<NativeObjectInfo*>(info);
1844 auto engine = externalInfo->engine;
1845 auto callback = externalInfo->callback;
1846 auto hint = externalInfo->hint;
1847 if (callback != nullptr) {
1848 callback(engine, data, hint);
1849 }
1850 delete externalInfo;
1851 },
1852 cbinfo);
1853 *result = JsValueFromLocalValue(object);
1854 return GET_RETURN_STATUS(env);
1855 }
1856
napi_get_arraybuffer_info(napi_env env,napi_value arraybuffer,void ** data,size_t * byte_length)1857 NAPI_EXTERN napi_status napi_get_arraybuffer_info(napi_env env,
1858 napi_value arraybuffer,
1859 void** data,
1860 size_t* byte_length)
1861 {
1862 CHECK_ENV(env);
1863 CHECK_ARG(env, arraybuffer);
1864 CHECK_ARG(env, data);
1865 CHECK_ARG(env, byte_length);
1866
1867 auto nativeValue = LocalValueFromJsValue(arraybuffer);
1868 RETURN_STATUS_IF_FALSE(env, nativeValue->IsArrayBuffer(), napi_status::napi_arraybuffer_expected);
1869 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1870 Local<panda::ArrayBufferRef> res = nativeValue->ToObject(vm);
1871 *data = res->GetBuffer();
1872 *byte_length = res->ByteLength(vm);
1873
1874 return napi_clear_last_error(env);
1875 }
1876
napi_is_typedarray(napi_env env,napi_value value,bool * result)1877 NAPI_EXTERN napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result)
1878 {
1879 CHECK_ENV(env);
1880 CHECK_ARG(env, value);
1881
1882 auto nativeValue = LocalValueFromJsValue(value);
1883 *result = nativeValue->IsTypedArray();
1884
1885 return napi_clear_last_error(env);
1886 }
1887
1888 EXTERN_C_START
napi_is_buffer(napi_env env,napi_value value,bool * result)1889 NAPI_EXTERN napi_status napi_is_buffer(napi_env env, napi_value value, bool* result)
1890 {
1891 CHECK_ENV(env);
1892 CHECK_ARG(env, value);
1893 CHECK_ARG(env, result);
1894
1895 auto nativeValue = LocalValueFromJsValue(value);
1896 *result = nativeValue->IsBuffer();
1897
1898 return napi_clear_last_error(env);
1899 }
1900
napi_create_buffer(napi_env env,size_t size,void ** data,napi_value * result)1901 NAPI_EXTERN napi_status napi_create_buffer(napi_env env, size_t size, void** data, napi_value* result)
1902 {
1903 CHECK_ENV(env);
1904 CHECK_ARG(env, data);
1905 CHECK_ARG(env, result);
1906 RETURN_STATUS_IF_FALSE(env, size > 0, napi_invalid_arg);
1907
1908 uint8_t** value = reinterpret_cast<uint8_t**>(data);
1909 if (!value) {
1910 HILOG_ERROR("value is empty");
1911 return napi_set_last_error(env, napi_invalid_arg);
1912 }
1913
1914 if (size > MAX_BYTE_LENGTH) {
1915 HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
1916 static_cast<float>(size) / static_cast<float>(ONEMIB_BYTE_SIZE),
1917 static_cast<float>(MAX_BYTE_LENGTH) / static_cast<float>(ONEMIB_BYTE_SIZE));
1918 *value = nullptr;
1919 return napi_set_last_error(env, napi_invalid_arg);
1920 }
1921 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1922 Local<panda::BufferRef> obj = BufferRef::New(vm, size);
1923 *value = reinterpret_cast<uint8_t*>(obj->GetBuffer());
1924
1925 CHECK_ARG(env, *data);
1926 void* ptr = obj->GetBuffer();
1927 CHECK_ARG(env, ptr);
1928
1929 *result = JsValueFromLocalValue(obj);
1930 return napi_clear_last_error(env);
1931 }
1932
napi_create_buffer_copy(napi_env env,size_t length,const void * data,void ** result_data,napi_value * result)1933 NAPI_EXTERN napi_status napi_create_buffer_copy(napi_env env,
1934 size_t length,
1935 const void* data,
1936 void** result_data,
1937 napi_value* result)
1938 {
1939 CHECK_ENV(env);
1940 CHECK_ARG(env, data);
1941 CHECK_ARG(env, result_data);
1942 CHECK_ARG(env, result);
1943 RETURN_STATUS_IF_FALSE(env, length > 0, napi_invalid_arg);
1944
1945 uint8_t** value = reinterpret_cast<uint8_t**>(result_data);
1946 const uint8_t* recvdata = (uint8_t*)data;
1947 if (!value) {
1948 HILOG_ERROR("value is empty");
1949 return napi_set_last_error(env, napi_invalid_arg);
1950 }
1951 if (length > MAX_BYTE_LENGTH) {
1952 HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
1953 static_cast<float>(length) / static_cast<float>(ONEMIB_BYTE_SIZE),
1954 static_cast<float>(MAX_BYTE_LENGTH) / static_cast<float>(ONEMIB_BYTE_SIZE));
1955 *value = nullptr;
1956 return napi_set_last_error(env, napi_invalid_arg);
1957 }
1958 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1959 Local<panda::BufferRef> obj = BufferRef::New(vm, length);
1960 if (obj->IsUndefined()) {
1961 HILOG_INFO("engine create buffer_copy failed!");
1962 }
1963 *value = reinterpret_cast<uint8_t*>(obj->GetBuffer());
1964 if (memcpy_s(*value, length, recvdata, length) != EOK) {
1965 HILOG_ERROR("memcpy_s failed");
1966 }
1967
1968 void* ptr = obj->GetBuffer();
1969 CHECK_ARG(env, ptr);
1970
1971 *result = JsValueFromLocalValue(obj);
1972 return napi_clear_last_error(env);
1973 }
1974
napi_create_external_buffer(napi_env env,size_t length,void * data,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)1975 NAPI_EXTERN napi_status napi_create_external_buffer(napi_env env,
1976 size_t length,
1977 void* data,
1978 napi_finalize finalize_cb,
1979 void* finalize_hint,
1980 napi_value* result)
1981 {
1982 NAPI_PREAMBLE(env);
1983 CHECK_ARG(env, result);
1984 CHECK_ARG(env, data);
1985 RETURN_STATUS_IF_FALSE(env, length > 0, napi_invalid_arg);
1986
1987 auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
1988 uint8_t* value = (uint8_t*)data;
1989 if (!value) {
1990 HILOG_ERROR("value is empty");
1991 return napi_set_last_error(env, napi_invalid_arg);
1992 }
1993 if (length > MAX_BYTE_LENGTH) {
1994 HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
1995 static_cast<float>(length) / static_cast<float>(ONEMIB_BYTE_SIZE),
1996 static_cast<float>(MAX_BYTE_LENGTH) / static_cast<float>(ONEMIB_BYTE_SIZE));
1997 value = nullptr;
1998 return napi_set_last_error(env, napi_invalid_arg);
1999 }
2000
2001 auto engine = reinterpret_cast<NativeEngine*>(env);
2002 auto vm = engine->GetEcmaVm();
2003 std::unique_ptr<NativeObjectInfo> cbinfo(NativeObjectInfo::CreateNewInstance());
2004 if (!cbinfo) {
2005 HILOG_ERROR("cbinfo is nullptr");
2006 return napi_set_last_error(env, napi_function_expected);
2007 }
2008 cbinfo->engine = engine;
2009 cbinfo->callback = callback;
2010 cbinfo->hint = finalize_hint;
2011
2012 Local<panda::BufferRef> object = panda::BufferRef::New(vm, value, length,
2013 [](void* data, void* info) {
2014 auto externalInfo = reinterpret_cast<NativeObjectInfo*>(info);
2015 auto engine = externalInfo->engine;
2016 auto callback = externalInfo->callback;
2017 auto hint = externalInfo->hint;
2018 if (callback != nullptr) {
2019 callback(engine, data, hint);
2020 }
2021 delete externalInfo;
2022 },
2023 cbinfo.get());
2024 cbinfo.release();
2025 void* ptr = object->GetBuffer();
2026 CHECK_ARG(env, ptr);
2027
2028 *result = JsValueFromLocalValue(object);
2029 return GET_RETURN_STATUS(env);
2030 }
2031
napi_get_buffer_info(napi_env env,napi_value value,void ** data,size_t * length)2032 NAPI_EXTERN napi_status napi_get_buffer_info(napi_env env, napi_value value, void** data, size_t* length)
2033 {
2034 CHECK_ENV(env);
2035 CHECK_ARG(env, value);
2036
2037 auto nativeValue = LocalValueFromJsValue(value);
2038 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBuffer(), napi_status::napi_arraybuffer_expected);
2039 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2040 Local<panda::BufferRef> res = nativeValue->ToObject(vm);
2041 *data = res->GetBuffer();
2042 *length = res->ByteLength(vm);
2043
2044 return napi_clear_last_error(env);
2045 }
2046
napi_object_freeze(napi_env env,napi_value object)2047 NAPI_EXTERN napi_status napi_object_freeze(napi_env env, napi_value object)
2048 {
2049 NAPI_PREAMBLE(env);
2050 CHECK_ARG(env, object);
2051
2052 auto nativeValue = LocalValueFromJsValue(object);
2053 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(), napi_object_expected);
2054 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2055 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
2056 obj->Freeze(vm);
2057
2058 return GET_RETURN_STATUS(env);
2059 }
2060
napi_object_seal(napi_env env,napi_value object)2061 NAPI_EXTERN napi_status napi_object_seal(napi_env env, napi_value object)
2062 {
2063 NAPI_PREAMBLE(env);
2064 CHECK_ARG(env, object);
2065
2066 auto nativeValue = LocalValueFromJsValue(object);
2067 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(), napi_object_expected);
2068 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2069 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
2070 obj->Seal(vm);
2071
2072 return GET_RETURN_STATUS(env);
2073 }
2074
2075 EXTERN_C_END
2076
napi_create_typedarray(napi_env env,napi_typedarray_type type,size_t length,napi_value arraybuffer,size_t byte_offset,napi_value * result)2077 NAPI_EXTERN napi_status napi_create_typedarray(napi_env env,
2078 napi_typedarray_type type,
2079 size_t length,
2080 napi_value arraybuffer,
2081 size_t byte_offset,
2082 napi_value* result)
2083 {
2084 NAPI_PREAMBLE(env);
2085 CHECK_ARG(env, arraybuffer);
2086 CHECK_ARG(env, result);
2087
2088 auto value = LocalValueFromJsValue(arraybuffer);
2089 auto typedArrayType = (NativeTypedArrayType)type;
2090 RETURN_STATUS_IF_FALSE(env, value->IsArrayBuffer(), napi_status::napi_arraybuffer_expected);
2091 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2092 Local<panda::ArrayBufferRef> arrayBuf = value->ToObject(vm);
2093 Local<panda::TypedArrayRef> typedArray(panda::JSValueRef::Undefined(vm));
2094
2095 switch (typedArrayType) {
2096 case NATIVE_INT8_ARRAY:
2097 typedArray = panda::Int8ArrayRef::New(vm, arrayBuf, byte_offset, length);
2098 break;
2099 case NATIVE_UINT8_ARRAY:
2100 typedArray = panda::Uint8ArrayRef::New(vm, arrayBuf, byte_offset, length);
2101 break;
2102 case NATIVE_UINT8_CLAMPED_ARRAY:
2103 typedArray = panda::Uint8ClampedArrayRef::New(vm, arrayBuf, byte_offset, length);
2104 break;
2105 case NATIVE_INT16_ARRAY:
2106 typedArray = panda::Int16ArrayRef::New(vm, arrayBuf, byte_offset, length);
2107 break;
2108 case NATIVE_UINT16_ARRAY:
2109 typedArray = panda::Uint16ArrayRef::New(vm, arrayBuf, byte_offset, length);
2110 break;
2111 case NATIVE_INT32_ARRAY:
2112 typedArray = panda::Int32ArrayRef::New(vm, arrayBuf, byte_offset, length);
2113 break;
2114 case NATIVE_UINT32_ARRAY:
2115 typedArray = panda::Uint32ArrayRef::New(vm, arrayBuf, byte_offset, length);
2116 break;
2117 case NATIVE_FLOAT32_ARRAY:
2118 typedArray = panda::Float32ArrayRef::New(vm, arrayBuf, byte_offset, length);
2119 break;
2120 case NATIVE_FLOAT64_ARRAY:
2121 typedArray = panda::Float64ArrayRef::New(vm, arrayBuf, byte_offset, length);
2122 break;
2123 case NATIVE_BIGINT64_ARRAY:
2124 typedArray = panda::BigInt64ArrayRef::New(vm, arrayBuf, byte_offset, length);
2125 break;
2126 case NATIVE_BIGUINT64_ARRAY:
2127 typedArray = panda::BigUint64ArrayRef::New(vm, arrayBuf, byte_offset, length);
2128 break;
2129 default:
2130 *result = nullptr;
2131 return napi_set_last_error(env, napi_invalid_arg);
2132 }
2133 *result = JsValueFromLocalValue(typedArray);
2134 return GET_RETURN_STATUS(env);
2135 }
2136
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)2137 NAPI_EXTERN napi_status napi_get_typedarray_info(napi_env env,
2138 napi_value typedarray,
2139 napi_typedarray_type* type,
2140 size_t* length,
2141 void** data,
2142 napi_value* arraybuffer,
2143 size_t* byte_offset)
2144 {
2145 CHECK_ENV(env);
2146 CHECK_ARG(env, typedarray);
2147
2148 auto value = LocalValueFromJsValue(typedarray);
2149 RETURN_STATUS_IF_FALSE(env, value->IsTypedArray(), napi_status::napi_invalid_arg);
2150 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2151 Local<panda::TypedArrayRef> typedArray = value->ToObject(vm);
2152 if (type != nullptr) {
2153 NativeTypedArrayType thisType = NATIVE_INT8_ARRAY;
2154 if (typedArray->IsInt8Array()) {
2155 thisType = NATIVE_INT8_ARRAY;
2156 } else if (typedArray->IsUint8Array()) {
2157 thisType = NATIVE_UINT8_ARRAY;
2158 } else if (typedArray->IsUint8ClampedArray()) {
2159 thisType = NATIVE_UINT8_CLAMPED_ARRAY;
2160 } else if (typedArray->IsInt16Array()) {
2161 thisType = NATIVE_INT16_ARRAY;
2162 } else if (typedArray->IsUint16Array()) {
2163 thisType = NATIVE_UINT16_ARRAY;
2164 } else if (typedArray->IsInt32Array()) {
2165 thisType = NATIVE_INT32_ARRAY;
2166 } else if (typedArray->IsUint32Array()) {
2167 thisType = NATIVE_UINT32_ARRAY;
2168 } else if (typedArray->IsFloat32Array()) {
2169 thisType = NATIVE_FLOAT32_ARRAY;
2170 } else if (typedArray->IsFloat64Array()) {
2171 thisType = NATIVE_FLOAT64_ARRAY;
2172 } else if (typedArray->IsBigInt64Array()) {
2173 thisType = NATIVE_BIGINT64_ARRAY;
2174 } else if (typedArray->IsBigUint64Array()) {
2175 thisType = NATIVE_BIGUINT64_ARRAY;
2176 }
2177 *type = (napi_typedarray_type)(thisType);
2178 }
2179 if (length != nullptr) {
2180 *length = typedArray->ByteLength(vm);
2181 }
2182 if (data != nullptr) {
2183 *data = static_cast<uint8_t*>(typedArray->GetArrayBuffer(vm)->GetBuffer()) + typedArray->ByteOffset(vm);
2184 }
2185 if (arraybuffer != nullptr) {
2186 *arraybuffer = JsValueFromLocalValue(typedArray->GetArrayBuffer(vm));
2187 }
2188 if (byte_offset != nullptr) {
2189 *byte_offset = typedArray->ByteOffset(vm);
2190 }
2191
2192 return napi_clear_last_error(env);
2193 }
2194
napi_create_dataview(napi_env env,size_t length,napi_value arraybuffer,size_t byte_offset,napi_value * result)2195 NAPI_EXTERN napi_status napi_create_dataview(napi_env env,
2196 size_t length,
2197 napi_value arraybuffer,
2198 size_t byte_offset,
2199 napi_value* result)
2200 {
2201 NAPI_PREAMBLE(env);
2202 CHECK_ARG(env, arraybuffer);
2203 CHECK_ARG(env, result);
2204
2205 auto arrayBufferValue = LocalValueFromJsValue(arraybuffer);
2206 RETURN_STATUS_IF_FALSE(env, arrayBufferValue->IsArrayBuffer(), napi_status::napi_arraybuffer_expected);
2207 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2208 Local<panda::ArrayBufferRef> res = arrayBufferValue->ToObject(vm);
2209 if (length + byte_offset > static_cast<size_t>(res->ByteLength(vm))) {
2210 napi_throw_range_error(
2211 env,
2212 "ERR_NAPI_INVALID_DATAVIEW_ARGS",
2213 "byte_offset + byte_length should be less than or "
2214 "equal to the size in bytes of the array passed in");
2215 return napi_set_last_error(env, napi_pending_exception);
2216 }
2217
2218 Local<panda::DataViewRef> dataView = panda::DataViewRef::New(vm, res, byte_offset, length);
2219 *result = JsValueFromLocalValue(dataView);
2220 return GET_RETURN_STATUS(env);
2221 }
2222
napi_is_dataview(napi_env env,napi_value value,bool * result)2223 NAPI_EXTERN napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
2224 {
2225 CHECK_ENV(env);
2226 CHECK_ARG(env, value);
2227 CHECK_ARG(env, result);
2228
2229 auto nativeValue = LocalValueFromJsValue(value);
2230 *result = nativeValue->IsDataView();
2231
2232 return napi_clear_last_error(env);
2233 }
2234
napi_get_dataview_info(napi_env env,napi_value dataview,size_t * bytelength,void ** data,napi_value * arraybuffer,size_t * byte_offset)2235 NAPI_EXTERN napi_status napi_get_dataview_info(napi_env env,
2236 napi_value dataview,
2237 size_t* bytelength,
2238 void** data,
2239 napi_value* arraybuffer,
2240 size_t* byte_offset)
2241 {
2242 CHECK_ENV(env);
2243 CHECK_ARG(env, dataview);
2244
2245 auto nativeValue = LocalValueFromJsValue(dataview);
2246 RETURN_STATUS_IF_FALSE(env, nativeValue->IsDataView(), napi_status::napi_invalid_arg);
2247 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2248 Local<panda::DataViewRef> dataViewObj = nativeValue->ToObject(vm);
2249 if (bytelength != nullptr) {
2250 *bytelength = dataViewObj->ByteLength();
2251 }
2252 if (data != nullptr) {
2253 *data = dataViewObj->GetArrayBuffer(vm)->GetBuffer();
2254 }
2255 if (arraybuffer != nullptr) {
2256 *arraybuffer = JsValueFromLocalValue(dataViewObj->GetArrayBuffer(vm));
2257 }
2258 if (byte_offset != nullptr) {
2259 *byte_offset = dataViewObj->ByteOffset();
2260 }
2261
2262 return napi_clear_last_error(env);
2263 }
2264
2265 // version management
napi_get_version(napi_env env,uint32_t * result)2266 NAPI_EXTERN napi_status napi_get_version(napi_env env, uint32_t* result)
2267 {
2268 CHECK_ENV(env);
2269 CHECK_ARG(env, result);
2270
2271 *result = NAPI_VERSION;
2272 return napi_clear_last_error(env);
2273 }
2274
2275 // Promises
napi_create_promise(napi_env env,napi_deferred * deferred,napi_value * promise)2276 NAPI_EXTERN napi_status napi_create_promise(napi_env env, napi_deferred* deferred, napi_value* promise)
2277 {
2278 NAPI_PREAMBLE(env);
2279 CHECK_ARG(env, deferred);
2280 CHECK_ARG(env, promise);
2281
2282 auto engine = reinterpret_cast<NativeEngine*>(env);
2283 auto resultValue = engine->CreatePromise(reinterpret_cast<NativeDeferred**>(deferred));
2284 *promise = resultValue;
2285
2286 return GET_RETURN_STATUS(env);
2287 }
2288
napi_resolve_deferred(napi_env env,napi_deferred deferred,napi_value resolution)2289 NAPI_EXTERN napi_status napi_resolve_deferred(napi_env env, napi_deferred deferred, napi_value resolution)
2290 {
2291 NAPI_PREAMBLE(env);
2292 CHECK_ARG(env, deferred);
2293 CHECK_ARG(env, resolution);
2294
2295 auto nativeDeferred = reinterpret_cast<NativeDeferred*>(deferred);
2296 nativeDeferred->Resolve(resolution);
2297 delete nativeDeferred;
2298 return GET_RETURN_STATUS(env);
2299 }
2300
napi_reject_deferred(napi_env env,napi_deferred deferred,napi_value rejection)2301 NAPI_EXTERN napi_status napi_reject_deferred(napi_env env, napi_deferred deferred, napi_value rejection)
2302 {
2303 NAPI_PREAMBLE(env);
2304 CHECK_ARG(env, deferred);
2305 CHECK_ARG(env, rejection);
2306
2307 auto nativeDeferred = reinterpret_cast<NativeDeferred*>(deferred);
2308 nativeDeferred->Reject(rejection);
2309 delete nativeDeferred;
2310 return GET_RETURN_STATUS(env);
2311 }
2312
napi_is_promise(napi_env env,napi_value value,bool * is_promise)2313 NAPI_EXTERN napi_status napi_is_promise(napi_env env, napi_value value, bool* is_promise)
2314 {
2315 CHECK_ENV(env);
2316 CHECK_ARG(env, value);
2317 CHECK_ARG(env, is_promise);
2318
2319 auto nativeValue = LocalValueFromJsValue(value);
2320 *is_promise = nativeValue->IsPromise();
2321
2322 return napi_clear_last_error(env);
2323 }
2324
2325 // promise reject events
napi_set_promise_rejection_callback(napi_env env,napi_ref ref,napi_ref checkRef)2326 NAPI_EXTERN napi_status napi_set_promise_rejection_callback(napi_env env, napi_ref ref, napi_ref checkRef)
2327 {
2328 CHECK_ENV(env);
2329 CHECK_ARG(env, ref);
2330 CHECK_ARG(env, checkRef);
2331
2332 auto rejectCallbackRef = reinterpret_cast<NativeReference*>(ref);
2333 auto checkCallbackRef = reinterpret_cast<NativeReference*>(checkRef);
2334 if (rejectCallbackRef == nullptr || checkCallbackRef == nullptr) {
2335 HILOG_ERROR("rejectCallbackRef or checkCallbackRef is nullptr");
2336 } else {
2337 auto engine = reinterpret_cast<NativeEngine*>(env);
2338 auto vm = const_cast<EcmaVM*>(engine->GetEcmaVm());
2339 engine->SetPromiseRejectCallBackRef(rejectCallbackRef);
2340 engine->SetCheckCallbackRef(checkCallbackRef);
2341 panda::JSNApi::SetHostPromiseRejectionTracker(const_cast<EcmaVM*>(vm), engine->GetPromiseRejectCallback(),
2342 reinterpret_cast<void*>(engine));
2343 }
2344
2345 return napi_clear_last_error(env);
2346 }
2347
2348 // Running a script
napi_run_script(napi_env env,napi_value script,napi_value * result)2349 NAPI_EXTERN napi_status napi_run_script(napi_env env, napi_value script, napi_value* result)
2350 {
2351 CHECK_ENV(env);
2352 CHECK_ARG(env, script);
2353 CHECK_ARG(env, result);
2354
2355 *result = nullptr;
2356 return napi_clear_last_error(env);
2357 }
2358
2359 // Runnint a buffer script, only used in ark
napi_run_buffer_script(napi_env env,std::vector<uint8_t> & buffer,napi_value * result)2360 NAPI_EXTERN napi_status napi_run_buffer_script(napi_env env, std::vector<uint8_t>& buffer, napi_value* result)
2361 {
2362 NAPI_PREAMBLE(env);
2363 CHECK_ARG(env, result);
2364
2365 auto engine = reinterpret_cast<NativeEngine*>(env);
2366 auto vm = const_cast<EcmaVM*>(engine->GetEcmaVm());
2367 [[maybe_unused]] bool ret = panda::JSNApi::Execute(vm, buffer.data(), buffer.size(), PANDA_MAIN_FUNCTION);
2368 if (panda::JSNApi::HasPendingException(vm)) {
2369 if (engine->GetNapiUncaughtExceptionCallback() != nullptr) {
2370 LocalScope scope(vm);
2371 Local<ObjectRef> exception = panda::JSNApi::GetAndClearUncaughtException(vm);
2372 auto value = JsValueFromLocalValue(exception);
2373 if (!exception.IsEmpty() && !exception->IsHole()) {
2374 engine->GetNapiUncaughtExceptionCallback()(value);
2375 }
2376 }
2377 *result = nullptr;
2378 }
2379
2380 Local<PrimitiveRef> value = panda::JSValueRef::Undefined(vm);
2381 *result = JsValueFromLocalValue(value);
2382 return GET_RETURN_STATUS(env);
2383 }
2384
napi_run_actor(napi_env env,std::vector<uint8_t> & buffer,const char * descriptor,napi_value * result,char * entryPoint)2385 NAPI_EXTERN napi_status napi_run_actor(napi_env env,
2386 std::vector<uint8_t>& buffer,
2387 const char* descriptor,
2388 napi_value* result,
2389 char* entryPoint)
2390 {
2391 NAPI_PREAMBLE(env);
2392 CHECK_ARG(env, result);
2393
2394 auto engine = reinterpret_cast<NativeEngine*>(env);
2395 *result = engine->RunActor(buffer, descriptor, entryPoint);
2396 return GET_RETURN_STATUS(env);
2397 }
2398
napi_load_module(napi_env env,const char * path,napi_value * result)2399 NAPI_EXTERN napi_status napi_load_module(napi_env env, const char* path, napi_value* result)
2400 {
2401 CHECK_ENV(env);
2402 CHECK_ARG(env, result);
2403
2404 auto engine = reinterpret_cast<NativeEngine*>(env);
2405 *result = engine->NapiLoadModule(path);
2406 return napi_clear_last_error(env);
2407 }
2408
2409 // Memory management
napi_adjust_external_memory(napi_env env,int64_t change_in_bytes,int64_t * adjusted_value)2410 NAPI_INNER_EXTERN napi_status napi_adjust_external_memory(
2411 napi_env env, int64_t change_in_bytes, int64_t* adjusted_value)
2412 {
2413 CHECK_ENV(env);
2414 CHECK_ARG(env, adjusted_value);
2415
2416 auto engine = reinterpret_cast<NativeEngine*>(env);
2417 engine->AdjustExternalMemory(change_in_bytes, adjusted_value);
2418
2419 return napi_clear_last_error(env);
2420 }
2421
napi_is_callable(napi_env env,napi_value value,bool * result)2422 NAPI_EXTERN napi_status napi_is_callable(napi_env env, napi_value value, bool* result)
2423 {
2424 CHECK_ENV(env);
2425 CHECK_ARG(env, value);
2426 CHECK_ARG(env, result);
2427
2428 auto nativeValue = LocalValueFromJsValue(value);
2429 *result = nativeValue->IsFunction();
2430
2431 return napi_clear_last_error(env);
2432 }
2433
napi_is_arguments_object(napi_env env,napi_value value,bool * result)2434 NAPI_EXTERN napi_status napi_is_arguments_object(napi_env env, napi_value value, bool* result)
2435 {
2436 CHECK_ENV(env);
2437 CHECK_ARG(env, value);
2438 CHECK_ARG(env, result);
2439
2440 auto nativeValue = LocalValueFromJsValue(value);
2441 *result = nativeValue->IsArgumentsObject();
2442
2443 return napi_clear_last_error(env);
2444 }
2445
napi_is_async_function(napi_env env,napi_value value,bool * result)2446 NAPI_EXTERN napi_status napi_is_async_function(napi_env env, napi_value value, bool* result)
2447 {
2448 CHECK_ENV(env);
2449 CHECK_ARG(env, value);
2450 CHECK_ARG(env, result);
2451
2452 auto nativeValue = LocalValueFromJsValue(value);
2453 *result = nativeValue->IsAsyncFunction();
2454 return napi_clear_last_error(env);
2455 }
2456
napi_is_boolean_object(napi_env env,napi_value value,bool * result)2457 NAPI_EXTERN napi_status napi_is_boolean_object(napi_env env, napi_value value, bool* result)
2458 {
2459 CHECK_ENV(env);
2460 CHECK_ARG(env, value);
2461 CHECK_ARG(env, result);
2462
2463 auto nativeValue = LocalValueFromJsValue(value);
2464 *result = nativeValue->IsJSPrimitiveBoolean();
2465
2466 return napi_clear_last_error(env);
2467 }
2468
napi_is_generator_function(napi_env env,napi_value value,bool * result)2469 NAPI_EXTERN napi_status napi_is_generator_function(napi_env env, napi_value value, bool* result)
2470 {
2471 CHECK_ENV(env);
2472 CHECK_ARG(env, value);
2473 CHECK_ARG(env, result);
2474
2475 auto nativeValue = LocalValueFromJsValue(value);
2476 *result = nativeValue->IsGeneratorFunction();
2477
2478 return napi_clear_last_error(env);
2479 }
2480
napi_is_map_iterator(napi_env env,napi_value value,bool * result)2481 NAPI_EXTERN napi_status napi_is_map_iterator(napi_env env, napi_value value, bool* result)
2482 {
2483 CHECK_ENV(env);
2484 CHECK_ARG(env, value);
2485 CHECK_ARG(env, result);
2486
2487 auto nativeValue = LocalValueFromJsValue(value);
2488 *result = nativeValue->IsMapIterator();
2489
2490 return napi_clear_last_error(env);
2491 }
2492
napi_is_set_iterator(napi_env env,napi_value value,bool * result)2493 NAPI_EXTERN napi_status napi_is_set_iterator(napi_env env, napi_value value, bool* result)
2494 {
2495 CHECK_ENV(env);
2496 CHECK_ARG(env, value);
2497 CHECK_ARG(env, result);
2498
2499 auto nativeValue = LocalValueFromJsValue(value);
2500 *result = nativeValue->IsSetIterator();
2501
2502 return napi_clear_last_error(env);
2503 }
2504
napi_is_generator_object(napi_env env,napi_value value,bool * result)2505 NAPI_EXTERN napi_status napi_is_generator_object(napi_env env, napi_value value, bool* result)
2506 {
2507 CHECK_ENV(env);
2508 CHECK_ARG(env, value);
2509 CHECK_ARG(env, result);
2510
2511 auto nativeValue = LocalValueFromJsValue(value);
2512 *result = nativeValue->IsGeneratorObject();
2513
2514 return napi_clear_last_error(env);
2515 }
2516
napi_is_module_namespace_object(napi_env env,napi_value value,bool * result)2517 NAPI_EXTERN napi_status napi_is_module_namespace_object(napi_env env, napi_value value, bool* result)
2518 {
2519 CHECK_ENV(env);
2520 CHECK_ARG(env, value);
2521 CHECK_ARG(env, result);
2522
2523 auto nativeValue = LocalValueFromJsValue(value);
2524 *result = nativeValue->IsModuleNamespaceObject();
2525
2526 return napi_clear_last_error(env);
2527 }
2528
napi_is_proxy(napi_env env,napi_value value,bool * result)2529 NAPI_EXTERN napi_status napi_is_proxy(napi_env env, napi_value value, bool* result)
2530 {
2531 CHECK_ENV(env);
2532 CHECK_ARG(env, value);
2533 CHECK_ARG(env, result);
2534
2535 auto nativeValue = LocalValueFromJsValue(value);
2536 *result = nativeValue->IsProxy();
2537 return napi_clear_last_error(env);
2538 }
2539
napi_is_reg_exp(napi_env env,napi_value value,bool * result)2540 NAPI_EXTERN napi_status napi_is_reg_exp(napi_env env, napi_value value, bool* result)
2541 {
2542 CHECK_ENV(env);
2543 CHECK_ARG(env, value);
2544 CHECK_ARG(env, result);
2545
2546 auto nativeValue = LocalValueFromJsValue(value);
2547 *result = nativeValue->IsRegExp();
2548 return napi_clear_last_error(env);
2549 }
2550
napi_is_number_object(napi_env env,napi_value value,bool * result)2551 NAPI_EXTERN napi_status napi_is_number_object(napi_env env, napi_value value, bool* result)
2552 {
2553 CHECK_ENV(env);
2554 CHECK_ARG(env, value);
2555 CHECK_ARG(env, result);
2556
2557 auto nativeValue = LocalValueFromJsValue(value);
2558 *result = nativeValue->IsJSPrimitiveNumber();
2559
2560 return napi_clear_last_error(env);
2561 }
2562
napi_is_map(napi_env env,napi_value value,bool * result)2563 NAPI_EXTERN napi_status napi_is_map(napi_env env, napi_value value, bool* result)
2564 {
2565 CHECK_ENV(env);
2566 CHECK_ARG(env, value);
2567 CHECK_ARG(env, result);
2568
2569 auto nativeValue = LocalValueFromJsValue(value);
2570 *result = nativeValue->IsMap();
2571 return napi_clear_last_error(env);
2572 }
2573
napi_is_set(napi_env env,napi_value value,bool * result)2574 NAPI_EXTERN napi_status napi_is_set(napi_env env, napi_value value, bool* result)
2575 {
2576 CHECK_ENV(env);
2577 CHECK_ARG(env, value);
2578 CHECK_ARG(env, result);
2579
2580 auto nativeValue = LocalValueFromJsValue(value);
2581 *result = nativeValue->IsSet();
2582 return napi_clear_last_error(env);
2583 }
2584
napi_is_string_object(napi_env env,napi_value value,bool * result)2585 NAPI_EXTERN napi_status napi_is_string_object(napi_env env, napi_value value, bool* result)
2586 {
2587 CHECK_ENV(env);
2588 CHECK_ARG(env, value);
2589 CHECK_ARG(env, result);
2590
2591 auto nativeValue = LocalValueFromJsValue(value);
2592 *result = nativeValue->IsJSPrimitiveString();
2593
2594 return napi_clear_last_error(env);
2595 }
2596
napi_is_symbol_object(napi_env env,napi_value value,bool * result)2597 NAPI_EXTERN napi_status napi_is_symbol_object(napi_env env, napi_value value, bool* result)
2598 {
2599 CHECK_ENV(env);
2600 CHECK_ARG(env, value);
2601 CHECK_ARG(env, result);
2602
2603 auto nativeValue = LocalValueFromJsValue(value);
2604 *result = nativeValue->IsJSPrimitiveSymbol();
2605 return napi_clear_last_error(env);
2606 }
2607
napi_is_weak_map(napi_env env,napi_value value,bool * result)2608 NAPI_EXTERN napi_status napi_is_weak_map(napi_env env, napi_value value, bool* result)
2609 {
2610 CHECK_ENV(env);
2611 CHECK_ARG(env, value);
2612 CHECK_ARG(env, result);
2613
2614 auto nativeValue = LocalValueFromJsValue(value);
2615 *result = nativeValue->IsWeakMap();
2616 return napi_clear_last_error(env);
2617 }
2618
napi_is_weak_set(napi_env env,napi_value value,bool * result)2619 NAPI_EXTERN napi_status napi_is_weak_set(napi_env env, napi_value value, bool* result)
2620 {
2621 CHECK_ENV(env);
2622 CHECK_ARG(env, value);
2623 CHECK_ARG(env, result);
2624
2625 auto nativeValue = LocalValueFromJsValue(value);
2626 *result = nativeValue->IsWeakSet();
2627 return napi_clear_last_error(env);
2628 }
2629
napi_create_runtime(napi_env env,napi_env * result_env)2630 NAPI_EXTERN napi_status napi_create_runtime(napi_env env, napi_env* result_env)
2631 {
2632 CHECK_ENV(env);
2633 CHECK_ARG(env, result_env);
2634
2635 auto engine = reinterpret_cast<NativeEngine*>(env);
2636 auto result = engine->CreateRuntime();
2637 *result_env = reinterpret_cast<napi_env>(result);
2638
2639 return napi_clear_last_error(env);
2640 }
2641
napi_serialize(napi_env env,napi_value object,napi_value transfer_list,napi_value clone_list,bool defaultTransfer,bool defaultCloneSendable,napi_value * result)2642 NAPI_EXTERN napi_status napi_serialize(napi_env env, napi_value object, napi_value transfer_list,
2643 napi_value clone_list, bool defaultTransfer, bool defaultCloneSendable,
2644 napi_value* result)
2645 {
2646 CHECK_ENV(env);
2647 CHECK_ARG(env, object);
2648 CHECK_ARG(env, transfer_list);
2649 CHECK_ARG(env, result);
2650
2651 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2652 auto nativeValue = LocalValueFromJsValue(object);
2653 auto transferList = LocalValueFromJsValue(transfer_list);
2654 auto cloneList = LocalValueFromJsValue(clone_list);
2655 void* res =
2656 panda::JSNApi::SerializeValue(vm, nativeValue, transferList, cloneList, defaultTransfer, defaultCloneSendable);
2657 *result = reinterpret_cast<napi_value>(res);
2658
2659 return napi_clear_last_error(env);
2660 }
2661
napi_deserialize(napi_env env,napi_value recorder,napi_value * object)2662 NAPI_EXTERN napi_status napi_deserialize(napi_env env, napi_value recorder, napi_value* object)
2663 {
2664 CHECK_ENV(env);
2665 CHECK_ARG(env, recorder);
2666 CHECK_ARG(env, object);
2667
2668 auto engine = reinterpret_cast<NativeEngine*>(env);
2669 auto vm = engine->GetEcmaVm();
2670 auto recorderValue = reinterpret_cast<void*>(recorder);
2671 Local<panda::JSValueRef> res = panda::JSNApi::DeserializeValue(vm, recorderValue, reinterpret_cast<void*>(engine));
2672 *object = JsValueFromLocalValue(res);
2673
2674 return napi_clear_last_error(env);
2675 }
2676
napi_delete_serialization_data(napi_env env,napi_value value)2677 NAPI_EXTERN napi_status napi_delete_serialization_data(napi_env env, napi_value value)
2678 {
2679 CHECK_ENV(env);
2680 CHECK_ARG(env, value);
2681
2682 void* data = reinterpret_cast<void*>(value);
2683 panda::JSNApi::DeleteSerializationData(data);
2684
2685 return napi_clear_last_error(env);
2686 }
2687
napi_create_bigint_int64(napi_env env,int64_t value,napi_value * result)2688 NAPI_EXTERN napi_status napi_create_bigint_int64(napi_env env, int64_t value, napi_value* result)
2689 {
2690 CHECK_ENV(env);
2691 CHECK_ARG(env, result);
2692
2693 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2694 Local<panda::BigIntRef> object = panda::BigIntRef::New(vm, value);
2695 *result = JsValueFromLocalValue(object);
2696
2697 return napi_clear_last_error(env);
2698 }
2699
napi_create_bigint_uint64(napi_env env,uint64_t value,napi_value * result)2700 NAPI_EXTERN napi_status napi_create_bigint_uint64(napi_env env, uint64_t value, napi_value* result)
2701 {
2702 CHECK_ENV(env);
2703 CHECK_ARG(env, result);
2704
2705 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2706 Local<panda::BigIntRef> object = panda::BigIntRef::New(vm, value);
2707 *result = JsValueFromLocalValue(object);
2708
2709 return napi_clear_last_error(env);
2710 }
2711
napi_get_value_bigint_int64(napi_env env,napi_value value,int64_t * result,bool * lossless)2712 NAPI_EXTERN napi_status napi_get_value_bigint_int64(
2713 napi_env env, napi_value value, int64_t* result, bool* lossless)
2714 {
2715 CHECK_ENV(env);
2716 CHECK_ARG(env, value);
2717 CHECK_ARG(env, result);
2718 CHECK_ARG(env, lossless);
2719
2720 auto nativeValue = LocalValueFromJsValue(value);
2721 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBigInt(), napi_bigint_expected);
2722 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2723 Local<panda::BigIntRef> bigIntVal = nativeValue->ToBigInt(vm);
2724 bigIntVal->BigIntToInt64(vm, result, lossless);
2725
2726 return napi_clear_last_error(env);
2727 }
2728
napi_get_value_bigint_uint64(napi_env env,napi_value value,uint64_t * result,bool * lossless)2729 NAPI_EXTERN napi_status napi_get_value_bigint_uint64(
2730 napi_env env, napi_value value, uint64_t* result, bool* lossless)
2731 {
2732 CHECK_ENV(env);
2733 CHECK_ARG(env, value);
2734 CHECK_ARG(env, result);
2735 CHECK_ARG(env, lossless);
2736
2737 auto nativeValue = LocalValueFromJsValue(value);
2738 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBigInt(), napi_bigint_expected);
2739 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2740 Local<panda::BigIntRef> bigIntVal = nativeValue->ToBigInt(vm);
2741 bigIntVal->BigIntToUint64(vm, result, lossless);
2742
2743 return napi_clear_last_error(env);
2744 }
2745
napi_is_date(napi_env env,napi_value value,bool * result)2746 NAPI_EXTERN napi_status napi_is_date(napi_env env, napi_value value, bool* result)
2747 {
2748 CHECK_ENV(env);
2749 CHECK_ARG(env, value);
2750 CHECK_ARG(env, result);
2751
2752 auto nativeValue = LocalValueFromJsValue(value);
2753 *result = nativeValue->IsDate();
2754 return napi_clear_last_error(env);
2755 }
2756
napi_is_detached_arraybuffer(napi_env env,napi_value arraybuffer,bool * result)2757 NAPI_EXTERN napi_status napi_is_detached_arraybuffer(napi_env env, napi_value arraybuffer, bool* result)
2758 {
2759 CHECK_ENV(env);
2760 CHECK_ARG(env, arraybuffer);
2761 CHECK_ARG(env, result);
2762
2763 auto nativeValue = LocalValueFromJsValue(arraybuffer);
2764 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2765 auto isArrayBuffer = nativeValue->IsArrayBuffer();
2766 Local<panda::ArrayBufferRef> bufObj = nativeValue->ToObject(vm);
2767 if (isArrayBuffer) {
2768 *result = bufObj->IsDetach();
2769 } else {
2770 return napi_set_last_error(env, napi_invalid_arg);
2771 }
2772 return napi_clear_last_error(env);
2773 }
2774
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)2775 NAPI_EXTERN napi_status napi_get_all_property_names(
2776 napi_env env, napi_value object, napi_key_collection_mode key_mode,
2777 napi_key_filter key_filter, napi_key_conversion key_conversion, napi_value* result)
2778 {
2779 NAPI_PREAMBLE(env);
2780 CHECK_ARG(env, object);
2781 CHECK_ARG(env, result);
2782
2783 auto nativeValue = LocalValueFromJsValue(object);
2784 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject() || nativeValue->IsFunction(), napi_object_expected);
2785 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2786 Local<panda::ObjectRef> obj = nativeValue->ToObject(vm);
2787 uint32_t filter = NATIVE_DEFAULT;
2788 if (key_filter & napi_key_writable) {
2789 filter = static_cast<uint32_t>(filter | NATIVE_WRITABLE);
2790 }
2791 if (key_filter & napi_key_enumerable) {
2792 filter = static_cast<uint32_t>(filter | NATIVE_ENUMERABLE);
2793 }
2794 if (key_filter & napi_key_configurable) {
2795 filter = static_cast<uint32_t>(filter | NATIVE_CONFIGURABLE);
2796 }
2797 if (key_filter & napi_key_skip_strings) {
2798 filter = static_cast<uint32_t>(filter | NATIVE_KEY_SKIP_STRINGS);
2799 }
2800 if (key_filter & napi_key_skip_symbols) {
2801 filter = static_cast<uint32_t>(filter | NATIVE_KEY_SKIP_SYMBOLS);
2802 }
2803
2804 switch (key_mode) {
2805 case napi_key_include_prototypes:
2806 filter = static_cast<uint32_t>(filter | NATIVE_KEY_INCLUDE_PROTOTYPES);
2807 break;
2808 case napi_key_own_only:
2809 filter = static_cast<uint32_t>(filter | NATIVE_KEY_OWN_ONLY);
2810 break;
2811 default:
2812 *result = nullptr;
2813 return napi_set_last_error(env, napi_invalid_arg);
2814 }
2815
2816 switch (key_conversion) {
2817 case napi_key_keep_numbers:
2818 filter = static_cast<uint32_t>(filter | NATIVE_KEY_KEEP_NUMBERS);
2819 break;
2820 case napi_key_numbers_to_strings:
2821 filter = static_cast<uint32_t>(filter | NATIVE_KEY_NUMBERS_TO_STRINGS);
2822 break;
2823 default:
2824 *result = nullptr;
2825 return napi_set_last_error(env, napi_invalid_arg);
2826 }
2827 Local<panda::ArrayRef> arrayVal = obj->GetAllPropertyNames(vm, filter);
2828 *result = JsValueFromLocalValue(arrayVal);
2829 return GET_RETURN_STATUS(env);
2830 }
2831
napi_detach_arraybuffer(napi_env env,napi_value arraybuffer)2832 NAPI_EXTERN napi_status napi_detach_arraybuffer(napi_env env, napi_value arraybuffer)
2833 {
2834 CHECK_ENV(env);
2835 CHECK_ARG(env, arraybuffer);
2836
2837 auto nativeValue = LocalValueFromJsValue(arraybuffer);
2838 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(), napi_object_expected);
2839 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2840 auto isArrayBuffer = nativeValue->IsArrayBuffer();
2841 Local<panda::ArrayBufferRef> bufObj = nativeValue->ToObject(vm);
2842 if (isArrayBuffer) {
2843 if (!bufObj->IsDetach()) {
2844 bufObj->Detach(vm);
2845 }
2846 } else {
2847 return napi_set_last_error(env, napi_invalid_arg);
2848 }
2849 return napi_clear_last_error(env);
2850 }
2851
napi_type_tag_object(napi_env env,napi_value js_object,const napi_type_tag * type_tag)2852 NAPI_EXTERN napi_status napi_type_tag_object(napi_env env, napi_value js_object, const napi_type_tag* type_tag)
2853 {
2854 NAPI_PREAMBLE(env);
2855 CHECK_ARG(env, js_object);
2856 CHECK_ARG(env, type_tag);
2857
2858 auto nativeValue = LocalValueFromJsValue(js_object);
2859 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(), napi_object_expected);
2860 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2861 auto obj = nativeValue->ToObject(vm);
2862 NapiTypeTag* typeTag = (NapiTypeTag*)type_tag;
2863 const char name[] = "ACENAPI_TYPETAG";
2864 bool hasPribate = false;
2865 bool result = true;
2866 Local<panda::StringRef> key = StringRef::NewFromUtf8(vm, name);
2867 hasPribate = obj->Has(vm, key);
2868 if (!hasPribate) {
2869 constexpr int bigintMod = 2; // 2 : used for even number judgment
2870 int sign_bit = 0;
2871 size_t word_count = 2;
2872 bool sign = false;
2873 if ((sign_bit % bigintMod) == 1) {
2874 sign = true;
2875 }
2876 uint32_t size = (uint32_t)word_count;
2877 Local<panda::JSValueRef> value = panda::BigIntRef::CreateBigWords(vm, sign, size,
2878 reinterpret_cast<const uint64_t*>(typeTag));
2879 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, name);
2880 result = obj->Set(vm, key, value);
2881 }
2882 if (!result) {
2883 return napi_set_last_error(env, napi_invalid_arg);
2884 }
2885
2886 return napi_clear_last_error(env);
2887 }
2888
BigIntGetWordsArray(Local<panda::BigIntRef> & value,int * signBit,size_t * wordCount,uint64_t * words)2889 bool BigIntGetWordsArray(Local<panda::BigIntRef> &value, int* signBit, size_t* wordCount, uint64_t* words)
2890 {
2891 if (wordCount == nullptr) {
2892 return false;
2893 }
2894 size_t size = static_cast<size_t>(value->GetWordsArraySize());
2895 if (signBit == nullptr && words == nullptr) {
2896 *wordCount = size;
2897 return true;
2898 } else if (signBit != nullptr && words != nullptr) {
2899 if (size > *wordCount) {
2900 size = *wordCount;
2901 }
2902 bool sign = false;
2903 value->GetWordsArray(&sign, size, words);
2904 if (sign) {
2905 *signBit = 1;
2906 } else {
2907 *signBit = 0;
2908 }
2909 *wordCount = size;
2910 return true;
2911 }
2912 return false;
2913 }
2914
napi_check_object_type_tag(napi_env env,napi_value js_object,const napi_type_tag * type_tag,bool * result)2915 NAPI_EXTERN napi_status napi_check_object_type_tag(napi_env env,
2916 napi_value js_object,
2917 const napi_type_tag* type_tag,
2918 bool* result)
2919 {
2920 NAPI_PREAMBLE(env);
2921 CHECK_ARG(env, js_object);
2922 CHECK_ARG(env, type_tag);
2923 CHECK_ARG(env, result);
2924
2925 auto nativeValue = LocalValueFromJsValue(js_object);
2926 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(), napi_object_expected);
2927 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2928 auto obj = nativeValue->ToObject(vm);
2929 NapiTypeTag* typeTag = (NapiTypeTag*)type_tag;
2930 *result = false;
2931 const char name[] = "ACENAPI_TYPETAG";
2932
2933 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, name);
2934 *result = obj->Has(vm, key);
2935 if (*result) {
2936 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, name);
2937 Local<panda::JSValueRef> object = obj->Get(vm, key);
2938 if (object->IsBigInt()) {
2939 int sign;
2940 size_t size = 2; // 2: Indicates that the number of elements is 2
2941 NapiTypeTag tag;
2942 Local<panda::BigIntRef> bigintObj = object->ToBigInt(vm);
2943 BigIntGetWordsArray(bigintObj, &sign, &size, reinterpret_cast<uint64_t*>(&tag));
2944 if (sign == 0 && ((size == 1) || (size == 2))) { // 2: Indicates that the number of elements is 2
2945 *result = (tag.lower == typeTag->lower && tag.upper == typeTag->upper);
2946 }
2947 }
2948 }
2949 return napi_clear_last_error(env);
2950 }
2951
napi_create_date(napi_env env,double time,napi_value * result)2952 NAPI_EXTERN napi_status napi_create_date(napi_env env, double time, napi_value* result)
2953 {
2954 NAPI_PREAMBLE(env);
2955 CHECK_ARG(env, result);
2956
2957 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2958 *result = JsValueFromLocalValue(DateRef::New(vm, time));
2959
2960 return napi_clear_last_error(env);
2961 }
2962
napi_get_date_value(napi_env env,napi_value value,double * result)2963 NAPI_EXTERN napi_status napi_get_date_value(napi_env env, napi_value value, double* result)
2964 {
2965 NAPI_PREAMBLE(env);
2966 CHECK_ARG(env, value);
2967 CHECK_ARG(env, result);
2968
2969 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2970 auto nativeValue = LocalValueFromJsValue(value);
2971 auto IsDate_result = nativeValue->IsDate();
2972 Local<panda::DateRef> dateObj = nativeValue->ToObject(vm);
2973 if (IsDate_result) {
2974 *result = dateObj->GetTime();
2975 } else {
2976 return napi_set_last_error(env, napi_date_expected);
2977 }
2978
2979 return napi_clear_last_error(env);
2980 }
2981
napi_add_finalizer(napi_env env,napi_value js_object,void * native_object,napi_finalize finalize_cb,void * finalize_hint,napi_ref * result)2982 NAPI_EXTERN napi_status napi_add_finalizer(napi_env env,
2983 napi_value js_object,
2984 void* native_object,
2985 napi_finalize finalize_cb,
2986 void* finalize_hint,
2987 napi_ref* result)
2988 {
2989 CHECK_ENV(env);
2990 CHECK_ARG(env, js_object);
2991 CHECK_ARG(env, finalize_cb);
2992
2993 auto nativeValue = LocalValueFromJsValue(js_object);
2994 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
2995 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(), napi_object_expected);
2996 NativeReference* reference = nullptr;
2997 auto engine = reinterpret_cast<NativeEngine*>(env);
2998 if (result != nullptr) {
2999 reference = engine->CreateReference(js_object, 1, false, callback, native_object, finalize_hint);
3000 *result = reinterpret_cast<napi_ref>(reference);
3001 } else {
3002 reference = engine->CreateReference(js_object, 0, true, callback, native_object, finalize_hint);
3003 }
3004 return napi_clear_last_error(env);
3005 }
3006
napi_create_bigint_words(napi_env env,int sign_bit,size_t word_count,const uint64_t * words,napi_value * result)3007 NAPI_EXTERN napi_status napi_create_bigint_words(napi_env env,
3008 int sign_bit,
3009 size_t word_count,
3010 const uint64_t* words,
3011 napi_value* result)
3012 {
3013 NAPI_PREAMBLE(env);
3014 CHECK_ARG(env, words);
3015 CHECK_ARG(env, result);
3016 RETURN_STATUS_IF_FALSE(env, word_count <= INT_MAX, napi_invalid_arg);
3017
3018 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3019 constexpr int bigintMod = 2; // 2 : used for even number judgment
3020 bool sign = false;
3021 if ((sign_bit % bigintMod) == 1) {
3022 sign = true;
3023 }
3024 uint32_t size = (uint32_t)word_count;
3025 Local<panda::JSValueRef> value = panda::BigIntRef::CreateBigWords(vm, sign, size, words);
3026
3027 if (panda::JSNApi::HasPendingException(vm)) {
3028 return napi_set_last_error(env, napi_pending_exception);
3029 }
3030 *result = JsValueFromLocalValue(value);
3031 return GET_RETURN_STATUS(env);
3032 }
3033
napi_get_value_bigint_words(napi_env env,napi_value value,int * sign_bit,size_t * word_count,uint64_t * words)3034 NAPI_EXTERN napi_status napi_get_value_bigint_words(napi_env env,
3035 napi_value value,
3036 int* sign_bit,
3037 size_t* word_count,
3038 uint64_t* words)
3039 {
3040 CHECK_ENV(env);
3041 CHECK_ARG(env, value);
3042 CHECK_ARG(env, word_count);
3043
3044 auto nativeValue = LocalValueFromJsValue(value);
3045 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBigInt(), napi_object_expected);
3046 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3047 auto BigintObj = nativeValue->ToBigInt(vm);
3048 if (word_count == nullptr) {
3049 return napi_set_last_error(env, napi_invalid_arg);
3050 }
3051 size_t size = static_cast<size_t>(BigintObj->GetWordsArraySize());
3052 if (sign_bit == nullptr && words == nullptr) {
3053 *word_count = size;
3054 return napi_set_last_error(env, napi_ok);
3055 } else if (sign_bit != nullptr && words != nullptr) {
3056 if (size > *word_count) {
3057 size = *word_count;
3058 }
3059 bool sign = false;
3060 BigintObj->GetWordsArray(&sign, size, words);
3061 if (sign) {
3062 *sign_bit = 1;
3063 } else {
3064 *sign_bit = 0;
3065 }
3066 *word_count = size;
3067 return napi_set_last_error(env, napi_ok);
3068 }
3069
3070 return napi_clear_last_error(env);
3071 }
3072
napi_run_script_path(napi_env env,const char * path,napi_value * result)3073 NAPI_EXTERN napi_status napi_run_script_path(napi_env env, const char* path, napi_value* result)
3074 {
3075 NAPI_PREAMBLE(env);
3076 CHECK_ARG(env, result);
3077
3078 auto engine = reinterpret_cast<NativeEngine*>(env);
3079 *result = engine->RunScript(path);
3080 return GET_RETURN_STATUS(env);
3081 }
3082
napi_is_big_int64_array(napi_env env,napi_value value,bool * result)3083 NAPI_EXTERN napi_status napi_is_big_int64_array(napi_env env, napi_value value, bool* result)
3084 {
3085 CHECK_ENV(env);
3086 CHECK_ARG(env, value);
3087 CHECK_ARG(env, result);
3088
3089 auto nativeValue = LocalValueFromJsValue(value);
3090 *result = nativeValue->IsBigInt64Array();
3091 return napi_clear_last_error(env);
3092 }
3093
napi_is_big_uint64_array(napi_env env,napi_value value,bool * result)3094 NAPI_EXTERN napi_status napi_is_big_uint64_array(napi_env env, napi_value value, bool* result)
3095 {
3096 CHECK_ENV(env);
3097 CHECK_ARG(env, value);
3098 CHECK_ARG(env, result);
3099
3100 auto nativeValue = LocalValueFromJsValue(value);
3101 *result = nativeValue->IsBigUint64Array();
3102 return napi_clear_last_error(env);
3103 }
3104
napi_is_shared_array_buffer(napi_env env,napi_value value,bool * result)3105 NAPI_EXTERN napi_status napi_is_shared_array_buffer(napi_env env, napi_value value, bool* result)
3106 {
3107 CHECK_ENV(env);
3108 CHECK_ARG(env, value);
3109 CHECK_ARG(env, result);
3110
3111 auto nativeValue = LocalValueFromJsValue(value);
3112 *result = nativeValue->IsSharedArrayBuffer();
3113 return napi_clear_last_error(env);
3114 }
3115
napi_get_stack_trace(napi_env env,std::string & stack)3116 NAPI_EXTERN napi_status napi_get_stack_trace(napi_env env, std::string& stack)
3117 {
3118 CHECK_ENV(env);
3119
3120 auto engine = reinterpret_cast<NativeEngine*>(env);
3121 [[maybe_unused]] auto vm = engine->GetEcmaVm();
3122 std::string rawStack;
3123 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
3124 DFXJSNApi::BuildJsStackTrace(vm, rawStack);
3125 #else
3126 HILOG_WARN("GetStacktrace env get stack failed");
3127 #endif
3128 stack = engine->ExecuteTranslateBySourceMap(rawStack);
3129 return napi_clear_last_error(env);
3130 }
3131
napi_object_get_keys(napi_env env,napi_value data,napi_value * result)3132 NAPI_EXTERN napi_status napi_object_get_keys(napi_env env, napi_value data, napi_value* result)
3133 {
3134 CHECK_ENV(env);
3135
3136 auto nativeValue = LocalValueFromJsValue(data);
3137 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(), napi_object_expected);
3138 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3139 auto obj = nativeValue->ToObject(vm);
3140 Local<panda::ArrayRef> arrayVal = obj->GetOwnEnumerablePropertyNames(vm);
3141
3142 *result = JsValueFromLocalValue(arrayVal);
3143 return napi_clear_last_error(env);
3144 }
3145
napi_queue_async_work_with_qos(napi_env env,napi_async_work work,napi_qos_t qos)3146 NAPI_EXTERN napi_status napi_queue_async_work_with_qos(napi_env env, napi_async_work work, napi_qos_t qos)
3147 {
3148 CHECK_ENV(env);
3149 CHECK_ARG(env, work);
3150
3151 auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work);
3152 asyncWork->QueueWithQos(qos);
3153 return napi_status::napi_ok;
3154 }
3155
DetachFuncCallback(void * engine,void * object,void * hint,void * detachData)3156 void* DetachFuncCallback(void* engine, void* object, void* hint, void* detachData)
3157 {
3158 if (detachData == nullptr || (engine == nullptr || object ==nullptr)) {
3159 HILOG_ERROR("DetachFuncCallback params has nullptr");
3160 return nullptr;
3161 }
3162 DetachCallback detach = reinterpret_cast<DetachCallback>(detachData);
3163 void* detachVal = detach(reinterpret_cast<NativeEngine*>(engine), object, hint);
3164 return detachVal;
3165 }
3166
AttachFuncCallback(void * engine,void * buffer,void * hint,void * attachData)3167 Local<panda::JSValueRef> AttachFuncCallback(void* engine, void* buffer, void* hint, void* attachData)
3168 {
3169 if (attachData == nullptr || (engine == nullptr || buffer ==nullptr)) {
3170 HILOG_ERROR("AttachFuncCallback params has nullptr");
3171 }
3172 auto vm = reinterpret_cast<NativeEngine*>(engine)->GetEcmaVm();
3173 EscapeLocalScope scope(vm);
3174 Local<panda::JSValueRef> result = panda::JSValueRef::Undefined(vm);
3175 NapiAttachCallback attach = reinterpret_cast<NapiAttachCallback>(attachData);
3176 napi_value attachVal = attach(reinterpret_cast<napi_env>(engine), buffer, hint);
3177 if (attachVal == nullptr) {
3178 HILOG_WARN("AttachFunc return nullptr");
3179 } else {
3180 result = LocalValueFromJsValue(attachVal);
3181 }
3182 return scope.Escape(result);
3183 }
3184
napi_coerce_to_native_binding_object(napi_env env,napi_value js_object,napi_native_binding_detach_callback detach_cb,napi_native_binding_attach_callback attach_cb,void * native_object,void * hint)3185 NAPI_EXTERN napi_status napi_coerce_to_native_binding_object(napi_env env,
3186 napi_value js_object,
3187 napi_native_binding_detach_callback detach_cb,
3188 napi_native_binding_attach_callback attach_cb,
3189 void* native_object,
3190 void* hint)
3191 {
3192 CHECK_ENV(env);
3193 CHECK_ARG(env, js_object);
3194 CHECK_ARG(env, detach_cb);
3195 CHECK_ARG(env, attach_cb);
3196 CHECK_ARG(env, native_object);
3197
3198 auto jsValue = LocalValueFromJsValue(js_object);
3199 RETURN_STATUS_IF_FALSE(env, jsValue->IsObject(), napi_object_expected);
3200 auto engine = reinterpret_cast<NativeEngine*>(env);
3201 auto vm = engine->GetEcmaVm();
3202 auto obj = jsValue->ToObject(vm);
3203
3204 panda::JSNApi::NativeBindingInfo* data = panda::JSNApi::NativeBindingInfo::CreateNewInstance();
3205 if (data == nullptr) {
3206 HILOG_ERROR("data is nullptr");
3207 return napi_set_last_error(env, napi_invalid_arg);
3208 }
3209 data->env = env;
3210 data->nativeValue = native_object;
3211 data->attachFunc = reinterpret_cast<void*>(AttachFuncCallback);
3212 data->attachData = reinterpret_cast<void*>(attach_cb);
3213 data->detachFunc = reinterpret_cast<void*>(DetachFuncCallback);
3214 data->detachData = reinterpret_cast<void*>(detach_cb);
3215 data->hint = hint;
3216
3217 size_t nativeBindingSize = 7 * sizeof(void *); // 7 : params num
3218 Local<panda::NativePointerRef> value = panda::NativePointerRef::New(vm, data,
3219 [](void* data, void* info) {
3220 auto externalInfo = reinterpret_cast<panda::JSNApi::NativeBindingInfo*>(data);
3221 delete externalInfo;
3222 }, nullptr, nativeBindingSize);
3223
3224 bool res = obj->ConvertToNativeBindingObject(vm, value);
3225 if (res) {
3226 return napi_clear_last_error(env);
3227 }
3228 return napi_status::napi_generic_failure;
3229 }
3230
napi_get_print_string(napi_env env,napi_value value,std::string & result)3231 NAPI_EXTERN napi_status napi_get_print_string(napi_env env, napi_value value, std::string& result)
3232 {
3233 CHECK_ENV(env);
3234 CHECK_ARG(env, value);
3235
3236 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3237 auto nativeValue = LocalValueFromJsValue(value);
3238 if (nativeValue->IsString()) {
3239 Local<panda::StringRef> stringVal = nativeValue->ToString(vm);
3240 result = stringVal->ToString();
3241 }
3242 return napi_clear_last_error(env);
3243 }
3244
napi_run_module_path(napi_env env,const char * path,const char * entryPoint,napi_value * result)3245 NAPI_EXTERN napi_status napi_run_module_path(napi_env env, const char* path, const char* entryPoint, napi_value* result)
3246 {
3247 CHECK_ENV(env);
3248 CHECK_ARG(env, result);
3249
3250 auto engine = reinterpret_cast<NativeEngine*>(env);
3251 *result = engine->RunScriptForAbc(path, const_cast<char*>(entryPoint));
3252 return napi_clear_last_error(env);
3253 }
3254