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
20 #ifdef ENABLE_CONTAINER_SCOPE
21 #include "core/common/container_scope.h"
22 #endif
23 #include "native_api_internal.h"
24 #include "native_engine/impl/ark/ark_native_reference.h"
25 #include "native_engine/native_create_env.h"
26 #include "native_engine/native_utils.h"
27 #include "native_engine/worker_manager.h"
28 #include "securec.h"
29
30 using panda::ArrayRef;
31 using panda::ArrayBufferRef;
32 using panda::BigIntRef;
33 using panda::BooleanRef;
34 using panda::BufferRef;
35 using panda::DateRef;
36 using panda::DataViewRef;
37 using panda::EscapeLocalScope;
38 using panda::FunctionRef;
39 using panda::Global;
40 using panda::IntegerRef;
41 using panda::JSNApi;
42 using panda::JsiRuntimeCallInfo;
43 using panda::Local;
44 using panda::LocalScope;
45 using panda::NativePointerRef;
46 using panda::NumberRef;
47 using panda::ObjectRef;
48 using panda::PrimitiveRef;
49 using panda::PromiseCapabilityRef;
50 using panda::PromiseRef;
51 using panda::PropertyAttribute;
52 using panda::StringRef;
53 using panda::SymbolRef;
54 using panda::TypedArrayRef;
55 using panda::ecmascript::EcmaVM;
56
57 static constexpr size_t MAX_BYTE_LENGTH = 2097152;
58 static constexpr size_t ONEMIB_BYTE_SIZE = 1048576;
59 static constexpr size_t SMALL_STRING_SIZE = 16;
60
61 class HandleScopeWrapper {
62 public:
HandleScopeWrapper(NativeEngine * engine)63 explicit HandleScopeWrapper(NativeEngine* engine) : scope_(engine->GetEcmaVm()) {}
64
65 private:
66 LocalScope scope_;
67 };
68
69 class EscapableHandleScopeWrapper {
70 public:
EscapableHandleScopeWrapper(NativeEngine * engine)71 explicit EscapableHandleScopeWrapper(NativeEngine* engine)
72 : scope_(engine->GetEcmaVm()), escapeCalled_(false) {}
73
IsEscapeCalled() const74 bool IsEscapeCalled() const
75 {
76 return escapeCalled_;
77 }
78
79 template<typename T>
Escape(Local<T> value)80 Local<T> Escape(Local<T> value)
81 {
82 escapeCalled_ = true;
83 return scope_.Escape(value);
84 }
85
86 private:
87 EscapeLocalScope scope_;
88 bool escapeCalled_;
89 };
90
HandleScopeToNapiHandleScope(HandleScopeWrapper * s)91 inline napi_handle_scope HandleScopeToNapiHandleScope(HandleScopeWrapper* s)
92 {
93 return reinterpret_cast<napi_handle_scope>(s);
94 }
95
NapiHandleScopeToHandleScope(napi_handle_scope s)96 inline HandleScopeWrapper* NapiHandleScopeToHandleScope(napi_handle_scope s)
97 {
98 return reinterpret_cast<HandleScopeWrapper*>(s);
99 }
100
EscapableHandleScopeToNapiEscapableHandleScope(EscapableHandleScopeWrapper * s)101 inline napi_escapable_handle_scope EscapableHandleScopeToNapiEscapableHandleScope(EscapableHandleScopeWrapper* s)
102 {
103 return reinterpret_cast<napi_escapable_handle_scope>(s);
104 }
105
NapiEscapableHandleScopeToEscapableHandleScope(napi_escapable_handle_scope s)106 inline EscapableHandleScopeWrapper* NapiEscapableHandleScopeToEscapableHandleScope(napi_escapable_handle_scope s)
107 {
108 return reinterpret_cast<EscapableHandleScopeWrapper*>(s);
109 }
110
napi_get_last_error_info(napi_env env,const napi_extended_error_info ** result)111 NAPI_EXTERN napi_status napi_get_last_error_info(napi_env env, const napi_extended_error_info** result)
112 {
113 CHECK_ENV(env);
114 CHECK_ARG(env, result);
115
116 *result = reinterpret_cast<napi_extended_error_info*>(reinterpret_cast<NativeEngine*>(env)->GetLastError());
117 if ((*result)->error_code == napi_ok) {
118 napi_clear_last_error(env);
119 }
120
121 return napi_ok;
122 }
123
124 // Getters for defined singletons
napi_get_undefined(napi_env env,napi_value * result)125 NAPI_EXTERN napi_status napi_get_undefined(napi_env env, napi_value* result)
126 {
127 CHECK_ENV(env);
128 CHECK_ARG(env, result);
129
130 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
131 Local<panda::PrimitiveRef> value = panda::JSValueRef::Undefined(vm);
132 *result = JsValueFromLocalValue(value);
133
134 return napi_clear_last_error(env);
135 }
136
napi_get_null(napi_env env,napi_value * result)137 NAPI_EXTERN napi_status napi_get_null(napi_env env, napi_value* result)
138 {
139 CHECK_ENV(env);
140 CHECK_ARG(env, result);
141
142 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
143 Local<panda::PrimitiveRef> value = panda::JSValueRef::Null(vm);
144 *result = JsValueFromLocalValue(value);
145
146 return napi_clear_last_error(env);
147 }
148
napi_get_global(napi_env env,napi_value * result)149 NAPI_EXTERN napi_status napi_get_global(napi_env env, napi_value* result)
150 {
151 CHECK_ENV(env);
152 CHECK_ARG(env, result);
153
154 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
155 Local<panda::ObjectRef> value = panda::JSNApi::GetGlobalObject(vm);
156 *result = JsValueFromLocalValue(value);
157
158 return napi_clear_last_error(env);
159 }
160
napi_get_boolean(napi_env env,bool value,napi_value * result)161 NAPI_EXTERN napi_status napi_get_boolean(napi_env env, bool value, napi_value* result)
162 {
163 CHECK_ENV(env);
164 CHECK_ARG(env, result);
165
166 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
167 if (value) {
168 *result = JsValueFromLocalValue(panda::JSValueRef::True(vm));
169 } else {
170 *result = JsValueFromLocalValue(panda::JSValueRef::False(vm));
171 }
172
173 return napi_clear_last_error(env);
174 }
175
176 // Methods to create Primitive types/Objects
napi_create_object(napi_env env,napi_value * result)177 NAPI_EXTERN napi_status napi_create_object(napi_env env, napi_value* result)
178 {
179 CHECK_ENV(env);
180 CHECK_ARG(env, result);
181
182 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
183 auto obj = panda::ObjectRef::NewObject(vm);
184 *result = reinterpret_cast<napi_value>(obj);
185 return napi_clear_last_error(env);
186 }
187
188 // Create JSObject with initial properties given by descriptors, note that property key must be String, and
189 // 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)190 NAPI_EXTERN napi_status napi_create_object_with_properties(napi_env env, napi_value* result, size_t property_count,
191 const napi_property_descriptor* properties)
192 {
193 CHECK_ENV(env);
194 CHECK_ARG(env, result);
195
196 Local<panda::ObjectRef> object;
197 if (property_count <= panda::ObjectRef::MAX_PROPERTIES_ON_STACK) {
198 char attrs[sizeof(PropertyAttribute) * panda::ObjectRef::MAX_PROPERTIES_ON_STACK];
199 char keys[sizeof(Local<panda::JSValueRef>) * panda::ObjectRef::MAX_PROPERTIES_ON_STACK];
200 object = NapiCreateObjectWithProperties(env, property_count, properties,
201 reinterpret_cast<Local<panda::JSValueRef> *>(keys),
202 reinterpret_cast<PropertyAttribute *>(attrs));
203 } else {
204 void *attrs = malloc(sizeof(PropertyAttribute) * property_count);
205 void *keys = malloc(sizeof(Local<panda::JSValueRef>) * property_count);
206 if (attrs != nullptr && keys != nullptr) {
207 object = NapiCreateObjectWithProperties(env, property_count, properties,
208 reinterpret_cast<Local<panda::JSValueRef> *>(keys),
209 reinterpret_cast<PropertyAttribute *>(attrs));
210 } else {
211 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
212 object = panda::JSValueRef::Undefined(vm);
213 napi_throw_error(env, nullptr, "malloc failed in napi_create_object_with_properties");
214 }
215 if (attrs != nullptr) {
216 free(attrs);
217 }
218 if (keys != nullptr) {
219 free(keys);
220 }
221 }
222 *result = JsValueFromLocalValue(object);
223
224 return napi_clear_last_error(env);
225 }
226
227 // Create JSObject with initial properties given by keys and values, note that property key must be String, and
228 // 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)229 NAPI_EXTERN napi_status napi_create_object_with_named_properties(napi_env env, napi_value* result,
230 size_t property_count, const char** keys,
231 const napi_value* values)
232 {
233 CHECK_ENV(env);
234 CHECK_ARG(env, result);
235
236 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
237 Local<panda::ObjectRef> object = panda::ObjectRef::NewWithNamedProperties(vm, property_count, keys,
238 reinterpret_cast<const Local<JSValueRef> *>(values));
239 *result = JsValueFromLocalValue(object);
240
241 return napi_clear_last_error(env);
242 }
243
napi_create_array(napi_env env,napi_value * result)244 NAPI_EXTERN napi_status napi_create_array(napi_env env, napi_value* result)
245 {
246 CHECK_ENV(env);
247 CHECK_ARG(env, result);
248
249 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
250 Local<panda::ArrayRef> object = panda::ArrayRef::New(vm, 0);
251 *result = JsValueFromLocalValue(object);
252
253 return napi_clear_last_error(env);
254 }
255
napi_create_array_with_length(napi_env env,size_t length,napi_value * result)256 NAPI_EXTERN napi_status napi_create_array_with_length(napi_env env, size_t length, napi_value* result)
257 {
258 CHECK_ENV(env);
259 CHECK_ARG(env, result);
260
261 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
262 Local<panda::ArrayRef> object = panda::ArrayRef::New(vm, length);
263 *result = JsValueFromLocalValue(object);
264
265 return napi_clear_last_error(env);
266 }
267
napi_create_sendable_array(napi_env env,napi_value * result)268 NAPI_EXTERN napi_status napi_create_sendable_array(napi_env env, napi_value* result)
269 {
270 CHECK_ENV(env);
271 CHECK_ARG(env, result);
272
273 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
274 Local<panda::SendableArrayRef> object = panda::SendableArrayRef::New(vm, 0);
275 *result = JsValueFromLocalValue(object);
276
277 return napi_clear_last_error(env);
278 }
279
napi_create_sendable_array_with_length(napi_env env,size_t length,napi_value * result)280 NAPI_EXTERN napi_status napi_create_sendable_array_with_length(napi_env env, size_t length, napi_value* result)
281 {
282 CHECK_ENV(env);
283 CHECK_ARG(env, result);
284
285 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
286 Local<panda::SendableArrayRef> object = panda::SendableArrayRef::New(vm, length);
287 *result = JsValueFromLocalValue(object);
288
289 return napi_clear_last_error(env);
290 }
291
napi_create_double(napi_env env,double value,napi_value * result)292 NAPI_EXTERN napi_status napi_create_double(napi_env env, double value, napi_value* result)
293 {
294 CHECK_ENV(env);
295 CHECK_ARG(env, result);
296
297 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
298 Local<panda::NumberRef> object = panda::NumberRef::New(vm, value);
299 *result = JsValueFromLocalValue(object);
300
301 return napi_clear_last_error(env);
302 }
303
napi_create_int32(napi_env env,int32_t value,napi_value * result)304 NAPI_EXTERN napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)
305 {
306 CHECK_ENV(env);
307 CHECK_ARG(env, result);
308
309 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
310 Local<panda::NumberRef> object = panda::NumberRef::New(vm, value);
311 *result = JsValueFromLocalValue(object);
312
313 return napi_clear_last_error(env);
314 }
315
napi_create_uint32(napi_env env,uint32_t value,napi_value * result)316 NAPI_EXTERN napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)
317 {
318 CHECK_ENV(env);
319 CHECK_ARG(env, result);
320
321 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
322 Local<panda::NumberRef> object = panda::NumberRef::New(vm, value);
323 *result = JsValueFromLocalValue(object);
324
325 return napi_clear_last_error(env);
326 }
327
napi_create_int64(napi_env env,int64_t value,napi_value * result)328 NAPI_EXTERN napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)
329 {
330 CHECK_ENV(env);
331 CHECK_ARG(env, result);
332
333 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
334 Local<panda::NumberRef> object = panda::NumberRef::New(vm, value);
335 *result = JsValueFromLocalValue(object);
336
337 return napi_clear_last_error(env);
338 }
339
napi_create_string_latin1(napi_env env,const char * str,size_t length,napi_value * result)340 NAPI_EXTERN napi_status napi_create_string_latin1(napi_env env, const char* str, size_t length, napi_value* result)
341 {
342 CHECK_ENV(env);
343 CHECK_ARG(env, str);
344 CHECK_ARG(env, result);
345
346 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
347 if (length < SMALL_STRING_SIZE) {
348 Local<panda::StringRef> object = panda::StringRef::NewFromUtf8WithoutStringTable(
349 vm, str, (length == NAPI_AUTO_LENGTH) ? strlen(str) : length);
350 *result = JsValueFromLocalValue(object);
351 } else {
352 Local<panda::StringRef> object = panda::StringRef::NewFromUtf8(
353 vm, str, (length == NAPI_AUTO_LENGTH) ? strlen(str) : length);
354 *result = JsValueFromLocalValue(object);
355 }
356
357 return napi_clear_last_error(env);
358 }
359
napi_create_string_utf8(napi_env env,const char * str,size_t length,napi_value * result)360 NAPI_EXTERN napi_status napi_create_string_utf8(napi_env env, const char* str, size_t length, napi_value* result)
361 {
362 CHECK_ENV(env);
363 CHECK_ARG(env, str);
364 CHECK_ARG(env, result);
365
366 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
367 if (length < SMALL_STRING_SIZE) {
368 Local<panda::StringRef> object = panda::StringRef::NewFromUtf8WithoutStringTable(
369 vm, str, (length == NAPI_AUTO_LENGTH) ? strlen(str) : length);
370 *result = JsValueFromLocalValue(object);
371 } else {
372 Local<panda::StringRef> object = panda::StringRef::NewFromUtf8(
373 vm, str, (length == NAPI_AUTO_LENGTH) ? strlen(str) : length);
374 *result = JsValueFromLocalValue(object);
375 }
376
377 return napi_clear_last_error(env);
378 }
379
napi_create_string_utf16(napi_env env,const char16_t * str,size_t length,napi_value * result)380 NAPI_EXTERN napi_status napi_create_string_utf16(
381 napi_env env, const char16_t* str, size_t length, napi_value* result)
382 {
383 CHECK_ENV(env);
384 CHECK_ARG(env, str);
385 CHECK_ARG(env, result);
386 RETURN_STATUS_IF_FALSE(env, (length == NAPI_AUTO_LENGTH) || (length <= INT_MAX && length >= 0), napi_invalid_arg);
387
388 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
389 int char16Length = static_cast<int>(std::char_traits<char16_t>::length(str));
390 if (length != NAPI_AUTO_LENGTH && length != static_cast<size_t>(char16Length)) {
391 HILOG_WARN("`length` (%{public}zu) not equals to strlen(`str`) (%{public}d), result may be unexpected",
392 length, char16Length);
393 }
394 if (length < SMALL_STRING_SIZE) {
395 Local<panda::StringRef> object = panda::StringRef::NewFromUtf16WithoutStringTable(
396 vm, str, (length == NAPI_AUTO_LENGTH) ? char16Length : length);
397 *result = JsValueFromLocalValue(object);
398 } else {
399 Local<panda::StringRef> object = panda::StringRef::NewFromUtf16(
400 vm, str, (length == NAPI_AUTO_LENGTH) ? char16Length : length);
401 *result = JsValueFromLocalValue(object);
402 }
403
404 return napi_clear_last_error(env);
405 }
406
napi_create_symbol(napi_env env,napi_value description,napi_value * result)407 NAPI_EXTERN napi_status napi_create_symbol(napi_env env, napi_value description, napi_value* result)
408 {
409 CHECK_ENV(env);
410 CHECK_ARG(env, result);
411
412 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
413 panda::JsiFastNativeScope fastNativeScope(vm);
414 panda::Local<panda::JSValueRef> object = panda::JSValueRef::Undefined(vm);
415 if (description == nullptr) {
416 const char* str = "";
417 object = panda::StringRef::NewFromUtf8(vm, str, 0);
418 } else {
419 object = LocalValueFromJsValue(description);
420 }
421 RETURN_STATUS_IF_FALSE(env, object->IsString(vm), napi_invalid_arg);
422 Local<panda::SymbolRef> symbol = panda::SymbolRef::New(vm, object);
423 *result = JsValueFromLocalValue(symbol);
424
425 return napi_clear_last_error(env);
426 }
427
napi_create_function(napi_env env,const char * utf8name,size_t length,napi_callback cb,void * data,napi_value * result)428 NAPI_EXTERN napi_status napi_create_function(napi_env env,
429 const char* utf8name,
430 size_t length,
431 napi_callback cb,
432 void* data,
433 napi_value* result)
434 {
435 NAPI_PREAMBLE(env);
436 CHECK_ARG(env, cb);
437 CHECK_ARG(env, result);
438
439 auto vm = const_cast<EcmaVM*>(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm());
440 panda::JsiFastNativeScope fastNativeScope(vm);
441 EscapeLocalScope scope(vm);
442 auto callback = reinterpret_cast<NapiNativeCallback>(cb);
443 const char* name = "defaultName";
444 NapiFunctionInfo* funcInfo = NapiFunctionInfo::CreateNewInstance();
445 if (funcInfo == nullptr) {
446 HILOG_ERROR("funcInfo is nullptr");
447 return napi_set_last_error(env, napi_invalid_arg);
448 }
449 funcInfo->callback = callback;
450 funcInfo->data = data;
451 #ifdef ENABLE_CONTAINER_SCOPE
452 funcInfo->scopeId = OHOS::Ace::ContainerScope::CurrentId();
453 #endif
454
455 Local<panda::FunctionRef> fn = panda::FunctionRef::NewConcurrent(
456 vm, ArkNativeFunctionCallBack,
457 [](void* env, void* externalPointer, void* data) {
458 auto info = reinterpret_cast<NapiFunctionInfo*>(data);
459 if (info != nullptr) {
460 delete info;
461 }
462 },
463 reinterpret_cast<void*>(funcInfo), true
464 );
465 Local<panda::StringRef> fnName = panda::StringRef::NewFromUtf8(vm, utf8name != nullptr ? utf8name : name);
466 fn->SetName(vm, fnName);
467 *result = JsValueFromLocalValue(scope.Escape(fn));
468 return GET_RETURN_STATUS(env);
469 }
470
napi_create_error(napi_env env,napi_value code,napi_value msg,napi_value * result)471 NAPI_EXTERN napi_status napi_create_error(napi_env env, napi_value code, napi_value msg, napi_value* result)
472 {
473 CHECK_ENV(env);
474 CHECK_ARG(env, msg);
475 CHECK_ARG(env, result);
476
477 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
478 panda::JsiFastNativeScope fastNativeScope(vm);
479 Local<panda::JSValueRef> codeValue = panda::JSValueRef::Undefined(vm);
480 if (code != nullptr) {
481 codeValue = LocalValueFromJsValue(code);
482 RETURN_STATUS_IF_FALSE(env, codeValue->IsString(vm) || codeValue->IsNumber(), napi_invalid_arg);
483 }
484
485 auto msgValue = LocalValueFromJsValue(msg);
486 RETURN_STATUS_IF_FALSE(env, msgValue->IsString(vm), napi_invalid_arg);
487
488 Local<panda::JSValueRef> errorVal = panda::Exception::Error(vm, msgValue);
489 if (code != nullptr) {
490 Local<panda::StringRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
491 Local<panda::ObjectRef> errorObj(errorVal);
492 errorObj->Set(vm, codeKey, codeValue);
493 }
494 *result = JsValueFromLocalValue(errorVal);
495
496 return napi_clear_last_error(env);
497 }
498
napi_create_type_error(napi_env env,napi_value code,napi_value msg,napi_value * result)499 NAPI_EXTERN napi_status napi_create_type_error(napi_env env, napi_value code, napi_value msg, napi_value* result)
500 {
501 CHECK_ENV(env);
502 CHECK_ARG(env, msg);
503 CHECK_ARG(env, result);
504
505 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
506 panda::JsiFastNativeScope fastNativeScope(vm);
507 Local<panda::JSValueRef> codeValue = panda::JSValueRef::Undefined(vm);
508 if (code != nullptr) {
509 codeValue = LocalValueFromJsValue(code);
510 RETURN_STATUS_IF_FALSE(env, codeValue->IsString(vm) || codeValue->IsNumber(), napi_invalid_arg);
511 }
512 auto msgValue = LocalValueFromJsValue(msg);
513 RETURN_STATUS_IF_FALSE(env, msgValue->IsString(vm), napi_invalid_arg);
514
515 Local<panda::JSValueRef> errorVal = panda::Exception::Error(vm, msgValue);
516 if (code != nullptr) {
517 Local<panda::StringRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
518 Local<panda::ObjectRef> errorObj(errorVal);
519 errorObj->Set(vm, codeKey, codeValue);
520 }
521 *result = JsValueFromLocalValue(errorVal);
522
523 return napi_clear_last_error(env);
524 }
525
napi_create_range_error(napi_env env,napi_value code,napi_value msg,napi_value * result)526 NAPI_EXTERN napi_status napi_create_range_error(napi_env env, napi_value code, napi_value msg, napi_value* result)
527 {
528 CHECK_ENV(env);
529 CHECK_ARG(env, msg);
530 CHECK_ARG(env, result);
531
532 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
533 panda::JsiFastNativeScope fastNativeScope(vm);
534 Local<panda::JSValueRef> codeValue = panda::JSValueRef::Undefined(vm);
535
536 if (code != nullptr) {
537 codeValue = LocalValueFromJsValue(code);
538 RETURN_STATUS_IF_FALSE(env, codeValue->IsString(vm) || codeValue->IsNumber(), napi_invalid_arg);
539 }
540 auto msgValue = LocalValueFromJsValue(msg);
541 RETURN_STATUS_IF_FALSE(env, msgValue->IsString(vm), napi_invalid_arg);
542
543 Local<panda::JSValueRef> errorVal = panda::Exception::Error(vm, msgValue);
544 if (code != nullptr) {
545 Local<panda::StringRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
546 Local<panda::ObjectRef> errorObj(errorVal);
547 errorObj->Set(vm, codeKey, codeValue);
548 }
549 *result = JsValueFromLocalValue(errorVal);
550
551 return napi_clear_last_error(env);
552 }
553
554 // Methods to get the native napi_value from Primitive type
napi_typeof(napi_env env,napi_value value,napi_valuetype * result)555 NAPI_EXTERN napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result)
556 {
557 CHECK_ENV(env);
558 CHECK_ARG(env, value);
559 CHECK_ARG(env, result);
560
561 auto valueObj = LocalValueFromJsValue(value);
562 napi_valuetype resultType;
563 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
564 panda::JsiFastNativeScope fastNativeScope(vm);
565
566 if (valueObj->IsNumber()) {
567 resultType = napi_number;
568 } else if (valueObj->IsString(vm)) {
569 resultType = napi_string;
570 } else if (valueObj->IsFunction(vm)) {
571 resultType = napi_function;
572 } else if (valueObj->IsNativePointer(vm)) {
573 resultType = napi_external;
574 } else if (valueObj->IsNull()) {
575 resultType = napi_null;
576 } else if (valueObj->IsBoolean()) {
577 resultType = napi_boolean;
578 } else if (valueObj->IsUndefined()) {
579 resultType = napi_undefined;
580 } else if (valueObj->IsSymbol(vm)) {
581 resultType = napi_symbol;
582 } else if (valueObj->IsBigInt(vm)) {
583 resultType = napi_bigint;
584 } else if (valueObj->IsObject(vm)) {
585 resultType = napi_object;
586 } else {
587 resultType = napi_undefined;
588 }
589 *result = resultType;
590 return napi_clear_last_error(env);
591 }
592
napi_get_value_double(napi_env env,napi_value value,double * result)593 NAPI_EXTERN napi_status napi_get_value_double(napi_env env, napi_value value, double* result)
594 {
595 CHECK_ENV(env);
596 CHECK_ARG(env, value);
597 CHECK_ARG(env, result);
598
599 panda::JSValueRef* nativeValue = reinterpret_cast<panda::JSValueRef*>(value);
600 bool isNumber = false;
601 double dValue = nativeValue->GetValueDouble(isNumber);
602 RETURN_STATUS_IF_FALSE(env, isNumber, napi_number_expected);
603 *result = dValue;
604 return napi_clear_last_error(env);
605 }
606
napi_get_value_int32(napi_env env,napi_value value,int32_t * result)607 NAPI_EXTERN napi_status napi_get_value_int32(napi_env env, napi_value value, int32_t* result)
608 {
609 CHECK_ENV(env);
610 CHECK_ARG(env, value);
611 CHECK_ARG(env, result);
612
613 panda::JSValueRef* nativeValue = reinterpret_cast<panda::JSValueRef*>(value);
614 bool isNumber = false;
615 int32_t i32Value = nativeValue->GetValueInt32(isNumber);
616 RETURN_STATUS_IF_FALSE(env, isNumber, napi_number_expected);
617 *result = i32Value;
618
619 return napi_clear_last_error(env);
620 }
621
napi_get_value_uint32(napi_env env,napi_value value,uint32_t * result)622 NAPI_EXTERN napi_status napi_get_value_uint32(napi_env env, napi_value value, uint32_t* result)
623 {
624 CHECK_ENV(env);
625 CHECK_ARG(env, value);
626 CHECK_ARG(env, result);
627
628 panda::JSValueRef* nativeValue = reinterpret_cast<panda::JSValueRef*>(value);
629 bool isNumber = false;
630 uint32_t u32Value = nativeValue->GetValueUint32(isNumber);
631 RETURN_STATUS_IF_FALSE(env, isNumber, napi_number_expected);
632 *result = u32Value;
633 return napi_clear_last_error(env);
634 }
635
napi_get_value_int64(napi_env env,napi_value value,int64_t * result)636 NAPI_EXTERN napi_status napi_get_value_int64(napi_env env, napi_value value, int64_t* result)
637 {
638 CHECK_ENV(env);
639 CHECK_ARG(env, value);
640 CHECK_ARG(env, result);
641
642 panda::JSValueRef* nativeValue = reinterpret_cast<panda::JSValueRef*>(value);
643 bool isNumber = false;
644 int64_t i64Value = nativeValue->GetValueInt64(isNumber);
645 RETURN_STATUS_IF_FALSE(env, isNumber, napi_number_expected);
646 *result = i64Value;
647 return napi_clear_last_error(env);
648 }
649
napi_get_value_bool(napi_env env,napi_value value,bool * result)650 NAPI_EXTERN napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result)
651 {
652 CHECK_ENV(env);
653 CHECK_ARG(env, value);
654 CHECK_ARG(env, result);
655
656 panda::JSValueRef* nativeValue = reinterpret_cast<panda::JSValueRef*>(value);
657 bool isBool = false;
658 bool bValue = nativeValue->GetValueBool(isBool);
659 RETURN_STATUS_IF_FALSE(env, isBool, napi_boolean_expected);
660 *result = bValue;
661 return napi_clear_last_error(env);
662 }
663
664 // 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)665 NAPI_EXTERN napi_status napi_get_value_string_latin1(napi_env env,
666 napi_value value,
667 char* buf,
668 size_t bufsize,
669 size_t* result)
670 {
671 CHECK_ENV(env);
672 CHECK_ARG(env, value);
673
674 auto nativeValue = LocalValueFromJsValue(value);
675 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
676 panda::JsiFastNativeScope fastNativeScope(vm);
677
678 RETURN_STATUS_IF_FALSE(env, nativeValue->IsString(vm), napi_string_expected);
679 Local<panda::StringRef> stringVal(nativeValue);
680 if (buf == nullptr) {
681 CHECK_ARG(env, result);
682 *result = stringVal->Length(vm);
683 } else if (bufsize != 0) {
684 uint32_t copied = stringVal->WriteLatin1(vm, buf, bufsize);
685 buf[copied] = '\0';
686 if (result != nullptr) {
687 *result = copied;
688 }
689 } else if (result != nullptr) {
690 *result = 0;
691 }
692
693 return napi_clear_last_error(env);
694 }
695
696 // 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)697 NAPI_EXTERN napi_status napi_get_value_string_utf8(napi_env env,
698 napi_value value,
699 char* buf,
700 size_t bufsize,
701 size_t* result)
702 {
703 CHECK_ENV(env);
704 CHECK_ARG(env, value);
705
706 auto nativeValue = LocalValueFromJsValue(value);
707 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
708 panda::JsiFastNativeScope fastNativeScope(vm);
709
710 RETURN_STATUS_IF_FALSE(env, nativeValue->IsString(vm), napi_string_expected);
711 Local<panda::StringRef> stringVal(nativeValue);
712 if (buf == nullptr) {
713 CHECK_ARG(env, result);
714 *result = stringVal->Utf8Length(vm, true) - 1;
715 } else if (bufsize != 0) {
716 uint32_t copied = stringVal->WriteUtf8(vm, buf, bufsize - 1, true) - 1;
717 buf[copied] = '\0';
718 if (result != nullptr) {
719 *result = copied;
720 }
721 } else if (result != nullptr) {
722 *result = 0;
723 }
724
725 return napi_clear_last_error(env);
726 }
727
napi_get_value_string_utf16(napi_env env,napi_value value,char16_t * buf,size_t bufsize,size_t * result)728 NAPI_EXTERN napi_status napi_get_value_string_utf16(napi_env env,
729 napi_value value,
730 char16_t* buf,
731 size_t bufsize,
732 size_t* result)
733 {
734 CHECK_ENV(env);
735 CHECK_ARG(env, value);
736
737 auto nativeValue = LocalValueFromJsValue(value);
738 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
739 panda::JsiFastNativeScope fastNativeScope(vm);
740
741 RETURN_STATUS_IF_FALSE(env, nativeValue->IsString(vm), napi_string_expected);
742 Local<panda::StringRef> stringVal(nativeValue);
743 if (buf == nullptr) {
744 CHECK_ARG(env, result);
745 *result = stringVal->Length(vm);
746 } else if (bufsize == 1) {
747 buf[0] = '\0';
748 if (result != nullptr) {
749 *result = 0;
750 }
751 } else if (bufsize != 0) {
752 uint32_t copied = stringVal->WriteUtf16(vm, buf, bufsize - 1); // bufsize - 1 : reserve the position of buf "\0"
753 buf[copied] = '\0';
754 if (result != nullptr) {
755 *result = copied;
756 }
757 } else if (result != nullptr) {
758 *result = 0;
759 }
760
761 return napi_clear_last_error(env);
762 }
763
764 // Methods to coerce values
765 // These APIs may execute user scripts
napi_coerce_to_bool(napi_env env,napi_value value,napi_value * result)766 NAPI_EXTERN napi_status napi_coerce_to_bool(napi_env env, napi_value value, napi_value* result)
767 {
768 NAPI_PREAMBLE(env);
769 CHECK_ARG(env, value);
770 CHECK_ARG(env, result);
771
772 Local<panda::JSValueRef> val = LocalValueFromJsValue(value);
773 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
774 Local<panda::BooleanRef> boolVal = val->ToBoolean(vm);
775 *result = JsValueFromLocalValue(boolVal);
776
777 return napi_clear_last_error(env);
778 }
779
napi_coerce_to_number(napi_env env,napi_value value,napi_value * result)780 NAPI_EXTERN napi_status napi_coerce_to_number(napi_env env, napi_value value, napi_value* result)
781 {
782 CHECK_ENV(env);
783 CHECK_ARG(env, value);
784 CHECK_ARG(env, result);
785
786 auto nativeValue = LocalValueFromJsValue(value);
787 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
788 *result = JsValueFromLocalValue(nativeValue->ToNumber(vm));
789
790 return napi_clear_last_error(env);
791 }
792
napi_coerce_to_object(napi_env env,napi_value value,napi_value * result)793 NAPI_EXTERN napi_status napi_coerce_to_object(napi_env env, napi_value value, napi_value* result)
794 {
795 CHECK_ENV(env);
796 CHECK_ARG(env, value);
797 CHECK_ARG(env, result);
798
799 auto nativeValue = LocalValueFromJsValue(value);
800 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
801 *result = JsValueFromLocalValue(nativeValue->ToObject(vm));
802
803 return napi_clear_last_error(env);
804 }
805
napi_coerce_to_string(napi_env env,napi_value value,napi_value * result)806 NAPI_EXTERN napi_status napi_coerce_to_string(napi_env env, napi_value value, napi_value* result)
807 {
808 CHECK_ENV(env);
809 CHECK_ARG(env, value);
810 CHECK_ARG(env, result);
811
812 auto nativeValue = LocalValueFromJsValue(value);
813 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
814 *result = JsValueFromLocalValue(nativeValue->ToString(vm));
815
816 return napi_clear_last_error(env);
817 }
818
819 // Methods to work with Objects
napi_get_prototype(napi_env env,napi_value object,napi_value * result)820 NAPI_EXTERN napi_status napi_get_prototype(napi_env env, napi_value object, napi_value* result)
821 {
822 NAPI_PREAMBLE(env);
823 CHECK_ARG(env, object);
824 CHECK_ARG(env, result);
825
826 auto nativeValue = LocalValueFromJsValue(object);
827 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
828 panda::JsiFastNativeScope fastNativeScope(vm);
829 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj);
830 Local<panda::JSValueRef> val = obj->GetPrototype(vm);
831 *result = JsValueFromLocalValue(val);
832
833 return GET_RETURN_STATUS(env);
834 }
835
napi_get_property_names(napi_env env,napi_value object,napi_value * result)836 NAPI_EXTERN napi_status napi_get_property_names(napi_env env, napi_value object, napi_value* result)
837 {
838 CHECK_ENV(env);
839 CHECK_ARG(env, object);
840 CHECK_ARG(env, result);
841
842 auto nativeValue = LocalValueFromJsValue(object);
843 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
844 panda::JsiFastNativeScope fastNativeScope(vm);
845 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj);
846 Local<panda::ArrayRef> arrayVal = obj->GetOwnPropertyNames(vm);
847 *result = JsValueFromLocalValue(arrayVal);
848 return napi_clear_last_error(env);
849 }
850
napi_set_property(napi_env env,napi_value object,napi_value key,napi_value value)851 NAPI_EXTERN napi_status napi_set_property(napi_env env, napi_value object, napi_value key, napi_value value)
852 {
853 NAPI_PREAMBLE(env);
854 CHECK_ARG(env, object);
855 CHECK_ARG(env, key);
856 CHECK_ARG(env, value);
857
858 auto nativeValue = LocalValueFromJsValue(object);
859 auto propKey = LocalValueFromJsValue(key);
860 auto propValue = LocalValueFromJsValue(value);
861 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
862 panda::JsiFastNativeScope fastNativeScope(vm);
863 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj);
864 obj->Set(vm, propKey, propValue);
865
866 return GET_RETURN_STATUS(env);
867 }
868
napi_has_property(napi_env env,napi_value object,napi_value key,bool * result)869 NAPI_EXTERN napi_status napi_has_property(napi_env env, napi_value object, napi_value key, bool* result)
870 {
871 NAPI_PREAMBLE(env);
872 CHECK_ARG(env, object);
873 CHECK_ARG(env, key);
874 CHECK_ARG(env, result);
875
876 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
877 panda::JsiFastNativeScope fastNativeScope(vm);
878 Local<panda::JSValueRef> hasResult = JSNApi::NapiHasProperty(vm, reinterpret_cast<uintptr_t>(object),
879 reinterpret_cast<uintptr_t>(key));
880 RETURN_STATUS_IF_FALSE(env, NapiStatusValidationCheck(hasResult), napi_object_expected);
881 *result = hasResult->BooleaValue(vm);
882
883 return GET_RETURN_STATUS(env);
884 }
885
napi_get_property(napi_env env,napi_value object,napi_value key,napi_value * result)886 NAPI_EXTERN napi_status napi_get_property(napi_env env, napi_value object, napi_value key, napi_value* result)
887 {
888 NAPI_PREAMBLE(env);
889 CHECK_ARG(env, object);
890 CHECK_ARG(env, key);
891 CHECK_ARG(env, result);
892
893 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
894 panda::JsiFastNativeScope fastNativeScope(vm);
895 Local<panda::JSValueRef> value = JSNApi::NapiGetProperty(vm, reinterpret_cast<uintptr_t>(object),
896 reinterpret_cast<uintptr_t>(key));
897 RETURN_STATUS_IF_FALSE(env, NapiStatusValidationCheck(value), napi_object_expected);
898 #ifdef ENABLE_CONTAINER_SCOPE
899 FunctionSetContainerId(vm, value);
900 #endif
901 *result = JsValueFromLocalValue(value);
902
903 return GET_RETURN_STATUS(env);
904 }
905
napi_delete_property(napi_env env,napi_value object,napi_value key,bool * result)906 NAPI_EXTERN napi_status napi_delete_property(napi_env env, napi_value object, napi_value key, bool* result)
907 {
908 NAPI_PREAMBLE(env);
909 CHECK_ARG(env, object);
910 CHECK_ARG(env, key);
911
912 auto nativeValue = LocalValueFromJsValue(object);
913 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
914 panda::JsiFastNativeScope fastNativeScope(vm);
915 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm) || nativeValue->IsFunction(vm), napi_object_expected);
916 auto deleteResult = JSNApi::NapiDeleteProperty(vm, reinterpret_cast<uintptr_t>(object),
917 reinterpret_cast<uintptr_t>(key));
918 RETURN_STATUS_IF_FALSE(env, NapiStatusValidationCheck(deleteResult), napi_object_expected);
919 if (result) {
920 *result = deleteResult->BooleaValue(vm);
921 }
922
923 return GET_RETURN_STATUS(env);
924 }
925
napi_has_own_property(napi_env env,napi_value object,napi_value key,bool * result)926 NAPI_EXTERN napi_status napi_has_own_property(napi_env env, napi_value object, napi_value key, bool* result)
927 {
928 NAPI_PREAMBLE(env);
929 CHECK_ARG(env, object);
930 CHECK_ARG(env, key);
931 CHECK_ARG(env, result);
932
933 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
934 panda::JsiFastNativeScope fastNativeScope(vm);
935 auto hasResult = JSNApi::NapiHasOwnProperty(vm, reinterpret_cast<uintptr_t>(object),
936 reinterpret_cast<uintptr_t>(key));
937 RETURN_STATUS_IF_FALSE(env, NapiStatusValidationCheck(hasResult), napi_object_expected);
938 if (result) {
939 *result = hasResult->BooleaValue(vm);
940 }
941
942 return GET_RETURN_STATUS(env);
943 }
944
napi_set_named_property(napi_env env,napi_value object,const char * utf8name,napi_value value)945 NAPI_EXTERN napi_status napi_set_named_property(napi_env env, napi_value object, const char* utf8name, napi_value value)
946 {
947 NAPI_PREAMBLE(env);
948 CHECK_ARG(env, object);
949 CHECK_ARG(env, utf8name);
950 CHECK_ARG(env, value);
951
952 auto nativeValue = LocalValueFromJsValue(object);
953 auto propVal = LocalValueFromJsValue(value);
954 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
955 panda::JsiFastNativeScope fastNativeScope(vm);
956 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm) || nativeValue->IsFunction(vm), napi_object_expected);
957 Local<panda::ObjectRef> obj(nativeValue);
958 obj->Set(vm, utf8name, propVal);
959
960 return GET_RETURN_STATUS(env);
961 }
962
napi_has_named_property(napi_env env,napi_value object,const char * utf8name,bool * result)963 NAPI_EXTERN napi_status napi_has_named_property(napi_env env, napi_value object, const char* utf8name, bool* result)
964 {
965 NAPI_PREAMBLE(env);
966 CHECK_ARG(env, object);
967 CHECK_ARG(env, utf8name);
968 CHECK_ARG(env, result);
969
970 auto nativeValue = LocalValueFromJsValue(object);
971 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
972 panda::JsiFastNativeScope fastNativeScope(vm);
973 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj);
974 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, utf8name);
975 *result = obj->Has(vm, key);
976
977 return GET_RETURN_STATUS(env);
978 }
979
napi_get_named_property(napi_env env,napi_value object,const char * utf8name,napi_value * result)980 NAPI_EXTERN napi_status napi_get_named_property(napi_env env,
981 napi_value object,
982 const char* utf8name,
983 napi_value* result)
984 {
985 NAPI_PREAMBLE(env);
986 CHECK_ARG(env, object);
987 CHECK_ARG(env, utf8name);
988 CHECK_ARG(env, result);
989
990 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
991 panda::JsiFastNativeScope fastNativeScope(vm);
992 Local<panda::JSValueRef> value = JSNApi::NapiGetNamedProperty(vm, reinterpret_cast<uintptr_t>(object), utf8name);
993 RETURN_STATUS_IF_FALSE(env, NapiStatusValidationCheck(value), napi_object_expected);
994 #ifdef ENABLE_CONTAINER_SCOPE
995 FunctionSetContainerId(vm, value);
996 #endif
997 *result = JsValueFromLocalValue(value);
998
999 return GET_RETURN_STATUS(env);
1000 }
1001
napi_get_own_property_descriptor(napi_env env,napi_value object,const char * utf8name,napi_value * result)1002 NAPI_EXTERN napi_status napi_get_own_property_descriptor(napi_env env,
1003 napi_value object,
1004 const char* utf8name,
1005 napi_value* result)
1006 {
1007 CHECK_ENV(env);
1008 CHECK_ARG(env, object);
1009 CHECK_ARG(env, utf8name);
1010 CHECK_ARG(env, result);
1011
1012 auto nativeValue = LocalValueFromJsValue(object);
1013 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1014 panda::JsiFastNativeScope fastNativeScope(vm);
1015 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj);
1016 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, utf8name);
1017 panda::PropertyAttribute property;
1018 obj->GetOwnProperty(vm, key, property);
1019 *result = JsValueFromLocalValue(property.GetValue(vm));
1020 return napi_clear_last_error(env);
1021 }
1022
napi_set_element(napi_env env,napi_value object,uint32_t index,napi_value value)1023 NAPI_EXTERN napi_status napi_set_element(napi_env env, napi_value object, uint32_t index, napi_value value)
1024 {
1025 NAPI_PREAMBLE(env);
1026 CHECK_ARG(env, object);
1027 CHECK_ARG(env, value);
1028
1029 auto nativeValue = LocalValueFromJsValue(object);
1030 auto elementValue = LocalValueFromJsValue(value);
1031 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1032 panda::JsiFastNativeScope fastNativeScope(vm);
1033 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj);
1034 obj->Set(vm, index, elementValue);
1035
1036 return GET_RETURN_STATUS(env);
1037 }
1038
napi_has_element(napi_env env,napi_value object,uint32_t index,bool * result)1039 NAPI_EXTERN napi_status napi_has_element(napi_env env, napi_value object, uint32_t index, bool* result)
1040 {
1041 NAPI_PREAMBLE(env);
1042 CHECK_ARG(env, object);
1043 CHECK_ARG(env, result);
1044
1045 auto nativeValue = LocalValueFromJsValue(object);
1046 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1047 panda::JsiFastNativeScope fastNativeScope(vm);
1048 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj);
1049 *result = obj->Has(vm, index);
1050
1051 return GET_RETURN_STATUS(env);
1052 }
1053
napi_get_element(napi_env env,napi_value object,uint32_t index,napi_value * result)1054 NAPI_EXTERN napi_status napi_get_element(napi_env env, napi_value object, uint32_t index, napi_value* result)
1055 {
1056 NAPI_PREAMBLE(env);
1057 CHECK_ARG(env, object);
1058 CHECK_ARG(env, result);
1059
1060 auto nativeValue = LocalValueFromJsValue(object);
1061 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1062 panda::JsiFastNativeScope fastNativeScope(vm);
1063 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj);
1064 Local<panda::JSValueRef> value = obj->Get(vm, index);
1065 #ifdef ENABLE_CONTAINER_SCOPE
1066 FunctionSetContainerId(vm, value);
1067 #endif
1068 *result = JsValueFromLocalValue(value);
1069
1070 return GET_RETURN_STATUS(env);
1071 }
1072
napi_delete_element(napi_env env,napi_value object,uint32_t index,bool * result)1073 NAPI_EXTERN napi_status napi_delete_element(napi_env env, napi_value object, uint32_t index, bool* result)
1074 {
1075 NAPI_PREAMBLE(env);
1076 CHECK_ARG(env, object);
1077
1078 auto nativeValue = LocalValueFromJsValue(object);
1079 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1080 panda::JsiFastNativeScope fastNativeScope(vm);
1081 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj);
1082 bool deleteResult = obj->Delete(vm, index);
1083 if (result) {
1084 *result = deleteResult;
1085 }
1086
1087 return GET_RETURN_STATUS(env);
1088 }
1089
napi_define_properties(napi_env env,napi_value object,size_t property_count,const napi_property_descriptor * properties)1090 NAPI_EXTERN napi_status napi_define_properties(napi_env env,
1091 napi_value object,
1092 size_t property_count,
1093 const napi_property_descriptor* properties)
1094 {
1095 NAPI_PREAMBLE(env);
1096 CHECK_ARG(env, object);
1097 CHECK_ARG(env, properties);
1098
1099 auto nativeValue = LocalValueFromJsValue(object);
1100 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1101 panda::JsiFastNativeScope fastNativeScope(vm);
1102 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
1103
1104 auto nativeProperties = reinterpret_cast<const NapiPropertyDescriptor*>(properties);
1105 for (size_t i = 0; i < property_count; i++) {
1106 if (nativeProperties[i].utf8name == nullptr) {
1107 auto name = LocalValueFromJsValue(nativeProperties[i].name);
1108 RETURN_STATUS_IF_FALSE(env, !name.IsEmpty() && (name->IsString(vm) || name->IsSymbol(vm)),
1109 napi_name_expected);
1110 }
1111 NapiDefineProperty(env, nativeObject, nativeProperties[i]);
1112 }
1113 return GET_RETURN_STATUS(env);
1114 }
1115
1116 // Methods to work with Arrays
napi_is_array(napi_env env,napi_value value,bool * result)1117 NAPI_EXTERN napi_status napi_is_array(napi_env env, napi_value value, bool* result)
1118 {
1119 CHECK_ENV(env);
1120 CHECK_ARG(env, value);
1121 CHECK_ARG(env, result);
1122
1123 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1124 panda::JsiFastNativeScope fastNativeScope(vm);
1125
1126 auto nativeValue = LocalValueFromJsValue(value);
1127 *result = nativeValue->IsJSArray(vm) || nativeValue->IsSharedArray(vm);
1128 return napi_clear_last_error(env);
1129 }
1130
napi_get_array_length(napi_env env,napi_value value,uint32_t * result)1131 NAPI_EXTERN napi_status napi_get_array_length(napi_env env, napi_value value, uint32_t* result)
1132 {
1133 // Omit to use NAPI_PREAMBLE and CHECK_ARG directly for performance.
1134 CHECK_ENV(env);
1135 RETURN_STATUS_IF_FALSE(env, (reinterpret_cast<NativeEngine*>(env))->lastException_.IsEmpty(),
1136 napi_pending_exception);
1137 napi_clear_last_error((env));
1138
1139 // This interface will not throw JS exceptions actively.
1140 // JS exception can only occur before calling the interface.
1141 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1142
1143 // check value and result
1144 if ((value == nullptr) || (result == nullptr)) {
1145 if (panda::JSNApi::HasPendingException(vm)) {
1146 reinterpret_cast<NativeEngine *>(env)->lastException_ = panda::JSNApi::GetUncaughtException(vm);
1147 }
1148 return napi_set_last_error(env, napi_invalid_arg);
1149 }
1150
1151 // get array length
1152 bool isArrayOrSharedArray = false;
1153 bool isPendingException = false;
1154 panda::Local<panda::JSValueRef> nativeValue = LocalValueFromJsValue(value);
1155 nativeValue->TryGetArrayLength(vm, &isPendingException, &isArrayOrSharedArray, result);
1156
1157 if (!isArrayOrSharedArray) {
1158 if (isPendingException) {
1159 reinterpret_cast<NativeEngine *>(env)->lastException_ = panda::JSNApi::GetUncaughtException(vm);
1160 }
1161 return napi_set_last_error(env, napi_array_expected);
1162 }
1163
1164 if (UNLIKELY(isPendingException)) {
1165 HILOG_ERROR("pending exception before napi_get_array_length called, print exception info: ");
1166 panda::JSNApi::PrintExceptionInfo(vm);
1167 reinterpret_cast<NativeEngine *>(env)->lastException_ = panda::JSNApi::GetUncaughtException(vm);
1168 return napi_set_last_error(env, napi_pending_exception);
1169 }
1170 return napi_ok;
1171 }
1172
napi_is_sendable(napi_env env,napi_value value,bool * result)1173 NAPI_EXTERN napi_status napi_is_sendable(napi_env env, napi_value value, bool* result)
1174 {
1175 CHECK_ENV(env);
1176 CHECK_ARG(env, value);
1177 CHECK_ARG(env, result);
1178
1179 auto nativeValue = LocalValueFromJsValue(value);
1180 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1181 panda::JsiFastNativeScope fastNativeScope(vm);
1182
1183 *result = nativeValue->IsJSShared(vm) || nativeValue->IsString(vm) || nativeValue->IsNumber() ||
1184 nativeValue->IsBoolean() || nativeValue->IsUndefined() || nativeValue->IsNull() ||
1185 nativeValue->IsBigInt(vm);
1186 return napi_clear_last_error(env);
1187 }
1188
1189 // Methods to compare values
napi_strict_equals(napi_env env,napi_value lhs,napi_value rhs,bool * result)1190 NAPI_EXTERN napi_status napi_strict_equals(napi_env env, napi_value lhs, napi_value rhs, bool* result)
1191 {
1192 CHECK_ENV(env);
1193 CHECK_ARG(env, lhs);
1194 CHECK_ARG(env, rhs);
1195 CHECK_ARG(env, result);
1196
1197 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1198 auto nativeLhs = LocalValueFromJsValue(lhs);
1199 auto nativeRhs = LocalValueFromJsValue(rhs);
1200 *result = nativeLhs->IsStrictEquals(vm, nativeRhs);
1201 return napi_clear_last_error(env);
1202 }
1203
1204 // 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)1205 NAPI_EXTERN napi_status napi_call_function(napi_env env,
1206 napi_value recv,
1207 napi_value func,
1208 size_t argc,
1209 const napi_value* argv,
1210 napi_value* result)
1211 {
1212 CHECK_ENV((env));
1213 RETURN_STATUS_IF_FALSE((env), (reinterpret_cast<NativeEngine*>(env))->lastException_.IsEmpty(),
1214 napi_pending_exception);
1215 napi_clear_last_error((env));
1216 CHECK_ARG(env, func);
1217 if (argc > 0) {
1218 CHECK_ARG(env, argv);
1219 }
1220
1221 auto vm = reinterpret_cast<NativeEngine *>(env)->GetEcmaVm();
1222 panda::JsiFastNativeScope fastNativeScope(vm);
1223
1224 RETURN_STATUS_IF_FALSE(env, reinterpret_cast<panda::JSValueRef *>(func)->IsFunction(vm), napi_function_expected);
1225 panda::JSValueRef* thisObj = reinterpret_cast<panda::JSValueRef *>(recv);
1226 panda::FunctionRef* function = reinterpret_cast<panda::FunctionRef *>(func);
1227 #ifdef ENABLE_CONTAINER_SCOPE
1228 int32_t scopeId = OHOS::Ace::ContainerScope::CurrentId();
1229 if (!function->IsConcurrentFunction(vm)) {
1230 auto funcInfo = reinterpret_cast<NapiFunctionInfo *>(function->GetData(vm));
1231 if (funcInfo != nullptr) {
1232 scopeId = funcInfo->scopeId;
1233 }
1234 }
1235 OHOS::Ace::ContainerScope containerScope(scopeId);
1236 #endif
1237 panda::JSValueRef* value =
1238 function->CallForNapi(vm, thisObj, reinterpret_cast<panda::JSValueRef *const*>(argv), argc);
1239 // if pending exception, value will be a pointer to JSTaggedValue::Hole.
1240 if (UNLIKELY(!NapiStatusValidationCheck(value))) {
1241 HILOG_ERROR("pending exception when js function called, print exception info: ");
1242 panda::JSNApi::PrintExceptionInfo(vm);
1243 result = nullptr;
1244 reinterpret_cast<NativeEngine *>(env)->lastException_ = panda::JSNApi::GetUncaughtException(vm);
1245 return napi_set_last_error(env, napi_pending_exception);
1246 }
1247 if (result) {
1248 *result = reinterpret_cast<napi_value>(value);
1249 }
1250 return napi_clear_last_error(env);
1251 }
1252
napi_new_instance(napi_env env,napi_value constructor,size_t argc,const napi_value * argv,napi_value * result)1253 NAPI_EXTERN napi_status napi_new_instance(napi_env env,
1254 napi_value constructor,
1255 size_t argc,
1256 const napi_value* argv,
1257 napi_value* result)
1258 {
1259 NAPI_PREAMBLE(env);
1260 CHECK_ARG(env, constructor);
1261 if (argc > 0) {
1262 CHECK_ARG(env, argv);
1263 }
1264 CHECK_ARG(env, result);
1265
1266 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1267 panda::JsiFastNativeScope fastNativeScope(vm);
1268
1269 RETURN_STATUS_IF_FALSE(env, reinterpret_cast<panda::JSValueRef*>(constructor)->IsFunction(vm),
1270 napi_function_expected);
1271 panda::FunctionRef* constructorVal = reinterpret_cast<panda::FunctionRef*>(constructor);
1272 panda::JSValueRef* instance = constructorVal->ConstructorOptimize(vm,
1273 reinterpret_cast<panda::JSValueRef**>(const_cast<napi_value*>(argv)), argc);
1274 if (tryCatch.HasCaught()) {
1275 HILOG_ERROR("CreateInstance occur Exception");
1276 *result = nullptr;
1277 } else {
1278 *result = reinterpret_cast<napi_value>(instance);
1279 }
1280 return GET_RETURN_STATUS(env);
1281 }
1282
napi_instanceof(napi_env env,napi_value object,napi_value constructor,bool * result)1283 NAPI_EXTERN napi_status napi_instanceof(napi_env env, napi_value object, napi_value constructor, bool* result)
1284 {
1285 NAPI_PREAMBLE(env);
1286 CHECK_ARG(env, object);
1287 CHECK_ARG(env, constructor);
1288 CHECK_ARG(env, result);
1289
1290 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1291 panda::JsiFastNativeScope fastNativeScope(vm);
1292
1293 auto nativeValue = LocalValueFromJsValue(object);
1294 auto nativeConstructor = LocalValueFromJsValue(constructor);
1295 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
1296 RETURN_STATUS_IF_FALSE(env, nativeConstructor->IsFunction(vm), napi_function_expected);
1297 *result = nativeValue->InstanceOf(vm, nativeConstructor);
1298
1299 return GET_RETURN_STATUS(env);
1300 }
1301
1302 // Methods to work with napi_callbacks
1303 // 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)1304 NAPI_EXTERN napi_status napi_get_cb_info(napi_env env, // [in] NAPI environment handle
1305 napi_callback_info cbinfo, // [in] Opaque callback-info handle
1306 size_t* argc, // [in-out] Specifies the size of the provided argv array
1307 // and receives the actual count of args.
1308 napi_value* argv, // [out] Array of values
1309 napi_value* this_arg, // [out] Receives the JS 'this' arg for the call
1310 void** data) // [out] Receives the data pointer for the callback.
1311 {
1312 CHECK_ENV(env);
1313 CHECK_ARG(env, cbinfo);
1314
1315 auto info = reinterpret_cast<panda::JsiRuntimeCallInfo*>(cbinfo);
1316 if ((argc != nullptr) && (argv != nullptr)) {
1317 #ifdef ENABLE_CONTAINER_SCOPE
1318 auto *vm = info->GetVM();
1319 #endif
1320 size_t i = 0;
1321 if (*argc > 0) {
1322 size_t j = static_cast<size_t>(info->GetArgsNumber());
1323 for (; i < j && i < *argc; i++) {
1324 panda::Local<panda::JSValueRef> value = info->GetCallArgRef(i);
1325 #ifdef ENABLE_CONTAINER_SCOPE
1326 FunctionSetContainerId(vm, value);
1327 #endif
1328 argv[i] = JsValueFromLocalValue(value);
1329 }
1330 } else {
1331 i = static_cast<size_t>(info->GetArgsNumber());
1332 }
1333 if (i < *argc) {
1334 napi_value undefined = JsValueFromLocalValue(
1335 panda::JSValueRef::Undefined(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm()));
1336 for (; i < *argc; i++) {
1337 argv[i] = undefined;
1338 }
1339 }
1340 }
1341 if (argc != nullptr) {
1342 *argc = static_cast<size_t>(info->GetArgsNumber());
1343 }
1344 if (this_arg != nullptr) {
1345 *this_arg = JsValueFromLocalValue(info->GetThisRef());
1346 }
1347 if (data != nullptr) {
1348 auto funcInfo = static_cast<NapiFunctionInfo*>(info->GetData());
1349 if (funcInfo != nullptr) {
1350 *data = funcInfo->data;
1351 }
1352 }
1353
1354 return napi_clear_last_error(env);
1355 }
1356
napi_get_new_target(napi_env env,napi_callback_info cbinfo,napi_value * result)1357 NAPI_EXTERN napi_status napi_get_new_target(napi_env env, napi_callback_info cbinfo, napi_value* result)
1358 {
1359 NAPI_PREAMBLE(env);
1360 CHECK_ARG(env, cbinfo);
1361 CHECK_ARG(env, result);
1362
1363 auto info = reinterpret_cast<panda::JsiRuntimeCallInfo*>(cbinfo);
1364 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1365 auto thisVarObj = info->GetThisRef();
1366 #ifdef ENABLE_CONTAINER_SCOPE
1367 panda::Local<panda::JSValueRef> newValue = info->GetNewTargetRef();
1368 FunctionSetContainerId(vm, newValue);
1369 auto functionVal = newValue;
1370 #else
1371 auto functionVal = info->GetNewTargetRef();
1372 #endif
1373 if (thisVarObj->InstanceOf(vm, functionVal)) {
1374 *result = JsValueFromLocalValue(functionVal);
1375 } else {
1376 *result = nullptr;
1377 }
1378
1379 return GET_RETURN_STATUS(env);
1380 }
1381
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)1382 NAPI_EXTERN napi_status napi_define_class(napi_env env,
1383 const char* utf8name,
1384 size_t length,
1385 napi_callback constructor,
1386 void* data,
1387 size_t property_count,
1388 const napi_property_descriptor* properties,
1389 napi_value* result)
1390 {
1391 NAPI_PREAMBLE(env);
1392 CHECK_ARG(env, utf8name);
1393 RETURN_STATUS_IF_FALSE(env, length == NAPI_AUTO_LENGTH || length <= INT_MAX, napi_object_expected);
1394 CHECK_ARG(env, constructor);
1395 if (property_count > 0) {
1396 CHECK_ARG(env, properties);
1397 }
1398 CHECK_ARG(env, result);
1399
1400 auto callback = reinterpret_cast<NapiNativeCallback>(constructor);
1401 auto nativeProperties = reinterpret_cast<const NapiPropertyDescriptor*>(properties);
1402
1403 size_t nameLength = std::min(length, strlen(utf8name));
1404 char newName[nameLength + 1];
1405 if (strncpy_s(newName, nameLength + 1, utf8name, nameLength) != EOK) {
1406 HILOG_ERROR("napi_define_class strncpy_s failed");
1407 *result = nullptr;
1408 } else {
1409 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1410 panda::JsiFastNativeScope fastNativeScope(vm);
1411 EscapeLocalScope scope(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm());
1412 auto resultValue = NapiDefineClass(env, newName, callback, data, nativeProperties, property_count);
1413 *result = JsValueFromLocalValue(scope.Escape(resultValue));
1414 }
1415
1416 return GET_RETURN_STATUS(env);
1417 }
1418
napi_define_sendable_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 parent,napi_value * result)1419 NAPI_EXTERN napi_status napi_define_sendable_class(napi_env env,
1420 const char* utf8name,
1421 size_t length,
1422 napi_callback constructor,
1423 void* data,
1424 size_t property_count,
1425 const napi_property_descriptor* properties,
1426 napi_value parent,
1427 napi_value* result)
1428 {
1429 NAPI_PREAMBLE(env);
1430 CHECK_ARG(env, utf8name);
1431 RETURN_STATUS_IF_FALSE(env, length == NAPI_AUTO_LENGTH || length <= INT_MAX,
1432 napi_object_expected);
1433 CHECK_ARG(env, constructor);
1434 if (property_count > 0) {
1435 CHECK_ARG(env, properties);
1436 }
1437 CHECK_ARG(env, result);
1438
1439 auto callback = reinterpret_cast<NapiNativeCallback>(constructor);
1440 auto nativeProperties = reinterpret_cast<const NapiPropertyDescriptor*>(properties);
1441
1442 size_t nameLength = std::min(length, strlen(utf8name));
1443 char newName[nameLength + 1];
1444 if (strncpy_s(newName, nameLength + 1, utf8name, nameLength) != EOK) {
1445 HILOG_ERROR("napi_define_sendable_class strncpy_s failed");
1446 *result = nullptr;
1447 } else {
1448 EscapeLocalScope scope(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm());
1449 auto resultValue =
1450 NapiDefineSendableClass(env, newName, callback, data, nativeProperties, property_count, parent);
1451 *result = JsValueFromLocalValue(scope.Escape(resultValue));
1452 }
1453
1454 return GET_RETURN_STATUS(env);
1455 }
1456
napi_create_sendable_object_with_properties(napi_env env,size_t property_count,const napi_property_descriptor * properties,napi_value * result)1457 NAPI_EXTERN napi_status napi_create_sendable_object_with_properties(napi_env env,
1458 size_t property_count,
1459 const napi_property_descriptor* properties,
1460 napi_value* result)
1461 {
1462 CHECK_ENV(env);
1463 CHECK_ARG(env, result);
1464
1465 auto nativeProperties = reinterpret_cast<const NapiPropertyDescriptor*>(properties);
1466 auto object = NapiCreateSObjectWithProperties(env, property_count, nativeProperties);
1467 *result = JsValueFromLocalValue(object);
1468
1469 return napi_clear_last_error(env);
1470 }
1471
napi_create_map(napi_env env,napi_value * result)1472 NAPI_EXTERN napi_status napi_create_map(napi_env env, napi_value* result)
1473 {
1474 CHECK_ENV(env);
1475 CHECK_ARG(env, result);
1476
1477 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1478 Local<panda::ArrayRef> object = panda::MapRef::New(vm);
1479 *result = JsValueFromLocalValue(object);
1480
1481 return napi_clear_last_error(env);
1482 }
1483
napi_create_sendable_map(napi_env env,napi_value * result)1484 NAPI_EXTERN napi_status napi_create_sendable_map(napi_env env, napi_value* result)
1485 {
1486 CHECK_ENV(env);
1487 CHECK_ARG(env, result);
1488
1489 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1490 Local<panda::ArrayRef> object = panda::SendableMapRef::New(vm);
1491 *result = JsValueFromLocalValue(object);
1492
1493 return napi_clear_last_error(env);
1494 }
1495
napi_map_set_property(napi_env env,napi_value map,napi_value key,napi_value value)1496 NAPI_EXTERN napi_status napi_map_set_property(napi_env env, napi_value map, napi_value key, napi_value value)
1497 {
1498 NAPI_PREAMBLE(env);
1499 CHECK_ARG(env, map);
1500 CHECK_ARG(env, key);
1501 CHECK_ARG(env, value);
1502
1503 auto nativeValue = LocalValueFromJsValue(map);
1504 auto propKey = LocalValueFromJsValue(key);
1505 auto propValue = LocalValueFromJsValue(value);
1506 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1507 panda::JsiFastNativeScope fastNativeScope(vm);
1508 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1509 if (LIKELY(nativeValue->IsMap(vm))) {
1510 Local<panda::MapRef> mapRef(nativeValue);
1511 mapRef->Set(vm, propKey, propValue);
1512 } else {
1513 Local<panda::SendableMapRef> mapRef(nativeValue);
1514 mapRef->Set(vm, propKey, propValue);
1515 }
1516
1517 return GET_RETURN_STATUS(env);
1518 }
1519
napi_map_set_named_property(napi_env env,napi_value map,const char * utf8name,napi_value value)1520 NAPI_EXTERN napi_status napi_map_set_named_property(napi_env env,
1521 napi_value map,
1522 const char* utf8name,
1523 napi_value value)
1524 {
1525 NAPI_PREAMBLE(env);
1526 CHECK_ARG(env, map);
1527 CHECK_ARG(env, utf8name);
1528 CHECK_ARG(env, value);
1529
1530 auto nativeValue = LocalValueFromJsValue(map);
1531 auto propVal = LocalValueFromJsValue(value);
1532 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1533 panda::JsiFastNativeScope fastNativeScope(vm);
1534 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1535 Local<panda::MapRef> mapRef(nativeValue);
1536 if (LIKELY(nativeValue->IsMap(vm))) {
1537 Local<panda::MapRef> mapRef(nativeValue);
1538 mapRef->Set(vm, utf8name, propVal);
1539 } else {
1540 Local<panda::SendableMapRef> mapRef(nativeValue);
1541 mapRef->Set(vm, utf8name, propVal);
1542 }
1543
1544 return GET_RETURN_STATUS(env);
1545 }
1546
napi_map_get_property(napi_env env,napi_value map,napi_value key,napi_value * result)1547 NAPI_EXTERN napi_status napi_map_get_property(napi_env env, napi_value map, napi_value key, napi_value* result)
1548 {
1549 NAPI_PREAMBLE(env);
1550 CHECK_ARG(env, map);
1551 CHECK_ARG(env, key);
1552 CHECK_ARG(env, result);
1553
1554 auto nativeValue = LocalValueFromJsValue(map);
1555 auto propKey = LocalValueFromJsValue(key);
1556 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1557 panda::JsiFastNativeScope fastNativeScope(vm);
1558 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1559 Local<JSValueRef> value;
1560 if (LIKELY(nativeValue->IsMap(vm))) {
1561 Local<panda::MapRef> mapRef(nativeValue);
1562 value = mapRef->Get(vm, propKey);
1563 } else {
1564 Local<panda::SendableMapRef> mapRef(nativeValue);
1565 value = mapRef->Get(vm, propKey);
1566 }
1567 RETURN_STATUS_IF_FALSE(env, NapiStatusValidationCheck(value), napi_object_expected);
1568 *result = JsValueFromLocalValue(value);
1569
1570 return GET_RETURN_STATUS(env);
1571 }
1572
napi_map_get_named_property(napi_env env,napi_value map,const char * utf8name,napi_value * result)1573 NAPI_EXTERN napi_status napi_map_get_named_property(napi_env env,
1574 napi_value map,
1575 const char* utf8name,
1576 napi_value* result)
1577 {
1578 NAPI_PREAMBLE(env);
1579 CHECK_ARG(env, map);
1580 CHECK_ARG(env, utf8name);
1581 CHECK_ARG(env, result);
1582
1583 auto nativeValue = LocalValueFromJsValue(map);
1584 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1585 panda::JsiFastNativeScope fastNativeScope(vm);
1586 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1587 Local<JSValueRef> value;
1588 if (LIKELY(nativeValue->IsMap(vm))) {
1589 Local<panda::MapRef> mapRef(nativeValue);
1590 value = mapRef->Get(vm, utf8name);
1591 } else {
1592 Local<panda::SendableMapRef> mapRef(nativeValue);
1593 value = mapRef->Get(vm, utf8name);
1594 }
1595 RETURN_STATUS_IF_FALSE(env, NapiStatusValidationCheck(value), napi_object_expected);
1596 *result = JsValueFromLocalValue(value);
1597
1598 return GET_RETURN_STATUS(env);
1599 }
1600
napi_map_has_property(napi_env env,napi_value map,napi_value key,bool * result)1601 NAPI_EXTERN napi_status napi_map_has_property(napi_env env, napi_value map, napi_value key, bool* result)
1602 {
1603 NAPI_PREAMBLE(env);
1604 CHECK_ARG(env, map);
1605 CHECK_ARG(env, key);
1606 CHECK_ARG(env, result);
1607
1608 auto nativeValue = LocalValueFromJsValue(map);
1609 auto propKey = LocalValueFromJsValue(key);
1610 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1611 panda::JsiFastNativeScope fastNativeScope(vm);
1612 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1613 bool value;
1614 if (LIKELY(nativeValue->IsMap(vm))) {
1615 Local<panda::MapRef> mapRef(nativeValue);
1616 value = mapRef->Has(vm, propKey);
1617 } else {
1618 Local<panda::SendableMapRef> mapRef(nativeValue);
1619 value = mapRef->Has(vm, propKey);
1620 }
1621 *result = value;
1622
1623 return GET_RETURN_STATUS(env);
1624 }
1625
napi_map_has_named_property(napi_env env,napi_value map,const char * utf8name,bool * result)1626 NAPI_EXTERN napi_status napi_map_has_named_property(napi_env env, napi_value map, const char* utf8name, bool* result)
1627 {
1628 NAPI_PREAMBLE(env);
1629 CHECK_ARG(env, map);
1630 CHECK_ARG(env, utf8name);
1631 CHECK_ARG(env, result);
1632
1633 auto nativeValue = LocalValueFromJsValue(map);
1634 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1635 panda::JsiFastNativeScope fastNativeScope(vm);
1636 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1637 bool value;
1638 if (LIKELY(nativeValue->IsMap(vm))) {
1639 Local<panda::MapRef> mapRef(nativeValue);
1640 value = mapRef->Has(vm, utf8name);
1641 } else {
1642 Local<panda::SendableMapRef> mapRef(nativeValue);
1643 value = mapRef->Has(vm, utf8name);
1644 }
1645 *result = value;
1646
1647 return GET_RETURN_STATUS(env);
1648 }
1649
napi_map_delete_property(napi_env env,napi_value map,napi_value key)1650 NAPI_EXTERN napi_status napi_map_delete_property(napi_env env, napi_value map, napi_value key)
1651 {
1652 NAPI_PREAMBLE(env);
1653 CHECK_ARG(env, map);
1654 CHECK_ARG(env, key);
1655
1656 auto nativeValue = LocalValueFromJsValue(map);
1657 auto propKey = LocalValueFromJsValue(key);
1658 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1659 panda::JsiFastNativeScope fastNativeScope(vm);
1660 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1661 if (LIKELY(nativeValue->IsMap(vm))) {
1662 Local<panda::MapRef> mapRef(nativeValue);
1663 mapRef->Delete(vm, propKey);
1664 } else {
1665 Local<panda::SendableMapRef> mapRef(nativeValue);
1666 mapRef->Delete(vm, propKey);
1667 }
1668
1669 return GET_RETURN_STATUS(env);
1670 }
1671
napi_map_clear(napi_env env,napi_value map)1672 NAPI_EXTERN napi_status napi_map_clear(napi_env env, napi_value map)
1673 {
1674 NAPI_PREAMBLE(env);
1675 CHECK_ARG(env, map);
1676
1677 auto nativeValue = LocalValueFromJsValue(map);
1678 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1679 panda::JsiFastNativeScope fastNativeScope(vm);
1680 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1681 if (LIKELY(nativeValue->IsMap(vm))) {
1682 Local<panda::MapRef> mapRef(nativeValue);
1683 mapRef->Clear(vm);
1684 } else {
1685 Local<panda::SendableMapRef> mapRef(nativeValue);
1686 mapRef->Clear(vm);
1687 }
1688
1689 return GET_RETURN_STATUS(env);
1690 }
1691
napi_map_get_size(napi_env env,napi_value map,uint32_t * result)1692 NAPI_EXTERN napi_status napi_map_get_size(napi_env env, napi_value map, uint32_t* result)
1693 {
1694 NAPI_PREAMBLE(env);
1695 CHECK_ARG(env, map);
1696 CHECK_ARG(env, result);
1697
1698 auto nativeValue = LocalValueFromJsValue(map);
1699 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1700 panda::JsiFastNativeScope fastNativeScope(vm);
1701 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1702 uint32_t value;
1703 if (LIKELY(nativeValue->IsMap(vm))) {
1704 Local<panda::MapRef> mapRef(nativeValue);
1705 value = static_cast<uint32_t>(mapRef->GetSize(vm));
1706 } else {
1707 Local<panda::SendableMapRef> mapRef(nativeValue);
1708 value = static_cast<uint32_t>(mapRef->GetSize(vm));
1709 }
1710 *result = value;
1711
1712 return GET_RETURN_STATUS(env);
1713 }
1714
napi_map_get_entries(napi_env env,napi_value map,napi_value * result)1715 NAPI_EXTERN napi_status napi_map_get_entries(napi_env env, napi_value map, napi_value* result)
1716 {
1717 NAPI_PREAMBLE(env);
1718 CHECK_ARG(env, map);
1719 CHECK_ARG(env, result);
1720
1721 auto nativeValue = LocalValueFromJsValue(map);
1722 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1723 panda::JsiFastNativeScope fastNativeScope(vm);
1724 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1725 if (LIKELY(nativeValue->IsMap(vm))) {
1726 Local<panda::MapRef> mapRef(nativeValue);
1727 Local<panda::ArrayRef> arrayVal = mapRef->GetEntries(vm);
1728 *result = JsValueFromLocalValue(arrayVal);
1729 } else {
1730 Local<panda::SendableMapRef> mapRef(nativeValue);
1731 Local<panda::SendableArrayRef> arrayVal = mapRef->GetEntries(vm);
1732 *result = JsValueFromLocalValue(arrayVal);
1733 }
1734 return GET_RETURN_STATUS(env);
1735 }
1736
napi_map_get_keys(napi_env env,napi_value map,napi_value * result)1737 NAPI_EXTERN napi_status napi_map_get_keys(napi_env env, napi_value map, napi_value* result)
1738 {
1739 NAPI_PREAMBLE(env);
1740 CHECK_ARG(env, map);
1741 CHECK_ARG(env, result);
1742
1743 auto nativeValue = LocalValueFromJsValue(map);
1744 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1745 panda::JsiFastNativeScope fastNativeScope(vm);
1746 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1747 if (LIKELY(nativeValue->IsMap(vm))) {
1748 Local<panda::MapRef> mapRef(nativeValue);
1749 Local<panda::ArrayRef> arrayVal = mapRef->GetKeys(vm);
1750 *result = JsValueFromLocalValue(arrayVal);
1751 } else {
1752 Local<panda::SendableMapRef> mapRef(nativeValue);
1753 Local<panda::SendableArrayRef> arrayVal = mapRef->GetKeys(vm);
1754 *result = JsValueFromLocalValue(arrayVal);
1755 }
1756 return GET_RETURN_STATUS(env);
1757 }
1758
napi_map_get_values(napi_env env,napi_value map,napi_value * result)1759 NAPI_EXTERN napi_status napi_map_get_values(napi_env env, napi_value map, napi_value* result)
1760 {
1761 NAPI_PREAMBLE(env);
1762 CHECK_ARG(env, map);
1763 CHECK_ARG(env, result);
1764
1765 auto nativeValue = LocalValueFromJsValue(map);
1766 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1767 panda::JsiFastNativeScope fastNativeScope(vm);
1768 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1769 if (LIKELY(nativeValue->IsMap(vm))) {
1770 Local<panda::MapRef> mapRef(nativeValue);
1771 Local<panda::ArrayRef> arrayVal = mapRef->GetValues(vm);
1772 *result = JsValueFromLocalValue(arrayVal);
1773 } else {
1774 Local<panda::SendableMapRef> mapRef(nativeValue);
1775 Local<panda::SendableArrayRef> arrayVal = mapRef->GetValues(vm);
1776 *result = JsValueFromLocalValue(arrayVal);
1777 }
1778 return GET_RETURN_STATUS(env);
1779 }
1780
napi_map_iterator_get_next(napi_env env,napi_value iterator,napi_value * result)1781 NAPI_EXTERN napi_status napi_map_iterator_get_next(napi_env env, napi_value iterator, napi_value* result)
1782 {
1783 NAPI_PREAMBLE(env);
1784 CHECK_ARG(env, iterator);
1785 CHECK_ARG(env, result);
1786
1787 auto nativeValue = LocalValueFromJsValue(iterator);
1788 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1789 panda::JsiFastNativeScope fastNativeScope(vm);
1790 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMapIterator(vm) || nativeValue->IsSharedMapIterator(vm),
1791 napi_object_expected);
1792 Local<panda::JSValueRef> value;
1793 if (LIKELY(nativeValue->IsMapIterator(vm))) {
1794 Local<panda::MapIteratorRef> mapIter(nativeValue);
1795 value = mapIter->Next(vm);
1796 } else {
1797 Local<panda::SendableMapIteratorRef> mapIter(nativeValue);
1798 value = mapIter->Next(vm);
1799 }
1800 *result = JsValueFromLocalValue(value);
1801 return GET_RETURN_STATUS(env);
1802 }
1803
1804 // 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)1805 NAPI_EXTERN napi_status napi_wrap(napi_env env,
1806 napi_value js_object,
1807 void* native_object,
1808 napi_finalize finalize_cb,
1809 void* finalize_hint,
1810 napi_ref* result)
1811 {
1812 NAPI_PREAMBLE(env);
1813 CHECK_ARG(env, js_object);
1814 CHECK_ARG(env, native_object);
1815 CHECK_ARG(env, finalize_cb);
1816
1817 auto nativeValue = LocalValueFromJsValue(js_object);
1818 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
1819 auto engine = reinterpret_cast<NativeEngine*>(env);
1820 auto vm = engine->GetEcmaVm();
1821 panda::JsiFastNativeScope fastNativeScope(vm);
1822 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
1823 size_t nativeBindingSize = 0;
1824 auto reference = reinterpret_cast<NativeReference**>(result);
1825 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1826 if (native_object == nullptr && nativeObject->Has(vm, key)) {
1827 Local<panda::ObjectRef> wrapper = nativeObject->Get(vm, key);
1828 auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(vm, 0));
1829 // Try to remove native pointer from ArrayDataList
1830 wrapper->SetNativePointerField(vm, 0, nullptr, nullptr, nullptr, nativeBindingSize);
1831 nativeObject->Delete(vm, key);
1832 delete ref;
1833 } else {
1834 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
1835 NativeReference* ref = nullptr;
1836 if (reference != nullptr) {
1837 ref = engine->CreateReference(js_object, 1, false, callback, native_object, finalize_hint);
1838 *reference = ref;
1839 } else {
1840 ref = engine->CreateReference(js_object, 0, true, callback, native_object, finalize_hint);
1841 }
1842 object->SetNativePointerFieldCount(vm, 1);
1843 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, nativeBindingSize);
1844 PropertyAttribute attr(object, true, false, true);
1845 nativeObject->DefineProperty(vm, key, attr);
1846 }
1847 return GET_RETURN_STATUS(env);
1848 }
1849
1850 // Methods to work with external data objects, support pass native_object size and finalize_cb async execute or not
napi_wrap_enhance(napi_env env,napi_value js_object,void * native_object,napi_finalize finalize_cb,bool async_finalizer,void * finalize_hint,size_t native_binding_size,napi_ref * result)1851 NAPI_EXTERN napi_status napi_wrap_enhance(napi_env env,
1852 napi_value js_object,
1853 void* native_object,
1854 napi_finalize finalize_cb,
1855 bool async_finalizer,
1856 void* finalize_hint,
1857 size_t native_binding_size,
1858 napi_ref* result)
1859 {
1860 NAPI_PREAMBLE(env);
1861 CHECK_ARG(env, js_object);
1862 CHECK_ARG(env, native_object);
1863
1864 auto nativeValue = LocalValueFromJsValue(js_object);
1865 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
1866 auto engine = reinterpret_cast<NativeEngine*>(env);
1867 auto vm = engine->GetEcmaVm();
1868 panda::JsiFastNativeScope fastNativeScope(vm);
1869 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
1870 auto reference = reinterpret_cast<NativeReference**>(result);
1871 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1872 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
1873 NativeReference* ref = nullptr;
1874 if (!async_finalizer) {
1875 if (reference != nullptr) {
1876 ref = engine->CreateReference(js_object, 1, false, callback, native_object, finalize_hint,
1877 native_binding_size);
1878 *reference = ref;
1879 } else {
1880 ref = engine->CreateReference(js_object, 0, true, callback, native_object, finalize_hint,
1881 native_binding_size);
1882 }
1883 } else {
1884 if (reference != nullptr) {
1885 ref = engine->CreateAsyncReference(js_object, 1, false, callback, native_object, finalize_hint);
1886 *reference = ref;
1887 } else {
1888 ref = engine->CreateAsyncReference(js_object, 0, true, callback, native_object, finalize_hint);
1889 }
1890 }
1891 object->SetNativePointerFieldCount(vm, 1);
1892 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, native_binding_size);
1893 PropertyAttribute attr(object, true, false, true);
1894 nativeObject->DefineProperty(vm, key, attr);
1895 return GET_RETURN_STATUS(env);
1896 }
1897
1898 // Ensure thread safety! Async finalizer will be called on the async thread.
napi_wrap_async_finalizer(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)1899 NAPI_EXTERN napi_status napi_wrap_async_finalizer(napi_env env,
1900 napi_value js_object,
1901 void* native_object,
1902 napi_finalize finalize_cb,
1903 void* finalize_hint,
1904 napi_ref* result,
1905 size_t native_binding_size)
1906 {
1907 NAPI_PREAMBLE(env);
1908 CHECK_ARG(env, js_object);
1909 CHECK_ARG(env, native_object);
1910
1911 auto nativeValue = LocalValueFromJsValue(js_object);
1912 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
1913 auto engine = reinterpret_cast<NativeEngine*>(env);
1914 auto vm = engine->GetEcmaVm();
1915 panda::JsiFastNativeScope fastNativeScope(vm);
1916 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
1917 auto reference = reinterpret_cast<NativeReference**>(result);
1918 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1919 if (native_object == nullptr && nativeObject->Has(vm, key)) {
1920 Local<panda::ObjectRef> wrapper = nativeObject->Get(vm, key);
1921 auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(vm, 0));
1922 // Try to remove native pointer from ArrayDataList
1923 wrapper->SetNativePointerField(vm, 0, nullptr, nullptr, nullptr, native_binding_size);
1924 nativeObject->Delete(vm, key);
1925 delete ref;
1926 } else {
1927 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
1928 NativeReference* ref = nullptr;
1929 if (reference != nullptr) {
1930 ref = engine->CreateAsyncReference(js_object, 1, false, callback, native_object, finalize_hint);
1931 *reference = ref;
1932 } else {
1933 ref = engine->CreateAsyncReference(js_object, 0, true, callback, native_object, finalize_hint);
1934 }
1935 object->SetNativePointerFieldCount(vm, 1);
1936 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, native_binding_size);
1937 PropertyAttribute attr(object, true, false, true);
1938 nativeObject->DefineProperty(vm, key, attr);
1939 }
1940 return GET_RETURN_STATUS(env);
1941 }
1942
1943 // 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)1944 NAPI_EXTERN napi_status napi_wrap_with_size(napi_env env,
1945 napi_value js_object,
1946 void* native_object,
1947 napi_finalize finalize_cb,
1948 void* finalize_hint,
1949 napi_ref* result,
1950 size_t native_binding_size)
1951 {
1952 NAPI_PREAMBLE(env);
1953 CHECK_ARG(env, js_object);
1954 CHECK_ARG(env, native_object);
1955
1956 auto nativeValue = LocalValueFromJsValue(js_object);
1957 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
1958 auto engine = reinterpret_cast<NativeEngine*>(env);
1959 auto vm = engine->GetEcmaVm();
1960 panda::JsiFastNativeScope fastNativeScope(vm);
1961 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
1962 auto reference = reinterpret_cast<NativeReference**>(result);
1963 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1964 if (native_object == nullptr && nativeObject->Has(vm, key)) {
1965 Local<panda::ObjectRef> wrapper = nativeObject->Get(vm, key);
1966 auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(vm, 0));
1967 // Try to remove native pointer from ArrayDataList
1968 wrapper->SetNativePointerField(vm, 0, nullptr, nullptr, nullptr, native_binding_size);
1969 nativeObject->Delete(vm, key);
1970 delete ref;
1971 } else {
1972 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
1973 NativeReference* ref = nullptr;
1974 if (reference != nullptr) {
1975 ref = engine->CreateReference(js_object, 1, false, callback, native_object, finalize_hint,
1976 native_binding_size);
1977 *reference = ref;
1978 } else {
1979 ref = engine->CreateReference(js_object, 0, true, callback, native_object, finalize_hint,
1980 native_binding_size);
1981 }
1982 object->SetNativePointerFieldCount(vm, 1);
1983 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, native_binding_size);
1984 PropertyAttribute attr(object, true, false, true);
1985 nativeObject->DefineProperty(vm, key, attr);
1986 }
1987
1988 return GET_RETURN_STATUS(env);
1989 }
1990
napi_unwrap(napi_env env,napi_value js_object,void ** result)1991 NAPI_EXTERN napi_status napi_unwrap(napi_env env, napi_value js_object, void** result)
1992 {
1993 NAPI_PREAMBLE(env);
1994 CHECK_ARG(env, js_object);
1995 CHECK_ARG(env, result);
1996
1997 auto nativeValue = LocalValueFromJsValue(js_object);
1998 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1999 panda::JsiFastNativeScope fastNativeScope(vm);
2000 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
2001 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
2002 Local<panda::JSValueRef> val = nativeObject->Get(vm, key);
2003 *result = nullptr;
2004 if (val->IsObject(vm)) {
2005 Local<panda::ObjectRef> ext(val);
2006 auto ref = reinterpret_cast<NativeReference*>(ext->GetNativePointerField(vm, 0));
2007 *result = ref != nullptr ? ref->GetData() : nullptr;
2008 }
2009
2010 return GET_RETURN_STATUS(env);
2011 }
2012
napi_remove_wrap(napi_env env,napi_value js_object,void ** result)2013 NAPI_EXTERN napi_status napi_remove_wrap(napi_env env, napi_value js_object, void** result)
2014 {
2015 NAPI_PREAMBLE(env);
2016 CHECK_ARG(env, js_object);
2017 CHECK_ARG(env, result);
2018
2019 auto nativeValue = LocalValueFromJsValue(js_object);
2020 auto engine = reinterpret_cast<NativeEngine*>(env);
2021 auto vm = engine->GetEcmaVm();
2022 panda::JsiFastNativeScope fastNativeScope(vm);
2023 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
2024 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
2025 Local<panda::JSValueRef> val = nativeObject->Get(vm, key);
2026 *result = nullptr;
2027 if (val->IsObject(vm)) {
2028 Local<panda::ObjectRef> ext(val);
2029 auto ref = reinterpret_cast<NativeReference*>(ext->GetNativePointerField(vm, 0));
2030 *result = ref != nullptr ? ref->GetData() : nullptr;
2031 }
2032
2033 size_t nativeBindingSize = 0;
2034 if (nativeObject->Has(vm, key)) {
2035 Local<panda::ObjectRef> wrapper = val;
2036 auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(vm, 0));
2037 nativeObject->Delete(vm, key);
2038 delete ref;
2039 } else {
2040 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
2041 NativeReference* ref = nullptr;
2042 ref = engine->CreateReference(js_object, 0, true, nullptr, nullptr, nullptr);
2043 object->SetNativePointerFieldCount(vm, 1);
2044 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, nativeBindingSize);
2045 PropertyAttribute attr(object, true, false, true);
2046 nativeObject->DefineProperty(vm, key, attr);
2047 }
2048
2049 return GET_RETURN_STATUS(env);
2050 }
2051
napi_wrap_sendable(napi_env env,napi_value js_object,void * native_object,napi_finalize finalize_cb,void * finalize_hint)2052 NAPI_EXTERN napi_status napi_wrap_sendable(napi_env env,
2053 napi_value js_object,
2054 void* native_object,
2055 napi_finalize finalize_cb,
2056 void* finalize_hint)
2057 {
2058 NAPI_PREAMBLE(env);
2059 CHECK_ARG(env, js_object);
2060 CHECK_ARG(env, native_object);
2061
2062 auto nativeValue = LocalValueFromJsValue(js_object);
2063 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2064 auto engine = reinterpret_cast<NativeEngine*>(env);
2065 auto vm = engine->GetEcmaVm();
2066 panda::JsiFastNativeScope fastNativeScope(vm);
2067 RETURN_STATUS_IF_FALSE(env, nativeValue->IsSendableObject(vm), napi_object_expected);
2068 Local<ObjectRef> nativeObject(nativeValue);
2069 nativeObject->SetNativePointerFieldCount(vm, 1);
2070 nativeObject->SetNativePointerField(vm, 0, native_object, callback, finalize_hint);
2071 return GET_RETURN_STATUS(env);
2072 }
2073
napi_wrap_sendable_with_size(napi_env env,napi_value js_object,void * native_object,napi_finalize finalize_cb,void * finalize_hint,size_t native_binding_size)2074 NAPI_EXTERN napi_status napi_wrap_sendable_with_size(napi_env env,
2075 napi_value js_object,
2076 void* native_object,
2077 napi_finalize finalize_cb,
2078 void* finalize_hint,
2079 size_t native_binding_size)
2080 {
2081 NAPI_PREAMBLE(env);
2082 CHECK_ARG(env, js_object);
2083 CHECK_ARG(env, native_object);
2084
2085 auto nativeValue = LocalValueFromJsValue(js_object);
2086 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2087 auto engine = reinterpret_cast<NativeEngine*>(env);
2088 auto vm = engine->GetEcmaVm();
2089 panda::JsiFastNativeScope fastNativeScope(vm);
2090 RETURN_STATUS_IF_FALSE(env, nativeValue->IsSendableObject(vm), napi_object_expected);
2091 Local<ObjectRef> nativeObject(nativeValue);
2092 nativeObject->SetNativePointerFieldCount(vm, 1);
2093 nativeObject->SetNativePointerField(vm, 0, native_object, callback, finalize_hint, native_binding_size);
2094 return GET_RETURN_STATUS(env);
2095 }
2096
napi_unwrap_sendable(napi_env env,napi_value js_object,void ** result)2097 NAPI_EXTERN napi_status napi_unwrap_sendable(napi_env env, napi_value js_object, void** result)
2098 {
2099 NAPI_PREAMBLE(env);
2100 CHECK_ARG(env, js_object);
2101 CHECK_ARG(env, result);
2102
2103 auto nativeValue = LocalValueFromJsValue(js_object);
2104 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2105 panda::JsiFastNativeScope fastNativeScope(vm);
2106 RETURN_STATUS_IF_FALSE(env, nativeValue->IsSendableObject(vm), napi_object_expected);
2107 Local<ObjectRef> nativeObject(nativeValue);
2108 void* val = nativeObject->GetNativePointerField(vm, 0);
2109 *result = val;
2110 return GET_RETURN_STATUS(env);
2111 }
2112
napi_remove_wrap_sendable(napi_env env,napi_value js_object,void ** result)2113 NAPI_EXTERN napi_status napi_remove_wrap_sendable(napi_env env, napi_value js_object, void** result)
2114 {
2115 NAPI_PREAMBLE(env);
2116 CHECK_ARG(env, js_object);
2117 CHECK_ARG(env, result);
2118
2119 auto nativeValue = LocalValueFromJsValue(js_object);
2120 auto engine = reinterpret_cast<NativeEngine*>(env);
2121 auto vm = engine->GetEcmaVm();
2122 panda::JsiFastNativeScope fastNativeScope(vm);
2123 RETURN_STATUS_IF_FALSE(env, nativeValue->IsSendableObject(vm), napi_object_expected);
2124 Local<ObjectRef> nativeObject(nativeValue);
2125 void* val = nativeObject->GetNativePointerField(vm, 0);
2126 *result = val;
2127 nativeObject->SetNativePointerField(vm, 0, nullptr, nullptr, nullptr);
2128
2129 return GET_RETURN_STATUS(env);
2130 }
2131
napi_create_external(napi_env env,void * data,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)2132 NAPI_EXTERN napi_status napi_create_external(
2133 napi_env env, void* data, napi_finalize finalize_cb, void* finalize_hint, napi_value* result)
2134 {
2135 NAPI_PREAMBLE(env);
2136 CHECK_ARG(env, result);
2137
2138 auto engine = reinterpret_cast<NativeEngine*>(env);
2139 auto vm = engine->GetEcmaVm();
2140 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2141 Local<panda::NativePointerRef> object = panda::NativePointerRef::New(vm, data, callback, finalize_hint, 0);
2142
2143 *result = JsValueFromLocalValue(object);
2144 return napi_clear_last_error(env);
2145 }
2146
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)2147 NAPI_EXTERN napi_status napi_create_external_with_size(napi_env env,
2148 void* data,
2149 napi_finalize finalize_cb,
2150 void* finalize_hint,
2151 napi_value* result,
2152 size_t native_binding_size)
2153 {
2154 CHECK_ENV(env);
2155 CHECK_ARG(env, result);
2156
2157 auto engine = reinterpret_cast<NativeEngine*>(env);
2158 auto vm = engine->GetEcmaVm();
2159 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2160 Local<panda::NativePointerRef> object =
2161 panda::NativePointerRef::New(vm, data, callback, finalize_hint, native_binding_size);
2162
2163 *result = JsValueFromLocalValue(object);
2164 return napi_clear_last_error(env);
2165 }
2166
napi_get_value_external(napi_env env,napi_value value,void ** result)2167 NAPI_EXTERN napi_status napi_get_value_external(napi_env env, napi_value value, void** result)
2168 {
2169 CHECK_ENV(env);
2170 CHECK_ARG(env, value);
2171 CHECK_ARG(env, result);
2172
2173 auto nativeValue = LocalValueFromJsValue(value);
2174 bool isNativePointer = false;
2175 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2176 void* ret = nativeValue->GetNativePointerValue(vm, isNativePointer);
2177 RETURN_STATUS_IF_FALSE(env, isNativePointer, napi_object_expected);
2178 *result = ret;
2179 return napi_clear_last_error(env);
2180 }
2181
2182 // Methods to control object lifespan
2183 // 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)2184 NAPI_EXTERN napi_status napi_create_reference(napi_env env,
2185 napi_value value,
2186 uint32_t initial_refcount,
2187 napi_ref* result)
2188 {
2189 CHECK_ENV(env);
2190 CHECK_ARG(env, value);
2191 CHECK_ARG(env, result);
2192 auto engine = reinterpret_cast<ArkNativeEngine*>(env);
2193 auto ref = new ArkNativeReference(engine, value, initial_refcount);
2194
2195 *result = reinterpret_cast<napi_ref>(ref);
2196 return napi_clear_last_error(env);
2197 }
2198
2199 // Deletes a reference. The referenced value is released, and may
2200 // be GC'd unless there are other references to it.
napi_delete_reference(napi_env env,napi_ref ref)2201 NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref)
2202 {
2203 CHECK_ENV(env);
2204 CHECK_ARG(env, ref);
2205
2206 auto reference = reinterpret_cast<NativeReference*>(ref);
2207 uint32_t refCount = reference->GetRefCount();
2208 if (refCount > 0 || reference->GetFinalRun()) {
2209 delete reference;
2210 reference = nullptr;
2211 } else {
2212 reference->SetDeleteSelf();
2213 }
2214
2215 return napi_clear_last_error(env);
2216 }
2217
2218 // Increments the reference count, optionally returning the resulting count.
2219 // After this call the reference will be a strong reference because its
2220 // refcount is >0, and the referenced object is effectively "pinned".
2221 // Calling this when the refcount is 0 and the object is unavailable
2222 // results in an error.
napi_reference_ref(napi_env env,napi_ref ref,uint32_t * result)2223 NAPI_EXTERN napi_status napi_reference_ref(napi_env env, napi_ref ref, uint32_t* result)
2224 {
2225 CHECK_ENV(env);
2226 CHECK_ARG(env, ref);
2227
2228 auto reference = reinterpret_cast<NativeReference*>(ref);
2229 uint32_t refCount = reference->Ref();
2230
2231 if (result) {
2232 *result = refCount;
2233 }
2234
2235 return napi_clear_last_error(env);
2236 }
2237
2238 // Decrements the reference count, optionally returning the resulting count.
2239 // If the result is 0 the reference is now weak and the object may be GC'd
2240 // at any time if there are no other references. Calling this when the
2241 // refcount is already 0 results in an error.
napi_reference_unref(napi_env env,napi_ref ref,uint32_t * result)2242 NAPI_EXTERN napi_status napi_reference_unref(napi_env env, napi_ref ref, uint32_t* result)
2243 {
2244 CHECK_ENV(env);
2245 CHECK_ARG(env, ref);
2246
2247 auto reference = reinterpret_cast<NativeReference*>(ref);
2248 uint32_t unrefCount = reference->Unref();
2249
2250 if (result) {
2251 *result = unrefCount;
2252 }
2253
2254 return napi_clear_last_error(env);
2255 }
2256
2257 // Attempts to get a referenced value. If the reference is weak,
2258 // the value might no longer be available, in that case the call
2259 // is still successful but the result is nullptr.
napi_get_reference_value(napi_env env,napi_ref ref,napi_value * result)2260 NAPI_EXTERN napi_status napi_get_reference_value(napi_env env, napi_ref ref, napi_value* result)
2261 {
2262 CHECK_ENV(env);
2263 CHECK_ARG(env, ref);
2264 CHECK_ARG(env, result);
2265
2266 auto reference = reinterpret_cast<NativeReference*>(ref);
2267 NativeEngine* engine = reinterpret_cast<NativeEngine*>(env);
2268
2269 *result = reference->Get(engine);
2270 return napi_clear_last_error(env);
2271 }
2272
napi_open_handle_scope(napi_env env,napi_handle_scope * result)2273 NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env, napi_handle_scope* result)
2274 {
2275 CHECK_ENV(env);
2276 CHECK_ARG(env, result);
2277
2278 auto engine = reinterpret_cast<NativeEngine*>(env);
2279 *result = HandleScopeToNapiHandleScope(new HandleScopeWrapper(engine));
2280 engine->openHandleScopes_++;
2281 return napi_clear_last_error(env);
2282 }
2283
napi_close_handle_scope(napi_env env,napi_handle_scope scope)2284 NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env, napi_handle_scope scope)
2285 {
2286 CHECK_ENV(env);
2287 CHECK_ARG(env, scope);
2288
2289 auto engine = reinterpret_cast<NativeEngine*>(env);
2290 if (engine->openHandleScopes_ == 0) {
2291 return napi_handle_scope_mismatch;
2292 }
2293
2294 engine->openHandleScopes_--;
2295 delete NapiHandleScopeToHandleScope(scope);
2296 return napi_clear_last_error(env);
2297 }
2298
napi_open_escapable_handle_scope(napi_env env,napi_escapable_handle_scope * result)2299 NAPI_EXTERN napi_status napi_open_escapable_handle_scope(napi_env env, napi_escapable_handle_scope* result)
2300 {
2301 CHECK_ENV(env);
2302 CHECK_ARG(env, result);
2303
2304 auto engine = reinterpret_cast<NativeEngine*>(env);
2305 *result = EscapableHandleScopeToNapiEscapableHandleScope(new EscapableHandleScopeWrapper(engine));
2306 engine->openHandleScopes_++;
2307 return napi_clear_last_error(env);
2308 }
2309
napi_close_escapable_handle_scope(napi_env env,napi_escapable_handle_scope scope)2310 NAPI_EXTERN napi_status napi_close_escapable_handle_scope(napi_env env, napi_escapable_handle_scope scope)
2311 {
2312 CHECK_ENV(env);
2313 CHECK_ARG(env, scope);
2314
2315 auto engine = reinterpret_cast<NativeEngine*>(env);
2316 if (engine->openHandleScopes_ == 0) {
2317 return napi_handle_scope_mismatch;
2318 }
2319
2320 engine->openHandleScopes_--;
2321 delete NapiEscapableHandleScopeToEscapableHandleScope(scope);
2322 return napi_clear_last_error(env);
2323 }
2324
napi_escape_handle(napi_env env,napi_escapable_handle_scope scope,napi_value escapee,napi_value * result)2325 NAPI_EXTERN napi_status napi_escape_handle(napi_env env,
2326 napi_escapable_handle_scope scope,
2327 napi_value escapee,
2328 napi_value* result)
2329 {
2330 CHECK_ENV(env);
2331 CHECK_ARG(env, scope);
2332 CHECK_ARG(env, escapee);
2333 CHECK_ARG(env, result);
2334
2335 auto s = NapiEscapableHandleScopeToEscapableHandleScope(scope);
2336 if (!s->IsEscapeCalled()) {
2337 *result = JsValueFromLocalValue(s->Escape(LocalValueFromJsValue(escapee)));
2338 return napi_clear_last_error(env);
2339 }
2340 return napi_set_last_error(env, napi_escape_called_twice);
2341 }
2342
2343 // Methods to support error handling
napi_throw(napi_env env,napi_value error)2344 NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error)
2345 {
2346 CHECK_ENV(env);
2347 CHECK_ARG(env, error);
2348
2349 auto nativeValue = LocalValueFromJsValue(error);
2350 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2351 panda::JsiFastNativeScope fastNativeScope(vm);
2352
2353 RETURN_STATUS_IF_FALSE(env, nativeValue->IsError(vm), napi_invalid_arg);
2354 panda::JSNApi::ThrowException(vm, nativeValue);
2355 return napi_clear_last_error(env);
2356 }
2357
napi_throw_error(napi_env env,const char * code,const char * msg)2358 NAPI_EXTERN napi_status napi_throw_error(napi_env env, const char* code, const char* msg)
2359 {
2360 CHECK_ENV(env);
2361 CHECK_ARG(env, msg);
2362
2363 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2364 panda::JsiFastNativeScope fastNativeScope(vm);
2365 Local<panda::JSValueRef> error(panda::JSValueRef::Undefined(vm));
2366 error = panda::Exception::Error(vm, StringRef::NewFromUtf8(vm, msg));
2367 if (code != nullptr) {
2368 Local<panda::JSValueRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
2369 Local<panda::JSValueRef> codeValue = panda::StringRef::NewFromUtf8(vm, code);
2370 Local<panda::ObjectRef> errorObj(error);
2371 errorObj->Set(vm, codeKey, codeValue);
2372 }
2373 panda::JSNApi::ThrowException(vm, error);
2374 return napi_clear_last_error(env);
2375 }
2376
napi_throw_type_error(napi_env env,const char * code,const char * msg)2377 NAPI_EXTERN napi_status napi_throw_type_error(napi_env env, const char* code, const char* msg)
2378 {
2379 CHECK_ENV(env);
2380 CHECK_ARG(env, msg);
2381
2382 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2383 panda::JsiFastNativeScope fastNativeScope(vm);
2384 Local<panda::JSValueRef> error(panda::JSValueRef::Undefined(vm));
2385 error = panda::Exception::TypeError(vm, StringRef::NewFromUtf8(vm, msg));
2386 if (code != nullptr) {
2387 Local<panda::JSValueRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
2388 Local<panda::JSValueRef> codeValue = panda::StringRef::NewFromUtf8(vm, code);
2389 Local<panda::ObjectRef> errorObj(error);
2390 errorObj->Set(vm, codeKey, codeValue);
2391 }
2392 panda::JSNApi::ThrowException(vm, error);
2393 return napi_clear_last_error(env);
2394 }
2395
napi_throw_range_error(napi_env env,const char * code,const char * msg)2396 NAPI_EXTERN napi_status napi_throw_range_error(napi_env env, const char* code, const char* msg)
2397 {
2398 CHECK_ENV(env);
2399 CHECK_ARG(env, msg);
2400
2401 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2402 panda::JsiFastNativeScope fastNativeScope(vm);
2403 Local<panda::JSValueRef> error(panda::JSValueRef::Undefined(vm));
2404 error = panda::Exception::RangeError(vm, StringRef::NewFromUtf8(vm, msg));
2405 if (code != nullptr) {
2406 Local<panda::JSValueRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
2407 Local<panda::JSValueRef> codeValue = panda::StringRef::NewFromUtf8(vm, code);
2408 Local<panda::ObjectRef> errorObj(error);
2409 errorObj->Set(vm, codeKey, codeValue);
2410 }
2411 panda::JSNApi::ThrowException(vm, error);
2412 return napi_clear_last_error(env);
2413 }
2414
napi_is_error(napi_env env,napi_value value,bool * result)2415 NAPI_EXTERN napi_status napi_is_error(napi_env env, napi_value value, bool* result)
2416 {
2417 CHECK_ENV(env);
2418 CHECK_ARG(env, value);
2419 CHECK_ARG(env, result);
2420
2421 auto nativeValue = LocalValueFromJsValue(value);
2422 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2423 panda::JsiFastNativeScope fastNativeScope(vm);
2424 *result = nativeValue->IsError(vm);
2425
2426 return napi_clear_last_error(env);
2427 }
2428
2429 // Methods to support catching exceptions
napi_is_exception_pending(napi_env env,bool * result)2430 NAPI_EXTERN napi_status napi_is_exception_pending(napi_env env, bool* result)
2431 {
2432 CHECK_ENV(env);
2433 CHECK_ARG(env, result);
2434
2435 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2436 *result = panda::JSNApi::HasPendingException(vm);
2437 return napi_clear_last_error(env);
2438 }
2439
napi_get_and_clear_last_exception(napi_env env,napi_value * result)2440 NAPI_EXTERN napi_status napi_get_and_clear_last_exception(napi_env env, napi_value* result)
2441 {
2442 CHECK_ENV(env);
2443 CHECK_ARG(env, result);
2444
2445 auto engine = reinterpret_cast<NativeEngine*>(env);
2446 auto vm = engine->GetEcmaVm();
2447 engine->lastException_.Empty();
2448 Local<panda::ObjectRef> exception = panda::JSNApi::GetAndClearUncaughtException(vm);
2449 if (!exception.IsNull()) {
2450 *result = JsValueFromLocalValue(exception);
2451 }
2452
2453 return napi_clear_last_error(env);
2454 }
2455
2456 // Methods to work with array buffers and typed arrays
napi_is_arraybuffer(napi_env env,napi_value value,bool * result)2457 NAPI_EXTERN napi_status napi_is_arraybuffer(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 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2465 panda::JsiFastNativeScope fastNativeScope(vm);
2466
2467 *result = nativeValue->IsArrayBuffer(vm) || nativeValue->IsSendableArrayBuffer(vm);
2468
2469 return napi_clear_last_error(env);
2470 }
2471
napi_create_arraybuffer(napi_env env,size_t byte_length,void ** data,napi_value * result)2472 NAPI_EXTERN napi_status napi_create_arraybuffer(napi_env env, size_t byte_length, void** data, napi_value* result)
2473 {
2474 NAPI_PREAMBLE(env);
2475 CHECK_ARG(env, data);
2476 CHECK_ARG(env, result);
2477
2478 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2479 uint8_t** values = (uint8_t**)(data);
2480 Local<panda::ArrayBufferRef> res = panda::ArrayBufferRef::New(vm, byte_length);
2481 if (values != nullptr) {
2482 *values = reinterpret_cast<uint8_t*>(res->GetBuffer(vm));
2483 if (UNLIKELY(*values == nullptr && byte_length > 0)) {
2484 HILOG_WARN("Allocate ArrayBuffer failed, maybe size is too large, request size: %{public}zu", byte_length);
2485 }
2486 }
2487 *result = JsValueFromLocalValue(res);
2488
2489 return GET_RETURN_STATUS(env);
2490 }
2491
napi_create_sendable_arraybuffer(napi_env env,size_t byte_length,void ** data,napi_value * result)2492 NAPI_EXTERN napi_status napi_create_sendable_arraybuffer(napi_env env, size_t byte_length,
2493 void** data, napi_value* result)
2494 {
2495 NAPI_PREAMBLE(env);
2496 CHECK_ARG(env, data);
2497 CHECK_ARG(env, result);
2498
2499 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2500 uint8_t** values = (uint8_t**)(data);
2501 Local<panda::SendableArrayBufferRef> res = panda::SendableArrayBufferRef::New(vm, byte_length);
2502 if (values != nullptr) {
2503 *values = reinterpret_cast<uint8_t*>(res->GetBuffer(vm));
2504 }
2505 *result = JsValueFromLocalValue(res);
2506
2507 return GET_RETURN_STATUS(env);
2508 }
2509
napi_create_external_arraybuffer(napi_env env,void * external_data,size_t byte_length,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)2510 NAPI_EXTERN napi_status napi_create_external_arraybuffer(napi_env env,
2511 void* external_data,
2512 size_t byte_length,
2513 napi_finalize finalize_cb,
2514 void* finalize_hint,
2515 napi_value* result)
2516 {
2517 NAPI_PREAMBLE(env);
2518 CHECK_ARG(env, external_data);
2519 CHECK_ARG(env, finalize_cb);
2520 CHECK_ARG(env, result);
2521
2522 auto engine = reinterpret_cast<NativeEngine*>(env);
2523 auto vm = engine->GetEcmaVm();
2524 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2525 Local<panda::ArrayBufferRef> object =
2526 panda::ArrayBufferRef::New(vm, external_data, byte_length, callback, finalize_hint);
2527 *result = JsValueFromLocalValue(object);
2528 return GET_RETURN_STATUS(env);
2529 }
2530
napi_get_arraybuffer_info(napi_env env,napi_value arraybuffer,void ** data,size_t * byte_length)2531 NAPI_EXTERN napi_status napi_get_arraybuffer_info(napi_env env,
2532 napi_value arraybuffer,
2533 void** data,
2534 size_t* byte_length)
2535 {
2536 CHECK_ENV(env);
2537 CHECK_ARG(env, arraybuffer);
2538 CHECK_ARG(env, byte_length);
2539
2540 auto nativeValue = LocalValueFromJsValue(arraybuffer);
2541 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2542 panda::JsiFastNativeScope fastNativeScope(vm);
2543 if (LIKELY(nativeValue->IsArrayBuffer(vm))) {
2544 Local<panda::ArrayBufferRef> res(nativeValue);
2545 if (data != nullptr) {
2546 *data = res->GetBuffer(vm);
2547 }
2548 *byte_length = res->ByteLength(vm);
2549 } else if (nativeValue->IsSendableArrayBuffer(vm)) {
2550 Local<panda::SendableArrayBufferRef> res(nativeValue);
2551 if (data != nullptr) {
2552 *data = res->GetBuffer(vm);
2553 }
2554 *byte_length = res->ByteLength(vm);
2555 } else {
2556 return napi_set_last_error(env, napi_arraybuffer_expected);
2557 }
2558
2559 return napi_clear_last_error(env);
2560 }
2561
napi_is_typedarray(napi_env env,napi_value value,bool * result)2562 NAPI_EXTERN napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result)
2563 {
2564 CHECK_ENV(env);
2565 CHECK_ARG(env, value);
2566 CHECK_ARG(env, result);
2567
2568 auto nativeValue = LocalValueFromJsValue(value);
2569 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2570 panda::JsiFastNativeScope fastNativeScope(vm);
2571
2572 *result = nativeValue->IsTypedArray(vm) || nativeValue->IsSharedTypedArray(vm);
2573
2574 return napi_clear_last_error(env);
2575 }
2576
2577 EXTERN_C_START
napi_is_buffer(napi_env env,napi_value value,bool * result)2578 NAPI_EXTERN napi_status napi_is_buffer(napi_env env, napi_value value, bool* result)
2579 {
2580 CHECK_ENV(env);
2581 CHECK_ARG(env, value);
2582 CHECK_ARG(env, result);
2583
2584 auto nativeValue = LocalValueFromJsValue(value);
2585 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2586 panda::JsiFastNativeScope fastNativeScope(vm);
2587
2588 *result = nativeValue->IsBuffer(vm);
2589
2590 return napi_clear_last_error(env);
2591 }
2592
napi_create_buffer(napi_env env,size_t size,void ** data,napi_value * result)2593 NAPI_EXTERN napi_status napi_create_buffer(napi_env env, size_t size, void** data, napi_value* result)
2594 {
2595 CHECK_ENV(env);
2596 CHECK_ARG(env, data);
2597 CHECK_ARG(env, result);
2598 RETURN_STATUS_IF_FALSE(env, size > 0, napi_invalid_arg);
2599
2600 uint8_t** value = reinterpret_cast<uint8_t**>(data);
2601 if (!value) {
2602 HILOG_ERROR("value is empty");
2603 return napi_set_last_error(env, napi_invalid_arg);
2604 }
2605
2606 if (size > MAX_BYTE_LENGTH) {
2607 HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
2608 static_cast<float>(size) / static_cast<float>(ONEMIB_BYTE_SIZE),
2609 static_cast<float>(MAX_BYTE_LENGTH) / static_cast<float>(ONEMIB_BYTE_SIZE));
2610 *value = nullptr;
2611 return napi_set_last_error(env, napi_invalid_arg);
2612 }
2613 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2614 Local<panda::BufferRef> obj = BufferRef::New(vm, size);
2615 *value = reinterpret_cast<uint8_t*>(obj->GetBuffer(vm));
2616
2617 CHECK_ARG(env, *data);
2618 void* ptr = obj->GetBuffer(vm);
2619 CHECK_ARG(env, ptr);
2620
2621 *result = JsValueFromLocalValue(obj);
2622 return napi_clear_last_error(env);
2623 }
2624
napi_create_buffer_copy(napi_env env,size_t length,const void * data,void ** result_data,napi_value * result)2625 NAPI_EXTERN napi_status napi_create_buffer_copy(napi_env env,
2626 size_t length,
2627 const void* data,
2628 void** result_data,
2629 napi_value* result)
2630 {
2631 CHECK_ENV(env);
2632 CHECK_ARG(env, data);
2633 CHECK_ARG(env, result_data);
2634 CHECK_ARG(env, result);
2635 RETURN_STATUS_IF_FALSE(env, length > 0, napi_invalid_arg);
2636
2637 uint8_t** value = reinterpret_cast<uint8_t**>(result_data);
2638 const uint8_t* recvdata = (uint8_t*)data;
2639 if (!value) {
2640 HILOG_ERROR("value is empty");
2641 return napi_set_last_error(env, napi_invalid_arg);
2642 }
2643 if (length > MAX_BYTE_LENGTH) {
2644 HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
2645 static_cast<float>(length) / static_cast<float>(ONEMIB_BYTE_SIZE),
2646 static_cast<float>(MAX_BYTE_LENGTH) / static_cast<float>(ONEMIB_BYTE_SIZE));
2647 *value = nullptr;
2648 return napi_set_last_error(env, napi_invalid_arg);
2649 }
2650 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2651 Local<panda::BufferRef> obj = BufferRef::New(vm, length);
2652 if (obj->IsUndefined()) {
2653 HILOG_INFO("engine create buffer_copy failed!");
2654 }
2655 *value = reinterpret_cast<uint8_t*>(obj->GetBuffer(vm));
2656 if (memcpy_s(*value, length, recvdata, length) != EOK) {
2657 HILOG_ERROR("memcpy_s failed");
2658 }
2659
2660 void* ptr = obj->GetBuffer(vm);
2661 CHECK_ARG(env, ptr);
2662
2663 *result = JsValueFromLocalValue(obj);
2664 return napi_clear_last_error(env);
2665 }
2666
napi_create_external_buffer(napi_env env,size_t length,void * data,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)2667 NAPI_EXTERN napi_status napi_create_external_buffer(napi_env env,
2668 size_t length,
2669 void* data,
2670 napi_finalize finalize_cb,
2671 void* finalize_hint,
2672 napi_value* result)
2673 {
2674 NAPI_PREAMBLE(env);
2675 CHECK_ARG(env, result);
2676 CHECK_ARG(env, data);
2677 RETURN_STATUS_IF_FALSE(env, length > 0, napi_invalid_arg);
2678
2679 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2680 if (!data) {
2681 HILOG_ERROR("data is empty");
2682 return napi_set_last_error(env, napi_invalid_arg);
2683 }
2684 if (length > MAX_BYTE_LENGTH) {
2685 HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
2686 static_cast<float>(length) / static_cast<float>(ONEMIB_BYTE_SIZE),
2687 static_cast<float>(MAX_BYTE_LENGTH) / static_cast<float>(ONEMIB_BYTE_SIZE));
2688 data = nullptr;
2689 return napi_set_last_error(env, napi_invalid_arg);
2690 }
2691
2692 auto engine = reinterpret_cast<NativeEngine*>(env);
2693 auto vm = engine->GetEcmaVm();
2694 Local<panda::BufferRef> object = panda::BufferRef::New(vm, data, length, callback, finalize_hint);
2695 void* ptr = object->GetBuffer(vm);
2696 CHECK_ARG(env, ptr);
2697
2698 *result = JsValueFromLocalValue(object);
2699 return GET_RETURN_STATUS(env);
2700 }
2701
napi_get_buffer_info(napi_env env,napi_value value,void ** data,size_t * length)2702 NAPI_EXTERN napi_status napi_get_buffer_info(napi_env env, napi_value value, void** data, size_t* length)
2703 {
2704 CHECK_ENV(env);
2705 CHECK_ARG(env, value);
2706
2707 auto nativeValue = LocalValueFromJsValue(value);
2708 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2709 panda::JsiFastNativeScope fastNativeScope(vm);
2710 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBuffer(vm), napi_status::napi_arraybuffer_expected);
2711 Local<panda::BufferRef> res(nativeValue);
2712 *data = res->GetBuffer(vm);
2713 *length = res->ByteLength(vm);
2714
2715 return napi_clear_last_error(env);
2716 }
2717
napi_object_freeze(napi_env env,napi_value object)2718 NAPI_EXTERN napi_status napi_object_freeze(napi_env env, napi_value object)
2719 {
2720 NAPI_PREAMBLE(env);
2721 CHECK_ARG(env, object);
2722
2723 auto nativeValue = LocalValueFromJsValue(object);
2724 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2725 panda::JsiFastNativeScope fastNativeScope(vm);
2726 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
2727 Local<panda::ObjectRef> obj = nativeValue->ToEcmaObject(vm);
2728 obj->Freeze(vm);
2729
2730 return GET_RETURN_STATUS(env);
2731 }
2732
napi_object_seal(napi_env env,napi_value object)2733 NAPI_EXTERN napi_status napi_object_seal(napi_env env, napi_value object)
2734 {
2735 NAPI_PREAMBLE(env);
2736 CHECK_ARG(env, object);
2737
2738 auto nativeValue = LocalValueFromJsValue(object);
2739 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2740 panda::JsiFastNativeScope fastNativeScope(vm);
2741 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
2742 Local<panda::ObjectRef> obj = nativeValue->ToEcmaObject(vm);
2743 obj->Seal(vm);
2744
2745 return GET_RETURN_STATUS(env);
2746 }
2747
2748 EXTERN_C_END
2749
napi_create_typedarray(napi_env env,napi_typedarray_type type,size_t length,napi_value arraybuffer,size_t byte_offset,napi_value * result)2750 NAPI_EXTERN napi_status napi_create_typedarray(napi_env env,
2751 napi_typedarray_type type,
2752 size_t length,
2753 napi_value arraybuffer,
2754 size_t byte_offset,
2755 napi_value* result)
2756 {
2757 NAPI_PREAMBLE(env);
2758 CHECK_ARG(env, arraybuffer);
2759 CHECK_ARG(env, result);
2760
2761 auto value = LocalValueFromJsValue(arraybuffer);
2762 auto typedArrayType = (NativeTypedArrayType)type;
2763 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2764 panda::JsiFastNativeScope fastNativeScope(vm);
2765 RETURN_STATUS_IF_FALSE(env, value->IsArrayBuffer(vm), napi_status::napi_arraybuffer_expected);
2766 Local<panda::ArrayBufferRef> arrayBuf(value);
2767
2768 if (!reinterpret_cast<NativeEngine*>(env)->NapiNewTypedArray(vm, typedArrayType, arrayBuf,
2769 byte_offset, length, result)) {
2770 HILOG_ERROR("%{public}s invalid arg", __func__);
2771 return napi_set_last_error(env, napi_invalid_arg);
2772 }
2773 return GET_RETURN_STATUS(env);
2774 }
2775
napi_create_sendable_typedarray(napi_env env,napi_typedarray_type type,size_t length,napi_value arraybuffer,size_t byte_offset,napi_value * result)2776 NAPI_EXTERN napi_status napi_create_sendable_typedarray(napi_env env,
2777 napi_typedarray_type type,
2778 size_t length,
2779 napi_value arraybuffer,
2780 size_t byte_offset,
2781 napi_value* result)
2782 {
2783 NAPI_PREAMBLE(env);
2784 CHECK_ARG(env, arraybuffer);
2785 CHECK_ARG(env, result);
2786
2787 auto value = LocalValueFromJsValue(arraybuffer);
2788 auto typedArrayType = (NativeTypedArrayType)type;
2789 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2790 panda::JsiFastNativeScope fastNativeScope(vm);
2791 RETURN_STATUS_IF_FALSE(env, value->IsSendableArrayBuffer(vm), napi_status::napi_arraybuffer_expected);
2792 Local<panda::SendableArrayBufferRef> arrayBuf(value);
2793
2794 if (!reinterpret_cast<NativeEngine*>(env)->NapiNewSendableTypedArray(vm, typedArrayType,
2795 arrayBuf, byte_offset,
2796 length, result)) {
2797 HILOG_ERROR("%{public}s invalid arg", __func__);
2798 return napi_set_last_error(env, napi_invalid_arg);
2799 }
2800 return GET_RETURN_STATUS(env);
2801 }
2802
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)2803 NAPI_EXTERN napi_status napi_get_typedarray_info(napi_env env,
2804 napi_value typedarray,
2805 napi_typedarray_type* type,
2806 size_t* length,
2807 void** data,
2808 napi_value* arraybuffer,
2809 size_t* byte_offset)
2810 {
2811 CHECK_ENV(env);
2812 CHECK_ARG(env, typedarray);
2813
2814 auto value = LocalValueFromJsValue(typedarray);
2815 auto engine = reinterpret_cast<NativeEngine*>(env);
2816 auto vm = engine->GetEcmaVm();
2817 panda::JsiFastNativeScope fastNativeScope(vm);
2818 if (LIKELY(value->IsTypedArray(vm))) {
2819 Local<panda::TypedArrayRef> typedArray = Local<panda::TypedArrayRef>(value);
2820 Local<ArrayBufferRef> localArrayBuffer = typedArray->GetArrayBuffer(vm);
2821 size_t byteOffset = typedArray->ByteOffset(vm);
2822 if (type != nullptr) {
2823 *type = static_cast<napi_typedarray_type>(engine->GetTypedArrayType(typedArray));
2824 }
2825 if (length != nullptr) {
2826 *length = typedArray->ByteLength(vm);
2827 }
2828 if (data != nullptr) {
2829 *data = static_cast<uint8_t*>(localArrayBuffer->GetBuffer(vm)) + byteOffset;
2830 }
2831 if (arraybuffer != nullptr) {
2832 *arraybuffer = JsValueFromLocalValue(localArrayBuffer);
2833 }
2834 if (byte_offset != nullptr) {
2835 *byte_offset = byteOffset;
2836 }
2837 } else if (value->IsSharedTypedArray(vm)) {
2838 Local<panda::SendableTypedArrayRef> typedArray = Local<panda::SendableTypedArrayRef>(value);
2839 Local<panda::SendableArrayBufferRef> localArrayBuffer = typedArray->GetArrayBuffer(vm);
2840 size_t byteOffset = typedArray->ByteOffset(vm);
2841 if (type != nullptr) {
2842 *type = static_cast<napi_typedarray_type>(engine->GetSendableTypedArrayType(typedArray));
2843 }
2844 if (length != nullptr) {
2845 *length = typedArray->ByteLength(vm);
2846 }
2847 if (data != nullptr) {
2848 *data = static_cast<uint8_t*>(localArrayBuffer->GetBuffer(vm)) + byteOffset;
2849 }
2850 if (arraybuffer != nullptr) {
2851 *arraybuffer = JsValueFromLocalValue(localArrayBuffer);
2852 }
2853 if (byte_offset != nullptr) {
2854 *byte_offset = byteOffset;
2855 }
2856 } else {
2857 HILOG_ERROR("%{public}s invalid arg", __func__);
2858 return napi_set_last_error(env, napi_invalid_arg);
2859 }
2860
2861 return napi_clear_last_error(env);
2862 }
2863
napi_create_dataview(napi_env env,size_t length,napi_value arraybuffer,size_t byte_offset,napi_value * result)2864 NAPI_EXTERN napi_status napi_create_dataview(napi_env env,
2865 size_t length,
2866 napi_value arraybuffer,
2867 size_t byte_offset,
2868 napi_value* result)
2869 {
2870 NAPI_PREAMBLE(env);
2871 CHECK_ARG(env, arraybuffer);
2872 CHECK_ARG(env, result);
2873
2874 auto arrayBufferValue = LocalValueFromJsValue(arraybuffer);
2875 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2876 panda::JsiFastNativeScope fastNativeScope(vm);
2877 RETURN_STATUS_IF_FALSE(env, arrayBufferValue->IsArrayBuffer(vm), napi_status::napi_arraybuffer_expected);
2878 Local<panda::ArrayBufferRef> res(arrayBufferValue);
2879 if (length + byte_offset > static_cast<size_t>(res->ByteLength(vm))) {
2880 napi_throw_range_error(
2881 env,
2882 "ERR_NAPI_INVALID_DATAVIEW_ARGS",
2883 "byte_offset + byte_length should be less than or "
2884 "equal to the size in bytes of the array passed in");
2885 return napi_set_last_error(env, napi_pending_exception);
2886 }
2887
2888 Local<panda::DataViewRef> dataView = panda::DataViewRef::New(vm, res, byte_offset, length);
2889 *result = JsValueFromLocalValue(dataView);
2890 return GET_RETURN_STATUS(env);
2891 }
2892
napi_is_dataview(napi_env env,napi_value value,bool * result)2893 NAPI_EXTERN napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
2894 {
2895 CHECK_ENV(env);
2896 CHECK_ARG(env, value);
2897 CHECK_ARG(env, result);
2898
2899 auto nativeValue = LocalValueFromJsValue(value);
2900 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2901 panda::JsiFastNativeScope fastNativeScope(vm);
2902 *result = nativeValue->IsDataView(vm);
2903
2904 return napi_clear_last_error(env);
2905 }
2906
napi_get_dataview_info(napi_env env,napi_value dataview,size_t * bytelength,void ** data,napi_value * arraybuffer,size_t * byte_offset)2907 NAPI_EXTERN napi_status napi_get_dataview_info(napi_env env,
2908 napi_value dataview,
2909 size_t* bytelength,
2910 void** data,
2911 napi_value* arraybuffer,
2912 size_t* byte_offset)
2913 {
2914 CHECK_ENV(env);
2915 CHECK_ARG(env, dataview);
2916
2917 auto nativeValue = LocalValueFromJsValue(dataview);
2918 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2919 bool isDataView = false;
2920 nativeValue->GetDataViewInfo(vm, isDataView, bytelength, data,
2921 reinterpret_cast<panda::JSValueRef**>(arraybuffer), byte_offset);
2922 RETURN_STATUS_IF_FALSE(env, isDataView, napi_status::napi_invalid_arg);
2923
2924 return napi_clear_last_error(env);
2925 }
2926
2927 // version management
napi_get_version(napi_env env,uint32_t * result)2928 NAPI_EXTERN napi_status napi_get_version(napi_env env, uint32_t* result)
2929 {
2930 CHECK_ENV(env);
2931 CHECK_ARG(env, result);
2932
2933 *result = NAPI_VERSION;
2934 return napi_clear_last_error(env);
2935 }
2936
2937 // Promises
napi_create_promise(napi_env env,napi_deferred * deferred,napi_value * promise)2938 NAPI_EXTERN napi_status napi_create_promise(napi_env env, napi_deferred* deferred, napi_value* promise)
2939 {
2940 NAPI_PREAMBLE(env);
2941 auto engine = reinterpret_cast<NativeEngine*>(env);
2942 if (panda::JSNApi::HasPendingException(engine->GetEcmaVm())) {
2943 return napi_pending_exception;
2944 }
2945 CHECK_ARG(env, deferred);
2946 CHECK_ARG(env, promise);
2947
2948 NativeDeferred* nativeDeferred = nullptr;
2949 auto resultValue = engine->CreatePromise(&nativeDeferred);
2950 if (LocalValueFromJsValue(resultValue)->IsUndefined()) {
2951 return napi_set_last_error(env, napi_generic_failure);
2952 }
2953 *deferred = reinterpret_cast<napi_deferred>(nativeDeferred);
2954 *promise = resultValue;
2955
2956 return GET_RETURN_STATUS(env);
2957 }
2958
napi_resolve_deferred(napi_env env,napi_deferred deferred,napi_value resolution)2959 NAPI_EXTERN napi_status napi_resolve_deferred(napi_env env, napi_deferred deferred, napi_value resolution)
2960 {
2961 NAPI_PREAMBLE(env);
2962 CHECK_ARG(env, deferred);
2963 CHECK_ARG(env, resolution);
2964
2965 auto nativeDeferred = reinterpret_cast<NativeDeferred*>(deferred);
2966 nativeDeferred->Resolve(resolution);
2967 delete nativeDeferred;
2968 return GET_RETURN_STATUS(env);
2969 }
2970
napi_reject_deferred(napi_env env,napi_deferred deferred,napi_value rejection)2971 NAPI_EXTERN napi_status napi_reject_deferred(napi_env env, napi_deferred deferred, napi_value rejection)
2972 {
2973 NAPI_PREAMBLE(env);
2974 CHECK_ARG(env, deferred);
2975 CHECK_ARG(env, rejection);
2976
2977 auto nativeDeferred = reinterpret_cast<NativeDeferred*>(deferred);
2978 nativeDeferred->Reject(rejection);
2979 delete nativeDeferred;
2980 return GET_RETURN_STATUS(env);
2981 }
2982
napi_is_promise(napi_env env,napi_value value,bool * is_promise)2983 NAPI_EXTERN napi_status napi_is_promise(napi_env env, napi_value value, bool* is_promise)
2984 {
2985 CHECK_ENV(env);
2986 CHECK_ARG(env, value);
2987 CHECK_ARG(env, is_promise);
2988
2989 auto nativeValue = LocalValueFromJsValue(value);
2990 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2991 panda::JsiFastNativeScope fastNativeScope(vm);
2992 *is_promise = nativeValue->IsPromise(vm);
2993
2994 return napi_clear_last_error(env);
2995 }
2996
2997 // promise reject events
napi_set_promise_rejection_callback(napi_env env,napi_ref ref,napi_ref checkRef)2998 NAPI_EXTERN napi_status napi_set_promise_rejection_callback(napi_env env, napi_ref ref, napi_ref checkRef)
2999 {
3000 CHECK_ENV(env);
3001 CHECK_ARG(env, ref);
3002 CHECK_ARG(env, checkRef);
3003
3004 auto rejectCallbackRef = reinterpret_cast<NativeReference*>(ref);
3005 auto checkCallbackRef = reinterpret_cast<NativeReference*>(checkRef);
3006 if (rejectCallbackRef == nullptr || checkCallbackRef == nullptr) {
3007 HILOG_ERROR("rejectCallbackRef or checkCallbackRef is nullptr");
3008 } else {
3009 auto engine = reinterpret_cast<NativeEngine*>(env);
3010 auto vm = const_cast<EcmaVM*>(engine->GetEcmaVm());
3011 engine->SetPromiseRejectCallBackRef(rejectCallbackRef);
3012 engine->SetCheckCallbackRef(checkCallbackRef);
3013 panda::JSNApi::SetHostPromiseRejectionTracker(const_cast<EcmaVM*>(vm), engine->GetPromiseRejectCallback(),
3014 reinterpret_cast<void*>(engine));
3015 }
3016
3017 return napi_clear_last_error(env);
3018 }
3019
3020 // Running a script
napi_run_script(napi_env env,napi_value script,napi_value * result)3021 NAPI_EXTERN napi_status napi_run_script(napi_env env, napi_value script, napi_value* result)
3022 {
3023 CHECK_ENV(env);
3024 CHECK_ARG(env, script);
3025 CHECK_ARG(env, result);
3026
3027 *result = nullptr;
3028 return napi_clear_last_error(env);
3029 }
3030
napi_run_actor(napi_env env,uint8_t * buffer,size_t bufferSize,const char * descriptor,napi_value * result,char * entryPoint)3031 NAPI_EXTERN napi_status napi_run_actor(napi_env env,
3032 uint8_t* buffer,
3033 size_t bufferSize,
3034 const char* descriptor,
3035 napi_value* result,
3036 char* entryPoint)
3037 {
3038 NAPI_PREAMBLE(env);
3039 CHECK_ARG(env, result);
3040
3041 auto engine = reinterpret_cast<NativeEngine*>(env);
3042 *result = engine->RunActor(buffer, bufferSize, descriptor, entryPoint, false);
3043 return GET_RETURN_STATUS(env);
3044 }
3045
napi_load_module(napi_env env,const char * path,napi_value * result)3046 NAPI_EXTERN napi_status napi_load_module(napi_env env, const char* path, napi_value* result)
3047 {
3048 NAPI_PREAMBLE(env);
3049 CHECK_ARG(env, result);
3050 auto engine = reinterpret_cast<NativeEngine*>(env);
3051 *result = engine->NapiLoadModule(path);
3052 return GET_RETURN_STATUS(env);
3053 }
3054
napi_load_module_with_info(napi_env env,const char * path,const char * module_info,napi_value * result)3055 NAPI_EXTERN napi_status napi_load_module_with_info(napi_env env,
3056 const char* path,
3057 const char* module_info,
3058 napi_value* result)
3059 {
3060 NAPI_PREAMBLE(env);
3061 CHECK_ARG(env, result);
3062 auto engine = reinterpret_cast<NativeEngine*>(env);
3063 *result = engine->NapiLoadModuleWithInfo(path, module_info);
3064 if (*result != nullptr) {
3065 RETURN_STATUS_IF_FALSE(env, !LocalValueFromJsValue(*result)->IsUndefined(), napi_generic_failure);
3066 }
3067 return GET_RETURN_STATUS(env);
3068 }
3069 // Memory management
napi_adjust_external_memory(napi_env env,int64_t change_in_bytes,int64_t * adjusted_value)3070 NAPI_INNER_EXTERN napi_status napi_adjust_external_memory(
3071 napi_env env, int64_t change_in_bytes, int64_t* adjusted_value)
3072 {
3073 CHECK_ENV(env);
3074 CHECK_ARG(env, adjusted_value);
3075
3076 auto engine = reinterpret_cast<NativeEngine*>(env);
3077 engine->AdjustExternalMemory(change_in_bytes, adjusted_value);
3078
3079 return napi_clear_last_error(env);
3080 }
3081
napi_is_callable(napi_env env,napi_value value,bool * result)3082 NAPI_EXTERN napi_status napi_is_callable(napi_env env, napi_value value, bool* result)
3083 {
3084 CHECK_ENV(env);
3085 CHECK_ARG(env, value);
3086 CHECK_ARG(env, result);
3087
3088 auto nativeValue = LocalValueFromJsValue(value);
3089 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3090 panda::JsiFastNativeScope fastNativeScope(vm);
3091
3092 *result = nativeValue->IsFunction(vm);
3093
3094 return napi_clear_last_error(env);
3095 }
3096
napi_is_arguments_object(napi_env env,napi_value value,bool * result)3097 NAPI_EXTERN napi_status napi_is_arguments_object(napi_env env, napi_value value, bool* result)
3098 {
3099 CHECK_ENV(env);
3100 CHECK_ARG(env, value);
3101 CHECK_ARG(env, result);
3102
3103 auto nativeValue = LocalValueFromJsValue(value);
3104 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3105 panda::JsiFastNativeScope fastNativeScope(vm);
3106
3107 *result = nativeValue->IsArgumentsObject(vm);
3108
3109 return napi_clear_last_error(env);
3110 }
3111
napi_is_async_function(napi_env env,napi_value value,bool * result)3112 NAPI_EXTERN napi_status napi_is_async_function(napi_env env, napi_value value, bool* result)
3113 {
3114 CHECK_ENV(env);
3115 CHECK_ARG(env, value);
3116 CHECK_ARG(env, result);
3117
3118 auto nativeValue = LocalValueFromJsValue(value);
3119 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3120 panda::JsiFastNativeScope fastNativeScope(vm);
3121
3122 *result = nativeValue->IsAsyncFunction(vm);
3123 return napi_clear_last_error(env);
3124 }
3125
napi_is_boolean_object(napi_env env,napi_value value,bool * result)3126 NAPI_EXTERN napi_status napi_is_boolean_object(napi_env env, napi_value value, bool* result)
3127 {
3128 CHECK_ENV(env);
3129 CHECK_ARG(env, value);
3130 CHECK_ARG(env, result);
3131
3132 auto nativeValue = LocalValueFromJsValue(value);
3133 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3134 panda::JsiFastNativeScope fastNativeScope(vm);
3135
3136 *result = nativeValue->IsJSPrimitiveBoolean(vm);
3137
3138 return napi_clear_last_error(env);
3139 }
3140
napi_is_generator_function(napi_env env,napi_value value,bool * result)3141 NAPI_EXTERN napi_status napi_is_generator_function(napi_env env, napi_value value, bool* result)
3142 {
3143 CHECK_ENV(env);
3144 CHECK_ARG(env, value);
3145 CHECK_ARG(env, result);
3146
3147 auto nativeValue = LocalValueFromJsValue(value);
3148 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3149 panda::JsiFastNativeScope fastNativeScope(vm);
3150
3151 *result = nativeValue->IsGeneratorFunction(vm);
3152
3153 return napi_clear_last_error(env);
3154 }
3155
napi_is_map_iterator(napi_env env,napi_value value,bool * result)3156 NAPI_EXTERN napi_status napi_is_map_iterator(napi_env env, napi_value value, bool* result)
3157 {
3158 CHECK_ENV(env);
3159 CHECK_ARG(env, value);
3160 CHECK_ARG(env, result);
3161
3162 auto nativeValue = LocalValueFromJsValue(value);
3163 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3164 panda::JsiFastNativeScope fastNativeScope(vm);
3165
3166 *result = nativeValue->IsMapIterator(vm);
3167
3168 return napi_clear_last_error(env);
3169 }
3170
napi_is_set_iterator(napi_env env,napi_value value,bool * result)3171 NAPI_EXTERN napi_status napi_is_set_iterator(napi_env env, napi_value value, bool* result)
3172 {
3173 CHECK_ENV(env);
3174 CHECK_ARG(env, value);
3175 CHECK_ARG(env, result);
3176
3177 auto nativeValue = LocalValueFromJsValue(value);
3178 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3179 panda::JsiFastNativeScope fastNativeScope(vm);
3180
3181 *result = nativeValue->IsSetIterator(vm);
3182
3183 return napi_clear_last_error(env);
3184 }
3185
napi_is_generator_object(napi_env env,napi_value value,bool * result)3186 NAPI_EXTERN napi_status napi_is_generator_object(napi_env env, napi_value value, bool* result)
3187 {
3188 CHECK_ENV(env);
3189 CHECK_ARG(env, value);
3190 CHECK_ARG(env, result);
3191
3192 auto nativeValue = LocalValueFromJsValue(value);
3193 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3194 panda::JsiFastNativeScope fastNativeScope(vm);
3195
3196 *result = nativeValue->IsGeneratorObject(vm);
3197
3198 return napi_clear_last_error(env);
3199 }
3200
napi_is_module_namespace_object(napi_env env,napi_value value,bool * result)3201 NAPI_EXTERN napi_status napi_is_module_namespace_object(napi_env env, napi_value value, bool* result)
3202 {
3203 CHECK_ENV(env);
3204 CHECK_ARG(env, value);
3205 CHECK_ARG(env, result);
3206
3207 auto nativeValue = LocalValueFromJsValue(value);
3208 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3209 panda::JsiFastNativeScope fastNativeScope(vm);
3210
3211 *result = nativeValue->IsModuleNamespaceObject(vm);
3212
3213 return napi_clear_last_error(env);
3214 }
3215
napi_is_proxy(napi_env env,napi_value value,bool * result)3216 NAPI_EXTERN napi_status napi_is_proxy(napi_env env, napi_value value, bool* result)
3217 {
3218 CHECK_ENV(env);
3219 CHECK_ARG(env, value);
3220 CHECK_ARG(env, result);
3221
3222 auto nativeValue = LocalValueFromJsValue(value);
3223 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3224 panda::JsiFastNativeScope fastNativeScope(vm);
3225
3226 *result = nativeValue->IsProxy(vm);
3227 return napi_clear_last_error(env);
3228 }
3229
napi_is_reg_exp(napi_env env,napi_value value,bool * result)3230 NAPI_EXTERN napi_status napi_is_reg_exp(napi_env env, napi_value value, bool* result)
3231 {
3232 CHECK_ENV(env);
3233 CHECK_ARG(env, value);
3234 CHECK_ARG(env, result);
3235
3236 auto nativeValue = LocalValueFromJsValue(value);
3237 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3238 panda::JsiFastNativeScope fastNativeScope(vm);
3239
3240 *result = nativeValue->IsRegExp(vm);
3241 return napi_clear_last_error(env);
3242 }
3243
napi_is_number_object(napi_env env,napi_value value,bool * result)3244 NAPI_EXTERN napi_status napi_is_number_object(napi_env env, napi_value value, bool* result)
3245 {
3246 CHECK_ENV(env);
3247 CHECK_ARG(env, value);
3248 CHECK_ARG(env, result);
3249
3250 auto nativeValue = LocalValueFromJsValue(value);
3251 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3252 panda::JsiFastNativeScope fastNativeScope(vm);
3253
3254 *result = nativeValue->IsJSPrimitiveNumber(vm);
3255
3256 return napi_clear_last_error(env);
3257 }
3258
napi_is_map(napi_env env,napi_value value,bool * result)3259 NAPI_EXTERN napi_status napi_is_map(napi_env env, napi_value value, bool* result)
3260 {
3261 CHECK_ENV(env);
3262 CHECK_ARG(env, value);
3263 CHECK_ARG(env, result);
3264
3265 auto nativeValue = LocalValueFromJsValue(value);
3266 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3267 panda::JsiFastNativeScope fastNativeScope(vm);
3268
3269 *result = nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm);
3270 return napi_clear_last_error(env);
3271 }
3272
napi_is_set(napi_env env,napi_value value,bool * result)3273 NAPI_EXTERN napi_status napi_is_set(napi_env env, napi_value value, bool* result)
3274 {
3275 CHECK_ENV(env);
3276 CHECK_ARG(env, value);
3277 CHECK_ARG(env, result);
3278
3279 auto nativeValue = LocalValueFromJsValue(value);
3280 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3281 panda::JsiFastNativeScope fastNativeScope(vm);
3282
3283 *result = nativeValue->IsSet(vm) || nativeValue->IsSharedSet(vm);
3284 return napi_clear_last_error(env);
3285 }
3286
napi_is_string_object(napi_env env,napi_value value,bool * result)3287 NAPI_EXTERN napi_status napi_is_string_object(napi_env env, napi_value value, bool* result)
3288 {
3289 CHECK_ENV(env);
3290 CHECK_ARG(env, value);
3291 CHECK_ARG(env, result);
3292
3293 auto nativeValue = LocalValueFromJsValue(value);
3294 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3295 panda::JsiFastNativeScope fastNativeScope(vm);
3296
3297 *result = nativeValue->IsJSPrimitiveString(vm);
3298
3299 return napi_clear_last_error(env);
3300 }
3301
napi_is_symbol_object(napi_env env,napi_value value,bool * result)3302 NAPI_EXTERN napi_status napi_is_symbol_object(napi_env env, napi_value value, bool* result)
3303 {
3304 CHECK_ENV(env);
3305 CHECK_ARG(env, value);
3306 CHECK_ARG(env, result);
3307
3308 auto nativeValue = LocalValueFromJsValue(value);
3309 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3310 panda::JsiFastNativeScope fastNativeScope(vm);
3311
3312 *result = nativeValue->IsJSPrimitiveSymbol(vm);
3313 return napi_clear_last_error(env);
3314 }
3315
napi_is_weak_map(napi_env env,napi_value value,bool * result)3316 NAPI_EXTERN napi_status napi_is_weak_map(napi_env env, napi_value value, bool* result)
3317 {
3318 CHECK_ENV(env);
3319 CHECK_ARG(env, value);
3320 CHECK_ARG(env, result);
3321
3322 auto nativeValue = LocalValueFromJsValue(value);
3323 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3324 panda::JsiFastNativeScope fastNativeScope(vm);
3325
3326 *result = nativeValue->IsWeakMap(vm);
3327 return napi_clear_last_error(env);
3328 }
3329
napi_is_weak_set(napi_env env,napi_value value,bool * result)3330 NAPI_EXTERN napi_status napi_is_weak_set(napi_env env, napi_value value, bool* result)
3331 {
3332 CHECK_ENV(env);
3333 CHECK_ARG(env, value);
3334 CHECK_ARG(env, result);
3335
3336 auto nativeValue = LocalValueFromJsValue(value);
3337 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3338 panda::JsiFastNativeScope fastNativeScope(vm);
3339
3340 *result = nativeValue->IsWeakSet(vm);
3341 return napi_clear_last_error(env);
3342 }
3343
napi_create_runtime(napi_env env,napi_env * result_env)3344 NAPI_EXTERN napi_status napi_create_runtime(napi_env env, napi_env* result_env)
3345 {
3346 CHECK_ENV(env);
3347 CHECK_ARG(env, result_env);
3348
3349 auto engine = reinterpret_cast<NativeEngine*>(env);
3350 auto result = engine->CreateRuntime();
3351 if (result == nullptr) {
3352 return napi_generic_failure;
3353 }
3354 *result_env = reinterpret_cast<napi_env>(result);
3355
3356 return napi_ok;
3357 }
3358
napi_serialize(napi_env env,napi_value object,napi_value transfer_list,napi_value clone_list,void ** result)3359 NAPI_EXTERN napi_status napi_serialize(napi_env env,
3360 napi_value object,
3361 napi_value transfer_list,
3362 napi_value clone_list,
3363 void** result)
3364 {
3365 CHECK_ENV(env);
3366 CHECK_ARG(env, object);
3367 CHECK_ARG(env, transfer_list);
3368 CHECK_ARG(env, clone_list);
3369 CHECK_ARG(env, result);
3370
3371 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3372 auto nativeValue = LocalValueFromJsValue(object);
3373 auto transferList = LocalValueFromJsValue(transfer_list);
3374 RETURN_STATUS_IF_FALSE(env, transferList->IsUndefined() || transferList->IsJSArray(vm), napi_invalid_arg);
3375 auto cloneList = LocalValueFromJsValue(clone_list);
3376 RETURN_STATUS_IF_FALSE(env, cloneList->IsUndefined() || cloneList->IsJSArray(vm), napi_invalid_arg);
3377 *result = panda::JSNApi::SerializeValue(vm, nativeValue, transferList, cloneList, false, false);
3378
3379 return napi_clear_last_error(env);
3380 }
3381
napi_serialize_inner(napi_env env,napi_value object,napi_value transfer_list,napi_value clone_list,bool defaultTransfer,bool defaultCloneSendable,void ** result)3382 NAPI_EXTERN napi_status napi_serialize_inner(napi_env env, napi_value object, napi_value transfer_list,
3383 napi_value clone_list, bool defaultTransfer, bool defaultCloneSendable,
3384 void** result)
3385 {
3386 CHECK_ENV(env);
3387 CHECK_ARG(env, object);
3388 CHECK_ARG(env, transfer_list);
3389 CHECK_ARG(env, result);
3390
3391 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3392 auto nativeValue = LocalValueFromJsValue(object);
3393 auto transferList = LocalValueFromJsValue(transfer_list);
3394 auto cloneList = LocalValueFromJsValue(clone_list);
3395 *result =
3396 panda::JSNApi::SerializeValue(vm, nativeValue, transferList, cloneList, defaultTransfer, defaultCloneSendable);
3397
3398 return napi_clear_last_error(env);
3399 }
3400
napi_deserialize(napi_env env,void * buffer,napi_value * object)3401 NAPI_EXTERN napi_status napi_deserialize(napi_env env, void* buffer, napi_value* object)
3402 {
3403 CHECK_ENV(env);
3404 CHECK_ARG(env, buffer);
3405 CHECK_ARG(env, object);
3406
3407 auto engine = reinterpret_cast<NativeEngine*>(env);
3408 auto vm = engine->GetEcmaVm();
3409 Local<panda::JSValueRef> res = panda::JSNApi::DeserializeValue(vm, buffer, reinterpret_cast<void*>(engine));
3410 *object = JsValueFromLocalValue(res);
3411
3412 return napi_clear_last_error(env);
3413 }
3414
napi_delete_serialization_data(napi_env env,void * buffer)3415 NAPI_EXTERN napi_status napi_delete_serialization_data(napi_env env, void* buffer)
3416 {
3417 CHECK_ENV(env);
3418 CHECK_ARG(env, buffer);
3419
3420 panda::JSNApi::DeleteSerializationData(buffer);
3421
3422 return napi_clear_last_error(env);
3423 }
3424
napi_create_bigint_int64(napi_env env,int64_t value,napi_value * result)3425 NAPI_EXTERN napi_status napi_create_bigint_int64(napi_env env, int64_t value, napi_value* result)
3426 {
3427 CHECK_ENV(env);
3428 CHECK_ARG(env, result);
3429
3430 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3431 Local<panda::BigIntRef> object = panda::BigIntRef::New(vm, value);
3432 *result = JsValueFromLocalValue(object);
3433
3434 return napi_clear_last_error(env);
3435 }
3436
napi_create_bigint_uint64(napi_env env,uint64_t value,napi_value * result)3437 NAPI_EXTERN napi_status napi_create_bigint_uint64(napi_env env, uint64_t value, napi_value* result)
3438 {
3439 CHECK_ENV(env);
3440 CHECK_ARG(env, result);
3441
3442 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3443 Local<panda::BigIntRef> object = panda::BigIntRef::New(vm, value);
3444 *result = JsValueFromLocalValue(object);
3445
3446 return napi_clear_last_error(env);
3447 }
3448
napi_get_value_bigint_int64(napi_env env,napi_value value,int64_t * result,bool * lossless)3449 NAPI_EXTERN napi_status napi_get_value_bigint_int64(
3450 napi_env env, napi_value value, int64_t* result, bool* lossless)
3451 {
3452 CHECK_ENV(env);
3453 CHECK_ARG(env, value);
3454 CHECK_ARG(env, result);
3455 CHECK_ARG(env, lossless);
3456
3457 auto nativeValue = LocalValueFromJsValue(value);
3458 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3459 panda::JsiFastNativeScope fastNativeScope(vm);
3460 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBigInt(vm), napi_bigint_expected);
3461 Local<panda::BigIntRef> bigIntVal = nativeValue->ToBigInt(vm);
3462 bigIntVal->BigIntToInt64(vm, result, lossless);
3463
3464 return napi_clear_last_error(env);
3465 }
3466
napi_get_value_bigint_uint64(napi_env env,napi_value value,uint64_t * result,bool * lossless)3467 NAPI_EXTERN napi_status napi_get_value_bigint_uint64(
3468 napi_env env, napi_value value, uint64_t* result, bool* lossless)
3469 {
3470 CHECK_ENV(env);
3471 CHECK_ARG(env, value);
3472 CHECK_ARG(env, result);
3473 CHECK_ARG(env, lossless);
3474
3475 auto nativeValue = LocalValueFromJsValue(value);
3476 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3477 panda::JsiFastNativeScope fastNativeScope(vm);
3478 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBigInt(vm), napi_bigint_expected);
3479 Local<panda::BigIntRef> bigIntVal = nativeValue->ToBigInt(vm);
3480 bigIntVal->BigIntToUint64(vm, result, lossless);
3481
3482 return napi_clear_last_error(env);
3483 }
3484
napi_is_date(napi_env env,napi_value value,bool * result)3485 NAPI_EXTERN napi_status napi_is_date(napi_env env, napi_value value, bool* result)
3486 {
3487 CHECK_ENV(env);
3488 CHECK_ARG(env, value);
3489 CHECK_ARG(env, result);
3490
3491 auto nativeValue = LocalValueFromJsValue(value);
3492 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3493 panda::JsiFastNativeScope fastNativeScope(vm);
3494
3495 *result = nativeValue->IsDate(vm);
3496 return napi_clear_last_error(env);
3497 }
3498
napi_is_detached_arraybuffer(napi_env env,napi_value arraybuffer,bool * result)3499 NAPI_EXTERN napi_status napi_is_detached_arraybuffer(napi_env env, napi_value arraybuffer, bool* result)
3500 {
3501 CHECK_ENV(env);
3502 CHECK_ARG(env, arraybuffer);
3503 CHECK_ARG(env, result);
3504
3505 auto nativeValue = LocalValueFromJsValue(arraybuffer);
3506 bool isArrayBuffer = false;
3507 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3508 panda::JsiFastNativeScope fastNativeScope(vm);
3509
3510 bool isDetach = nativeValue->IsDetachedArraybuffer(vm, isArrayBuffer);
3511 if (isArrayBuffer) {
3512 *result = isDetach;
3513 return napi_clear_last_error(env);
3514 } else {
3515 return napi_set_last_error(env, napi_invalid_arg);
3516 }
3517 }
3518
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)3519 NAPI_EXTERN napi_status napi_get_all_property_names(
3520 napi_env env, napi_value object, napi_key_collection_mode key_mode,
3521 napi_key_filter key_filter, napi_key_conversion key_conversion, napi_value* result)
3522 {
3523 NAPI_PREAMBLE(env);
3524 CHECK_ARG(env, object);
3525 CHECK_ARG(env, result);
3526 auto nativeValue = LocalValueFromJsValue(object);
3527 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3528 panda::JsiFastNativeScope fastNativeScope(vm);
3529 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj);
3530 uint32_t filter = NATIVE_DEFAULT;
3531 if (key_filter & napi_key_writable) {
3532 filter = static_cast<uint32_t>(filter | NATIVE_WRITABLE);
3533 }
3534 if (key_filter & napi_key_enumerable) {
3535 filter = static_cast<uint32_t>(filter | NATIVE_ENUMERABLE);
3536 }
3537 if (key_filter & napi_key_configurable) {
3538 filter = static_cast<uint32_t>(filter | NATIVE_CONFIGURABLE);
3539 }
3540 if (key_filter & napi_key_skip_strings) {
3541 filter = static_cast<uint32_t>(filter | NATIVE_KEY_SKIP_STRINGS);
3542 }
3543 if (key_filter & napi_key_skip_symbols) {
3544 filter = static_cast<uint32_t>(filter | NATIVE_KEY_SKIP_SYMBOLS);
3545 }
3546
3547 switch (key_mode) {
3548 case napi_key_include_prototypes:
3549 filter = static_cast<uint32_t>(filter | NATIVE_KEY_INCLUDE_PROTOTYPES);
3550 break;
3551 case napi_key_own_only:
3552 filter = static_cast<uint32_t>(filter | NATIVE_KEY_OWN_ONLY);
3553 break;
3554 default:
3555 *result = nullptr;
3556 HILOG_ERROR("%{public}s invalid arg", __func__);
3557 return napi_set_last_error(env, napi_invalid_arg);
3558 }
3559
3560 switch (key_conversion) {
3561 case napi_key_keep_numbers:
3562 filter = static_cast<uint32_t>(filter | NATIVE_KEY_KEEP_NUMBERS);
3563 break;
3564 case napi_key_numbers_to_strings:
3565 filter = static_cast<uint32_t>(filter | NATIVE_KEY_NUMBERS_TO_STRINGS);
3566 break;
3567 default:
3568 *result = nullptr;
3569 HILOG_ERROR("%{public}s invalid arg", __func__);
3570 return napi_set_last_error(env, napi_invalid_arg);
3571 }
3572 Local<panda::ArrayRef> arrayVal = obj->GetAllPropertyNames(vm, filter);
3573 *result = JsValueFromLocalValue(arrayVal);
3574 return GET_RETURN_STATUS(env);
3575 }
3576
napi_detach_arraybuffer(napi_env env,napi_value arraybuffer)3577 NAPI_EXTERN napi_status napi_detach_arraybuffer(napi_env env, napi_value arraybuffer)
3578 {
3579 CHECK_ENV(env);
3580 CHECK_ARG(env, arraybuffer);
3581
3582 auto nativeValue = LocalValueFromJsValue(arraybuffer);
3583 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3584 panda::JsiFastNativeScope fastNativeScope(vm);
3585
3586 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
3587 bool isArrayBuffer = false;
3588 nativeValue->DetachedArraybuffer(vm, isArrayBuffer);
3589 if (!isArrayBuffer) {
3590 return napi_set_last_error(env, napi_invalid_arg);
3591 }
3592 return napi_clear_last_error(env);
3593 }
3594
napi_type_tag_object(napi_env env,napi_value js_object,const napi_type_tag * type_tag)3595 NAPI_EXTERN napi_status napi_type_tag_object(napi_env env, napi_value js_object, const napi_type_tag* type_tag)
3596 {
3597 NAPI_PREAMBLE(env);
3598 CHECK_ARG(env, js_object);
3599 CHECK_ARG(env, type_tag);
3600
3601 auto nativeValue = LocalValueFromJsValue(js_object);
3602 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3603 panda::JsiFastNativeScope fastNativeScope(vm);
3604 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
3605 auto obj = nativeValue->ToEcmaObject(vm);
3606 NapiTypeTag* typeTag = (NapiTypeTag*)type_tag;
3607 const char name[] = "ACENAPI_TYPETAG";
3608 bool hasPribate = false;
3609 bool result = true;
3610 Local<panda::StringRef> key = StringRef::NewFromUtf8(vm, name);
3611 hasPribate = obj->Has(vm, key);
3612 if (!hasPribate) {
3613 constexpr int bigintMod = 2; // 2 : used for even number judgment
3614 int sign_bit = 0;
3615 size_t word_count = 2;
3616 bool sign = false;
3617 if ((sign_bit % bigintMod) == 1) {
3618 sign = true;
3619 }
3620 uint32_t size = (uint32_t)word_count;
3621 Local<panda::JSValueRef> value = panda::BigIntRef::CreateBigWords(vm, sign, size,
3622 reinterpret_cast<const uint64_t*>(typeTag));
3623 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, name);
3624 result = obj->Set(vm, key, value);
3625 }
3626 if (!result) {
3627 HILOG_ERROR("%{public}s invalid arg", __func__);
3628 return napi_set_last_error(env, napi_invalid_arg);
3629 }
3630
3631 return napi_clear_last_error(env);
3632 }
3633
BigIntGetWordsArray(const EcmaVM * vm,Local<panda::BigIntRef> & value,int * signBit,size_t * wordCount,uint64_t * words)3634 bool BigIntGetWordsArray(const EcmaVM* vm, Local<panda::BigIntRef> &value, int* signBit,
3635 size_t* wordCount, uint64_t* words)
3636 {
3637 if (wordCount == nullptr) {
3638 return false;
3639 }
3640 size_t size = static_cast<size_t>(value->GetWordsArraySize(vm));
3641 if (signBit == nullptr && words == nullptr) {
3642 *wordCount = size;
3643 return true;
3644 } else if (signBit != nullptr && words != nullptr) {
3645 if (size > *wordCount) {
3646 size = *wordCount;
3647 }
3648 bool sign = false;
3649 value->GetWordsArray(vm, &sign, size, words);
3650 if (sign) {
3651 *signBit = 1;
3652 } else {
3653 *signBit = 0;
3654 }
3655 *wordCount = size;
3656 return true;
3657 }
3658 return false;
3659 }
3660
napi_check_object_type_tag(napi_env env,napi_value js_object,const napi_type_tag * type_tag,bool * result)3661 NAPI_EXTERN napi_status napi_check_object_type_tag(napi_env env,
3662 napi_value js_object,
3663 const napi_type_tag* type_tag,
3664 bool* result)
3665 {
3666 NAPI_PREAMBLE(env);
3667 CHECK_ARG(env, js_object);
3668 CHECK_ARG(env, type_tag);
3669 CHECK_ARG(env, result);
3670
3671 auto nativeValue = LocalValueFromJsValue(js_object);
3672 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3673 panda::JsiFastNativeScope fastNativeScope(vm);
3674 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
3675 auto obj = nativeValue->ToEcmaObject(vm);
3676 NapiTypeTag* typeTag = (NapiTypeTag*)type_tag;
3677 *result = false;
3678 const char name[] = "ACENAPI_TYPETAG";
3679
3680 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, name);
3681 *result = obj->Has(vm, key);
3682 if (*result) {
3683 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, name);
3684 Local<panda::JSValueRef> object = obj->Get(vm, key);
3685 if (object->IsBigInt(vm)) {
3686 int sign;
3687 size_t size = 2; // 2: Indicates that the number of elements is 2
3688 NapiTypeTag tag;
3689 Local<panda::BigIntRef> bigintObj = object->ToBigInt(vm);
3690 BigIntGetWordsArray(vm, bigintObj, &sign, &size, reinterpret_cast<uint64_t*>(&tag));
3691 if (sign == 0 && ((size == 1) || (size == 2))) { // 2: Indicates that the number of elements is 2
3692 *result = (tag.lower == typeTag->lower && tag.upper == typeTag->upper);
3693 }
3694 }
3695 }
3696 return napi_clear_last_error(env);
3697 }
3698
napi_create_date(napi_env env,double time,napi_value * result)3699 NAPI_EXTERN napi_status napi_create_date(napi_env env, double time, napi_value* result)
3700 {
3701 NAPI_PREAMBLE(env);
3702 CHECK_ARG(env, result);
3703
3704 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3705 *result = JsValueFromLocalValue(DateRef::New(vm, time));
3706
3707 return napi_clear_last_error(env);
3708 }
3709
napi_get_date_value(napi_env env,napi_value value,double * result)3710 NAPI_EXTERN napi_status napi_get_date_value(napi_env env, napi_value value, double* result)
3711 {
3712 NAPI_PREAMBLE(env);
3713 CHECK_ARG(env, value);
3714 CHECK_ARG(env, result);
3715
3716 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3717 auto nativeValue = LocalValueFromJsValue(value);
3718 panda::JsiFastNativeScope fastNativeScope(vm);
3719
3720 auto IsDate_result = nativeValue->IsDate(vm);
3721 Local<panda::DateRef> dateObj(nativeValue);
3722 if (IsDate_result) {
3723 *result = dateObj->GetTime(vm);
3724 } else {
3725 HILOG_ERROR("%{public}s date expected", __func__);
3726 return napi_set_last_error(env, napi_date_expected);
3727 }
3728
3729 return napi_clear_last_error(env);
3730 }
3731
napi_add_finalizer(napi_env env,napi_value js_object,void * native_object,napi_finalize finalize_cb,void * finalize_hint,napi_ref * result)3732 NAPI_EXTERN napi_status napi_add_finalizer(napi_env env,
3733 napi_value js_object,
3734 void* native_object,
3735 napi_finalize finalize_cb,
3736 void* finalize_hint,
3737 napi_ref* result)
3738 {
3739 CHECK_ENV(env);
3740 CHECK_ARG(env, js_object);
3741 CHECK_ARG(env, finalize_cb);
3742
3743 auto nativeValue = LocalValueFromJsValue(js_object);
3744 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
3745 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3746 panda::JsiFastNativeScope fastNativeScope(vm);
3747
3748 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
3749 NativeReference* reference = nullptr;
3750 auto engine = reinterpret_cast<NativeEngine*>(env);
3751 if (result != nullptr) {
3752 reference = engine->CreateReference(js_object, 1, false, callback, native_object, finalize_hint);
3753 *result = reinterpret_cast<napi_ref>(reference);
3754 } else {
3755 reference = engine->CreateReference(js_object, 0, true, callback, native_object, finalize_hint);
3756 }
3757 return napi_clear_last_error(env);
3758 }
3759
napi_create_bigint_words(napi_env env,int sign_bit,size_t word_count,const uint64_t * words,napi_value * result)3760 NAPI_EXTERN napi_status napi_create_bigint_words(napi_env env,
3761 int sign_bit,
3762 size_t word_count,
3763 const uint64_t* words,
3764 napi_value* result)
3765 {
3766 NAPI_PREAMBLE(env);
3767 CHECK_ARG(env, words);
3768 CHECK_ARG(env, result);
3769 RETURN_STATUS_IF_FALSE(env, word_count <= INT_MAX, napi_invalid_arg);
3770
3771 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3772 constexpr int bigintMod = 2; // 2 : used for even number judgment
3773 bool sign = false;
3774 if ((sign_bit % bigintMod) == 1) {
3775 sign = true;
3776 }
3777 uint32_t size = (uint32_t)word_count;
3778 Local<panda::JSValueRef> value = panda::BigIntRef::CreateBigWords(vm, sign, size, words);
3779
3780 if (panda::JSNApi::HasPendingException(vm)) {
3781 HILOG_ERROR("%{public}s pending exception", __func__);
3782 return napi_set_last_error(env, napi_pending_exception);
3783 }
3784 *result = JsValueFromLocalValue(value);
3785 return GET_RETURN_STATUS(env);
3786 }
3787
napi_get_value_bigint_words(napi_env env,napi_value value,int * sign_bit,size_t * word_count,uint64_t * words)3788 NAPI_EXTERN napi_status napi_get_value_bigint_words(napi_env env,
3789 napi_value value,
3790 int* sign_bit,
3791 size_t* word_count,
3792 uint64_t* words)
3793 {
3794 CHECK_ENV(env);
3795 CHECK_ARG(env, value);
3796 CHECK_ARG(env, word_count);
3797
3798 auto nativeValue = LocalValueFromJsValue(value);
3799 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3800 panda::JsiFastNativeScope fastNativeScope(vm);
3801
3802 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBigInt(vm), napi_object_expected);
3803 auto BigintObj = nativeValue->ToBigInt(vm);
3804 if (word_count == nullptr) {
3805 return napi_set_last_error(env, napi_invalid_arg);
3806 }
3807 size_t size = static_cast<size_t>(BigintObj->GetWordsArraySize(vm));
3808 if (sign_bit == nullptr && words == nullptr) {
3809 *word_count = size;
3810 return napi_set_last_error(env, napi_ok);
3811 } else if (sign_bit != nullptr && words != nullptr) {
3812 if (size > *word_count) {
3813 size = *word_count;
3814 }
3815 bool sign = false;
3816 BigintObj->GetWordsArray(vm, &sign, size, words);
3817 if (sign) {
3818 *sign_bit = 1;
3819 } else {
3820 *sign_bit = 0;
3821 }
3822 *word_count = size;
3823 return napi_set_last_error(env, napi_ok);
3824 }
3825
3826 return napi_clear_last_error(env);
3827 }
3828
napi_run_script_path(napi_env env,const char * path,napi_value * result)3829 NAPI_EXTERN napi_status napi_run_script_path(napi_env env, const char* path, napi_value* result)
3830 {
3831 NAPI_PREAMBLE(env);
3832 CHECK_ARG(env, result);
3833
3834 auto engine = reinterpret_cast<NativeEngine*>(env);
3835 std::string pathStr(path);
3836 if (engine->IsApplicationApiVersionAPI11Plus()) {
3837 pathStr = panda::JSNApi::NormalizePath(path);
3838 }
3839 HILOG_DEBUG("napi_run_script_path path: %{public}s", pathStr.c_str());
3840 if (engine->IsRestrictedWorkerThread()) {
3841 *result = engine->RunScriptInRestrictedThread(pathStr.c_str());
3842 } else {
3843 *result = engine->RunScript(pathStr.c_str());
3844 }
3845 return GET_RETURN_STATUS(env);
3846 }
3847
napi_is_big_int64_array(napi_env env,napi_value value,bool * result)3848 NAPI_EXTERN napi_status napi_is_big_int64_array(napi_env env, napi_value value, bool* result)
3849 {
3850 CHECK_ENV(env);
3851 CHECK_ARG(env, value);
3852 CHECK_ARG(env, result);
3853
3854 auto nativeValue = LocalValueFromJsValue(value);
3855 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3856 panda::JsiFastNativeScope fastNativeScope(vm);
3857
3858 *result = nativeValue->IsBigInt64Array(vm);
3859 return napi_clear_last_error(env);
3860 }
3861
napi_is_big_uint64_array(napi_env env,napi_value value,bool * result)3862 NAPI_EXTERN napi_status napi_is_big_uint64_array(napi_env env, napi_value value, bool* result)
3863 {
3864 CHECK_ENV(env);
3865 CHECK_ARG(env, value);
3866 CHECK_ARG(env, result);
3867
3868 auto nativeValue = LocalValueFromJsValue(value);
3869 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3870 panda::JsiFastNativeScope fastNativeScope(vm);
3871
3872 *result = nativeValue->IsBigUint64Array(vm);
3873 return napi_clear_last_error(env);
3874 }
3875
napi_is_shared_array_buffer(napi_env env,napi_value value,bool * result)3876 NAPI_EXTERN napi_status napi_is_shared_array_buffer(napi_env env, napi_value value, bool* result)
3877 {
3878 CHECK_ENV(env);
3879 CHECK_ARG(env, value);
3880 CHECK_ARG(env, result);
3881
3882 auto nativeValue = LocalValueFromJsValue(value);
3883 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3884 panda::JsiFastNativeScope fastNativeScope(vm);
3885
3886 *result = nativeValue->IsSharedArrayBuffer(vm);
3887 return napi_clear_last_error(env);
3888 }
3889
napi_get_stack_trace(napi_env env,std::string & stack)3890 NAPI_EXTERN napi_status napi_get_stack_trace(napi_env env, std::string& stack)
3891 {
3892 CHECK_ENV(env);
3893
3894 auto engine = reinterpret_cast<NativeEngine*>(env);
3895 [[maybe_unused]] auto vm = engine->GetEcmaVm();
3896 std::string rawStack;
3897 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
3898 DFXJSNApi::BuildJsStackTrace(vm, rawStack);
3899 stack = engine->ExecuteTranslateBySourceMap(rawStack);
3900 #else
3901 HILOG_WARN("GetStacktrace env get stack failed");
3902 #endif
3903
3904 return napi_clear_last_error(env);
3905 }
3906
napi_get_hybrid_stack_trace(napi_env env,std::string & stack)3907 NAPI_EXTERN napi_status napi_get_hybrid_stack_trace(napi_env env, std::string& stack)
3908 {
3909 CHECK_ENV(env);
3910
3911 auto engine = reinterpret_cast<NativeEngine*>(env);
3912 auto vm = engine->GetEcmaVm();
3913 if (DumpHybridStack(vm, stack, 3)) { // 3: skiped frames
3914 return napi_ok;
3915 } else {
3916 HILOG_WARN("GetHybridStacktrace env get hybrid stack failed");
3917 return napi_generic_failure;
3918 }
3919 }
3920
napi_object_get_keys(napi_env env,napi_value data,napi_value * result)3921 NAPI_EXTERN napi_status napi_object_get_keys(napi_env env, napi_value data, napi_value* result)
3922 {
3923 CHECK_ENV(env);
3924
3925 auto nativeValue = LocalValueFromJsValue(data);
3926 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3927 panda::JsiFastNativeScope fastNativeScope(vm);
3928 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
3929 auto obj = nativeValue->ToEcmaObject(vm);
3930 Local<panda::ArrayRef> arrayVal = obj->GetOwnEnumerablePropertyNames(vm);
3931
3932 *result = JsValueFromLocalValue(arrayVal);
3933 return napi_clear_last_error(env);
3934 }
3935
napi_queue_async_work_with_qos(napi_env env,napi_async_work work,napi_qos_t qos)3936 NAPI_EXTERN napi_status napi_queue_async_work_with_qos(napi_env env, napi_async_work work, napi_qos_t qos)
3937 {
3938 CHECK_ENV(env);
3939 CHECK_ARG(env, work);
3940
3941 auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work);
3942 asyncWork->QueueWithQos(reinterpret_cast<NativeEngine*>(env), qos);
3943 return napi_status::napi_ok;
3944 }
3945
DetachFuncCallback(void * engine,void * object,void * hint,void * detachData)3946 static void* DetachFuncCallback(void* engine, void* object, void* hint, void* detachData)
3947 {
3948 if (detachData == nullptr || (engine == nullptr || object ==nullptr)) {
3949 HILOG_ERROR("DetachFuncCallback params has nullptr");
3950 return nullptr;
3951 }
3952 DetachCallback detach = reinterpret_cast<DetachCallback>(detachData);
3953 void* detachVal = detach(reinterpret_cast<NativeEngine*>(engine), object, hint);
3954 return detachVal;
3955 }
3956
AttachFuncCallback(void * engine,void * buffer,void * hint,void * attachData)3957 static Local<panda::JSValueRef> AttachFuncCallback(void* engine, void* buffer, void* hint, void* attachData)
3958 {
3959 if (engine == nullptr) {
3960 HILOG_ERROR("AttachFuncCallback engine is nullptr");
3961 return Local<panda::JSValueRef>();
3962 }
3963 auto vm = reinterpret_cast<NativeEngine*>(engine)->GetEcmaVm();
3964 if (attachData == nullptr || buffer ==nullptr) {
3965 HILOG_ERROR("AttachFuncCallback params has nullptr");
3966 return panda::JSValueRef::Undefined(vm);
3967 }
3968 EscapeLocalScope scope(vm);
3969 Local<panda::JSValueRef> result = panda::JSValueRef::Undefined(vm);
3970 NapiAttachCallback attach = reinterpret_cast<NapiAttachCallback>(attachData);
3971 napi_value attachVal = attach(reinterpret_cast<napi_env>(engine), buffer, hint);
3972 if (attachVal == nullptr) {
3973 HILOG_WARN("AttachFunc return nullptr");
3974 } else {
3975 result = LocalValueFromJsValue(attachVal);
3976 }
3977 return scope.Escape(result);
3978 }
3979
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)3980 NAPI_EXTERN napi_status napi_coerce_to_native_binding_object(napi_env env,
3981 napi_value js_object,
3982 napi_native_binding_detach_callback detach_cb,
3983 napi_native_binding_attach_callback attach_cb,
3984 void* native_object,
3985 void* hint)
3986 {
3987 CHECK_ENV(env);
3988 CHECK_ARG(env, js_object);
3989 CHECK_ARG(env, detach_cb);
3990 CHECK_ARG(env, attach_cb);
3991 CHECK_ARG(env, native_object);
3992
3993 auto jsValue = LocalValueFromJsValue(js_object);
3994 auto engine = reinterpret_cast<NativeEngine*>(env);
3995 auto vm = engine->GetEcmaVm();
3996 panda::JsiFastNativeScope fastNativeScope(vm);
3997
3998 RETURN_STATUS_IF_FALSE(env, jsValue->IsObject(vm), napi_object_expected);
3999 auto obj = jsValue->ToEcmaObject(vm);
4000
4001 panda::JSNApi::NativeBindingInfo* data = panda::JSNApi::NativeBindingInfo::CreateNewInstance();
4002 if (data == nullptr) {
4003 HILOG_ERROR("data is nullptr");
4004 return napi_set_last_error(env, napi_invalid_arg);
4005 }
4006 data->env = env;
4007 data->nativeValue = native_object;
4008 data->attachFunc = reinterpret_cast<void*>(AttachFuncCallback);
4009 data->attachData = reinterpret_cast<void*>(attach_cb);
4010 data->detachFunc = reinterpret_cast<void*>(DetachFuncCallback);
4011 data->detachData = reinterpret_cast<void*>(detach_cb);
4012 data->hint = hint;
4013
4014 size_t nativeBindingSize = 7 * sizeof(void *); // 7 : params num
4015 Local<panda::NativePointerRef> value = panda::NativePointerRef::NewConcurrent(vm, data,
4016 [](void* env, void* data, void* info) {
4017 auto externalInfo = reinterpret_cast<panda::JSNApi::NativeBindingInfo*>(data);
4018 delete externalInfo;
4019 }, nullptr, nativeBindingSize);
4020
4021 bool res = obj->ConvertToNativeBindingObject(vm, value);
4022 if (res) {
4023 return napi_clear_last_error(env);
4024 }
4025 return napi_status::napi_generic_failure;
4026 }
4027
napi_add_detached_finalizer(napi_env env,napi_value native_binding_object,napi_detach_finalize_callback detach_finalize_cb,void * finalize_hint)4028 NAPI_EXTERN napi_status napi_add_detached_finalizer(napi_env env,
4029 napi_value native_binding_object,
4030 napi_detach_finalize_callback detach_finalize_cb,
4031 void* finalize_hint)
4032 {
4033 CHECK_ENV(env);
4034 CHECK_ARG(env, native_binding_object);
4035 CHECK_ARG(env, detach_finalize_cb);
4036
4037 auto jsValue = LocalValueFromJsValue(native_binding_object);
4038 auto engine = reinterpret_cast<NativeEngine*>(env);
4039 auto vm = engine->GetEcmaVm();
4040 panda::JsiFastNativeScope fastNativeScope(vm);
4041
4042 RETURN_STATUS_IF_FALSE(env, jsValue->IsNativeBindingObject(vm), napi_object_expected);
4043 Local<ObjectRef> nativeObject(jsValue);
4044
4045 Local<panda::NativePointerRef> nativeBindingPointer = nativeObject->GetNativeBindingPointer(vm);
4046 if (!nativeBindingPointer->IsNativePointer(vm)) {
4047 return napi_generic_failure;
4048 }
4049
4050 auto info = static_cast<panda::JSNApi::NativeBindingInfo*>(nativeBindingPointer->Value());
4051 if (info == nullptr) {
4052 return napi_generic_failure;
4053 }
4054
4055 info->detachedFinalizer = reinterpret_cast<void *>(detach_finalize_cb);
4056 info->detachedHint = finalize_hint;
4057
4058 return napi_clear_last_error(env);
4059 }
4060
napi_get_print_string(napi_env env,napi_value value,std::string & result)4061 NAPI_EXTERN napi_status napi_get_print_string(napi_env env, napi_value value, std::string& result)
4062 {
4063 CHECK_ENV(env);
4064 CHECK_ARG(env, value);
4065
4066 auto nativeValue = LocalValueFromJsValue(value);
4067 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
4068 panda::JsiFastNativeScope fastNativeScope(vm);
4069
4070 if (nativeValue->IsString(vm)) {
4071 Local<panda::StringRef> stringVal(nativeValue);
4072 result = stringVal->ToString(vm);
4073 }
4074 return napi_clear_last_error(env);
4075 }
4076
napi_run_event_loop(napi_env env,napi_event_mode mode)4077 NAPI_EXTERN napi_status napi_run_event_loop(napi_env env, napi_event_mode mode)
4078 {
4079 CHECK_ENV(env);
4080
4081 if (mode < napi_event_mode_default || mode > napi_event_mode_nowait) {
4082 HILOG_ERROR("invalid mode %{public}d", static_cast<int32_t>(mode));
4083 return napi_status::napi_invalid_arg;
4084 }
4085
4086 auto nativeEngine = reinterpret_cast<NativeEngine*>(env);
4087 auto result = nativeEngine->RunEventLoop(mode);
4088 if (result != napi_status::napi_ok) {
4089 HILOG_ERROR("failed due to error %{public}d", static_cast<int32_t>(result));
4090 return napi_set_last_error(env, result);
4091 }
4092
4093 return napi_clear_last_error(env);
4094 }
4095
napi_stop_event_loop(napi_env env)4096 NAPI_EXTERN napi_status napi_stop_event_loop(napi_env env)
4097 {
4098 CHECK_ENV(env);
4099
4100 auto nativeEngine = reinterpret_cast<NativeEngine*>(env);
4101 auto result = nativeEngine->StopEventLoop();
4102 if (result != napi_status::napi_ok) {
4103 HILOG_ERROR("stop event loop failed due to error %{public}d", static_cast<int32_t>(result));
4104 return napi_set_last_error(env, result);
4105 }
4106 return napi_clear_last_error(env);
4107 }
4108
napi_create_ark_runtime(napi_env * env)4109 NAPI_EXTERN napi_status napi_create_ark_runtime(napi_env* env)
4110 {
4111 if (NativeCreateEnv::g_createNapiEnvCallback == nullptr) {
4112 HILOG_ERROR("invalid create callback");
4113 return napi_status::napi_invalid_arg;
4114 }
4115
4116 bool success = WorkerManager::IncrementArkRuntimeCount();
4117 if (!success) {
4118 HILOG_ERROR("reach max ARKRuntime count limit");
4119 return napi_status::napi_create_ark_runtime_too_many_envs;
4120 }
4121
4122 napi_status result = NativeCreateEnv::g_createNapiEnvCallback(env);
4123 if (result == napi_ok) {
4124 auto vm = reinterpret_cast<NativeEngine*>(*env)->GetEcmaVm();
4125 panda::JSNApi::SetExecuteBufferMode(vm);
4126 } else {
4127 WorkerManager::DecrementArkRuntimeCount();
4128 }
4129 return result;
4130 }
4131
napi_destroy_ark_runtime(napi_env * env)4132 NAPI_EXTERN napi_status napi_destroy_ark_runtime(napi_env* env)
4133 {
4134 if (NativeCreateEnv::g_destroyNapiEnvCallback == nullptr) {
4135 HILOG_ERROR("invalid destroy callback");
4136 return napi_status::napi_invalid_arg;
4137 }
4138
4139 napi_status result = NativeCreateEnv::g_destroyNapiEnvCallback(env);
4140 if (result == napi_status::napi_ok) {
4141 WorkerManager::DecrementArkRuntimeCount();
4142 }
4143 return result;
4144 }
4145
napi_is_concurrent_function(napi_env env,napi_value value,bool * result)4146 NAPI_EXTERN napi_status napi_is_concurrent_function(napi_env env, napi_value value, bool* result)
4147 {
4148 CHECK_ENV(env);
4149 CHECK_ARG(env, value);
4150 CHECK_ARG(env, result);
4151
4152 auto nativeValue = LocalValueFromJsValue(value);
4153 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
4154 panda::JsiFastNativeScope fastNativeScope(vm);
4155
4156 *result = nativeValue->IsConcurrentFunction(vm);
4157 return napi_clear_last_error(env);
4158 }
4159
napi_call_threadsafe_function_with_priority(napi_threadsafe_function func,void * data,napi_task_priority priority,bool isTail)4160 NAPI_EXTERN napi_status napi_call_threadsafe_function_with_priority(napi_threadsafe_function func,
4161 void *data,
4162 napi_task_priority priority,
4163 bool isTail)
4164 {
4165 CHECK_ENV(func);
4166
4167 if (priority < napi_priority_immediate || priority > napi_priority_idle) {
4168 HILOG_ERROR("invalid priority %{public}d", static_cast<int32_t>(priority));
4169 return napi_status::napi_invalid_arg;
4170 }
4171 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
4172 int32_t innerPriority = static_cast<int32_t>(priority);
4173 auto res = safeAsyncWork->PostTask(data, innerPriority, isTail);
4174 if (res != napi_ok) {
4175 HILOG_ERROR("post task failed due to error %{public}d", res);
4176 }
4177 return res;
4178 }
4179
napi_open_fast_native_scope(napi_env env,napi_fast_native_scope * scope)4180 NAPI_EXTERN napi_status napi_open_fast_native_scope(napi_env env, napi_fast_native_scope* scope)
4181 {
4182 CHECK_ENV(env);
4183 CHECK_ARG(env, scope);
4184
4185 auto engine = reinterpret_cast<NativeEngine*>(env);
4186 *scope = reinterpret_cast<napi_fast_native_scope>(new panda::JsiFastNativeScope(engine->GetEcmaVm()));
4187 return napi_clear_last_error(env);
4188 }
4189
napi_close_fast_native_scope(napi_env env,napi_fast_native_scope scope)4190 NAPI_EXTERN napi_status napi_close_fast_native_scope(napi_env env, napi_fast_native_scope scope)
4191 {
4192 CHECK_ENV(env);
4193 CHECK_ARG(env, scope);
4194
4195 delete reinterpret_cast<panda::JsiFastNativeScope*>(scope);
4196 return napi_clear_last_error(env);
4197 }
4198
napi_get_shared_array_buffer_info(napi_env env,napi_value arraybuffer,void ** data,size_t * byte_length)4199 NAPI_EXTERN napi_status napi_get_shared_array_buffer_info(napi_env env,
4200 napi_value arraybuffer,
4201 void** data,
4202 size_t* byte_length)
4203 {
4204 CHECK_ENV(env);
4205 CHECK_ARG(env, arraybuffer);
4206 CHECK_ARG(env, byte_length);
4207
4208 auto nativeValue = LocalValueFromJsValue(arraybuffer);
4209 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
4210 panda::JsiFastNativeScope fastNativeScope(vm);
4211 if (LIKELY(nativeValue->IsSharedArrayBuffer(vm))) {
4212 Local<panda::ArrayBufferRef> res(nativeValue);
4213 if (data != nullptr) {
4214 *data = res->GetBuffer(vm);
4215 }
4216 *byte_length = res->ByteLength(vm);
4217 } else {
4218 return napi_set_last_error(env, napi_arraybuffer_expected);
4219 }
4220
4221 return napi_clear_last_error(env);
4222 }
4223
napi_encode(napi_env env,napi_value src,napi_value * result)4224 NAPI_EXTERN napi_status napi_encode(napi_env env, napi_value src, napi_value* result)
4225 {
4226 CHECK_ENV(env);
4227 CHECK_ARG(env, src);
4228 CHECK_ARG(env, result);
4229
4230 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
4231 panda::JsiFastNativeScope fastNativeScoper(vm);
4232
4233 auto nativeValue = LocalValueFromJsValue(src);
4234 RETURN_STATUS_IF_FALSE(env, nativeValue->IsString(vm), napi_string_expected);
4235 Local<panda::StringRef> stringVal(nativeValue);
4236 Local<TypedArrayRef> typedArray = stringVal->EncodeIntoUint8Array(vm);
4237 *result = JsValueFromLocalValue(typedArray);
4238
4239 return napi_clear_last_error(env);
4240 }
4241
napi_is_bitvector(napi_env env,napi_value value,bool * result)4242 NAPI_EXTERN napi_status napi_is_bitvector(napi_env env, napi_value value, bool* result)
4243 {
4244 CHECK_ENV(env);
4245 CHECK_ARG(env, value);
4246 CHECK_ARG(env, result);
4247
4248 auto nativeValue = LocalValueFromJsValue(value);
4249 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
4250 panda::JsiFastNativeScope fastNativeScope(vm);
4251
4252 *result = nativeValue->IsBitVector(vm);
4253
4254 return napi_clear_last_error(env);
4255 }
4256