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