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