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 auto funcInfo = reinterpret_cast<NapiFunctionInfo *>(function->GetData(vm));
1222 if (funcInfo != nullptr) {
1223 scopeId = funcInfo->scopeId;
1224 }
1225 OHOS::Ace::ContainerScope containerScope(scopeId);
1226 #endif
1227 panda::JSValueRef* value =
1228 function->CallForNapi(vm, thisObj, reinterpret_cast<panda::JSValueRef *const*>(argv), argc);
1229 // if pending exception, value will be a pointer to JSTaggedValue::Hole.
1230 if (UNLIKELY(!NapiStatusValidationCheck(value))) {
1231 HILOG_ERROR("pending exception when js function called, print exception info: ");
1232 panda::JSNApi::PrintExceptionInfo(vm);
1233 result = nullptr;
1234 reinterpret_cast<NativeEngine *>(env)->lastException_ = panda::JSNApi::GetUncaughtException(vm);
1235 return napi_set_last_error(env, napi_pending_exception);
1236 }
1237 if (result) {
1238 *result = reinterpret_cast<napi_value>(value);
1239 }
1240 return napi_clear_last_error(env);
1241 }
1242
napi_new_instance(napi_env env,napi_value constructor,size_t argc,const napi_value * argv,napi_value * result)1243 NAPI_EXTERN napi_status napi_new_instance(napi_env env,
1244 napi_value constructor,
1245 size_t argc,
1246 const napi_value* argv,
1247 napi_value* result)
1248 {
1249 NAPI_PREAMBLE(env);
1250 CHECK_ARG(env, constructor);
1251 if (argc > 0) {
1252 CHECK_ARG(env, argv);
1253 }
1254 CHECK_ARG(env, result);
1255
1256 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1257 panda::JsiFastNativeScope fastNativeScope(vm);
1258
1259 RETURN_STATUS_IF_FALSE(env, reinterpret_cast<panda::JSValueRef*>(constructor)->IsFunction(vm),
1260 napi_function_expected);
1261 panda::FunctionRef* constructorVal = reinterpret_cast<panda::FunctionRef*>(constructor);
1262 panda::JSValueRef* instance = constructorVal->ConstructorOptimize(vm,
1263 reinterpret_cast<panda::JSValueRef**>(const_cast<napi_value*>(argv)), argc);
1264 if (tryCatch.HasCaught()) {
1265 HILOG_ERROR("CreateInstance occur Exception");
1266 *result = nullptr;
1267 } else {
1268 *result = reinterpret_cast<napi_value>(instance);
1269 }
1270 return GET_RETURN_STATUS(env);
1271 }
1272
napi_instanceof(napi_env env,napi_value object,napi_value constructor,bool * result)1273 NAPI_EXTERN napi_status napi_instanceof(napi_env env, napi_value object, napi_value constructor, bool* result)
1274 {
1275 NAPI_PREAMBLE(env);
1276 CHECK_ARG(env, object);
1277 CHECK_ARG(env, constructor);
1278 CHECK_ARG(env, result);
1279
1280 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1281 panda::JsiFastNativeScope fastNativeScope(vm);
1282
1283 auto nativeValue = LocalValueFromJsValue(object);
1284 auto nativeConstructor = LocalValueFromJsValue(constructor);
1285 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
1286 RETURN_STATUS_IF_FALSE(env, nativeConstructor->IsFunction(vm), napi_function_expected);
1287 *result = nativeValue->InstanceOf(vm, nativeConstructor);
1288
1289 return GET_RETURN_STATUS(env);
1290 }
1291
1292 // Methods to work with napi_callbacks
1293 // 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)1294 NAPI_EXTERN napi_status napi_get_cb_info(napi_env env, // [in] NAPI environment handle
1295 napi_callback_info cbinfo, // [in] Opaque callback-info handle
1296 size_t* argc, // [in-out] Specifies the size of the provided argv array
1297 // and receives the actual count of args.
1298 napi_value* argv, // [out] Array of values
1299 napi_value* this_arg, // [out] Receives the JS 'this' arg for the call
1300 void** data) // [out] Receives the data pointer for the callback.
1301 {
1302 CHECK_ENV(env);
1303 CHECK_ARG(env, cbinfo);
1304
1305 auto info = reinterpret_cast<panda::JsiRuntimeCallInfo*>(cbinfo);
1306 if ((argc != nullptr) && (argv != nullptr)) {
1307 #ifdef ENABLE_CONTAINER_SCOPE
1308 auto *vm = info->GetVM();
1309 #endif
1310 size_t i = 0;
1311 if (*argc > 0) {
1312 size_t j = static_cast<size_t>(info->GetArgsNumber());
1313 for (; i < j && i < *argc; i++) {
1314 panda::Local<panda::JSValueRef> value = info->GetCallArgRef(i);
1315 #ifdef ENABLE_CONTAINER_SCOPE
1316 FunctionSetContainerId(vm, value);
1317 #endif
1318 argv[i] = JsValueFromLocalValue(value);
1319 }
1320 } else {
1321 i = static_cast<size_t>(info->GetArgsNumber());
1322 }
1323 if (i < *argc) {
1324 napi_value undefined = JsValueFromLocalValue(
1325 panda::JSValueRef::Undefined(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm()));
1326 for (; i < *argc; i++) {
1327 argv[i] = undefined;
1328 }
1329 }
1330 }
1331 if (argc != nullptr) {
1332 *argc = static_cast<size_t>(info->GetArgsNumber());
1333 }
1334 if (this_arg != nullptr) {
1335 *this_arg = JsValueFromLocalValue(info->GetThisRef());
1336 }
1337 if (data != nullptr) {
1338 auto funcInfo = static_cast<NapiFunctionInfo*>(info->GetData());
1339 if (funcInfo != nullptr) {
1340 *data = funcInfo->data;
1341 }
1342 }
1343
1344 return napi_clear_last_error(env);
1345 }
1346
napi_get_new_target(napi_env env,napi_callback_info cbinfo,napi_value * result)1347 NAPI_EXTERN napi_status napi_get_new_target(napi_env env, napi_callback_info cbinfo, napi_value* result)
1348 {
1349 NAPI_PREAMBLE(env);
1350 CHECK_ARG(env, cbinfo);
1351 CHECK_ARG(env, result);
1352
1353 auto info = reinterpret_cast<panda::JsiRuntimeCallInfo*>(cbinfo);
1354 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1355 auto thisVarObj = info->GetThisRef();
1356 #ifdef ENABLE_CONTAINER_SCOPE
1357 panda::Local<panda::JSValueRef> newValue = info->GetNewTargetRef();
1358 FunctionSetContainerId(vm, newValue);
1359 auto functionVal = newValue;
1360 #else
1361 auto functionVal = info->GetNewTargetRef();
1362 #endif
1363 if (thisVarObj->InstanceOf(vm, functionVal)) {
1364 *result = JsValueFromLocalValue(functionVal);
1365 } else {
1366 *result = nullptr;
1367 }
1368
1369 return GET_RETURN_STATUS(env);
1370 }
1371
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)1372 NAPI_EXTERN napi_status napi_define_class(napi_env env,
1373 const char* utf8name,
1374 size_t length,
1375 napi_callback constructor,
1376 void* data,
1377 size_t property_count,
1378 const napi_property_descriptor* properties,
1379 napi_value* result)
1380 {
1381 NAPI_PREAMBLE(env);
1382 CHECK_ARG(env, utf8name);
1383 RETURN_STATUS_IF_FALSE(env, length == NAPI_AUTO_LENGTH || length <= INT_MAX, napi_object_expected);
1384 CHECK_ARG(env, constructor);
1385 if (property_count > 0) {
1386 CHECK_ARG(env, properties);
1387 }
1388 CHECK_ARG(env, result);
1389
1390 auto callback = reinterpret_cast<NapiNativeCallback>(constructor);
1391 auto nativeProperties = reinterpret_cast<const NapiPropertyDescriptor*>(properties);
1392
1393 size_t nameLength = std::min(length, strlen(utf8name));
1394 char newName[nameLength + 1];
1395 if (strncpy_s(newName, nameLength + 1, utf8name, nameLength) != EOK) {
1396 HILOG_ERROR("napi_define_class strncpy_s failed");
1397 *result = nullptr;
1398 } else {
1399 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1400 panda::JsiFastNativeScope fastNativeScope(vm);
1401 EscapeLocalScope scope(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm());
1402 auto resultValue = NapiDefineClass(env, newName, callback, data, nativeProperties, property_count);
1403 *result = JsValueFromLocalValue(scope.Escape(resultValue));
1404 }
1405
1406 return GET_RETURN_STATUS(env);
1407 }
1408
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)1409 NAPI_EXTERN napi_status napi_define_sendable_class(napi_env env,
1410 const char* utf8name,
1411 size_t length,
1412 napi_callback constructor,
1413 void* data,
1414 size_t property_count,
1415 const napi_property_descriptor* properties,
1416 napi_value parent,
1417 napi_value* result)
1418 {
1419 NAPI_PREAMBLE(env);
1420 CHECK_ARG(env, utf8name);
1421 RETURN_STATUS_IF_FALSE(env, length == NAPI_AUTO_LENGTH || length <= INT_MAX,
1422 napi_object_expected);
1423 CHECK_ARG(env, constructor);
1424 if (property_count > 0) {
1425 CHECK_ARG(env, properties);
1426 }
1427 CHECK_ARG(env, result);
1428
1429 auto callback = reinterpret_cast<NapiNativeCallback>(constructor);
1430 auto nativeProperties = reinterpret_cast<const NapiPropertyDescriptor*>(properties);
1431
1432 size_t nameLength = std::min(length, strlen(utf8name));
1433 char newName[nameLength + 1];
1434 if (strncpy_s(newName, nameLength + 1, utf8name, nameLength) != EOK) {
1435 HILOG_ERROR("napi_define_sendable_class strncpy_s failed");
1436 *result = nullptr;
1437 } else {
1438 EscapeLocalScope scope(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm());
1439 auto resultValue =
1440 NapiDefineSendableClass(env, newName, callback, data, nativeProperties, property_count, parent);
1441 *result = JsValueFromLocalValue(scope.Escape(resultValue));
1442 }
1443
1444 return GET_RETURN_STATUS(env);
1445 }
1446
napi_create_sendable_object_with_properties(napi_env env,size_t property_count,const napi_property_descriptor * properties,napi_value * result)1447 NAPI_EXTERN napi_status napi_create_sendable_object_with_properties(napi_env env,
1448 size_t property_count,
1449 const napi_property_descriptor* properties,
1450 napi_value* result)
1451 {
1452 CHECK_ENV(env);
1453 CHECK_ARG(env, result);
1454
1455 auto nativeProperties = reinterpret_cast<const NapiPropertyDescriptor*>(properties);
1456 auto object = NapiCreateSObjectWithProperties(env, property_count, nativeProperties);
1457 *result = JsValueFromLocalValue(object);
1458
1459 return napi_clear_last_error(env);
1460 }
1461
napi_create_map(napi_env env,napi_value * result)1462 NAPI_EXTERN napi_status napi_create_map(napi_env env, napi_value* result)
1463 {
1464 CHECK_ENV(env);
1465 CHECK_ARG(env, result);
1466
1467 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1468 Local<panda::ArrayRef> object = panda::MapRef::New(vm);
1469 *result = JsValueFromLocalValue(object);
1470
1471 return napi_clear_last_error(env);
1472 }
1473
napi_create_sendable_map(napi_env env,napi_value * result)1474 NAPI_EXTERN napi_status napi_create_sendable_map(napi_env env, napi_value* result)
1475 {
1476 CHECK_ENV(env);
1477 CHECK_ARG(env, result);
1478
1479 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1480 Local<panda::ArrayRef> object = panda::SendableMapRef::New(vm);
1481 *result = JsValueFromLocalValue(object);
1482
1483 return napi_clear_last_error(env);
1484 }
1485
napi_map_set_property(napi_env env,napi_value map,napi_value key,napi_value value)1486 NAPI_EXTERN napi_status napi_map_set_property(napi_env env, napi_value map, napi_value key, napi_value value)
1487 {
1488 NAPI_PREAMBLE(env);
1489 CHECK_ARG(env, map);
1490 CHECK_ARG(env, key);
1491 CHECK_ARG(env, value);
1492
1493 auto nativeValue = LocalValueFromJsValue(map);
1494 auto propKey = LocalValueFromJsValue(key);
1495 auto propValue = LocalValueFromJsValue(value);
1496 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1497 panda::JsiFastNativeScope fastNativeScope(vm);
1498 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1499 if (LIKELY(nativeValue->IsMap(vm))) {
1500 Local<panda::MapRef> mapRef(nativeValue);
1501 mapRef->Set(vm, propKey, propValue);
1502 } else {
1503 Local<panda::SendableMapRef> mapRef(nativeValue);
1504 mapRef->Set(vm, propKey, propValue);
1505 }
1506
1507 return GET_RETURN_STATUS(env);
1508 }
1509
napi_map_set_named_property(napi_env env,napi_value map,const char * utf8name,napi_value value)1510 NAPI_EXTERN napi_status napi_map_set_named_property(napi_env env,
1511 napi_value map,
1512 const char* utf8name,
1513 napi_value value)
1514 {
1515 NAPI_PREAMBLE(env);
1516 CHECK_ARG(env, map);
1517 CHECK_ARG(env, utf8name);
1518 CHECK_ARG(env, value);
1519
1520 auto nativeValue = LocalValueFromJsValue(map);
1521 auto propVal = LocalValueFromJsValue(value);
1522 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1523 panda::JsiFastNativeScope fastNativeScope(vm);
1524 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1525 Local<panda::MapRef> mapRef(nativeValue);
1526 if (LIKELY(nativeValue->IsMap(vm))) {
1527 Local<panda::MapRef> mapRef(nativeValue);
1528 mapRef->Set(vm, utf8name, propVal);
1529 } else {
1530 Local<panda::SendableMapRef> mapRef(nativeValue);
1531 mapRef->Set(vm, utf8name, propVal);
1532 }
1533
1534 return GET_RETURN_STATUS(env);
1535 }
1536
napi_map_get_property(napi_env env,napi_value map,napi_value key,napi_value * result)1537 NAPI_EXTERN napi_status napi_map_get_property(napi_env env, napi_value map, napi_value key, napi_value* result)
1538 {
1539 NAPI_PREAMBLE(env);
1540 CHECK_ARG(env, map);
1541 CHECK_ARG(env, key);
1542 CHECK_ARG(env, result);
1543
1544 auto nativeValue = LocalValueFromJsValue(map);
1545 auto propKey = LocalValueFromJsValue(key);
1546 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1547 panda::JsiFastNativeScope fastNativeScope(vm);
1548 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1549 Local<JSValueRef> value;
1550 if (LIKELY(nativeValue->IsMap(vm))) {
1551 Local<panda::MapRef> mapRef(nativeValue);
1552 value = mapRef->Get(vm, propKey);
1553 } else {
1554 Local<panda::SendableMapRef> mapRef(nativeValue);
1555 value = mapRef->Get(vm, propKey);
1556 }
1557 RETURN_STATUS_IF_FALSE(env, NapiStatusValidationCheck(value), napi_object_expected);
1558 *result = JsValueFromLocalValue(value);
1559
1560 return GET_RETURN_STATUS(env);
1561 }
1562
napi_map_get_named_property(napi_env env,napi_value map,const char * utf8name,napi_value * result)1563 NAPI_EXTERN napi_status napi_map_get_named_property(napi_env env,
1564 napi_value map,
1565 const char* utf8name,
1566 napi_value* result)
1567 {
1568 NAPI_PREAMBLE(env);
1569 CHECK_ARG(env, map);
1570 CHECK_ARG(env, utf8name);
1571 CHECK_ARG(env, result);
1572
1573 auto nativeValue = LocalValueFromJsValue(map);
1574 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1575 panda::JsiFastNativeScope fastNativeScope(vm);
1576 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1577 Local<JSValueRef> value;
1578 if (LIKELY(nativeValue->IsMap(vm))) {
1579 Local<panda::MapRef> mapRef(nativeValue);
1580 value = mapRef->Get(vm, utf8name);
1581 } else {
1582 Local<panda::SendableMapRef> mapRef(nativeValue);
1583 value = mapRef->Get(vm, utf8name);
1584 }
1585 RETURN_STATUS_IF_FALSE(env, NapiStatusValidationCheck(value), napi_object_expected);
1586 *result = JsValueFromLocalValue(value);
1587
1588 return GET_RETURN_STATUS(env);
1589 }
1590
napi_map_has_property(napi_env env,napi_value map,napi_value key,bool * result)1591 NAPI_EXTERN napi_status napi_map_has_property(napi_env env, napi_value map, napi_value key, bool* result)
1592 {
1593 NAPI_PREAMBLE(env);
1594 CHECK_ARG(env, map);
1595 CHECK_ARG(env, key);
1596 CHECK_ARG(env, result);
1597
1598 auto nativeValue = LocalValueFromJsValue(map);
1599 auto propKey = LocalValueFromJsValue(key);
1600 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1601 panda::JsiFastNativeScope fastNativeScope(vm);
1602 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1603 bool value;
1604 if (LIKELY(nativeValue->IsMap(vm))) {
1605 Local<panda::MapRef> mapRef(nativeValue);
1606 value = mapRef->Has(vm, propKey);
1607 } else {
1608 Local<panda::SendableMapRef> mapRef(nativeValue);
1609 value = mapRef->Has(vm, propKey);
1610 }
1611 *result = value;
1612
1613 return GET_RETURN_STATUS(env);
1614 }
1615
napi_map_has_named_property(napi_env env,napi_value map,const char * utf8name,bool * result)1616 NAPI_EXTERN napi_status napi_map_has_named_property(napi_env env, napi_value map, const char* utf8name, bool* result)
1617 {
1618 NAPI_PREAMBLE(env);
1619 CHECK_ARG(env, map);
1620 CHECK_ARG(env, utf8name);
1621 CHECK_ARG(env, result);
1622
1623 auto nativeValue = LocalValueFromJsValue(map);
1624 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1625 panda::JsiFastNativeScope fastNativeScope(vm);
1626 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1627 bool value;
1628 if (LIKELY(nativeValue->IsMap(vm))) {
1629 Local<panda::MapRef> mapRef(nativeValue);
1630 value = mapRef->Has(vm, utf8name);
1631 } else {
1632 Local<panda::SendableMapRef> mapRef(nativeValue);
1633 value = mapRef->Has(vm, utf8name);
1634 }
1635 *result = value;
1636
1637 return GET_RETURN_STATUS(env);
1638 }
1639
napi_map_delete_property(napi_env env,napi_value map,napi_value key)1640 NAPI_EXTERN napi_status napi_map_delete_property(napi_env env, napi_value map, napi_value key)
1641 {
1642 NAPI_PREAMBLE(env);
1643 CHECK_ARG(env, map);
1644 CHECK_ARG(env, key);
1645
1646 auto nativeValue = LocalValueFromJsValue(map);
1647 auto propKey = LocalValueFromJsValue(key);
1648 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1649 panda::JsiFastNativeScope fastNativeScope(vm);
1650 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1651 if (LIKELY(nativeValue->IsMap(vm))) {
1652 Local<panda::MapRef> mapRef(nativeValue);
1653 mapRef->Delete(vm, propKey);
1654 } else {
1655 Local<panda::SendableMapRef> mapRef(nativeValue);
1656 mapRef->Delete(vm, propKey);
1657 }
1658
1659 return GET_RETURN_STATUS(env);
1660 }
1661
napi_map_clear(napi_env env,napi_value map)1662 NAPI_EXTERN napi_status napi_map_clear(napi_env env, napi_value map)
1663 {
1664 NAPI_PREAMBLE(env);
1665 CHECK_ARG(env, map);
1666
1667 auto nativeValue = LocalValueFromJsValue(map);
1668 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1669 panda::JsiFastNativeScope fastNativeScope(vm);
1670 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1671 if (LIKELY(nativeValue->IsMap(vm))) {
1672 Local<panda::MapRef> mapRef(nativeValue);
1673 mapRef->Clear(vm);
1674 } else {
1675 Local<panda::SendableMapRef> mapRef(nativeValue);
1676 mapRef->Clear(vm);
1677 }
1678
1679 return GET_RETURN_STATUS(env);
1680 }
1681
napi_map_get_size(napi_env env,napi_value map,uint32_t * result)1682 NAPI_EXTERN napi_status napi_map_get_size(napi_env env, napi_value map, uint32_t* result)
1683 {
1684 NAPI_PREAMBLE(env);
1685 CHECK_ARG(env, map);
1686 CHECK_ARG(env, result);
1687
1688 auto nativeValue = LocalValueFromJsValue(map);
1689 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1690 panda::JsiFastNativeScope fastNativeScope(vm);
1691 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1692 uint32_t value;
1693 if (LIKELY(nativeValue->IsMap(vm))) {
1694 Local<panda::MapRef> mapRef(nativeValue);
1695 value = static_cast<uint32_t>(mapRef->GetSize(vm));
1696 } else {
1697 Local<panda::SendableMapRef> mapRef(nativeValue);
1698 value = static_cast<uint32_t>(mapRef->GetSize(vm));
1699 }
1700 *result = value;
1701
1702 return GET_RETURN_STATUS(env);
1703 }
1704
napi_map_get_entries(napi_env env,napi_value map,napi_value * result)1705 NAPI_EXTERN napi_status napi_map_get_entries(napi_env env, napi_value map, napi_value* result)
1706 {
1707 NAPI_PREAMBLE(env);
1708 CHECK_ARG(env, map);
1709 CHECK_ARG(env, result);
1710
1711 auto nativeValue = LocalValueFromJsValue(map);
1712 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1713 panda::JsiFastNativeScope fastNativeScope(vm);
1714 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1715 if (LIKELY(nativeValue->IsMap(vm))) {
1716 Local<panda::MapRef> mapRef(nativeValue);
1717 Local<panda::ArrayRef> arrayVal = mapRef->GetEntries(vm);
1718 *result = JsValueFromLocalValue(arrayVal);
1719 } else {
1720 Local<panda::SendableMapRef> mapRef(nativeValue);
1721 Local<panda::SendableArrayRef> arrayVal = mapRef->GetEntries(vm);
1722 *result = JsValueFromLocalValue(arrayVal);
1723 }
1724 return GET_RETURN_STATUS(env);
1725 }
1726
napi_map_get_keys(napi_env env,napi_value map,napi_value * result)1727 NAPI_EXTERN napi_status napi_map_get_keys(napi_env env, napi_value map, napi_value* result)
1728 {
1729 NAPI_PREAMBLE(env);
1730 CHECK_ARG(env, map);
1731 CHECK_ARG(env, result);
1732
1733 auto nativeValue = LocalValueFromJsValue(map);
1734 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1735 panda::JsiFastNativeScope fastNativeScope(vm);
1736 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1737 if (LIKELY(nativeValue->IsMap(vm))) {
1738 Local<panda::MapRef> mapRef(nativeValue);
1739 Local<panda::ArrayRef> arrayVal = mapRef->GetKeys(vm);
1740 *result = JsValueFromLocalValue(arrayVal);
1741 } else {
1742 Local<panda::SendableMapRef> mapRef(nativeValue);
1743 Local<panda::SendableArrayRef> arrayVal = mapRef->GetKeys(vm);
1744 *result = JsValueFromLocalValue(arrayVal);
1745 }
1746 return GET_RETURN_STATUS(env);
1747 }
1748
napi_map_get_values(napi_env env,napi_value map,napi_value * result)1749 NAPI_EXTERN napi_status napi_map_get_values(napi_env env, napi_value map, napi_value* result)
1750 {
1751 NAPI_PREAMBLE(env);
1752 CHECK_ARG(env, map);
1753 CHECK_ARG(env, result);
1754
1755 auto nativeValue = LocalValueFromJsValue(map);
1756 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1757 panda::JsiFastNativeScope fastNativeScope(vm);
1758 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm), napi_object_expected);
1759 if (LIKELY(nativeValue->IsMap(vm))) {
1760 Local<panda::MapRef> mapRef(nativeValue);
1761 Local<panda::ArrayRef> arrayVal = mapRef->GetValues(vm);
1762 *result = JsValueFromLocalValue(arrayVal);
1763 } else {
1764 Local<panda::SendableMapRef> mapRef(nativeValue);
1765 Local<panda::SendableArrayRef> arrayVal = mapRef->GetValues(vm);
1766 *result = JsValueFromLocalValue(arrayVal);
1767 }
1768 return GET_RETURN_STATUS(env);
1769 }
1770
napi_map_iterator_get_next(napi_env env,napi_value iterator,napi_value * result)1771 NAPI_EXTERN napi_status napi_map_iterator_get_next(napi_env env, napi_value iterator, napi_value* result)
1772 {
1773 NAPI_PREAMBLE(env);
1774 CHECK_ARG(env, iterator);
1775 CHECK_ARG(env, result);
1776
1777 auto nativeValue = LocalValueFromJsValue(iterator);
1778 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1779 panda::JsiFastNativeScope fastNativeScope(vm);
1780 RETURN_STATUS_IF_FALSE(env, nativeValue->IsMapIterator(vm) || nativeValue->IsSharedMapIterator(vm),
1781 napi_object_expected);
1782 Local<panda::JSValueRef> value;
1783 if (LIKELY(nativeValue->IsMapIterator(vm))) {
1784 Local<panda::MapIteratorRef> mapIter(nativeValue);
1785 value = mapIter->Next(vm);
1786 } else {
1787 Local<panda::SendableMapIteratorRef> mapIter(nativeValue);
1788 value = mapIter->Next(vm);
1789 }
1790 *result = JsValueFromLocalValue(value);
1791 return GET_RETURN_STATUS(env);
1792 }
1793
1794 // 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)1795 NAPI_EXTERN napi_status napi_wrap(napi_env env,
1796 napi_value js_object,
1797 void* native_object,
1798 napi_finalize finalize_cb,
1799 void* finalize_hint,
1800 napi_ref* result)
1801 {
1802 NAPI_PREAMBLE(env);
1803 CHECK_ARG(env, js_object);
1804 CHECK_ARG(env, native_object);
1805 CHECK_ARG(env, finalize_cb);
1806
1807 auto nativeValue = LocalValueFromJsValue(js_object);
1808 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
1809 auto engine = reinterpret_cast<NativeEngine*>(env);
1810 auto vm = engine->GetEcmaVm();
1811 panda::JsiFastNativeScope fastNativeScope(vm);
1812 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
1813 size_t nativeBindingSize = 0;
1814 auto reference = reinterpret_cast<NativeReference**>(result);
1815 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1816 if (native_object == nullptr && nativeObject->Has(vm, key)) {
1817 Local<panda::ObjectRef> wrapper = nativeObject->Get(vm, key);
1818 auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(vm, 0));
1819 // Try to remove native pointer from ArrayDataList
1820 wrapper->SetNativePointerField(vm, 0, nullptr, nullptr, nullptr, nativeBindingSize);
1821 nativeObject->Delete(vm, key);
1822 delete ref;
1823 } else {
1824 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
1825 NativeReference* ref = nullptr;
1826 if (reference != nullptr) {
1827 ref = engine->CreateReference(js_object, 1, false, callback, native_object, finalize_hint);
1828 *reference = ref;
1829 } else {
1830 ref = engine->CreateReference(js_object, 0, true, callback, native_object, finalize_hint);
1831 }
1832 object->SetNativePointerFieldCount(vm, 1);
1833 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, nativeBindingSize);
1834 PropertyAttribute attr(object, true, false, true);
1835 nativeObject->DefineProperty(vm, key, attr);
1836 }
1837 return GET_RETURN_STATUS(env);
1838 }
1839
1840 // 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)1841 NAPI_EXTERN napi_status napi_wrap_async_finalizer(napi_env env,
1842 napi_value js_object,
1843 void* native_object,
1844 napi_finalize finalize_cb,
1845 void* finalize_hint,
1846 napi_ref* result,
1847 size_t native_binding_size)
1848 {
1849 NAPI_PREAMBLE(env);
1850 CHECK_ARG(env, js_object);
1851 CHECK_ARG(env, native_object);
1852
1853 auto nativeValue = LocalValueFromJsValue(js_object);
1854 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
1855 auto engine = reinterpret_cast<NativeEngine*>(env);
1856 auto vm = engine->GetEcmaVm();
1857 panda::JsiFastNativeScope fastNativeScope(vm);
1858 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
1859 auto reference = reinterpret_cast<NativeReference**>(result);
1860 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1861 if (native_object == nullptr && nativeObject->Has(vm, key)) {
1862 Local<panda::ObjectRef> wrapper = nativeObject->Get(vm, key);
1863 auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(vm, 0));
1864 // Try to remove native pointer from ArrayDataList
1865 wrapper->SetNativePointerField(vm, 0, nullptr, nullptr, nullptr, native_binding_size);
1866 nativeObject->Delete(vm, key);
1867 delete ref;
1868 } else {
1869 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
1870 NativeReference* ref = nullptr;
1871 if (reference != nullptr) {
1872 ref = engine->CreateAsyncReference(js_object, 1, false, callback, native_object, finalize_hint);
1873 *reference = ref;
1874 } else {
1875 ref = engine->CreateAsyncReference(js_object, 0, true, callback, native_object, finalize_hint);
1876 }
1877 object->SetNativePointerFieldCount(vm, 1);
1878 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, native_binding_size);
1879 PropertyAttribute attr(object, true, false, true);
1880 nativeObject->DefineProperty(vm, key, attr);
1881 }
1882 return GET_RETURN_STATUS(env);
1883 }
1884
1885 // 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)1886 NAPI_EXTERN napi_status napi_wrap_with_size(napi_env env,
1887 napi_value js_object,
1888 void* native_object,
1889 napi_finalize finalize_cb,
1890 void* finalize_hint,
1891 napi_ref* result,
1892 size_t native_binding_size)
1893 {
1894 NAPI_PREAMBLE(env);
1895 CHECK_ARG(env, js_object);
1896 CHECK_ARG(env, native_object);
1897
1898 auto nativeValue = LocalValueFromJsValue(js_object);
1899 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
1900 auto engine = reinterpret_cast<NativeEngine*>(env);
1901 auto vm = engine->GetEcmaVm();
1902 panda::JsiFastNativeScope fastNativeScope(vm);
1903 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
1904 auto reference = reinterpret_cast<NativeReference**>(result);
1905 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1906 if (native_object == nullptr && nativeObject->Has(vm, key)) {
1907 Local<panda::ObjectRef> wrapper = nativeObject->Get(vm, key);
1908 auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(vm, 0));
1909 // Try to remove native pointer from ArrayDataList
1910 wrapper->SetNativePointerField(vm, 0, nullptr, nullptr, nullptr, native_binding_size);
1911 nativeObject->Delete(vm, key);
1912 delete ref;
1913 } else {
1914 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
1915 NativeReference* ref = nullptr;
1916 if (reference != nullptr) {
1917 ref = engine->CreateReference(js_object, 1, false, callback, native_object, finalize_hint,
1918 native_binding_size);
1919 *reference = ref;
1920 } else {
1921 ref = engine->CreateReference(js_object, 0, true, callback, native_object, finalize_hint,
1922 native_binding_size);
1923 }
1924 object->SetNativePointerFieldCount(vm, 1);
1925 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, native_binding_size);
1926 PropertyAttribute attr(object, true, false, true);
1927 nativeObject->DefineProperty(vm, key, attr);
1928 }
1929
1930 return GET_RETURN_STATUS(env);
1931 }
1932
napi_unwrap(napi_env env,napi_value js_object,void ** result)1933 NAPI_EXTERN napi_status napi_unwrap(napi_env env, napi_value js_object, void** result)
1934 {
1935 NAPI_PREAMBLE(env);
1936 CHECK_ARG(env, js_object);
1937 CHECK_ARG(env, result);
1938
1939 auto nativeValue = LocalValueFromJsValue(js_object);
1940 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
1941 panda::JsiFastNativeScope fastNativeScope(vm);
1942 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
1943 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1944 Local<panda::JSValueRef> val = nativeObject->Get(vm, key);
1945 *result = nullptr;
1946 if (val->IsObject(vm)) {
1947 Local<panda::ObjectRef> ext(val);
1948 auto ref = reinterpret_cast<NativeReference*>(ext->GetNativePointerField(vm, 0));
1949 *result = ref != nullptr ? ref->GetData() : nullptr;
1950 }
1951
1952 return GET_RETURN_STATUS(env);
1953 }
1954
napi_remove_wrap(napi_env env,napi_value js_object,void ** result)1955 NAPI_EXTERN napi_status napi_remove_wrap(napi_env env, napi_value js_object, void** result)
1956 {
1957 NAPI_PREAMBLE(env);
1958 CHECK_ARG(env, js_object);
1959 CHECK_ARG(env, result);
1960
1961 auto nativeValue = LocalValueFromJsValue(js_object);
1962 auto engine = reinterpret_cast<NativeEngine*>(env);
1963 auto vm = engine->GetEcmaVm();
1964 panda::JsiFastNativeScope fastNativeScope(vm);
1965 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, nativeObject);
1966 Local<panda::StringRef> key = panda::StringRef::GetNapiWrapperString(vm);
1967 Local<panda::JSValueRef> val = nativeObject->Get(vm, key);
1968 *result = nullptr;
1969 if (val->IsObject(vm)) {
1970 Local<panda::ObjectRef> ext(val);
1971 auto ref = reinterpret_cast<NativeReference*>(ext->GetNativePointerField(vm, 0));
1972 *result = ref != nullptr ? ref->GetData() : nullptr;
1973 }
1974
1975 size_t nativeBindingSize = 0;
1976 if (nativeObject->Has(vm, key)) {
1977 Local<panda::ObjectRef> wrapper = val;
1978 auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(vm, 0));
1979 nativeObject->Delete(vm, key);
1980 delete ref;
1981 } else {
1982 Local<panda::ObjectRef> object = panda::ObjectRef::New(vm);
1983 NativeReference* ref = nullptr;
1984 ref = engine->CreateReference(js_object, 0, true, nullptr, nullptr, nullptr);
1985 object->SetNativePointerFieldCount(vm, 1);
1986 object->SetNativePointerField(vm, 0, ref, nullptr, nullptr, nativeBindingSize);
1987 PropertyAttribute attr(object, true, false, true);
1988 nativeObject->DefineProperty(vm, key, attr);
1989 }
1990
1991 return GET_RETURN_STATUS(env);
1992 }
1993
napi_wrap_sendable(napi_env env,napi_value js_object,void * native_object,napi_finalize finalize_cb,void * finalize_hint)1994 NAPI_EXTERN napi_status napi_wrap_sendable(napi_env env,
1995 napi_value js_object,
1996 void* native_object,
1997 napi_finalize finalize_cb,
1998 void* finalize_hint)
1999 {
2000 NAPI_PREAMBLE(env);
2001 CHECK_ARG(env, js_object);
2002 CHECK_ARG(env, native_object);
2003
2004 auto nativeValue = LocalValueFromJsValue(js_object);
2005 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2006 auto engine = reinterpret_cast<NativeEngine*>(env);
2007 auto vm = engine->GetEcmaVm();
2008 panda::JsiFastNativeScope fastNativeScope(vm);
2009 RETURN_STATUS_IF_FALSE(env, nativeValue->IsSendableObject(vm), napi_object_expected);
2010 Local<ObjectRef> nativeObject(nativeValue);
2011 nativeObject->SetNativePointerFieldCount(vm, 1);
2012 nativeObject->SetNativePointerField(vm, 0, native_object, callback, finalize_hint);
2013 return GET_RETURN_STATUS(env);
2014 }
2015
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)2016 NAPI_EXTERN napi_status napi_wrap_sendable_with_size(napi_env env,
2017 napi_value js_object,
2018 void* native_object,
2019 napi_finalize finalize_cb,
2020 void* finalize_hint,
2021 size_t native_binding_size)
2022 {
2023 NAPI_PREAMBLE(env);
2024 CHECK_ARG(env, js_object);
2025 CHECK_ARG(env, native_object);
2026
2027 auto nativeValue = LocalValueFromJsValue(js_object);
2028 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2029 auto engine = reinterpret_cast<NativeEngine*>(env);
2030 auto vm = engine->GetEcmaVm();
2031 panda::JsiFastNativeScope fastNativeScope(vm);
2032 RETURN_STATUS_IF_FALSE(env, nativeValue->IsSendableObject(vm), napi_object_expected);
2033 Local<ObjectRef> nativeObject(nativeValue);
2034 nativeObject->SetNativePointerFieldCount(vm, 1);
2035 nativeObject->SetNativePointerField(vm, 0, native_object, callback, finalize_hint, native_binding_size);
2036 return GET_RETURN_STATUS(env);
2037 }
2038
napi_unwrap_sendable(napi_env env,napi_value js_object,void ** result)2039 NAPI_EXTERN napi_status napi_unwrap_sendable(napi_env env, napi_value js_object, void** result)
2040 {
2041 NAPI_PREAMBLE(env);
2042 CHECK_ARG(env, js_object);
2043 CHECK_ARG(env, result);
2044
2045 auto nativeValue = LocalValueFromJsValue(js_object);
2046 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2047 panda::JsiFastNativeScope fastNativeScope(vm);
2048 RETURN_STATUS_IF_FALSE(env, nativeValue->IsSendableObject(vm), napi_object_expected);
2049 Local<ObjectRef> nativeObject(nativeValue);
2050 void* val = nativeObject->GetNativePointerField(vm, 0);
2051 *result = val;
2052 return GET_RETURN_STATUS(env);
2053 }
2054
napi_remove_wrap_sendable(napi_env env,napi_value js_object,void ** result)2055 NAPI_EXTERN napi_status napi_remove_wrap_sendable(napi_env env, napi_value js_object, void** result)
2056 {
2057 NAPI_PREAMBLE(env);
2058 CHECK_ARG(env, js_object);
2059 CHECK_ARG(env, result);
2060
2061 auto nativeValue = LocalValueFromJsValue(js_object);
2062 auto engine = reinterpret_cast<NativeEngine*>(env);
2063 auto vm = engine->GetEcmaVm();
2064 panda::JsiFastNativeScope fastNativeScope(vm);
2065 RETURN_STATUS_IF_FALSE(env, nativeValue->IsSendableObject(vm), napi_object_expected);
2066 Local<ObjectRef> nativeObject(nativeValue);
2067 void* val = nativeObject->GetNativePointerField(vm, 0);
2068 *result = val;
2069 nativeObject->SetNativePointerField(vm, 0, nullptr, nullptr, nullptr);
2070
2071 return GET_RETURN_STATUS(env);
2072 }
2073
napi_create_external(napi_env env,void * data,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)2074 NAPI_EXTERN napi_status napi_create_external(
2075 napi_env env, void* data, napi_finalize finalize_cb, void* finalize_hint, napi_value* result)
2076 {
2077 NAPI_PREAMBLE(env);
2078 CHECK_ARG(env, result);
2079
2080 auto engine = reinterpret_cast<NativeEngine*>(env);
2081 auto vm = engine->GetEcmaVm();
2082 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2083 Local<panda::NativePointerRef> object = panda::NativePointerRef::New(vm, data, callback, finalize_hint, 0);
2084
2085 *result = JsValueFromLocalValue(object);
2086 return napi_clear_last_error(env);
2087 }
2088
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)2089 NAPI_EXTERN napi_status napi_create_external_with_size(napi_env env,
2090 void* data,
2091 napi_finalize finalize_cb,
2092 void* finalize_hint,
2093 napi_value* result,
2094 size_t native_binding_size)
2095 {
2096 CHECK_ENV(env);
2097 CHECK_ARG(env, result);
2098
2099 auto engine = reinterpret_cast<NativeEngine*>(env);
2100 auto vm = engine->GetEcmaVm();
2101 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2102 Local<panda::NativePointerRef> object =
2103 panda::NativePointerRef::New(vm, data, callback, finalize_hint, native_binding_size);
2104
2105 *result = JsValueFromLocalValue(object);
2106 return napi_clear_last_error(env);
2107 }
2108
napi_get_value_external(napi_env env,napi_value value,void ** result)2109 NAPI_EXTERN napi_status napi_get_value_external(napi_env env, napi_value value, void** result)
2110 {
2111 CHECK_ENV(env);
2112 CHECK_ARG(env, value);
2113 CHECK_ARG(env, result);
2114
2115 auto nativeValue = LocalValueFromJsValue(value);
2116 bool isNativePointer = false;
2117 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2118 void* ret = nativeValue->GetNativePointerValue(vm, isNativePointer);
2119 RETURN_STATUS_IF_FALSE(env, isNativePointer, napi_object_expected);
2120 *result = ret;
2121 return napi_clear_last_error(env);
2122 }
2123
2124 // Methods to control object lifespan
2125 // 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)2126 NAPI_EXTERN napi_status napi_create_reference(napi_env env,
2127 napi_value value,
2128 uint32_t initial_refcount,
2129 napi_ref* result)
2130 {
2131 CHECK_ENV(env);
2132 CHECK_ARG(env, value);
2133 CHECK_ARG(env, result);
2134 auto engine = reinterpret_cast<ArkNativeEngine*>(env);
2135 auto ref = new ArkNativeReference(engine, value, initial_refcount);
2136
2137 *result = reinterpret_cast<napi_ref>(ref);
2138 return napi_clear_last_error(env);
2139 }
2140
2141 // Deletes a reference. The referenced value is released, and may
2142 // be GC'd unless there are other references to it.
napi_delete_reference(napi_env env,napi_ref ref)2143 NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref)
2144 {
2145 CHECK_ENV(env);
2146 CHECK_ARG(env, ref);
2147
2148 auto reference = reinterpret_cast<NativeReference*>(ref);
2149 uint32_t refCount = reference->GetRefCount();
2150 if (refCount > 0 || reference->GetFinalRun()) {
2151 delete reference;
2152 reference = nullptr;
2153 } else {
2154 reference->SetDeleteSelf();
2155 }
2156
2157 return napi_clear_last_error(env);
2158 }
2159
2160 // Increments the reference count, optionally returning the resulting count.
2161 // After this call the reference will be a strong reference because its
2162 // refcount is >0, and the referenced object is effectively "pinned".
2163 // Calling this when the refcount is 0 and the object is unavailable
2164 // results in an error.
napi_reference_ref(napi_env env,napi_ref ref,uint32_t * result)2165 NAPI_EXTERN napi_status napi_reference_ref(napi_env env, napi_ref ref, uint32_t* result)
2166 {
2167 CHECK_ENV(env);
2168 CHECK_ARG(env, ref);
2169
2170 auto reference = reinterpret_cast<NativeReference*>(ref);
2171 uint32_t refCount = reference->Ref();
2172
2173 if (result) {
2174 *result = refCount;
2175 }
2176
2177 return napi_clear_last_error(env);
2178 }
2179
2180 // Decrements the reference count, optionally returning the resulting count.
2181 // If the result is 0 the reference is now weak and the object may be GC'd
2182 // at any time if there are no other references. Calling this when the
2183 // refcount is already 0 results in an error.
napi_reference_unref(napi_env env,napi_ref ref,uint32_t * result)2184 NAPI_EXTERN napi_status napi_reference_unref(napi_env env, napi_ref ref, uint32_t* result)
2185 {
2186 CHECK_ENV(env);
2187 CHECK_ARG(env, ref);
2188
2189 auto reference = reinterpret_cast<NativeReference*>(ref);
2190 uint32_t unrefCount = reference->Unref();
2191
2192 if (result) {
2193 *result = unrefCount;
2194 }
2195
2196 return napi_clear_last_error(env);
2197 }
2198
2199 // Attempts to get a referenced value. If the reference is weak,
2200 // the value might no longer be available, in that case the call
2201 // is still successful but the result is nullptr.
napi_get_reference_value(napi_env env,napi_ref ref,napi_value * result)2202 NAPI_EXTERN napi_status napi_get_reference_value(napi_env env, napi_ref ref, napi_value* result)
2203 {
2204 CHECK_ENV(env);
2205 CHECK_ARG(env, ref);
2206 CHECK_ARG(env, result);
2207
2208 auto reference = reinterpret_cast<NativeReference*>(ref);
2209 NativeEngine* engine = reinterpret_cast<NativeEngine*>(env);
2210
2211 *result = reference->Get(engine);
2212 return napi_clear_last_error(env);
2213 }
2214
napi_open_handle_scope(napi_env env,napi_handle_scope * result)2215 NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env, napi_handle_scope* result)
2216 {
2217 CHECK_ENV(env);
2218 CHECK_ARG(env, result);
2219
2220 auto engine = reinterpret_cast<NativeEngine*>(env);
2221 *result = HandleScopeToNapiHandleScope(new HandleScopeWrapper(engine));
2222 engine->openHandleScopes_++;
2223 return napi_clear_last_error(env);
2224 }
2225
napi_close_handle_scope(napi_env env,napi_handle_scope scope)2226 NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env, napi_handle_scope scope)
2227 {
2228 CHECK_ENV(env);
2229 CHECK_ARG(env, scope);
2230
2231 auto engine = reinterpret_cast<NativeEngine*>(env);
2232 if (engine->openHandleScopes_ == 0) {
2233 return napi_handle_scope_mismatch;
2234 }
2235
2236 engine->openHandleScopes_--;
2237 delete NapiHandleScopeToHandleScope(scope);
2238 return napi_clear_last_error(env);
2239 }
2240
napi_open_escapable_handle_scope(napi_env env,napi_escapable_handle_scope * result)2241 NAPI_EXTERN napi_status napi_open_escapable_handle_scope(napi_env env, napi_escapable_handle_scope* result)
2242 {
2243 CHECK_ENV(env);
2244 CHECK_ARG(env, result);
2245
2246 auto engine = reinterpret_cast<NativeEngine*>(env);
2247 *result = EscapableHandleScopeToNapiEscapableHandleScope(new EscapableHandleScopeWrapper(engine));
2248 engine->openHandleScopes_++;
2249 return napi_clear_last_error(env);
2250 }
2251
napi_close_escapable_handle_scope(napi_env env,napi_escapable_handle_scope scope)2252 NAPI_EXTERN napi_status napi_close_escapable_handle_scope(napi_env env, napi_escapable_handle_scope scope)
2253 {
2254 CHECK_ENV(env);
2255 CHECK_ARG(env, scope);
2256
2257 auto engine = reinterpret_cast<NativeEngine*>(env);
2258 if (engine->openHandleScopes_ == 0) {
2259 return napi_handle_scope_mismatch;
2260 }
2261
2262 engine->openHandleScopes_--;
2263 delete NapiEscapableHandleScopeToEscapableHandleScope(scope);
2264 return napi_clear_last_error(env);
2265 }
2266
napi_escape_handle(napi_env env,napi_escapable_handle_scope scope,napi_value escapee,napi_value * result)2267 NAPI_EXTERN napi_status napi_escape_handle(napi_env env,
2268 napi_escapable_handle_scope scope,
2269 napi_value escapee,
2270 napi_value* result)
2271 {
2272 CHECK_ENV(env);
2273 CHECK_ARG(env, scope);
2274 CHECK_ARG(env, escapee);
2275 CHECK_ARG(env, result);
2276
2277 auto s = NapiEscapableHandleScopeToEscapableHandleScope(scope);
2278 if (!s->IsEscapeCalled()) {
2279 *result = JsValueFromLocalValue(s->Escape(LocalValueFromJsValue(escapee)));
2280 return napi_clear_last_error(env);
2281 }
2282 return napi_set_last_error(env, napi_escape_called_twice);
2283 }
2284
2285 // Methods to support error handling
napi_throw(napi_env env,napi_value error)2286 NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error)
2287 {
2288 CHECK_ENV(env);
2289 CHECK_ARG(env, error);
2290
2291 auto nativeValue = LocalValueFromJsValue(error);
2292 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2293 panda::JsiFastNativeScope fastNativeScope(vm);
2294
2295 RETURN_STATUS_IF_FALSE(env, nativeValue->IsError(vm), napi_invalid_arg);
2296 panda::JSNApi::ThrowException(vm, nativeValue);
2297 return napi_clear_last_error(env);
2298 }
2299
napi_throw_error(napi_env env,const char * code,const char * msg)2300 NAPI_EXTERN napi_status napi_throw_error(napi_env env, const char* code, const char* msg)
2301 {
2302 CHECK_ENV(env);
2303 CHECK_ARG(env, msg);
2304
2305 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2306 panda::JsiFastNativeScope fastNativeScope(vm);
2307 Local<panda::JSValueRef> error(panda::JSValueRef::Undefined(vm));
2308 error = panda::Exception::Error(vm, StringRef::NewFromUtf8(vm, msg));
2309 if (code != nullptr) {
2310 Local<panda::JSValueRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
2311 Local<panda::JSValueRef> codeValue = panda::StringRef::NewFromUtf8(vm, code);
2312 Local<panda::ObjectRef> errorObj(error);
2313 errorObj->Set(vm, codeKey, codeValue);
2314 }
2315 panda::JSNApi::ThrowException(vm, error);
2316 return napi_clear_last_error(env);
2317 }
2318
napi_throw_type_error(napi_env env,const char * code,const char * msg)2319 NAPI_EXTERN napi_status napi_throw_type_error(napi_env env, const char* code, const char* msg)
2320 {
2321 CHECK_ENV(env);
2322 CHECK_ARG(env, msg);
2323
2324 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2325 panda::JsiFastNativeScope fastNativeScope(vm);
2326 Local<panda::JSValueRef> error(panda::JSValueRef::Undefined(vm));
2327 error = panda::Exception::TypeError(vm, StringRef::NewFromUtf8(vm, msg));
2328 if (code != nullptr) {
2329 Local<panda::JSValueRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
2330 Local<panda::JSValueRef> codeValue = panda::StringRef::NewFromUtf8(vm, code);
2331 Local<panda::ObjectRef> errorObj(error);
2332 errorObj->Set(vm, codeKey, codeValue);
2333 }
2334 panda::JSNApi::ThrowException(vm, error);
2335 return napi_clear_last_error(env);
2336 }
2337
napi_throw_range_error(napi_env env,const char * code,const char * msg)2338 NAPI_EXTERN napi_status napi_throw_range_error(napi_env env, const char* code, const char* msg)
2339 {
2340 CHECK_ENV(env);
2341 CHECK_ARG(env, msg);
2342
2343 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2344 panda::JsiFastNativeScope fastNativeScope(vm);
2345 Local<panda::JSValueRef> error(panda::JSValueRef::Undefined(vm));
2346 error = panda::Exception::RangeError(vm, StringRef::NewFromUtf8(vm, msg));
2347 if (code != nullptr) {
2348 Local<panda::JSValueRef> codeKey = panda::StringRef::NewFromUtf8(vm, "code");
2349 Local<panda::JSValueRef> codeValue = panda::StringRef::NewFromUtf8(vm, code);
2350 Local<panda::ObjectRef> errorObj(error);
2351 errorObj->Set(vm, codeKey, codeValue);
2352 }
2353 panda::JSNApi::ThrowException(vm, error);
2354 return napi_clear_last_error(env);
2355 }
2356
napi_is_error(napi_env env,napi_value value,bool * result)2357 NAPI_EXTERN napi_status napi_is_error(napi_env env, napi_value value, bool* result)
2358 {
2359 CHECK_ENV(env);
2360 CHECK_ARG(env, value);
2361 CHECK_ARG(env, result);
2362
2363 auto nativeValue = LocalValueFromJsValue(value);
2364 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2365 panda::JsiFastNativeScope fastNativeScope(vm);
2366 *result = nativeValue->IsError(vm);
2367
2368 return napi_clear_last_error(env);
2369 }
2370
2371 // Methods to support catching exceptions
napi_is_exception_pending(napi_env env,bool * result)2372 NAPI_EXTERN napi_status napi_is_exception_pending(napi_env env, bool* result)
2373 {
2374 CHECK_ENV(env);
2375 CHECK_ARG(env, result);
2376
2377 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2378 *result = panda::JSNApi::HasPendingException(vm);
2379 return napi_clear_last_error(env);
2380 }
2381
napi_get_and_clear_last_exception(napi_env env,napi_value * result)2382 NAPI_EXTERN napi_status napi_get_and_clear_last_exception(napi_env env, napi_value* result)
2383 {
2384 CHECK_ENV(env);
2385 CHECK_ARG(env, result);
2386
2387 auto engine = reinterpret_cast<NativeEngine*>(env);
2388 auto vm = engine->GetEcmaVm();
2389 engine->lastException_.Empty();
2390 Local<panda::ObjectRef> exception = panda::JSNApi::GetAndClearUncaughtException(vm);
2391 if (!exception.IsNull()) {
2392 *result = JsValueFromLocalValue(exception);
2393 }
2394
2395 return napi_clear_last_error(env);
2396 }
2397
2398 // Methods to work with array buffers and typed arrays
napi_is_arraybuffer(napi_env env,napi_value value,bool * result)2399 NAPI_EXTERN napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result)
2400 {
2401 CHECK_ENV(env);
2402 CHECK_ARG(env, value);
2403 CHECK_ARG(env, result);
2404
2405 auto nativeValue = LocalValueFromJsValue(value);
2406 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2407 panda::JsiFastNativeScope fastNativeScope(vm);
2408
2409 *result = nativeValue->IsArrayBuffer(vm) || nativeValue->IsSendableArrayBuffer(vm);
2410
2411 return napi_clear_last_error(env);
2412 }
2413
napi_create_arraybuffer(napi_env env,size_t byte_length,void ** data,napi_value * result)2414 NAPI_EXTERN napi_status napi_create_arraybuffer(napi_env env, size_t byte_length, void** data, napi_value* result)
2415 {
2416 NAPI_PREAMBLE(env);
2417 CHECK_ARG(env, data);
2418 CHECK_ARG(env, result);
2419
2420 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2421 uint8_t** values = (uint8_t**)(data);
2422 Local<panda::ArrayBufferRef> res = panda::ArrayBufferRef::New(vm, byte_length);
2423 if (values != nullptr) {
2424 *values = reinterpret_cast<uint8_t*>(res->GetBuffer(vm));
2425 }
2426 *result = JsValueFromLocalValue(res);
2427
2428 return GET_RETURN_STATUS(env);
2429 }
2430
napi_create_sendable_arraybuffer(napi_env env,size_t byte_length,void ** data,napi_value * result)2431 NAPI_EXTERN napi_status napi_create_sendable_arraybuffer(napi_env env, size_t byte_length,
2432 void** data, napi_value* result)
2433 {
2434 NAPI_PREAMBLE(env);
2435 CHECK_ARG(env, data);
2436 CHECK_ARG(env, result);
2437
2438 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2439 uint8_t** values = (uint8_t**)(data);
2440 Local<panda::SendableArrayBufferRef> res = panda::SendableArrayBufferRef::New(vm, byte_length);
2441 if (values != nullptr) {
2442 *values = reinterpret_cast<uint8_t*>(res->GetBuffer(vm));
2443 }
2444 *result = JsValueFromLocalValue(res);
2445
2446 return GET_RETURN_STATUS(env);
2447 }
2448
napi_create_external_arraybuffer(napi_env env,void * external_data,size_t byte_length,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)2449 NAPI_EXTERN napi_status napi_create_external_arraybuffer(napi_env env,
2450 void* external_data,
2451 size_t byte_length,
2452 napi_finalize finalize_cb,
2453 void* finalize_hint,
2454 napi_value* result)
2455 {
2456 NAPI_PREAMBLE(env);
2457 CHECK_ARG(env, external_data);
2458 CHECK_ARG(env, finalize_cb);
2459 CHECK_ARG(env, result);
2460
2461 auto engine = reinterpret_cast<NativeEngine*>(env);
2462 auto vm = engine->GetEcmaVm();
2463 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2464 Local<panda::ArrayBufferRef> object =
2465 panda::ArrayBufferRef::New(vm, external_data, byte_length, callback, finalize_hint);
2466 *result = JsValueFromLocalValue(object);
2467 return GET_RETURN_STATUS(env);
2468 }
2469
napi_get_arraybuffer_info(napi_env env,napi_value arraybuffer,void ** data,size_t * byte_length)2470 NAPI_EXTERN napi_status napi_get_arraybuffer_info(napi_env env,
2471 napi_value arraybuffer,
2472 void** data,
2473 size_t* byte_length)
2474 {
2475 CHECK_ENV(env);
2476 CHECK_ARG(env, arraybuffer);
2477 CHECK_ARG(env, byte_length);
2478
2479 auto nativeValue = LocalValueFromJsValue(arraybuffer);
2480 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2481 panda::JsiFastNativeScope fastNativeScope(vm);
2482 if (LIKELY(nativeValue->IsArrayBuffer(vm))) {
2483 Local<panda::ArrayBufferRef> res(nativeValue);
2484 if (data != nullptr) {
2485 *data = res->GetBuffer(vm);
2486 }
2487 *byte_length = res->ByteLength(vm);
2488 } else if (nativeValue->IsSendableArrayBuffer(vm)) {
2489 Local<panda::SendableArrayBufferRef> res(nativeValue);
2490 if (data != nullptr) {
2491 *data = res->GetBuffer(vm);
2492 }
2493 *byte_length = res->ByteLength(vm);
2494 } else {
2495 return napi_set_last_error(env, napi_arraybuffer_expected);
2496 }
2497
2498 return napi_clear_last_error(env);
2499 }
2500
napi_is_typedarray(napi_env env,napi_value value,bool * result)2501 NAPI_EXTERN napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result)
2502 {
2503 CHECK_ENV(env);
2504 CHECK_ARG(env, value);
2505 CHECK_ARG(env, result);
2506
2507 auto nativeValue = LocalValueFromJsValue(value);
2508 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2509 panda::JsiFastNativeScope fastNativeScope(vm);
2510
2511 *result = nativeValue->IsTypedArray(vm) || nativeValue->IsSharedTypedArray(vm);
2512
2513 return napi_clear_last_error(env);
2514 }
2515
2516 EXTERN_C_START
napi_is_buffer(napi_env env,napi_value value,bool * result)2517 NAPI_EXTERN napi_status napi_is_buffer(napi_env env, napi_value value, bool* result)
2518 {
2519 CHECK_ENV(env);
2520 CHECK_ARG(env, value);
2521 CHECK_ARG(env, result);
2522
2523 auto nativeValue = LocalValueFromJsValue(value);
2524 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2525 panda::JsiFastNativeScope fastNativeScope(vm);
2526
2527 *result = nativeValue->IsBuffer(vm);
2528
2529 return napi_clear_last_error(env);
2530 }
2531
napi_create_buffer(napi_env env,size_t size,void ** data,napi_value * result)2532 NAPI_EXTERN napi_status napi_create_buffer(napi_env env, size_t size, void** data, napi_value* result)
2533 {
2534 CHECK_ENV(env);
2535 CHECK_ARG(env, data);
2536 CHECK_ARG(env, result);
2537 RETURN_STATUS_IF_FALSE(env, size > 0, napi_invalid_arg);
2538
2539 uint8_t** value = reinterpret_cast<uint8_t**>(data);
2540 if (!value) {
2541 HILOG_ERROR("value is empty");
2542 return napi_set_last_error(env, napi_invalid_arg);
2543 }
2544
2545 if (size > MAX_BYTE_LENGTH) {
2546 HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
2547 static_cast<float>(size) / static_cast<float>(ONEMIB_BYTE_SIZE),
2548 static_cast<float>(MAX_BYTE_LENGTH) / static_cast<float>(ONEMIB_BYTE_SIZE));
2549 *value = nullptr;
2550 return napi_set_last_error(env, napi_invalid_arg);
2551 }
2552 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2553 Local<panda::BufferRef> obj = BufferRef::New(vm, size);
2554 *value = reinterpret_cast<uint8_t*>(obj->GetBuffer(vm));
2555
2556 CHECK_ARG(env, *data);
2557 void* ptr = obj->GetBuffer(vm);
2558 CHECK_ARG(env, ptr);
2559
2560 *result = JsValueFromLocalValue(obj);
2561 return napi_clear_last_error(env);
2562 }
2563
napi_create_buffer_copy(napi_env env,size_t length,const void * data,void ** result_data,napi_value * result)2564 NAPI_EXTERN napi_status napi_create_buffer_copy(napi_env env,
2565 size_t length,
2566 const void* data,
2567 void** result_data,
2568 napi_value* result)
2569 {
2570 CHECK_ENV(env);
2571 CHECK_ARG(env, data);
2572 CHECK_ARG(env, result_data);
2573 CHECK_ARG(env, result);
2574 RETURN_STATUS_IF_FALSE(env, length > 0, napi_invalid_arg);
2575
2576 uint8_t** value = reinterpret_cast<uint8_t**>(result_data);
2577 const uint8_t* recvdata = (uint8_t*)data;
2578 if (!value) {
2579 HILOG_ERROR("value is empty");
2580 return napi_set_last_error(env, napi_invalid_arg);
2581 }
2582 if (length > MAX_BYTE_LENGTH) {
2583 HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
2584 static_cast<float>(length) / static_cast<float>(ONEMIB_BYTE_SIZE),
2585 static_cast<float>(MAX_BYTE_LENGTH) / static_cast<float>(ONEMIB_BYTE_SIZE));
2586 *value = nullptr;
2587 return napi_set_last_error(env, napi_invalid_arg);
2588 }
2589 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2590 Local<panda::BufferRef> obj = BufferRef::New(vm, length);
2591 if (obj->IsUndefined()) {
2592 HILOG_INFO("engine create buffer_copy failed!");
2593 }
2594 *value = reinterpret_cast<uint8_t*>(obj->GetBuffer(vm));
2595 if (memcpy_s(*value, length, recvdata, length) != EOK) {
2596 HILOG_ERROR("memcpy_s failed");
2597 }
2598
2599 void* ptr = obj->GetBuffer(vm);
2600 CHECK_ARG(env, ptr);
2601
2602 *result = JsValueFromLocalValue(obj);
2603 return napi_clear_last_error(env);
2604 }
2605
napi_create_external_buffer(napi_env env,size_t length,void * data,napi_finalize finalize_cb,void * finalize_hint,napi_value * result)2606 NAPI_EXTERN napi_status napi_create_external_buffer(napi_env env,
2607 size_t length,
2608 void* data,
2609 napi_finalize finalize_cb,
2610 void* finalize_hint,
2611 napi_value* result)
2612 {
2613 NAPI_PREAMBLE(env);
2614 CHECK_ARG(env, result);
2615 CHECK_ARG(env, data);
2616 RETURN_STATUS_IF_FALSE(env, length > 0, napi_invalid_arg);
2617
2618 auto callback = reinterpret_cast<panda::NativePointerCallback>(finalize_cb);
2619 if (!data) {
2620 HILOG_ERROR("data is empty");
2621 return napi_set_last_error(env, napi_invalid_arg);
2622 }
2623 if (length > MAX_BYTE_LENGTH) {
2624 HILOG_ERROR("Creat failed, current size: %{public}2f MiB, limit size: %{public}2f MiB",
2625 static_cast<float>(length) / static_cast<float>(ONEMIB_BYTE_SIZE),
2626 static_cast<float>(MAX_BYTE_LENGTH) / static_cast<float>(ONEMIB_BYTE_SIZE));
2627 data = nullptr;
2628 return napi_set_last_error(env, napi_invalid_arg);
2629 }
2630
2631 auto engine = reinterpret_cast<NativeEngine*>(env);
2632 auto vm = engine->GetEcmaVm();
2633 Local<panda::BufferRef> object = panda::BufferRef::New(vm, data, length, callback, finalize_hint);
2634 void* ptr = object->GetBuffer(vm);
2635 CHECK_ARG(env, ptr);
2636
2637 *result = JsValueFromLocalValue(object);
2638 return GET_RETURN_STATUS(env);
2639 }
2640
napi_get_buffer_info(napi_env env,napi_value value,void ** data,size_t * length)2641 NAPI_EXTERN napi_status napi_get_buffer_info(napi_env env, napi_value value, void** data, size_t* length)
2642 {
2643 CHECK_ENV(env);
2644 CHECK_ARG(env, value);
2645
2646 auto nativeValue = LocalValueFromJsValue(value);
2647 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2648 panda::JsiFastNativeScope fastNativeScope(vm);
2649 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBuffer(vm), napi_status::napi_arraybuffer_expected);
2650 Local<panda::BufferRef> res(nativeValue);
2651 *data = res->GetBuffer(vm);
2652 *length = res->ByteLength(vm);
2653
2654 return napi_clear_last_error(env);
2655 }
2656
napi_object_freeze(napi_env env,napi_value object)2657 NAPI_EXTERN napi_status napi_object_freeze(napi_env env, napi_value object)
2658 {
2659 NAPI_PREAMBLE(env);
2660 CHECK_ARG(env, object);
2661
2662 auto nativeValue = LocalValueFromJsValue(object);
2663 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2664 panda::JsiFastNativeScope fastNativeScope(vm);
2665 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
2666 Local<panda::ObjectRef> obj = nativeValue->ToEcmaObject(vm);
2667 obj->Freeze(vm);
2668
2669 return GET_RETURN_STATUS(env);
2670 }
2671
napi_object_seal(napi_env env,napi_value object)2672 NAPI_EXTERN napi_status napi_object_seal(napi_env env, napi_value object)
2673 {
2674 NAPI_PREAMBLE(env);
2675 CHECK_ARG(env, object);
2676
2677 auto nativeValue = LocalValueFromJsValue(object);
2678 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2679 panda::JsiFastNativeScope fastNativeScope(vm);
2680 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
2681 Local<panda::ObjectRef> obj = nativeValue->ToEcmaObject(vm);
2682 obj->Seal(vm);
2683
2684 return GET_RETURN_STATUS(env);
2685 }
2686
2687 EXTERN_C_END
2688
napi_create_typedarray(napi_env env,napi_typedarray_type type,size_t length,napi_value arraybuffer,size_t byte_offset,napi_value * result)2689 NAPI_EXTERN napi_status napi_create_typedarray(napi_env env,
2690 napi_typedarray_type type,
2691 size_t length,
2692 napi_value arraybuffer,
2693 size_t byte_offset,
2694 napi_value* result)
2695 {
2696 NAPI_PREAMBLE(env);
2697 CHECK_ARG(env, arraybuffer);
2698 CHECK_ARG(env, result);
2699
2700 auto value = LocalValueFromJsValue(arraybuffer);
2701 auto typedArrayType = (NativeTypedArrayType)type;
2702 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2703 panda::JsiFastNativeScope fastNativeScope(vm);
2704 RETURN_STATUS_IF_FALSE(env, value->IsArrayBuffer(vm), napi_status::napi_arraybuffer_expected);
2705 Local<panda::ArrayBufferRef> arrayBuf(value);
2706
2707 if (!reinterpret_cast<NativeEngine*>(env)->NapiNewTypedArray(vm, typedArrayType, arrayBuf,
2708 byte_offset, length, result)) {
2709 HILOG_ERROR("%{public}s invalid arg", __func__);
2710 return napi_set_last_error(env, napi_invalid_arg);
2711 }
2712 return GET_RETURN_STATUS(env);
2713 }
2714
napi_create_sendable_typedarray(napi_env env,napi_typedarray_type type,size_t length,napi_value arraybuffer,size_t byte_offset,napi_value * result)2715 NAPI_EXTERN napi_status napi_create_sendable_typedarray(napi_env env,
2716 napi_typedarray_type type,
2717 size_t length,
2718 napi_value arraybuffer,
2719 size_t byte_offset,
2720 napi_value* result)
2721 {
2722 NAPI_PREAMBLE(env);
2723 CHECK_ARG(env, arraybuffer);
2724 CHECK_ARG(env, result);
2725
2726 auto value = LocalValueFromJsValue(arraybuffer);
2727 auto typedArrayType = (NativeTypedArrayType)type;
2728 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2729 panda::JsiFastNativeScope fastNativeScope(vm);
2730 RETURN_STATUS_IF_FALSE(env, value->IsSendableArrayBuffer(vm), napi_status::napi_arraybuffer_expected);
2731 Local<panda::SendableArrayBufferRef> arrayBuf(value);
2732
2733 if (!reinterpret_cast<NativeEngine*>(env)->NapiNewSendableTypedArray(vm, typedArrayType,
2734 arrayBuf, byte_offset,
2735 length, result)) {
2736 HILOG_ERROR("%{public}s invalid arg", __func__);
2737 return napi_set_last_error(env, napi_invalid_arg);
2738 }
2739 return GET_RETURN_STATUS(env);
2740 }
2741
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)2742 NAPI_EXTERN napi_status napi_get_typedarray_info(napi_env env,
2743 napi_value typedarray,
2744 napi_typedarray_type* type,
2745 size_t* length,
2746 void** data,
2747 napi_value* arraybuffer,
2748 size_t* byte_offset)
2749 {
2750 CHECK_ENV(env);
2751 CHECK_ARG(env, typedarray);
2752
2753 auto value = LocalValueFromJsValue(typedarray);
2754 auto engine = reinterpret_cast<NativeEngine*>(env);
2755 auto vm = engine->GetEcmaVm();
2756 panda::JsiFastNativeScope fastNativeScope(vm);
2757 if (LIKELY(value->IsTypedArray(vm))) {
2758 Local<panda::TypedArrayRef> typedArray = Local<panda::TypedArrayRef>(value);
2759 if (type != nullptr) {
2760 *type = static_cast<napi_typedarray_type>(engine->GetTypedArrayType(typedArray));
2761 }
2762 if (length != nullptr) {
2763 *length = typedArray->ByteLength(vm);
2764 }
2765 if (data != nullptr) {
2766 *data = static_cast<uint8_t*>(typedArray->GetArrayBuffer(vm)->GetBuffer(vm)) + typedArray->ByteOffset(vm);
2767 }
2768 if (arraybuffer != nullptr) {
2769 *arraybuffer = JsValueFromLocalValue(typedArray->GetArrayBuffer(vm));
2770 }
2771 if (byte_offset != nullptr) {
2772 *byte_offset = typedArray->ByteOffset(vm);
2773 }
2774 } else if (value->IsSharedTypedArray(vm)) {
2775 Local<panda::SendableTypedArrayRef> typedArray = Local<panda::SendableTypedArrayRef>(value);
2776 if (type != nullptr) {
2777 *type = static_cast<napi_typedarray_type>(engine->GetSendableTypedArrayType(typedArray));
2778 }
2779 if (length != nullptr) {
2780 *length = typedArray->ByteLength(vm);
2781 }
2782 if (data != nullptr) {
2783 *data = static_cast<uint8_t*>(typedArray->GetArrayBuffer(vm)->GetBuffer(vm)) + typedArray->ByteOffset(vm);
2784 }
2785 if (arraybuffer != nullptr) {
2786 *arraybuffer = JsValueFromLocalValue(typedArray->GetArrayBuffer(vm));
2787 }
2788 if (byte_offset != nullptr) {
2789 *byte_offset = typedArray->ByteOffset(vm);
2790 }
2791 } else {
2792 HILOG_ERROR("%{public}s invalid arg", __func__);
2793 return napi_set_last_error(env, napi_invalid_arg);
2794 }
2795
2796 return napi_clear_last_error(env);
2797 }
2798
napi_create_dataview(napi_env env,size_t length,napi_value arraybuffer,size_t byte_offset,napi_value * result)2799 NAPI_EXTERN napi_status napi_create_dataview(napi_env env,
2800 size_t length,
2801 napi_value arraybuffer,
2802 size_t byte_offset,
2803 napi_value* result)
2804 {
2805 NAPI_PREAMBLE(env);
2806 CHECK_ARG(env, arraybuffer);
2807 CHECK_ARG(env, result);
2808
2809 auto arrayBufferValue = LocalValueFromJsValue(arraybuffer);
2810 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2811 panda::JsiFastNativeScope fastNativeScope(vm);
2812 RETURN_STATUS_IF_FALSE(env, arrayBufferValue->IsArrayBuffer(vm), napi_status::napi_arraybuffer_expected);
2813 Local<panda::ArrayBufferRef> res(arrayBufferValue);
2814 if (length + byte_offset > static_cast<size_t>(res->ByteLength(vm))) {
2815 napi_throw_range_error(
2816 env,
2817 "ERR_NAPI_INVALID_DATAVIEW_ARGS",
2818 "byte_offset + byte_length should be less than or "
2819 "equal to the size in bytes of the array passed in");
2820 return napi_set_last_error(env, napi_pending_exception);
2821 }
2822
2823 Local<panda::DataViewRef> dataView = panda::DataViewRef::New(vm, res, byte_offset, length);
2824 *result = JsValueFromLocalValue(dataView);
2825 return GET_RETURN_STATUS(env);
2826 }
2827
napi_is_dataview(napi_env env,napi_value value,bool * result)2828 NAPI_EXTERN napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
2829 {
2830 CHECK_ENV(env);
2831 CHECK_ARG(env, value);
2832 CHECK_ARG(env, result);
2833
2834 auto nativeValue = LocalValueFromJsValue(value);
2835 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2836 panda::JsiFastNativeScope fastNativeScope(vm);
2837 *result = nativeValue->IsDataView(vm);
2838
2839 return napi_clear_last_error(env);
2840 }
2841
napi_get_dataview_info(napi_env env,napi_value dataview,size_t * bytelength,void ** data,napi_value * arraybuffer,size_t * byte_offset)2842 NAPI_EXTERN napi_status napi_get_dataview_info(napi_env env,
2843 napi_value dataview,
2844 size_t* bytelength,
2845 void** data,
2846 napi_value* arraybuffer,
2847 size_t* byte_offset)
2848 {
2849 CHECK_ENV(env);
2850 CHECK_ARG(env, dataview);
2851
2852 auto nativeValue = LocalValueFromJsValue(dataview);
2853 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2854 bool isDataView = false;
2855 nativeValue->GetDataViewInfo(vm, isDataView, bytelength, data,
2856 reinterpret_cast<panda::JSValueRef**>(arraybuffer), byte_offset);
2857 RETURN_STATUS_IF_FALSE(env, isDataView, napi_status::napi_invalid_arg);
2858
2859 return napi_clear_last_error(env);
2860 }
2861
2862 // version management
napi_get_version(napi_env env,uint32_t * result)2863 NAPI_EXTERN napi_status napi_get_version(napi_env env, uint32_t* result)
2864 {
2865 CHECK_ENV(env);
2866 CHECK_ARG(env, result);
2867
2868 *result = NAPI_VERSION;
2869 return napi_clear_last_error(env);
2870 }
2871
2872 // Promises
napi_create_promise(napi_env env,napi_deferred * deferred,napi_value * promise)2873 NAPI_EXTERN napi_status napi_create_promise(napi_env env, napi_deferred* deferred, napi_value* promise)
2874 {
2875 NAPI_PREAMBLE(env);
2876 auto engine = reinterpret_cast<NativeEngine*>(env);
2877 if (panda::JSNApi::HasPendingException(engine->GetEcmaVm())) {
2878 return napi_pending_exception;
2879 }
2880 CHECK_ARG(env, deferred);
2881 CHECK_ARG(env, promise);
2882
2883 auto resultValue = engine->CreatePromise(reinterpret_cast<NativeDeferred**>(deferred));
2884 *promise = resultValue;
2885
2886 return GET_RETURN_STATUS(env);
2887 }
2888
napi_resolve_deferred(napi_env env,napi_deferred deferred,napi_value resolution)2889 NAPI_EXTERN napi_status napi_resolve_deferred(napi_env env, napi_deferred deferred, napi_value resolution)
2890 {
2891 NAPI_PREAMBLE(env);
2892 CHECK_ARG(env, deferred);
2893 CHECK_ARG(env, resolution);
2894
2895 auto nativeDeferred = reinterpret_cast<NativeDeferred*>(deferred);
2896 nativeDeferred->Resolve(resolution);
2897 delete nativeDeferred;
2898 return GET_RETURN_STATUS(env);
2899 }
2900
napi_reject_deferred(napi_env env,napi_deferred deferred,napi_value rejection)2901 NAPI_EXTERN napi_status napi_reject_deferred(napi_env env, napi_deferred deferred, napi_value rejection)
2902 {
2903 NAPI_PREAMBLE(env);
2904 CHECK_ARG(env, deferred);
2905 CHECK_ARG(env, rejection);
2906
2907 auto nativeDeferred = reinterpret_cast<NativeDeferred*>(deferred);
2908 nativeDeferred->Reject(rejection);
2909 delete nativeDeferred;
2910 return GET_RETURN_STATUS(env);
2911 }
2912
napi_is_promise(napi_env env,napi_value value,bool * is_promise)2913 NAPI_EXTERN napi_status napi_is_promise(napi_env env, napi_value value, bool* is_promise)
2914 {
2915 CHECK_ENV(env);
2916 CHECK_ARG(env, value);
2917 CHECK_ARG(env, is_promise);
2918
2919 auto nativeValue = LocalValueFromJsValue(value);
2920 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
2921 panda::JsiFastNativeScope fastNativeScope(vm);
2922 *is_promise = nativeValue->IsPromise(vm);
2923
2924 return napi_clear_last_error(env);
2925 }
2926
2927 // promise reject events
napi_set_promise_rejection_callback(napi_env env,napi_ref ref,napi_ref checkRef)2928 NAPI_EXTERN napi_status napi_set_promise_rejection_callback(napi_env env, napi_ref ref, napi_ref checkRef)
2929 {
2930 CHECK_ENV(env);
2931 CHECK_ARG(env, ref);
2932 CHECK_ARG(env, checkRef);
2933
2934 auto rejectCallbackRef = reinterpret_cast<NativeReference*>(ref);
2935 auto checkCallbackRef = reinterpret_cast<NativeReference*>(checkRef);
2936 if (rejectCallbackRef == nullptr || checkCallbackRef == nullptr) {
2937 HILOG_ERROR("rejectCallbackRef or checkCallbackRef is nullptr");
2938 } else {
2939 auto engine = reinterpret_cast<NativeEngine*>(env);
2940 auto vm = const_cast<EcmaVM*>(engine->GetEcmaVm());
2941 engine->SetPromiseRejectCallBackRef(rejectCallbackRef);
2942 engine->SetCheckCallbackRef(checkCallbackRef);
2943 panda::JSNApi::SetHostPromiseRejectionTracker(const_cast<EcmaVM*>(vm), engine->GetPromiseRejectCallback(),
2944 reinterpret_cast<void*>(engine));
2945 }
2946
2947 return napi_clear_last_error(env);
2948 }
2949
2950 // Running a script
napi_run_script(napi_env env,napi_value script,napi_value * result)2951 NAPI_EXTERN napi_status napi_run_script(napi_env env, napi_value script, napi_value* result)
2952 {
2953 CHECK_ENV(env);
2954 CHECK_ARG(env, script);
2955 CHECK_ARG(env, result);
2956
2957 *result = nullptr;
2958 return napi_clear_last_error(env);
2959 }
2960
napi_run_actor(napi_env env,uint8_t * buffer,size_t bufferSize,const char * descriptor,napi_value * result,char * entryPoint)2961 NAPI_EXTERN napi_status napi_run_actor(napi_env env,
2962 uint8_t* buffer,
2963 size_t bufferSize,
2964 const char* descriptor,
2965 napi_value* result,
2966 char* entryPoint)
2967 {
2968 NAPI_PREAMBLE(env);
2969 CHECK_ARG(env, result);
2970
2971 auto engine = reinterpret_cast<NativeEngine*>(env);
2972 *result = engine->RunActor(buffer, bufferSize, descriptor, entryPoint, false);
2973 return GET_RETURN_STATUS(env);
2974 }
2975
napi_load_module(napi_env env,const char * path,napi_value * result)2976 NAPI_EXTERN napi_status napi_load_module(napi_env env, const char* path, napi_value* result)
2977 {
2978 NAPI_PREAMBLE(env);
2979 CHECK_ARG(env, result);
2980 auto engine = reinterpret_cast<NativeEngine*>(env);
2981 *result = engine->NapiLoadModule(path, nullptr);
2982 return GET_RETURN_STATUS(env);
2983 }
2984
napi_load_module_with_info(napi_env env,const char * path,const char * module_info,napi_value * result)2985 NAPI_EXTERN napi_status napi_load_module_with_info(napi_env env,
2986 const char* path,
2987 const char* module_info,
2988 napi_value* result)
2989 {
2990 NAPI_PREAMBLE(env);
2991 CHECK_ARG(env, result);
2992 auto engine = reinterpret_cast<NativeEngine*>(env);
2993 *result = engine->NapiLoadModuleWithInfo(path, module_info);
2994 return GET_RETURN_STATUS(env);
2995 }
2996 // Memory management
napi_adjust_external_memory(napi_env env,int64_t change_in_bytes,int64_t * adjusted_value)2997 NAPI_INNER_EXTERN napi_status napi_adjust_external_memory(
2998 napi_env env, int64_t change_in_bytes, int64_t* adjusted_value)
2999 {
3000 CHECK_ENV(env);
3001 CHECK_ARG(env, adjusted_value);
3002
3003 auto engine = reinterpret_cast<NativeEngine*>(env);
3004 engine->AdjustExternalMemory(change_in_bytes, adjusted_value);
3005
3006 return napi_clear_last_error(env);
3007 }
3008
napi_is_callable(napi_env env,napi_value value,bool * result)3009 NAPI_EXTERN napi_status napi_is_callable(napi_env env, napi_value value, bool* result)
3010 {
3011 CHECK_ENV(env);
3012 CHECK_ARG(env, value);
3013 CHECK_ARG(env, result);
3014
3015 auto nativeValue = LocalValueFromJsValue(value);
3016 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3017 panda::JsiFastNativeScope fastNativeScope(vm);
3018
3019 *result = nativeValue->IsFunction(vm);
3020
3021 return napi_clear_last_error(env);
3022 }
3023
napi_is_arguments_object(napi_env env,napi_value value,bool * result)3024 NAPI_EXTERN napi_status napi_is_arguments_object(napi_env env, napi_value value, bool* result)
3025 {
3026 CHECK_ENV(env);
3027 CHECK_ARG(env, value);
3028 CHECK_ARG(env, result);
3029
3030 auto nativeValue = LocalValueFromJsValue(value);
3031 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3032 panda::JsiFastNativeScope fastNativeScope(vm);
3033
3034 *result = nativeValue->IsArgumentsObject(vm);
3035
3036 return napi_clear_last_error(env);
3037 }
3038
napi_is_async_function(napi_env env,napi_value value,bool * result)3039 NAPI_EXTERN napi_status napi_is_async_function(napi_env env, napi_value value, bool* result)
3040 {
3041 CHECK_ENV(env);
3042 CHECK_ARG(env, value);
3043 CHECK_ARG(env, result);
3044
3045 auto nativeValue = LocalValueFromJsValue(value);
3046 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3047 panda::JsiFastNativeScope fastNativeScope(vm);
3048
3049 *result = nativeValue->IsAsyncFunction(vm);
3050 return napi_clear_last_error(env);
3051 }
3052
napi_is_boolean_object(napi_env env,napi_value value,bool * result)3053 NAPI_EXTERN napi_status napi_is_boolean_object(napi_env env, napi_value value, bool* result)
3054 {
3055 CHECK_ENV(env);
3056 CHECK_ARG(env, value);
3057 CHECK_ARG(env, result);
3058
3059 auto nativeValue = LocalValueFromJsValue(value);
3060 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3061 panda::JsiFastNativeScope fastNativeScope(vm);
3062
3063 *result = nativeValue->IsJSPrimitiveBoolean(vm);
3064
3065 return napi_clear_last_error(env);
3066 }
3067
napi_is_generator_function(napi_env env,napi_value value,bool * result)3068 NAPI_EXTERN napi_status napi_is_generator_function(napi_env env, napi_value value, bool* result)
3069 {
3070 CHECK_ENV(env);
3071 CHECK_ARG(env, value);
3072 CHECK_ARG(env, result);
3073
3074 auto nativeValue = LocalValueFromJsValue(value);
3075 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3076 panda::JsiFastNativeScope fastNativeScope(vm);
3077
3078 *result = nativeValue->IsGeneratorFunction(vm);
3079
3080 return napi_clear_last_error(env);
3081 }
3082
napi_is_map_iterator(napi_env env,napi_value value,bool * result)3083 NAPI_EXTERN napi_status napi_is_map_iterator(napi_env env, napi_value value, bool* result)
3084 {
3085 CHECK_ENV(env);
3086 CHECK_ARG(env, value);
3087 CHECK_ARG(env, result);
3088
3089 auto nativeValue = LocalValueFromJsValue(value);
3090 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3091 panda::JsiFastNativeScope fastNativeScope(vm);
3092
3093 *result = nativeValue->IsMapIterator(vm);
3094
3095 return napi_clear_last_error(env);
3096 }
3097
napi_is_set_iterator(napi_env env,napi_value value,bool * result)3098 NAPI_EXTERN napi_status napi_is_set_iterator(napi_env env, napi_value value, bool* result)
3099 {
3100 CHECK_ENV(env);
3101 CHECK_ARG(env, value);
3102 CHECK_ARG(env, result);
3103
3104 auto nativeValue = LocalValueFromJsValue(value);
3105 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3106 panda::JsiFastNativeScope fastNativeScope(vm);
3107
3108 *result = nativeValue->IsSetIterator(vm);
3109
3110 return napi_clear_last_error(env);
3111 }
3112
napi_is_generator_object(napi_env env,napi_value value,bool * result)3113 NAPI_EXTERN napi_status napi_is_generator_object(napi_env env, napi_value value, bool* result)
3114 {
3115 CHECK_ENV(env);
3116 CHECK_ARG(env, value);
3117 CHECK_ARG(env, result);
3118
3119 auto nativeValue = LocalValueFromJsValue(value);
3120 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3121 panda::JsiFastNativeScope fastNativeScope(vm);
3122
3123 *result = nativeValue->IsGeneratorObject(vm);
3124
3125 return napi_clear_last_error(env);
3126 }
3127
napi_is_module_namespace_object(napi_env env,napi_value value,bool * result)3128 NAPI_EXTERN napi_status napi_is_module_namespace_object(napi_env env, napi_value value, bool* result)
3129 {
3130 CHECK_ENV(env);
3131 CHECK_ARG(env, value);
3132 CHECK_ARG(env, result);
3133
3134 auto nativeValue = LocalValueFromJsValue(value);
3135 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3136 panda::JsiFastNativeScope fastNativeScope(vm);
3137
3138 *result = nativeValue->IsModuleNamespaceObject(vm);
3139
3140 return napi_clear_last_error(env);
3141 }
3142
napi_is_proxy(napi_env env,napi_value value,bool * result)3143 NAPI_EXTERN napi_status napi_is_proxy(napi_env env, napi_value value, bool* result)
3144 {
3145 CHECK_ENV(env);
3146 CHECK_ARG(env, value);
3147 CHECK_ARG(env, result);
3148
3149 auto nativeValue = LocalValueFromJsValue(value);
3150 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3151 panda::JsiFastNativeScope fastNativeScope(vm);
3152
3153 *result = nativeValue->IsProxy(vm);
3154 return napi_clear_last_error(env);
3155 }
3156
napi_is_reg_exp(napi_env env,napi_value value,bool * result)3157 NAPI_EXTERN napi_status napi_is_reg_exp(napi_env env, napi_value value, bool* result)
3158 {
3159 CHECK_ENV(env);
3160 CHECK_ARG(env, value);
3161 CHECK_ARG(env, result);
3162
3163 auto nativeValue = LocalValueFromJsValue(value);
3164 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3165 panda::JsiFastNativeScope fastNativeScope(vm);
3166
3167 *result = nativeValue->IsRegExp(vm);
3168 return napi_clear_last_error(env);
3169 }
3170
napi_is_number_object(napi_env env,napi_value value,bool * result)3171 NAPI_EXTERN napi_status napi_is_number_object(napi_env env, napi_value value, bool* result)
3172 {
3173 CHECK_ENV(env);
3174 CHECK_ARG(env, value);
3175 CHECK_ARG(env, result);
3176
3177 auto nativeValue = LocalValueFromJsValue(value);
3178 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3179 panda::JsiFastNativeScope fastNativeScope(vm);
3180
3181 *result = nativeValue->IsJSPrimitiveNumber(vm);
3182
3183 return napi_clear_last_error(env);
3184 }
3185
napi_is_map(napi_env env,napi_value value,bool * result)3186 NAPI_EXTERN napi_status napi_is_map(napi_env env, napi_value value, bool* result)
3187 {
3188 CHECK_ENV(env);
3189 CHECK_ARG(env, value);
3190 CHECK_ARG(env, result);
3191
3192 auto nativeValue = LocalValueFromJsValue(value);
3193 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3194 panda::JsiFastNativeScope fastNativeScope(vm);
3195
3196 *result = nativeValue->IsMap(vm) || nativeValue->IsSharedMap(vm);
3197 return napi_clear_last_error(env);
3198 }
3199
napi_is_set(napi_env env,napi_value value,bool * result)3200 NAPI_EXTERN napi_status napi_is_set(napi_env env, napi_value value, bool* result)
3201 {
3202 CHECK_ENV(env);
3203 CHECK_ARG(env, value);
3204 CHECK_ARG(env, result);
3205
3206 auto nativeValue = LocalValueFromJsValue(value);
3207 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3208 panda::JsiFastNativeScope fastNativeScope(vm);
3209
3210 *result = nativeValue->IsSet(vm) || nativeValue->IsSharedSet(vm);
3211 return napi_clear_last_error(env);
3212 }
3213
napi_is_string_object(napi_env env,napi_value value,bool * result)3214 NAPI_EXTERN napi_status napi_is_string_object(napi_env env, napi_value value, bool* result)
3215 {
3216 CHECK_ENV(env);
3217 CHECK_ARG(env, value);
3218 CHECK_ARG(env, result);
3219
3220 auto nativeValue = LocalValueFromJsValue(value);
3221 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3222 panda::JsiFastNativeScope fastNativeScope(vm);
3223
3224 *result = nativeValue->IsJSPrimitiveString(vm);
3225
3226 return napi_clear_last_error(env);
3227 }
3228
napi_is_symbol_object(napi_env env,napi_value value,bool * result)3229 NAPI_EXTERN napi_status napi_is_symbol_object(napi_env env, napi_value value, bool* result)
3230 {
3231 CHECK_ENV(env);
3232 CHECK_ARG(env, value);
3233 CHECK_ARG(env, result);
3234
3235 auto nativeValue = LocalValueFromJsValue(value);
3236 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3237 panda::JsiFastNativeScope fastNativeScope(vm);
3238
3239 *result = nativeValue->IsJSPrimitiveSymbol(vm);
3240 return napi_clear_last_error(env);
3241 }
3242
napi_is_weak_map(napi_env env,napi_value value,bool * result)3243 NAPI_EXTERN napi_status napi_is_weak_map(napi_env env, napi_value value, bool* result)
3244 {
3245 CHECK_ENV(env);
3246 CHECK_ARG(env, value);
3247 CHECK_ARG(env, result);
3248
3249 auto nativeValue = LocalValueFromJsValue(value);
3250 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3251 panda::JsiFastNativeScope fastNativeScope(vm);
3252
3253 *result = nativeValue->IsWeakMap(vm);
3254 return napi_clear_last_error(env);
3255 }
3256
napi_is_weak_set(napi_env env,napi_value value,bool * result)3257 NAPI_EXTERN napi_status napi_is_weak_set(napi_env env, napi_value value, bool* result)
3258 {
3259 CHECK_ENV(env);
3260 CHECK_ARG(env, value);
3261 CHECK_ARG(env, result);
3262
3263 auto nativeValue = LocalValueFromJsValue(value);
3264 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3265 panda::JsiFastNativeScope fastNativeScope(vm);
3266
3267 *result = nativeValue->IsWeakSet(vm);
3268 return napi_clear_last_error(env);
3269 }
3270
napi_create_runtime(napi_env env,napi_env * result_env)3271 NAPI_EXTERN napi_status napi_create_runtime(napi_env env, napi_env* result_env)
3272 {
3273 CHECK_ENV(env);
3274 CHECK_ARG(env, result_env);
3275
3276 auto engine = reinterpret_cast<NativeEngine*>(env);
3277 auto result = engine->CreateRuntime();
3278 *result_env = reinterpret_cast<napi_env>(result);
3279
3280 return napi_clear_last_error(env);
3281 }
3282
napi_serialize(napi_env env,napi_value object,napi_value transfer_list,napi_value clone_list,void ** result)3283 NAPI_EXTERN napi_status napi_serialize(napi_env env,
3284 napi_value object,
3285 napi_value transfer_list,
3286 napi_value clone_list,
3287 void** result)
3288 {
3289 CHECK_ENV(env);
3290 CHECK_ARG(env, object);
3291 CHECK_ARG(env, transfer_list);
3292 CHECK_ARG(env, clone_list);
3293 CHECK_ARG(env, result);
3294
3295 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3296 auto nativeValue = LocalValueFromJsValue(object);
3297 auto transferList = LocalValueFromJsValue(transfer_list);
3298 RETURN_STATUS_IF_FALSE(env, transferList->IsUndefined() || transferList->IsJSArray(vm), napi_invalid_arg);
3299 auto cloneList = LocalValueFromJsValue(clone_list);
3300 RETURN_STATUS_IF_FALSE(env, cloneList->IsUndefined() || cloneList->IsJSArray(vm), napi_invalid_arg);
3301 *result = panda::JSNApi::SerializeValue(vm, nativeValue, transferList, cloneList, false, false);
3302
3303 return napi_clear_last_error(env);
3304 }
3305
napi_serialize_inner(napi_env env,napi_value object,napi_value transfer_list,napi_value clone_list,bool defaultTransfer,bool defaultCloneSendable,void ** result)3306 NAPI_EXTERN napi_status napi_serialize_inner(napi_env env, napi_value object, napi_value transfer_list,
3307 napi_value clone_list, bool defaultTransfer, bool defaultCloneSendable,
3308 void** result)
3309 {
3310 CHECK_ENV(env);
3311 CHECK_ARG(env, object);
3312 CHECK_ARG(env, transfer_list);
3313 CHECK_ARG(env, result);
3314
3315 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3316 auto nativeValue = LocalValueFromJsValue(object);
3317 auto transferList = LocalValueFromJsValue(transfer_list);
3318 auto cloneList = LocalValueFromJsValue(clone_list);
3319 *result =
3320 panda::JSNApi::SerializeValue(vm, nativeValue, transferList, cloneList, defaultTransfer, defaultCloneSendable);
3321
3322 return napi_clear_last_error(env);
3323 }
3324
napi_deserialize(napi_env env,void * buffer,napi_value * object)3325 NAPI_EXTERN napi_status napi_deserialize(napi_env env, void* buffer, napi_value* object)
3326 {
3327 CHECK_ENV(env);
3328 CHECK_ARG(env, buffer);
3329 CHECK_ARG(env, object);
3330
3331 auto engine = reinterpret_cast<NativeEngine*>(env);
3332 auto vm = engine->GetEcmaVm();
3333 Local<panda::JSValueRef> res = panda::JSNApi::DeserializeValue(vm, buffer, reinterpret_cast<void*>(engine));
3334 *object = JsValueFromLocalValue(res);
3335
3336 return napi_clear_last_error(env);
3337 }
3338
napi_delete_serialization_data(napi_env env,void * buffer)3339 NAPI_EXTERN napi_status napi_delete_serialization_data(napi_env env, void* buffer)
3340 {
3341 CHECK_ENV(env);
3342 CHECK_ARG(env, buffer);
3343
3344 panda::JSNApi::DeleteSerializationData(buffer);
3345
3346 return napi_clear_last_error(env);
3347 }
3348
napi_create_bigint_int64(napi_env env,int64_t value,napi_value * result)3349 NAPI_EXTERN napi_status napi_create_bigint_int64(napi_env env, int64_t value, napi_value* result)
3350 {
3351 CHECK_ENV(env);
3352 CHECK_ARG(env, result);
3353
3354 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3355 Local<panda::BigIntRef> object = panda::BigIntRef::New(vm, value);
3356 *result = JsValueFromLocalValue(object);
3357
3358 return napi_clear_last_error(env);
3359 }
3360
napi_create_bigint_uint64(napi_env env,uint64_t value,napi_value * result)3361 NAPI_EXTERN napi_status napi_create_bigint_uint64(napi_env env, uint64_t value, napi_value* result)
3362 {
3363 CHECK_ENV(env);
3364 CHECK_ARG(env, result);
3365
3366 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3367 Local<panda::BigIntRef> object = panda::BigIntRef::New(vm, value);
3368 *result = JsValueFromLocalValue(object);
3369
3370 return napi_clear_last_error(env);
3371 }
3372
napi_get_value_bigint_int64(napi_env env,napi_value value,int64_t * result,bool * lossless)3373 NAPI_EXTERN napi_status napi_get_value_bigint_int64(
3374 napi_env env, napi_value value, int64_t* result, bool* lossless)
3375 {
3376 CHECK_ENV(env);
3377 CHECK_ARG(env, value);
3378 CHECK_ARG(env, result);
3379 CHECK_ARG(env, lossless);
3380
3381 auto nativeValue = LocalValueFromJsValue(value);
3382 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3383 panda::JsiFastNativeScope fastNativeScope(vm);
3384 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBigInt(vm), napi_bigint_expected);
3385 Local<panda::BigIntRef> bigIntVal = nativeValue->ToBigInt(vm);
3386 bigIntVal->BigIntToInt64(vm, result, lossless);
3387
3388 return napi_clear_last_error(env);
3389 }
3390
napi_get_value_bigint_uint64(napi_env env,napi_value value,uint64_t * result,bool * lossless)3391 NAPI_EXTERN napi_status napi_get_value_bigint_uint64(
3392 napi_env env, napi_value value, uint64_t* result, bool* lossless)
3393 {
3394 CHECK_ENV(env);
3395 CHECK_ARG(env, value);
3396 CHECK_ARG(env, result);
3397 CHECK_ARG(env, lossless);
3398
3399 auto nativeValue = LocalValueFromJsValue(value);
3400 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3401 panda::JsiFastNativeScope fastNativeScope(vm);
3402 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBigInt(vm), napi_bigint_expected);
3403 Local<panda::BigIntRef> bigIntVal = nativeValue->ToBigInt(vm);
3404 bigIntVal->BigIntToUint64(vm, result, lossless);
3405
3406 return napi_clear_last_error(env);
3407 }
3408
napi_is_date(napi_env env,napi_value value,bool * result)3409 NAPI_EXTERN napi_status napi_is_date(napi_env env, napi_value value, bool* result)
3410 {
3411 CHECK_ENV(env);
3412 CHECK_ARG(env, value);
3413 CHECK_ARG(env, result);
3414
3415 auto nativeValue = LocalValueFromJsValue(value);
3416 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3417 panda::JsiFastNativeScope fastNativeScope(vm);
3418
3419 *result = nativeValue->IsDate(vm);
3420 return napi_clear_last_error(env);
3421 }
3422
napi_is_detached_arraybuffer(napi_env env,napi_value arraybuffer,bool * result)3423 NAPI_EXTERN napi_status napi_is_detached_arraybuffer(napi_env env, napi_value arraybuffer, bool* result)
3424 {
3425 CHECK_ENV(env);
3426 CHECK_ARG(env, arraybuffer);
3427 CHECK_ARG(env, result);
3428
3429 auto nativeValue = LocalValueFromJsValue(arraybuffer);
3430 bool isArrayBuffer = false;
3431 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3432 panda::JsiFastNativeScope fastNativeScope(vm);
3433
3434 bool isDetach = nativeValue->IsDetachedArraybuffer(vm, isArrayBuffer);
3435 if (isArrayBuffer) {
3436 *result = isDetach;
3437 return napi_clear_last_error(env);
3438 } else {
3439 return napi_set_last_error(env, napi_invalid_arg);
3440 }
3441 }
3442
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)3443 NAPI_EXTERN napi_status napi_get_all_property_names(
3444 napi_env env, napi_value object, napi_key_collection_mode key_mode,
3445 napi_key_filter key_filter, napi_key_conversion key_conversion, napi_value* result)
3446 {
3447 NAPI_PREAMBLE(env);
3448 CHECK_ARG(env, object);
3449 CHECK_ARG(env, result);
3450 auto nativeValue = LocalValueFromJsValue(object);
3451 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3452 panda::JsiFastNativeScope fastNativeScope(vm);
3453 CHECK_AND_CONVERT_TO_OBJECT(env, vm, nativeValue, obj);
3454 uint32_t filter = NATIVE_DEFAULT;
3455 if (key_filter & napi_key_writable) {
3456 filter = static_cast<uint32_t>(filter | NATIVE_WRITABLE);
3457 }
3458 if (key_filter & napi_key_enumerable) {
3459 filter = static_cast<uint32_t>(filter | NATIVE_ENUMERABLE);
3460 }
3461 if (key_filter & napi_key_configurable) {
3462 filter = static_cast<uint32_t>(filter | NATIVE_CONFIGURABLE);
3463 }
3464 if (key_filter & napi_key_skip_strings) {
3465 filter = static_cast<uint32_t>(filter | NATIVE_KEY_SKIP_STRINGS);
3466 }
3467 if (key_filter & napi_key_skip_symbols) {
3468 filter = static_cast<uint32_t>(filter | NATIVE_KEY_SKIP_SYMBOLS);
3469 }
3470
3471 switch (key_mode) {
3472 case napi_key_include_prototypes:
3473 filter = static_cast<uint32_t>(filter | NATIVE_KEY_INCLUDE_PROTOTYPES);
3474 break;
3475 case napi_key_own_only:
3476 filter = static_cast<uint32_t>(filter | NATIVE_KEY_OWN_ONLY);
3477 break;
3478 default:
3479 *result = nullptr;
3480 HILOG_ERROR("%{public}s invalid arg", __func__);
3481 return napi_set_last_error(env, napi_invalid_arg);
3482 }
3483
3484 switch (key_conversion) {
3485 case napi_key_keep_numbers:
3486 filter = static_cast<uint32_t>(filter | NATIVE_KEY_KEEP_NUMBERS);
3487 break;
3488 case napi_key_numbers_to_strings:
3489 filter = static_cast<uint32_t>(filter | NATIVE_KEY_NUMBERS_TO_STRINGS);
3490 break;
3491 default:
3492 *result = nullptr;
3493 HILOG_ERROR("%{public}s invalid arg", __func__);
3494 return napi_set_last_error(env, napi_invalid_arg);
3495 }
3496 Local<panda::ArrayRef> arrayVal = obj->GetAllPropertyNames(vm, filter);
3497 *result = JsValueFromLocalValue(arrayVal);
3498 return GET_RETURN_STATUS(env);
3499 }
3500
napi_detach_arraybuffer(napi_env env,napi_value arraybuffer)3501 NAPI_EXTERN napi_status napi_detach_arraybuffer(napi_env env, napi_value arraybuffer)
3502 {
3503 CHECK_ENV(env);
3504 CHECK_ARG(env, arraybuffer);
3505
3506 auto nativeValue = LocalValueFromJsValue(arraybuffer);
3507 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3508 panda::JsiFastNativeScope fastNativeScope(vm);
3509
3510 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
3511 bool isArrayBuffer = false;
3512 nativeValue->DetachedArraybuffer(vm, isArrayBuffer);
3513 if (!isArrayBuffer) {
3514 return napi_set_last_error(env, napi_invalid_arg);
3515 }
3516 return napi_clear_last_error(env);
3517 }
3518
napi_type_tag_object(napi_env env,napi_value js_object,const napi_type_tag * type_tag)3519 NAPI_EXTERN napi_status napi_type_tag_object(napi_env env, napi_value js_object, const napi_type_tag* type_tag)
3520 {
3521 NAPI_PREAMBLE(env);
3522 CHECK_ARG(env, js_object);
3523 CHECK_ARG(env, type_tag);
3524
3525 auto nativeValue = LocalValueFromJsValue(js_object);
3526 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3527 panda::JsiFastNativeScope fastNativeScope(vm);
3528 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
3529 auto obj = nativeValue->ToEcmaObject(vm);
3530 NapiTypeTag* typeTag = (NapiTypeTag*)type_tag;
3531 const char name[] = "ACENAPI_TYPETAG";
3532 bool hasPribate = false;
3533 bool result = true;
3534 Local<panda::StringRef> key = StringRef::NewFromUtf8(vm, name);
3535 hasPribate = obj->Has(vm, key);
3536 if (!hasPribate) {
3537 constexpr int bigintMod = 2; // 2 : used for even number judgment
3538 int sign_bit = 0;
3539 size_t word_count = 2;
3540 bool sign = false;
3541 if ((sign_bit % bigintMod) == 1) {
3542 sign = true;
3543 }
3544 uint32_t size = (uint32_t)word_count;
3545 Local<panda::JSValueRef> value = panda::BigIntRef::CreateBigWords(vm, sign, size,
3546 reinterpret_cast<const uint64_t*>(typeTag));
3547 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, name);
3548 result = obj->Set(vm, key, value);
3549 }
3550 if (!result) {
3551 HILOG_ERROR("%{public}s invalid arg", __func__);
3552 return napi_set_last_error(env, napi_invalid_arg);
3553 }
3554
3555 return napi_clear_last_error(env);
3556 }
3557
BigIntGetWordsArray(const EcmaVM * vm,Local<panda::BigIntRef> & value,int * signBit,size_t * wordCount,uint64_t * words)3558 bool BigIntGetWordsArray(const EcmaVM* vm, Local<panda::BigIntRef> &value, int* signBit,
3559 size_t* wordCount, uint64_t* words)
3560 {
3561 if (wordCount == nullptr) {
3562 return false;
3563 }
3564 size_t size = static_cast<size_t>(value->GetWordsArraySize(vm));
3565 if (signBit == nullptr && words == nullptr) {
3566 *wordCount = size;
3567 return true;
3568 } else if (signBit != nullptr && words != nullptr) {
3569 if (size > *wordCount) {
3570 size = *wordCount;
3571 }
3572 bool sign = false;
3573 value->GetWordsArray(vm, &sign, size, words);
3574 if (sign) {
3575 *signBit = 1;
3576 } else {
3577 *signBit = 0;
3578 }
3579 *wordCount = size;
3580 return true;
3581 }
3582 return false;
3583 }
3584
napi_check_object_type_tag(napi_env env,napi_value js_object,const napi_type_tag * type_tag,bool * result)3585 NAPI_EXTERN napi_status napi_check_object_type_tag(napi_env env,
3586 napi_value js_object,
3587 const napi_type_tag* type_tag,
3588 bool* result)
3589 {
3590 NAPI_PREAMBLE(env);
3591 CHECK_ARG(env, js_object);
3592 CHECK_ARG(env, type_tag);
3593 CHECK_ARG(env, result);
3594
3595 auto nativeValue = LocalValueFromJsValue(js_object);
3596 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3597 panda::JsiFastNativeScope fastNativeScope(vm);
3598 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
3599 auto obj = nativeValue->ToEcmaObject(vm);
3600 NapiTypeTag* typeTag = (NapiTypeTag*)type_tag;
3601 *result = false;
3602 const char name[] = "ACENAPI_TYPETAG";
3603
3604 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, name);
3605 *result = obj->Has(vm, key);
3606 if (*result) {
3607 Local<panda::StringRef> key = panda::StringRef::NewFromUtf8(vm, name);
3608 Local<panda::JSValueRef> object = obj->Get(vm, key);
3609 if (object->IsBigInt(vm)) {
3610 int sign;
3611 size_t size = 2; // 2: Indicates that the number of elements is 2
3612 NapiTypeTag tag;
3613 Local<panda::BigIntRef> bigintObj = object->ToBigInt(vm);
3614 BigIntGetWordsArray(vm, bigintObj, &sign, &size, reinterpret_cast<uint64_t*>(&tag));
3615 if (sign == 0 && ((size == 1) || (size == 2))) { // 2: Indicates that the number of elements is 2
3616 *result = (tag.lower == typeTag->lower && tag.upper == typeTag->upper);
3617 }
3618 }
3619 }
3620 return napi_clear_last_error(env);
3621 }
3622
napi_create_date(napi_env env,double time,napi_value * result)3623 NAPI_EXTERN napi_status napi_create_date(napi_env env, double time, napi_value* result)
3624 {
3625 NAPI_PREAMBLE(env);
3626 CHECK_ARG(env, result);
3627
3628 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3629 *result = JsValueFromLocalValue(DateRef::New(vm, time));
3630
3631 return napi_clear_last_error(env);
3632 }
3633
napi_get_date_value(napi_env env,napi_value value,double * result)3634 NAPI_EXTERN napi_status napi_get_date_value(napi_env env, napi_value value, double* result)
3635 {
3636 NAPI_PREAMBLE(env);
3637 CHECK_ARG(env, value);
3638 CHECK_ARG(env, result);
3639
3640 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3641 auto nativeValue = LocalValueFromJsValue(value);
3642 panda::JsiFastNativeScope fastNativeScope(vm);
3643
3644 auto IsDate_result = nativeValue->IsDate(vm);
3645 Local<panda::DateRef> dateObj(nativeValue);
3646 if (IsDate_result) {
3647 *result = dateObj->GetTime(vm);
3648 } else {
3649 HILOG_ERROR("%{public}s date expected", __func__);
3650 return napi_set_last_error(env, napi_date_expected);
3651 }
3652
3653 return napi_clear_last_error(env);
3654 }
3655
napi_add_finalizer(napi_env env,napi_value js_object,void * native_object,napi_finalize finalize_cb,void * finalize_hint,napi_ref * result)3656 NAPI_EXTERN napi_status napi_add_finalizer(napi_env env,
3657 napi_value js_object,
3658 void* native_object,
3659 napi_finalize finalize_cb,
3660 void* finalize_hint,
3661 napi_ref* result)
3662 {
3663 CHECK_ENV(env);
3664 CHECK_ARG(env, js_object);
3665 CHECK_ARG(env, finalize_cb);
3666
3667 auto nativeValue = LocalValueFromJsValue(js_object);
3668 auto callback = reinterpret_cast<NapiNativeFinalize>(finalize_cb);
3669 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3670 panda::JsiFastNativeScope fastNativeScope(vm);
3671
3672 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
3673 NativeReference* reference = nullptr;
3674 auto engine = reinterpret_cast<NativeEngine*>(env);
3675 if (result != nullptr) {
3676 reference = engine->CreateReference(js_object, 1, false, callback, native_object, finalize_hint);
3677 *result = reinterpret_cast<napi_ref>(reference);
3678 } else {
3679 reference = engine->CreateReference(js_object, 0, true, callback, native_object, finalize_hint);
3680 }
3681 return napi_clear_last_error(env);
3682 }
3683
napi_create_bigint_words(napi_env env,int sign_bit,size_t word_count,const uint64_t * words,napi_value * result)3684 NAPI_EXTERN napi_status napi_create_bigint_words(napi_env env,
3685 int sign_bit,
3686 size_t word_count,
3687 const uint64_t* words,
3688 napi_value* result)
3689 {
3690 NAPI_PREAMBLE(env);
3691 CHECK_ARG(env, words);
3692 CHECK_ARG(env, result);
3693 RETURN_STATUS_IF_FALSE(env, word_count <= INT_MAX, napi_invalid_arg);
3694
3695 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3696 constexpr int bigintMod = 2; // 2 : used for even number judgment
3697 bool sign = false;
3698 if ((sign_bit % bigintMod) == 1) {
3699 sign = true;
3700 }
3701 uint32_t size = (uint32_t)word_count;
3702 Local<panda::JSValueRef> value = panda::BigIntRef::CreateBigWords(vm, sign, size, words);
3703
3704 if (panda::JSNApi::HasPendingException(vm)) {
3705 HILOG_ERROR("%{public}s pending exception", __func__);
3706 return napi_set_last_error(env, napi_pending_exception);
3707 }
3708 *result = JsValueFromLocalValue(value);
3709 return GET_RETURN_STATUS(env);
3710 }
3711
napi_get_value_bigint_words(napi_env env,napi_value value,int * sign_bit,size_t * word_count,uint64_t * words)3712 NAPI_EXTERN napi_status napi_get_value_bigint_words(napi_env env,
3713 napi_value value,
3714 int* sign_bit,
3715 size_t* word_count,
3716 uint64_t* words)
3717 {
3718 CHECK_ENV(env);
3719 CHECK_ARG(env, value);
3720 CHECK_ARG(env, word_count);
3721
3722 auto nativeValue = LocalValueFromJsValue(value);
3723 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3724 panda::JsiFastNativeScope fastNativeScope(vm);
3725
3726 RETURN_STATUS_IF_FALSE(env, nativeValue->IsBigInt(vm), napi_object_expected);
3727 auto BigintObj = nativeValue->ToBigInt(vm);
3728 if (word_count == nullptr) {
3729 return napi_set_last_error(env, napi_invalid_arg);
3730 }
3731 size_t size = static_cast<size_t>(BigintObj->GetWordsArraySize(vm));
3732 if (sign_bit == nullptr && words == nullptr) {
3733 *word_count = size;
3734 return napi_set_last_error(env, napi_ok);
3735 } else if (sign_bit != nullptr && words != nullptr) {
3736 if (size > *word_count) {
3737 size = *word_count;
3738 }
3739 bool sign = false;
3740 BigintObj->GetWordsArray(vm, &sign, size, words);
3741 if (sign) {
3742 *sign_bit = 1;
3743 } else {
3744 *sign_bit = 0;
3745 }
3746 *word_count = size;
3747 return napi_set_last_error(env, napi_ok);
3748 }
3749
3750 return napi_clear_last_error(env);
3751 }
3752
napi_run_script_path(napi_env env,const char * path,napi_value * result)3753 NAPI_EXTERN napi_status napi_run_script_path(napi_env env, const char* path, napi_value* result)
3754 {
3755 NAPI_PREAMBLE(env);
3756 CHECK_ARG(env, result);
3757
3758 auto engine = reinterpret_cast<NativeEngine*>(env);
3759 std::string pathStr(path);
3760 if (engine->IsApplicationApiVersionAPI11Plus()) {
3761 pathStr = panda::JSNApi::NormalizePath(path);
3762 }
3763 HILOG_DEBUG("napi_run_script_path path: %{public}s", pathStr.c_str());
3764 if (engine->IsRestrictedWorkerThread()) {
3765 *result = engine->RunScriptInRestrictedThread(pathStr.c_str());
3766 } else {
3767 *result = engine->RunScript(pathStr.c_str());
3768 }
3769 return GET_RETURN_STATUS(env);
3770 }
3771
napi_is_big_int64_array(napi_env env,napi_value value,bool * result)3772 NAPI_EXTERN napi_status napi_is_big_int64_array(napi_env env, napi_value value, bool* result)
3773 {
3774 CHECK_ENV(env);
3775 CHECK_ARG(env, value);
3776 CHECK_ARG(env, result);
3777
3778 auto nativeValue = LocalValueFromJsValue(value);
3779 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3780 panda::JsiFastNativeScope fastNativeScope(vm);
3781
3782 *result = nativeValue->IsBigInt64Array(vm);
3783 return napi_clear_last_error(env);
3784 }
3785
napi_is_big_uint64_array(napi_env env,napi_value value,bool * result)3786 NAPI_EXTERN napi_status napi_is_big_uint64_array(napi_env env, napi_value value, bool* result)
3787 {
3788 CHECK_ENV(env);
3789 CHECK_ARG(env, value);
3790 CHECK_ARG(env, result);
3791
3792 auto nativeValue = LocalValueFromJsValue(value);
3793 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3794 panda::JsiFastNativeScope fastNativeScope(vm);
3795
3796 *result = nativeValue->IsBigUint64Array(vm);
3797 return napi_clear_last_error(env);
3798 }
3799
napi_is_shared_array_buffer(napi_env env,napi_value value,bool * result)3800 NAPI_EXTERN napi_status napi_is_shared_array_buffer(napi_env env, napi_value value, bool* result)
3801 {
3802 CHECK_ENV(env);
3803 CHECK_ARG(env, value);
3804 CHECK_ARG(env, result);
3805
3806 auto nativeValue = LocalValueFromJsValue(value);
3807 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3808 panda::JsiFastNativeScope fastNativeScope(vm);
3809
3810 *result = nativeValue->IsSharedArrayBuffer(vm);
3811 return napi_clear_last_error(env);
3812 }
3813
napi_get_stack_trace(napi_env env,std::string & stack)3814 NAPI_EXTERN napi_status napi_get_stack_trace(napi_env env, std::string& stack)
3815 {
3816 CHECK_ENV(env);
3817
3818 auto engine = reinterpret_cast<NativeEngine*>(env);
3819 [[maybe_unused]] auto vm = engine->GetEcmaVm();
3820 std::string rawStack;
3821 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
3822 DFXJSNApi::BuildJsStackTrace(vm, rawStack);
3823 stack = engine->ExecuteTranslateBySourceMap(rawStack);
3824 #else
3825 HILOG_WARN("GetStacktrace env get stack failed");
3826 #endif
3827
3828 return napi_clear_last_error(env);
3829 }
3830
napi_get_hybrid_stack_trace(napi_env env,std::string & stack)3831 NAPI_EXTERN napi_status napi_get_hybrid_stack_trace(napi_env env, std::string& stack)
3832 {
3833 CHECK_ENV(env);
3834
3835 #if defined(OHOS_PLATFORM) && !defined(is_arkui_x)
3836 auto engine = reinterpret_cast<NativeEngine*>(env);
3837 auto vm = engine->GetEcmaVm();
3838 stack = DumpHybridStack(vm);
3839 #else
3840 HILOG_WARN("GetHybridStacktrace env get hybrid stack failed");
3841 #endif
3842 return napi_clear_last_error(env);
3843 }
3844
napi_object_get_keys(napi_env env,napi_value data,napi_value * result)3845 NAPI_EXTERN napi_status napi_object_get_keys(napi_env env, napi_value data, napi_value* result)
3846 {
3847 CHECK_ENV(env);
3848
3849 auto nativeValue = LocalValueFromJsValue(data);
3850 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3851 panda::JsiFastNativeScope fastNativeScope(vm);
3852 RETURN_STATUS_IF_FALSE(env, nativeValue->IsObject(vm), napi_object_expected);
3853 auto obj = nativeValue->ToEcmaObject(vm);
3854 Local<panda::ArrayRef> arrayVal = obj->GetOwnEnumerablePropertyNames(vm);
3855
3856 *result = JsValueFromLocalValue(arrayVal);
3857 return napi_clear_last_error(env);
3858 }
3859
napi_queue_async_work_with_qos(napi_env env,napi_async_work work,napi_qos_t qos)3860 NAPI_EXTERN napi_status napi_queue_async_work_with_qos(napi_env env, napi_async_work work, napi_qos_t qos)
3861 {
3862 CHECK_ENV(env);
3863 CHECK_ARG(env, work);
3864
3865 auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work);
3866 asyncWork->QueueWithQos(qos);
3867 return napi_status::napi_ok;
3868 }
3869
DetachFuncCallback(void * engine,void * object,void * hint,void * detachData)3870 void* DetachFuncCallback(void* engine, void* object, void* hint, void* detachData)
3871 {
3872 if (detachData == nullptr || (engine == nullptr || object ==nullptr)) {
3873 HILOG_ERROR("DetachFuncCallback params has nullptr");
3874 return nullptr;
3875 }
3876 DetachCallback detach = reinterpret_cast<DetachCallback>(detachData);
3877 void* detachVal = detach(reinterpret_cast<NativeEngine*>(engine), object, hint);
3878 return detachVal;
3879 }
3880
AttachFuncCallback(void * engine,void * buffer,void * hint,void * attachData)3881 Local<panda::JSValueRef> AttachFuncCallback(void* engine, void* buffer, void* hint, void* attachData)
3882 {
3883 auto vm = reinterpret_cast<NativeEngine*>(engine)->GetEcmaVm();
3884 if (attachData == nullptr || (engine == nullptr || buffer ==nullptr)) {
3885 HILOG_ERROR("AttachFuncCallback params has nullptr");
3886 return panda::JSValueRef::Undefined(vm);
3887 }
3888 EscapeLocalScope scope(vm);
3889 Local<panda::JSValueRef> result = panda::JSValueRef::Undefined(vm);
3890 NapiAttachCallback attach = reinterpret_cast<NapiAttachCallback>(attachData);
3891 napi_value attachVal = attach(reinterpret_cast<napi_env>(engine), buffer, hint);
3892 if (attachVal == nullptr) {
3893 HILOG_WARN("AttachFunc return nullptr");
3894 } else {
3895 result = LocalValueFromJsValue(attachVal);
3896 }
3897 return scope.Escape(result);
3898 }
3899
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)3900 NAPI_EXTERN napi_status napi_coerce_to_native_binding_object(napi_env env,
3901 napi_value js_object,
3902 napi_native_binding_detach_callback detach_cb,
3903 napi_native_binding_attach_callback attach_cb,
3904 void* native_object,
3905 void* hint)
3906 {
3907 CHECK_ENV(env);
3908 CHECK_ARG(env, js_object);
3909 CHECK_ARG(env, detach_cb);
3910 CHECK_ARG(env, attach_cb);
3911 CHECK_ARG(env, native_object);
3912
3913 auto jsValue = LocalValueFromJsValue(js_object);
3914 auto engine = reinterpret_cast<NativeEngine*>(env);
3915 auto vm = engine->GetEcmaVm();
3916 panda::JsiFastNativeScope fastNativeScope(vm);
3917
3918 RETURN_STATUS_IF_FALSE(env, jsValue->IsObject(vm), napi_object_expected);
3919 auto obj = jsValue->ToEcmaObject(vm);
3920
3921 panda::JSNApi::NativeBindingInfo* data = panda::JSNApi::NativeBindingInfo::CreateNewInstance();
3922 if (data == nullptr) {
3923 HILOG_ERROR("data is nullptr");
3924 return napi_set_last_error(env, napi_invalid_arg);
3925 }
3926 data->env = env;
3927 data->nativeValue = native_object;
3928 data->attachFunc = reinterpret_cast<void*>(AttachFuncCallback);
3929 data->attachData = reinterpret_cast<void*>(attach_cb);
3930 data->detachFunc = reinterpret_cast<void*>(DetachFuncCallback);
3931 data->detachData = reinterpret_cast<void*>(detach_cb);
3932 data->hint = hint;
3933
3934 size_t nativeBindingSize = 7 * sizeof(void *); // 7 : params num
3935 Local<panda::NativePointerRef> value = panda::NativePointerRef::NewConcurrent(vm, data,
3936 [](void* env, void* data, void* info) {
3937 auto externalInfo = reinterpret_cast<panda::JSNApi::NativeBindingInfo*>(data);
3938 delete externalInfo;
3939 }, nullptr, nativeBindingSize);
3940
3941 bool res = obj->ConvertToNativeBindingObject(vm, value);
3942 if (res) {
3943 return napi_clear_last_error(env);
3944 }
3945 return napi_status::napi_generic_failure;
3946 }
3947
napi_get_print_string(napi_env env,napi_value value,std::string & result)3948 NAPI_EXTERN napi_status napi_get_print_string(napi_env env, napi_value value, std::string& result)
3949 {
3950 CHECK_ENV(env);
3951 CHECK_ARG(env, value);
3952
3953 auto nativeValue = LocalValueFromJsValue(value);
3954 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
3955 panda::JsiFastNativeScope fastNativeScope(vm);
3956
3957 if (nativeValue->IsString(vm)) {
3958 Local<panda::StringRef> stringVal(nativeValue);
3959 result = stringVal->ToString(vm);
3960 }
3961 return napi_clear_last_error(env);
3962 }
3963
napi_run_event_loop(napi_env env,napi_event_mode mode)3964 NAPI_EXTERN napi_status napi_run_event_loop(napi_env env, napi_event_mode mode)
3965 {
3966 CHECK_ENV(env);
3967
3968 if (mode < napi_event_mode_default || mode > napi_event_mode_nowait) {
3969 HILOG_ERROR("invalid mode %{public}d", static_cast<int32_t>(mode));
3970 return napi_status::napi_invalid_arg;
3971 }
3972
3973 auto nativeEngine = reinterpret_cast<NativeEngine*>(env);
3974 auto result = nativeEngine->RunEventLoop(mode);
3975 if (result != napi_status::napi_ok) {
3976 HILOG_ERROR("failed due to error %{public}d", static_cast<int32_t>(result));
3977 return napi_set_last_error(env, result);
3978 }
3979
3980 return napi_clear_last_error(env);
3981 }
3982
napi_stop_event_loop(napi_env env)3983 NAPI_EXTERN napi_status napi_stop_event_loop(napi_env env)
3984 {
3985 CHECK_ENV(env);
3986
3987 auto nativeEngine = reinterpret_cast<NativeEngine*>(env);
3988 auto result = nativeEngine->StopEventLoop();
3989 if (result != napi_status::napi_ok) {
3990 HILOG_ERROR("stop event loop failed due to error %{public}d", static_cast<int32_t>(result));
3991 return napi_set_last_error(env, result);
3992 }
3993 return napi_clear_last_error(env);
3994 }
3995
napi_create_ark_runtime(napi_env * env)3996 NAPI_EXTERN napi_status napi_create_ark_runtime(napi_env* env)
3997 {
3998 if (NativeCreateEnv::g_createNapiEnvCallback == nullptr) {
3999 HILOG_ERROR("invalid create callback");
4000 return napi_status::napi_invalid_arg;
4001 }
4002 napi_status result = NativeCreateEnv::g_createNapiEnvCallback(env);
4003 if (result == napi_ok) {
4004 auto vm = reinterpret_cast<NativeEngine*>(*env)->GetEcmaVm();
4005 panda::JSNApi::SetExecuteBufferMode(vm);
4006 }
4007 return result;
4008 }
4009
napi_destroy_ark_runtime(napi_env * env)4010 NAPI_EXTERN napi_status napi_destroy_ark_runtime(napi_env* env)
4011 {
4012 if (NativeCreateEnv::g_destroyNapiEnvCallback == nullptr) {
4013 HILOG_ERROR("invalid destroy callback");
4014 return napi_status::napi_invalid_arg;
4015 }
4016 return NativeCreateEnv::g_destroyNapiEnvCallback(env);
4017 }
4018
napi_is_concurrent_function(napi_env env,napi_value value,bool * result)4019 NAPI_EXTERN napi_status napi_is_concurrent_function(napi_env env, napi_value value, bool* result)
4020 {
4021 CHECK_ENV(env);
4022 CHECK_ARG(env, value);
4023 CHECK_ARG(env, result);
4024
4025 auto nativeValue = LocalValueFromJsValue(value);
4026 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
4027 panda::JsiFastNativeScope fastNativeScope(vm);
4028
4029 *result = nativeValue->IsConcurrentFunction(vm);
4030 return napi_clear_last_error(env);
4031 }
4032
napi_call_threadsafe_function_with_priority(napi_threadsafe_function func,void * data,napi_task_priority priority,bool isTail)4033 NAPI_EXTERN napi_status napi_call_threadsafe_function_with_priority(napi_threadsafe_function func,
4034 void *data,
4035 napi_task_priority priority,
4036 bool isTail)
4037 {
4038 CHECK_ENV(func);
4039
4040 if (priority < napi_priority_immediate || priority > napi_priority_idle) {
4041 HILOG_ERROR("invalid priority %{public}d", static_cast<int32_t>(priority));
4042 return napi_status::napi_invalid_arg;
4043 }
4044 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
4045 int32_t innerPriority = static_cast<int32_t>(priority);
4046 auto res = safeAsyncWork->PostTask(data, innerPriority, isTail);
4047 if (res != napi_ok) {
4048 HILOG_ERROR("post task failed due to error %{public}d", res);
4049 }
4050 return res;
4051 }
4052
napi_send_event(napi_env env,const std::function<void ()> cb,napi_event_priority priority)4053 NAPI_EXTERN napi_status napi_send_event(napi_env env, const std::function<void()> cb, napi_event_priority priority)
4054 {
4055 CHECK_ENV(env);
4056
4057 if (priority < napi_eprio_vip || priority > napi_eprio_idle) {
4058 HILOG_ERROR("invalid priority %{public}d", static_cast<int32_t>(priority));
4059 return napi_status::napi_invalid_arg;
4060 }
4061 NativeEngine *eng = reinterpret_cast<NativeEngine *>(env);
4062 if (NativeEngine::IsAlive(eng)) {
4063 return eng->SendEvent(cb, priority);
4064 } else {
4065 return napi_status::napi_closing;
4066 }
4067 }
4068
napi_open_fast_native_scope(napi_env env,napi_fast_native_scope * scope)4069 NAPI_EXTERN napi_status napi_open_fast_native_scope(napi_env env, napi_fast_native_scope* scope)
4070 {
4071 CHECK_ENV(env);
4072 CHECK_ARG(env, scope);
4073
4074 auto engine = reinterpret_cast<NativeEngine*>(env);
4075 *scope = reinterpret_cast<napi_fast_native_scope>(new panda::JsiFastNativeScope(engine->GetEcmaVm()));
4076 return napi_clear_last_error(env);
4077 }
4078
napi_close_fast_native_scope(napi_env env,napi_fast_native_scope scope)4079 NAPI_EXTERN napi_status napi_close_fast_native_scope(napi_env env, napi_fast_native_scope scope)
4080 {
4081 CHECK_ENV(env);
4082 CHECK_ARG(env, scope);
4083
4084 delete reinterpret_cast<panda::JsiFastNativeScope*>(scope);
4085 return napi_clear_last_error(env);
4086 }
4087
napi_get_shared_array_buffer_info(napi_env env,napi_value arraybuffer,void ** data,size_t * byte_length)4088 NAPI_EXTERN napi_status napi_get_shared_array_buffer_info(napi_env env,
4089 napi_value arraybuffer,
4090 void** data,
4091 size_t* byte_length)
4092 {
4093 CHECK_ENV(env);
4094 CHECK_ARG(env, arraybuffer);
4095 CHECK_ARG(env, byte_length);
4096
4097 auto nativeValue = LocalValueFromJsValue(arraybuffer);
4098 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
4099 panda::JsiFastNativeScope fastNativeScope(vm);
4100 if (LIKELY(nativeValue->IsSharedArrayBuffer(vm))) {
4101 Local<panda::ArrayBufferRef> res(nativeValue);
4102 if (data != nullptr) {
4103 *data = res->GetBuffer(vm);
4104 }
4105 *byte_length = res->ByteLength(vm);
4106 } else {
4107 return napi_set_last_error(env, napi_arraybuffer_expected);
4108 }
4109
4110 return napi_clear_last_error(env);
4111 }
4112
napi_is_bitvector(napi_env env,napi_value value,bool * result)4113 NAPI_EXTERN napi_status napi_is_bitvector(napi_env env, napi_value value, bool* result)
4114 {
4115 CHECK_ENV(env);
4116 CHECK_ARG(env, value);
4117 CHECK_ARG(env, result);
4118
4119 auto nativeValue = LocalValueFromJsValue(value);
4120 auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
4121 panda::JsiFastNativeScope fastNativeScope(vm);
4122
4123 *result = nativeValue->IsBitVector(vm);
4124
4125 return napi_clear_last_error(env);
4126 }
4127