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