1 /* 2 * Copyright (c) 2021 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 16 #include "jsnapi_helper-inl.h" 17 18 #include <array> 19 #include <cstdint> 20 21 #include "ecmascript/base/builtins_base.h" 22 #include "ecmascript/base/json_parser.h" 23 #include "ecmascript/base/json_stringifier.h" 24 #include "ecmascript/base/string_helper.h" 25 #include "ecmascript/base/typed_array_helper-inl.h" 26 #include "ecmascript/cpu_profiler/cpu_profiler.h" 27 #include "ecmascript/ecma_global_storage-inl.h" 28 #include "ecmascript/ecma_language_context.h" 29 #include "ecmascript/ecma_module.h" 30 #include "ecmascript/ecma_string.h" 31 #include "ecmascript/ecma_vm.h" 32 #include "ecmascript/global_env.h" 33 #include "ecmascript/internal_call_params.h" 34 #include "ecmascript/interpreter/fast_runtime_stub-inl.h" 35 #include "ecmascript/jobs/micro_job_queue.h" 36 #include "ecmascript/js_array.h" 37 #include "ecmascript/js_arraybuffer.h" 38 #include "ecmascript/js_bigint.h" 39 #include "ecmascript/js_dataview.h" 40 #include "ecmascript/js_function.h" 41 #include "ecmascript/js_map.h" 42 #include "ecmascript/js_primitive_ref.h" 43 #include "ecmascript/js_promise.h" 44 #include "ecmascript/js_regexp.h" 45 #include "ecmascript/js_runtime_options.h" 46 #include "ecmascript/js_serializer.h" 47 #include "ecmascript/js_set.h" 48 #include "ecmascript/js_tagged_number.h" 49 #include "ecmascript/js_thread.h" 50 #include "ecmascript/js_typed_array.h" 51 #include "ecmascript/mem/region.h" 52 #include "ecmascript/object_factory.h" 53 #include "ecmascript/tagged_array.h" 54 #include "generated/base_options.h" 55 #include "utils/pandargs.h" 56 57 #include "os/mutex.h" 58 59 namespace panda { 60 using ecmascript::CString; 61 using ecmascript::ECMAObject; 62 using ecmascript::EcmaString; 63 using ecmascript::ErrorType; 64 using ecmascript::FastRuntimeStub; 65 using ecmascript::GlobalEnv; 66 using ecmascript::GlobalEnvConstants; 67 using ecmascript::InternalCallParams; 68 using ecmascript::JSArray; 69 using ecmascript::JSArrayBuffer; 70 using ecmascript::JSDataView; 71 using ecmascript::JSDate; 72 using ecmascript::JSFunction; 73 using ecmascript::JSFunctionBase; 74 using ecmascript::JSHClass; 75 using ecmascript::JSMap; 76 using ecmascript::JSMethod; 77 using ecmascript::JSNativePointer; 78 using ecmascript::JSObject; 79 using ecmascript::JSPrimitiveRef; 80 using ecmascript::JSPromise; 81 using ecmascript::JSRegExp; 82 using ecmascript::JSSerializer; 83 using ecmascript::JSSet; 84 using ecmascript::JSSymbol; 85 using ecmascript::JSTaggedNumber; 86 using ecmascript::JSTaggedType; 87 using ecmascript::JSTaggedValue; 88 using ecmascript::JSThread; 89 using ecmascript::ObjectFactory; 90 using ecmascript::PromiseCapability; 91 using ecmascript::PropertyDescriptor; 92 using ecmascript::OperationResult; 93 using ecmascript::Region; 94 using ecmascript::TaggedArray; 95 using ecmascript::JSTypedArray; 96 using ecmascript::base::BuiltinsBase; 97 using ecmascript::base::JsonParser; 98 using ecmascript::base::JsonStringifier; 99 using ecmascript::base::StringHelper; 100 using ecmascript::base::TypedArrayHelper; 101 using ecmascript::job::MicroJobQueue; 102 using ecmascript::job::QueueType; 103 using ecmascript::JSRuntimeOptions; 104 using ecmascript::BigInt; 105 using ecmascript::CpuProfiler; 106 template<typename T> 107 using JSHandle = ecmascript::JSHandle<T>; 108 109 namespace { 110 // NOLINTNEXTLINE(fuchsia-statically-constructed-objects) 111 constexpr std::string_view ENTRY_POINTER = "_GLOBAL::func_main_0"; 112 } 113 114 int JSNApi::vmCount = 1; 115 static os::memory::Mutex mutex; 116 117 // ------------------------------------ Panda ----------------------------------------------- CreateRuntime(const RuntimeOption & option)118 bool JSNApi::CreateRuntime(const RuntimeOption &option) 119 { 120 JSRuntimeOptions runtimeOptions; 121 runtimeOptions.SetRuntimeType("ecmascript"); 122 123 // GC 124 runtimeOptions.SetGcType(option.GetGcType()); 125 runtimeOptions.SetRunGcInPlace(true); 126 runtimeOptions.SetArkProperties(option.GetArkProperties()); 127 // Mem 128 runtimeOptions.SetHeapSizeLimit(option.GetGcPoolSize()); 129 runtimeOptions.SetInternalAllocatorType("malloc"); 130 131 // Boot 132 runtimeOptions.SetShouldLoadBootPandaFiles(false); 133 runtimeOptions.SetShouldInitializeIntrinsics(false); 134 runtimeOptions.SetBootClassSpaces({"ecmascript"}); 135 136 // Dfx 137 base_options::Options baseOptions(""); 138 baseOptions.SetLogLevel(option.GetLogLevel()); 139 arg_list_t logComponents; 140 logComponents.emplace_back("all"); 141 baseOptions.SetLogComponents(logComponents); 142 Logger::Initialize(baseOptions); 143 if (option.GetLogBufPrint() != nullptr) { 144 Logger::SetMobileLogPrintEntryPointByPtr(reinterpret_cast<void *>(option.GetLogBufPrint())); 145 } 146 147 runtimeOptions.SetEnableArkTools(option.GetEnableArkTools()); 148 SetOptions(runtimeOptions); 149 static EcmaLanguageContext lcEcma; 150 if (!Runtime::Create(runtimeOptions, {&lcEcma})) { 151 std::cerr << "Error: cannot create runtime" << std::endl; 152 return false; 153 } 154 return true; 155 } 156 DestroyRuntime()157 bool JSNApi::DestroyRuntime() 158 { 159 return Runtime::Destroy(); 160 } 161 CreateJSVM(const RuntimeOption & option)162 EcmaVM *JSNApi::CreateJSVM(const RuntimeOption &option) 163 { 164 auto runtime = Runtime::GetCurrent(); 165 os::memory::LockHolder lock(mutex); 166 vmCount++; 167 if (runtime == nullptr) { 168 // Only Ark js app 169 if (!CreateRuntime(option)) { 170 vmCount = 0; 171 return nullptr; 172 } 173 vmCount--; 174 runtime = Runtime::GetCurrent(); 175 return EcmaVM::Cast(runtime->GetPandaVM()); 176 } 177 JSRuntimeOptions runtimeOptions; 178 runtimeOptions.SetArkProperties(option.GetArkProperties()); 179 // GC 180 runtimeOptions.SetGcTriggerType("no-gc-for-start-up"); // A non-production gc strategy. Prohibit stw-gc 10 times. 181 182 return EcmaVM::Cast(EcmaVM::Create(runtimeOptions)); 183 } 184 DestroyJSVM(EcmaVM * ecmaVm)185 void JSNApi::DestroyJSVM(EcmaVM *ecmaVm) 186 { 187 auto runtime = Runtime::GetCurrent(); 188 if (runtime != nullptr) { 189 os::memory::LockHolder lock(mutex); 190 vmCount--; 191 PandaVM *mainVm = runtime->GetPandaVM(); 192 // Only Ark js app 193 if (mainVm != ecmaVm) { 194 EcmaVM::Destroy(ecmaVm); 195 } 196 197 if (vmCount <= 0) { 198 DestroyRuntime(); 199 } 200 } 201 } 202 TriggerGC(const EcmaVM * vm,TRIGGER_GC_TYPE gcType)203 void JSNApi::TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType) 204 { 205 if (vm->GetJSThread() != nullptr && vm->IsInitialized()) { 206 switch (gcType) { 207 case TRIGGER_GC_TYPE::SEMI_GC: 208 vm->CollectGarbage(ecmascript::TriggerGCType::SEMI_GC); 209 break; 210 case TRIGGER_GC_TYPE::OLD_GC: 211 vm->CollectGarbage(ecmascript::TriggerGCType::OLD_GC); 212 break; 213 case TRIGGER_GC_TYPE::FULL_GC: 214 vm->CollectGarbage(ecmascript::TriggerGCType::FULL_GC); 215 break; 216 default: 217 break; 218 } 219 } 220 } 221 ThrowException(const EcmaVM * vm,Local<JSValueRef> error)222 void JSNApi::ThrowException(const EcmaVM *vm, Local<JSValueRef> error) 223 { 224 auto thread = vm->GetJSThread(); 225 thread->SetException(JSNApiHelper::ToJSTaggedValue(*error)); 226 } 227 StartDebugger(const char * libraryPath,EcmaVM * vm,bool isDebugMode,int32_t instanceId,const DebuggerPostTask & debuggerPostTask)228 bool JSNApi::StartDebugger(const char *libraryPath, EcmaVM *vm, bool isDebugMode, int32_t instanceId, 229 const DebuggerPostTask &debuggerPostTask) 230 { 231 if (vm->GetJsDebuggerManager()->GetDebuggerHandler() != nullptr) { 232 return false; 233 } 234 235 auto handle = panda::os::library_loader::Load(std::string(libraryPath)); 236 if (!handle) { 237 return false; 238 } 239 using StartDebugger = bool (*)(const std::string &, EcmaVM *, bool, int32_t, const DebuggerPostTask &); 240 241 auto sym = panda::os::library_loader::ResolveSymbol(handle.Value(), "StartDebug"); 242 if (!sym) { 243 LOG(ERROR, RUNTIME) << sym.Error().ToString(); 244 return false; 245 } 246 247 bool ret = reinterpret_cast<StartDebugger>(sym.Value())("PandaDebugger", vm, isDebugMode, instanceId, 248 debuggerPostTask); 249 if (ret) { 250 vm->GetJsDebuggerManager()->SetDebugMode(isDebugMode); 251 vm->GetJsDebuggerManager()->SetDebugLibraryHandle(std::move(handle.Value())); 252 } 253 return ret; 254 } 255 StopDebugger(EcmaVM * vm)256 bool JSNApi::StopDebugger(EcmaVM *vm) 257 { 258 if (vm == nullptr) { 259 return false; 260 } 261 262 const auto &handle = vm->GetJsDebuggerManager()->GetDebugLibraryHandle(); 263 using StopDebug = void (*)(const std::string &); 264 265 auto sym = panda::os::library_loader::ResolveSymbol(handle, "StopDebug"); 266 if (!sym) { 267 LOG(ERROR, RUNTIME) << sym.Error().ToString(); 268 return false; 269 } 270 271 reinterpret_cast<StopDebug>(sym.Value())("PandaDebugger"); 272 vm->GetJsDebuggerManager()->SetDebugMode(false); 273 return true; 274 } 275 Execute(EcmaVM * vm,const std::string & fileName,const std::string & entry)276 bool JSNApi::Execute(EcmaVM *vm, const std::string &fileName, const std::string &entry) 277 { 278 std::vector<std::string> argv; 279 LOG_ECMA(DEBUG) << "start to execute ark file" << fileName; 280 if (!vm->ExecuteFromPf(fileName, entry, argv)) { 281 LOG_ECMA(ERROR) << "Cannot execute ark file '" << fileName 282 << "' with entry '" << entry << "'" << std::endl; 283 return false; 284 } 285 return true; 286 } 287 Execute(EcmaVM * vm,const uint8_t * data,int32_t size,const std::string & entry,const std::string & filename)288 bool JSNApi::Execute(EcmaVM *vm, const uint8_t *data, int32_t size, 289 const std::string &entry, const std::string &filename) 290 { 291 std::vector<std::string> argv; 292 if (!vm->ExecuteFromBuffer(data, size, entry, argv, filename)) { 293 LOG_ECMA(ERROR) << "Cannot execute ark buffer file '" << filename 294 << "' with entry '" << entry << "'" << std::endl; 295 return false; 296 } 297 return true; 298 } 299 GetUncaughtException(const EcmaVM * vm)300 Local<ObjectRef> JSNApi::GetUncaughtException(const EcmaVM *vm) 301 { 302 return JSNApiHelper::ToLocal<ObjectRef>(vm->GetEcmaUncaughtException()); 303 } 304 GetAndClearUncaughtException(const EcmaVM * vm)305 Local<ObjectRef> JSNApi::GetAndClearUncaughtException(const EcmaVM *vm) 306 { 307 return JSNApiHelper::ToLocal<ObjectRef>(vm->GetAndClearEcmaUncaughtException()); 308 } 309 EnableUserUncaughtErrorHandler(EcmaVM * vm)310 void JSNApi::EnableUserUncaughtErrorHandler(EcmaVM *vm) 311 { 312 return vm->EnableUserUncaughtErrorHandler(); 313 } 314 GetGlobalObject(const EcmaVM * vm)315 Local<ObjectRef> JSNApi::GetGlobalObject(const EcmaVM *vm) 316 { 317 JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv(); 318 JSHandle<JSTaggedValue> global(vm->GetJSThread(), globalEnv->GetGlobalObject()); 319 return JSNApiHelper::ToLocal<ObjectRef>(global); 320 } 321 ExecutePendingJob(const EcmaVM * vm)322 void JSNApi::ExecutePendingJob(const EcmaVM *vm) 323 { 324 vm->ExecutePromisePendingJob(); 325 } 326 GetHandleAddr(const EcmaVM * vm,uintptr_t localAddress)327 uintptr_t JSNApi::GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress) 328 { 329 if (localAddress == 0) { 330 return 0; 331 } 332 JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(localAddress)); 333 return ecmascript::EcmaHandleScope::NewHandle(vm->GetJSThread(), value); 334 } 335 GetGlobalHandleAddr(const EcmaVM * vm,uintptr_t localAddress)336 uintptr_t JSNApi::GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress) 337 { 338 if (localAddress == 0) { 339 return 0; 340 } 341 JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(localAddress)); 342 return vm->GetJSThread()->GetEcmaGlobalStorage()->NewGlobalHandle(value); 343 } 344 SetWeak(const EcmaVM * vm,uintptr_t localAddress)345 uintptr_t JSNApi::SetWeak(const EcmaVM *vm, uintptr_t localAddress) 346 { 347 if (localAddress == 0) { 348 return 0; 349 } 350 return vm->GetJSThread()->GetEcmaGlobalStorage()->SetWeak(localAddress); 351 } 352 ClearWeak(const EcmaVM * vm,uintptr_t localAddress)353 uintptr_t JSNApi::ClearWeak(const EcmaVM *vm, uintptr_t localAddress) 354 { 355 if (localAddress == 0) { 356 return 0; 357 } 358 if (JSTaggedValue(reinterpret_cast<ecmascript::EcmaGlobalStorage::Node *>(localAddress)->GetObject()) 359 .IsUndefined()) { 360 LOG(ERROR, RUNTIME) << "The object of weak reference has been recycled!"; 361 return 0; 362 } 363 return vm->GetJSThread()->GetEcmaGlobalStorage()->ClearWeak(localAddress); 364 } 365 IsWeak(const EcmaVM * vm,uintptr_t localAddress)366 bool JSNApi::IsWeak(const EcmaVM *vm, uintptr_t localAddress) 367 { 368 if (localAddress == 0) { 369 return false; 370 } 371 return vm->GetJSThread()->GetEcmaGlobalStorage()->IsWeak(localAddress); 372 } 373 DisposeGlobalHandleAddr(const EcmaVM * vm,uintptr_t addr)374 void JSNApi::DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr) 375 { 376 if (addr == 0) { 377 return; 378 } 379 vm->GetJSThread()->GetEcmaGlobalStorage()->DisposeGlobalHandle(addr); 380 } 381 SerializeValue(const EcmaVM * vm,Local<JSValueRef> value,Local<JSValueRef> transfer)382 void *JSNApi::SerializeValue(const EcmaVM *vm, Local<JSValueRef> value, Local<JSValueRef> transfer) 383 { 384 ecmascript::JSThread *thread = vm->GetJSThread(); 385 ecmascript::Serializer serializer(thread); 386 JSHandle<JSTaggedValue> arkValue = JSNApiHelper::ToJSHandle(value); 387 JSHandle<JSTaggedValue> arkTransfer = JSNApiHelper::ToJSHandle(transfer); 388 std::unique_ptr<ecmascript::SerializationData> data; 389 if (serializer.WriteValue(thread, arkValue, arkTransfer)) { 390 data = serializer.Release(); 391 } 392 return reinterpret_cast<void *>(data.release()); 393 } 394 DeserializeValue(const EcmaVM * vm,void * recoder)395 Local<JSValueRef> JSNApi::DeserializeValue(const EcmaVM *vm, void *recoder) 396 { 397 ecmascript::JSThread *thread = vm->GetJSThread(); 398 std::unique_ptr<ecmascript::SerializationData> data(reinterpret_cast<ecmascript::SerializationData *>(recoder)); 399 ecmascript::Deserializer deserializer(thread, data.release()); 400 JSHandle<JSTaggedValue> result = deserializer.ReadValue(); 401 return JSNApiHelper::ToLocal<ObjectRef>(result); 402 } 403 DeleteSerializationData(void * data)404 void JSNApi::DeleteSerializationData(void *data) 405 { 406 ecmascript::SerializationData *value = reinterpret_cast<ecmascript::SerializationData *>(data); 407 delete value; 408 } 409 HostPromiseRejectionTracker(const EcmaVM * vm,const JSHandle<JSPromise> promise,const JSHandle<JSTaggedValue> reason,const ecmascript::PromiseRejectionEvent operation,void * data)410 void HostPromiseRejectionTracker(const EcmaVM *vm, 411 const JSHandle<JSPromise> promise, 412 const JSHandle<JSTaggedValue> reason, 413 const ecmascript::PromiseRejectionEvent operation, 414 void* data) 415 { 416 ecmascript::PromiseRejectCallback promiseRejectCallback = vm->GetPromiseRejectCallback(); 417 if (promiseRejectCallback != nullptr) { 418 Local<JSValueRef> promiseVal = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>::Cast(promise)); 419 PromiseRejectInfo promiseRejectInfo(promiseVal, JSNApiHelper::ToLocal<JSValueRef>(reason), 420 static_cast<PromiseRejectInfo::PROMISE_REJECTION_EVENT>(operation), data); 421 promiseRejectCallback(reinterpret_cast<void*>(&promiseRejectInfo)); 422 } 423 } 424 SetHostPromiseRejectionTracker(EcmaVM * vm,void * cb,void * data)425 void JSNApi::SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data) 426 { 427 vm->SetHostPromiseRejectionTracker(HostPromiseRejectionTracker); 428 vm->SetPromiseRejectCallback(reinterpret_cast<ecmascript::PromiseRejectCallback>(cb)); 429 vm->SetData(data); 430 } 431 SetHostEnqueueJob(const EcmaVM * vm,Local<JSValueRef> cb)432 void JSNApi::SetHostEnqueueJob(const EcmaVM *vm, Local<JSValueRef> cb) 433 { 434 JSHandle<JSFunction> fun = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(cb)); 435 JSHandle<TaggedArray> array = vm->GetFactory()->EmptyArray(); 436 JSHandle<MicroJobQueue> job = vm->GetMicroJobQueue(); 437 MicroJobQueue::EnqueueJob(vm->GetJSThread(), job, QueueType::QUEUE_PROMISE, fun, array); 438 } 439 PromiseRejectInfo(Local<JSValueRef> promise,Local<JSValueRef> reason,PromiseRejectInfo::PROMISE_REJECTION_EVENT operation,void * data)440 PromiseRejectInfo::PromiseRejectInfo(Local<JSValueRef> promise, Local<JSValueRef> reason, 441 PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data) 442 : promise_(promise), reason_(reason), operation_(operation), data_(data) {} 443 GetPromise() const444 Local<JSValueRef> PromiseRejectInfo::GetPromise() const 445 { 446 return promise_; 447 } 448 GetReason() const449 Local<JSValueRef> PromiseRejectInfo::GetReason() const 450 { 451 return reason_; 452 } 453 GetOperation() const454 PromiseRejectInfo::PROMISE_REJECTION_EVENT PromiseRejectInfo::GetOperation() const 455 { 456 return operation_; 457 } 458 GetData() const459 void* PromiseRejectInfo::GetData() const 460 { 461 return data_; 462 } 463 ExecuteModuleFromBuffer(EcmaVM * vm,const void * data,int32_t size,const std::string & file)464 bool JSNApi::ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file) 465 { 466 auto moduleManager = vm->GetModuleManager(); 467 moduleManager->SetCurrentExportModuleName(file); 468 // Update Current Module 469 std::vector<std::string> argv; 470 if (!vm->ExecuteFromBuffer(data, size, ENTRY_POINTER, argv)) { 471 std::cerr << "Cannot execute panda file from memory" << std::endl; 472 moduleManager->RestoreCurrentExportModuleName(); 473 return false; 474 } 475 476 // Restore Current Module 477 moduleManager->RestoreCurrentExportModuleName(); 478 return true; 479 } 480 GetExportObject(EcmaVM * vm,const std::string & file,const std::string & itemName)481 Local<ObjectRef> JSNApi::GetExportObject(EcmaVM *vm, const std::string &file, const std::string &itemName) 482 { 483 auto moduleManager = vm->GetModuleManager(); 484 ObjectFactory *factory = vm->GetFactory(); 485 JSHandle<JSTaggedValue> moduleName(factory->NewFromStdStringUnCheck(file, true)); 486 JSHandle<JSTaggedValue> moduleObj = moduleManager->GetModule(vm->GetJSThread(), moduleName); 487 JSHandle<JSTaggedValue> itemString(factory->NewFromStdString(itemName)); 488 JSHandle<JSTaggedValue> exportObj = moduleManager->GetModuleItem(vm->GetJSThread(), moduleObj, itemString); 489 return JSNApiHelper::ToLocal<ObjectRef>(exportObj); 490 } 491 SetOptions(const ecmascript::JSRuntimeOptions & options)492 void JSNApi::SetOptions(const ecmascript::JSRuntimeOptions &options) 493 { 494 ecmascript::EcmaVM::options_ = options; 495 } 496 // ----------------------------------- HandleScope ------------------------------------- LocalScope(const EcmaVM * vm)497 LocalScope::LocalScope(const EcmaVM *vm) : thread_(vm->GetJSThread()) 498 { 499 auto thread = reinterpret_cast<JSThread *>(thread_); 500 prevNext_ = thread->GetHandleScopeStorageNext(); 501 prevEnd_ = thread->GetHandleScopeStorageEnd(); 502 prevHandleStorageIndex_ = thread->GetCurrentHandleStorageIndex(); 503 thread->HandleScopeCountAdd(); 504 } 505 LocalScope(const EcmaVM * vm,JSTaggedType value)506 LocalScope::LocalScope(const EcmaVM *vm, JSTaggedType value) : thread_(vm->GetJSThread()) 507 { 508 auto thread = reinterpret_cast<JSThread *>(thread_); 509 ecmascript::EcmaHandleScope::NewHandle(thread, value); 510 prevNext_ = thread->GetHandleScopeStorageNext(); 511 prevEnd_ = thread->GetHandleScopeStorageEnd(); 512 prevHandleStorageIndex_ = thread->GetCurrentHandleStorageIndex(); 513 thread->HandleScopeCountAdd(); 514 } 515 ~LocalScope()516 LocalScope::~LocalScope() 517 { 518 auto thread = reinterpret_cast<JSThread *>(thread_); 519 thread->HandleScopeCountDec(); 520 thread->SetHandleScopeStorageNext(static_cast<JSTaggedType *>(prevNext_)); 521 if (thread->GetHandleScopeStorageEnd() != prevEnd_) { 522 thread->SetHandleScopeStorageEnd(static_cast<JSTaggedType *>(prevEnd_)); 523 thread->ShrinkHandleStorage(prevHandleStorageIndex_); 524 } 525 } 526 527 // ----------------------------------- EscapeLocalScope ------------------------------ EscapeLocalScope(const EcmaVM * vm)528 EscapeLocalScope::EscapeLocalScope(const EcmaVM *vm) : LocalScope(vm, 0U) 529 { 530 auto thread = vm->GetJSThread(); 531 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 532 escapeHandle_ = ToUintPtr(thread->GetHandleScopeStorageNext() - 1); 533 } 534 535 // ----------------------------------- NumberRef --------------------------------------- New(const EcmaVM * vm,double input)536 Local<NumberRef> NumberRef::New(const EcmaVM *vm, double input) 537 { 538 JSThread *thread = vm->GetJSThread(); 539 JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input)); 540 return JSNApiHelper::ToLocal<NumberRef>(number); 541 } 542 New(const EcmaVM * vm,int32_t input)543 Local<NumberRef> NumberRef::New(const EcmaVM *vm, int32_t input) 544 { 545 JSThread *thread = vm->GetJSThread(); 546 JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input)); 547 return JSNApiHelper::ToLocal<NumberRef>(number); 548 } 549 New(const EcmaVM * vm,uint32_t input)550 Local<NumberRef> NumberRef::New(const EcmaVM *vm, uint32_t input) 551 { 552 JSThread *thread = vm->GetJSThread(); 553 JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input)); 554 return JSNApiHelper::ToLocal<NumberRef>(number); 555 } 556 New(const EcmaVM * vm,int64_t input)557 Local<NumberRef> NumberRef::New(const EcmaVM *vm, int64_t input) 558 { 559 JSThread *thread = vm->GetJSThread(); 560 JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input)); 561 return JSNApiHelper::ToLocal<NumberRef>(number); 562 } 563 Value()564 double NumberRef::Value() 565 { 566 return JSTaggedNumber(JSNApiHelper::ToJSTaggedValue(this)).GetNumber(); 567 } 568 569 // ----------------------------------- BigIntRef --------------------------------------- New(const EcmaVM * vm,uint64_t input)570 Local<BigIntRef> BigIntRef::New(const EcmaVM *vm, uint64_t input) 571 { 572 JSThread *thread = vm->GetJSThread(); 573 JSHandle<BigInt> big = BigInt::Uint64ToBigInt(thread, input); 574 JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big); 575 return JSNApiHelper::ToLocal<BigIntRef>(bigint); 576 } 577 New(const EcmaVM * vm,int64_t input)578 Local<BigIntRef> BigIntRef::New(const EcmaVM *vm, int64_t input) 579 { 580 JSThread *thread = vm->GetJSThread(); 581 JSHandle<BigInt> big = BigInt::Int64ToBigInt(thread, input); 582 JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big); 583 return JSNApiHelper::ToLocal<BigIntRef>(bigint); 584 } 585 CreateBigWords(const EcmaVM * vm,bool sign,uint32_t size,const uint64_t * words)586 Local<JSValueRef> BigIntRef::CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words) 587 { 588 JSThread *thread = vm->GetJSThread(); 589 JSHandle<BigInt> big = BigInt::CreateBigWords(thread, sign, size, words); 590 JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big); 591 return JSNApiHelper::ToLocal<JSValueRef>(bigint); 592 } 593 BigIntToInt64(const EcmaVM * vm,int64_t * cValue,bool * lossless)594 void BigIntRef::BigIntToInt64(const EcmaVM *vm, int64_t *cValue, bool *lossless) 595 { 596 JSThread *thread = vm->GetJSThread(); 597 JSHandle<JSTaggedValue> bigintVal(JSNApiHelper::ToJSHandle(this)); 598 BigInt::BigIntToInt64(thread, bigintVal, cValue, lossless); 599 } 600 BigIntToUint64(const EcmaVM * vm,uint64_t * cValue,bool * lossless)601 void BigIntRef::BigIntToUint64(const EcmaVM *vm, uint64_t *cValue, bool *lossless) 602 { 603 JSThread *thread = vm->GetJSThread(); 604 JSHandle<JSTaggedValue> bigintVal(JSNApiHelper::ToJSHandle(this)); 605 BigInt::BigIntToUint64(thread, bigintVal, cValue, lossless); 606 } 607 GetWordsArray(bool * signBit,size_t wordCount,uint64_t * words)608 void BigIntRef::GetWordsArray(bool* signBit, size_t wordCount, uint64_t* words) 609 { 610 JSHandle<BigInt> bigintVal(JSNApiHelper::ToJSHandle(this)); 611 uint32_t len = bigintVal->GetLength(); 612 uint32_t count = 0; 613 uint32_t index = 0; 614 for (; index < wordCount - 1; ++index) { 615 words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++)); 616 words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits 617 } 618 if (len % 2 == 0) { // 2 : len is odd or even 619 words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++)); 620 words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits 621 } else { 622 words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++)); 623 } 624 *signBit = bigintVal->GetSign(); 625 } 626 GetWordsArraySize()627 uint32_t BigIntRef::GetWordsArraySize() 628 { 629 JSHandle<BigInt> bigintVal(JSNApiHelper::ToJSHandle(this)); 630 uint32_t len = bigintVal->GetLength(); 631 return len % 2 != 0 ? len / 2 + 1 : len / 2; // 2 : len is odd or even 632 } 633 634 // ----------------------------------- BooleanRef --------------------------------------- New(const EcmaVM * vm,bool input)635 Local<BooleanRef> BooleanRef::New(const EcmaVM *vm, bool input) 636 { 637 JSThread *thread = vm->GetJSThread(); 638 JSHandle<JSTaggedValue> boolean(thread, JSTaggedValue(input)); 639 return JSNApiHelper::ToLocal<BooleanRef>(boolean); 640 } 641 Value()642 bool BooleanRef::Value() 643 { 644 return JSNApiHelper::ToJSTaggedValue(this).IsTrue(); 645 } 646 647 // ----------------------------------- IntegerRef --------------------------------------- New(const EcmaVM * vm,int input)648 Local<IntegerRef> IntegerRef::New(const EcmaVM *vm, int input) 649 { 650 JSThread *thread = vm->GetJSThread(); 651 JSHandle<JSTaggedValue> integer(thread, JSTaggedValue(input)); 652 return JSNApiHelper::ToLocal<IntegerRef>(integer); 653 } 654 NewFromUnsigned(const EcmaVM * vm,unsigned int input)655 Local<IntegerRef> IntegerRef::NewFromUnsigned(const EcmaVM *vm, unsigned int input) 656 { 657 JSThread *thread = vm->GetJSThread(); 658 JSHandle<JSTaggedValue> integer(thread, JSTaggedValue(input)); 659 return JSNApiHelper::ToLocal<IntegerRef>(integer); 660 } 661 Value()662 int IntegerRef::Value() 663 { 664 return JSNApiHelper::ToJSTaggedValue(this).GetInt(); 665 } 666 667 // ----------------------------------- StringRef ---------------------------------------- NewFromUtf8(const EcmaVM * vm,const char * utf8,int length)668 Local<StringRef> StringRef::NewFromUtf8(const EcmaVM *vm, const char *utf8, int length) 669 { 670 ObjectFactory *factory = vm->GetFactory(); 671 if (length < 0) { 672 JSHandle<JSTaggedValue> current(factory->NewFromString(utf8)); 673 return JSNApiHelper::ToLocal<StringRef>(current); 674 } 675 JSHandle<JSTaggedValue> current(factory->NewFromUtf8(reinterpret_cast<const uint8_t *>(utf8), length)); 676 return JSNApiHelper::ToLocal<StringRef>(current); 677 } 678 ToString()679 std::string StringRef::ToString() 680 { 681 return StringHelper::ToStdString(EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())); 682 } 683 Length()684 int32_t StringRef::Length() 685 { 686 return EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetLength(); 687 } 688 Utf8Length()689 int32_t StringRef::Utf8Length() 690 { 691 return EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetUtf8Length(); 692 } 693 WriteUtf8(char * buffer,int length)694 int StringRef::WriteUtf8(char *buffer, int length) 695 { 696 return EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject()) 697 ->CopyDataUtf8(reinterpret_cast<uint8_t *>(buffer), length); 698 } 699 700 // ----------------------------------- SymbolRef ----------------------------------------- New(const EcmaVM * vm,Local<StringRef> description)701 Local<SymbolRef> SymbolRef::New(const EcmaVM *vm, Local<StringRef> description) 702 { 703 ObjectFactory *factory = vm->GetFactory(); 704 JSHandle<JSSymbol> symbol = factory->NewJSSymbol(); 705 JSTaggedValue desc = JSNApiHelper::ToJSTaggedValue(*description); 706 symbol->SetDescription(vm->GetJSThread(), desc); 707 return JSNApiHelper::ToLocal<SymbolRef>(JSHandle<JSTaggedValue>(symbol)); 708 } 709 GetDescription(const EcmaVM * vm)710 Local<StringRef> SymbolRef::GetDescription(const EcmaVM *vm) 711 { 712 JSTaggedValue description = JSSymbol::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetDescription(); 713 if (!description.IsString()) { 714 auto constants = vm->GetJSThread()->GlobalConstants(); 715 return JSNApiHelper::ToLocal<StringRef>(constants->GetHandledEmptyString()); 716 } 717 JSHandle<JSTaggedValue> descriptionHandle(vm->GetJSThread(), description); 718 return JSNApiHelper::ToLocal<StringRef>(descriptionHandle); 719 } 720 721 // -------------------------------- NativePointerRef ------------------------------------ New(const EcmaVM * vm,void * nativePointer)722 Local<NativePointerRef> NativePointerRef::New(const EcmaVM *vm, void *nativePointer) 723 { 724 ObjectFactory *factory = vm->GetFactory(); 725 JSHandle<JSNativePointer> obj = factory->NewJSNativePointer(nativePointer); 726 return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj)); 727 } 728 New(const EcmaVM * vm,void * nativePointer,NativePointerCallback callBack,void * data)729 Local<NativePointerRef> NativePointerRef::New( 730 const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, void *data) 731 { 732 ObjectFactory *factory = vm->GetFactory(); 733 JSHandle<JSNativePointer> obj = factory->NewJSNativePointer(nativePointer, callBack, data); 734 return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj)); 735 } 736 Value()737 void *NativePointerRef::Value() 738 { 739 JSHandle<JSTaggedValue> nativePointer = JSNApiHelper::ToJSHandle(this); 740 return JSHandle<JSNativePointer>(nativePointer)->GetExternalPointer(); 741 } 742 743 // ----------------------------------- ObjectRef ---------------------------------------- New(const EcmaVM * vm)744 Local<ObjectRef> ObjectRef::New(const EcmaVM *vm) 745 { 746 ObjectFactory *factory = vm->GetFactory(); 747 JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv(); 748 JSHandle<JSTaggedValue> constructor = globalEnv->GetObjectFunction(); 749 JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor)); 750 RETURN_VALUE_IF_ABRUPT(vm->GetJSThread(), JSValueRef::Exception(vm)); 751 return JSNApiHelper::ToLocal<ObjectRef>(object); 752 } 753 Set(const EcmaVM * vm,Local<JSValueRef> key,Local<JSValueRef> value)754 bool ObjectRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value) 755 { 756 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 757 JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key); 758 JSHandle<JSTaggedValue> valueValue = JSNApiHelper::ToJSHandle(value); 759 bool result = JSTaggedValue::SetProperty(vm->GetJSThread(), obj, keyValue, valueValue); 760 RETURN_VALUE_IF_ABRUPT(vm->GetJSThread(), false); 761 return result; 762 } 763 Set(const EcmaVM * vm,uint32_t key,Local<JSValueRef> value)764 bool ObjectRef::Set(const EcmaVM *vm, uint32_t key, Local<JSValueRef> value) 765 { 766 Local<JSValueRef> keyValue = NumberRef::New(vm, key); 767 return Set(vm, keyValue, value); 768 } 769 SetAccessorProperty(const EcmaVM * vm,Local<JSValueRef> key,Local<FunctionRef> getter,Local<FunctionRef> setter,PropertyAttribute attribute)770 bool ObjectRef::SetAccessorProperty(const EcmaVM *vm, Local<JSValueRef> key, Local<FunctionRef> getter, 771 Local<FunctionRef> setter, PropertyAttribute attribute) 772 { 773 JSThread *thread = vm->GetJSThread(); 774 JSHandle<JSTaggedValue> getterValue = JSNApiHelper::ToJSHandle(getter); 775 JSHandle<JSTaggedValue> setterValue = JSNApiHelper::ToJSHandle(setter); 776 PropertyDescriptor desc(thread, attribute.IsWritable(), attribute.IsEnumerable(), attribute.IsConfigurable()); 777 desc.SetValue(JSNApiHelper::ToJSHandle(attribute.GetValue(vm))); 778 desc.SetSetter(setterValue); 779 desc.SetGetter(getterValue); 780 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 781 JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key); 782 bool result = JSTaggedValue::DefineOwnProperty(thread, obj, keyValue, desc); 783 RETURN_VALUE_IF_ABRUPT(thread, false); 784 return result; 785 } 786 Get(const EcmaVM * vm,Local<JSValueRef> key)787 Local<JSValueRef> ObjectRef::Get(const EcmaVM *vm, Local<JSValueRef> key) 788 { 789 JSThread *thread = vm->GetJSThread(); 790 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 791 JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key); 792 OperationResult ret = JSTaggedValue::GetProperty(thread, obj, keyValue); 793 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 794 if (!ret.GetPropertyMetaData().IsFound()) { 795 return JSValueRef::Undefined(vm); 796 } 797 return JSNApiHelper::ToLocal<JSValueRef>(ret.GetValue()); 798 } 799 Get(const EcmaVM * vm,int32_t key)800 Local<JSValueRef> ObjectRef::Get(const EcmaVM *vm, int32_t key) 801 { 802 Local<JSValueRef> keyValue = IntegerRef::New(vm, key); 803 return Get(vm, keyValue); 804 } 805 GetOwnProperty(const EcmaVM * vm,Local<JSValueRef> key,PropertyAttribute & property)806 bool ObjectRef::GetOwnProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute &property) 807 { 808 JSThread *thread = vm->GetJSThread(); 809 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 810 JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key); 811 PropertyDescriptor desc(thread); 812 bool ret = JSObject::GetOwnProperty(thread, JSHandle<JSObject>(obj), keyValue, desc); 813 if (!ret) { 814 return false; 815 } 816 property.SetValue(JSNApiHelper::ToLocal<JSValueRef>(desc.GetValue())); 817 if (desc.HasGetter()) { 818 property.SetGetter(JSNApiHelper::ToLocal<JSValueRef>(desc.GetGetter())); 819 } 820 if (desc.HasSetter()) { 821 property.SetSetter(JSNApiHelper::ToLocal<JSValueRef>(desc.GetSetter())); 822 } 823 if (desc.HasWritable()) { 824 property.SetWritable(desc.IsWritable()); 825 } 826 if (desc.HasEnumerable()) { 827 property.SetEnumerable(desc.IsEnumerable()); 828 } 829 if (desc.HasConfigurable()) { 830 property.SetConfigurable(desc.IsConfigurable()); 831 } 832 833 return true; 834 } 835 GetOwnPropertyNames(const EcmaVM * vm)836 Local<ArrayRef> ObjectRef::GetOwnPropertyNames(const EcmaVM *vm) 837 { 838 JSThread *thread = vm->GetJSThread(); 839 JSHandle<JSTaggedValue> obj(JSNApiHelper::ToJSHandle(this)); 840 JSHandle<TaggedArray> array(JSTaggedValue::GetOwnPropertyKeys(thread, obj)); 841 JSHandle<JSTaggedValue> jsArray(JSArray::CreateArrayFromList(thread, array)); 842 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 843 return JSNApiHelper::ToLocal<ArrayRef>(jsArray); 844 } 845 GetOwnEnumerablePropertyNames(const EcmaVM * vm)846 Local<ArrayRef> ObjectRef::GetOwnEnumerablePropertyNames(const EcmaVM *vm) 847 { 848 JSThread *thread = vm->GetJSThread(); 849 JSHandle<JSObject> obj(JSNApiHelper::ToJSHandle(this)); 850 JSHandle<TaggedArray> array(JSObject::EnumerableOwnNames(thread, obj)); 851 JSHandle<JSTaggedValue> jsArray(JSArray::CreateArrayFromList(thread, array)); 852 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 853 return JSNApiHelper::ToLocal<ArrayRef>(jsArray); 854 } 855 GetPrototype(const EcmaVM * vm)856 Local<JSValueRef> ObjectRef::GetPrototype(const EcmaVM *vm) 857 { 858 JSThread *thread = vm->GetJSThread(); 859 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this)); 860 JSHandle<JSTaggedValue> prototype(thread, object->GetPrototype(thread)); 861 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 862 return JSNApiHelper::ToLocal<JSValueRef>(prototype); 863 } 864 DefineProperty(const EcmaVM * vm,Local<JSValueRef> key,PropertyAttribute attribute)865 bool ObjectRef::DefineProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute attribute) 866 { 867 JSThread *thread = vm->GetJSThread(); 868 JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this)); 869 JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key)); 870 PropertyDescriptor desc(thread, attribute.IsWritable(), attribute.IsEnumerable(), attribute.IsConfigurable()); 871 desc.SetValue(JSNApiHelper::ToJSHandle(attribute.GetValue(vm))); 872 bool result = object->DefinePropertyOrThrow(thread, object, keyValue, desc); 873 RETURN_VALUE_IF_ABRUPT(thread, false); 874 return result; 875 } 876 Has(const EcmaVM * vm,Local<JSValueRef> key)877 bool ObjectRef::Has(const EcmaVM *vm, Local<JSValueRef> key) 878 { 879 JSThread *thread = vm->GetJSThread(); 880 JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this)); 881 JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key)); 882 bool result = object->HasProperty(thread, object, keyValue); 883 RETURN_VALUE_IF_ABRUPT(thread, false); 884 return result; 885 } 886 Has(const EcmaVM * vm,uint32_t key)887 bool ObjectRef::Has(const EcmaVM *vm, uint32_t key) 888 { 889 JSThread *thread = vm->GetJSThread(); 890 JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this)); 891 bool result = object->HasProperty(thread, object, key); 892 RETURN_VALUE_IF_ABRUPT(thread, false); 893 return result; 894 } 895 Delete(const EcmaVM * vm,Local<JSValueRef> key)896 bool ObjectRef::Delete(const EcmaVM *vm, Local<JSValueRef> key) 897 { 898 JSThread *thread = vm->GetJSThread(); 899 JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this)); 900 JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key)); 901 bool result = object->DeleteProperty(thread, object, keyValue); 902 RETURN_VALUE_IF_ABRUPT(thread, false); 903 return result; 904 } 905 Delete(const EcmaVM * vm,uint32_t key)906 bool ObjectRef::Delete(const EcmaVM *vm, uint32_t key) 907 { 908 JSThread *thread = vm->GetJSThread(); 909 JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this)); 910 JSHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue(key)); 911 bool result = object->DeleteProperty(thread, object, keyHandle); 912 RETURN_VALUE_IF_ABRUPT(thread, false); 913 return result; 914 } 915 SetNativePointerFieldCount(int32_t count)916 void ObjectRef::SetNativePointerFieldCount(int32_t count) 917 { 918 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this)); 919 object->SetNativePointerFieldCount(count); 920 } 921 GetNativePointerFieldCount()922 int32_t ObjectRef::GetNativePointerFieldCount() 923 { 924 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this)); 925 return object->GetNativePointerFieldCount(); 926 } 927 GetNativePointerField(int32_t index)928 void *ObjectRef::GetNativePointerField(int32_t index) 929 { 930 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this)); 931 return object->GetNativePointerField(index); 932 } 933 SetNativePointerField(int32_t index,void * nativePointer,NativePointerCallback callBack,void * data)934 void ObjectRef::SetNativePointerField(int32_t index, void *nativePointer, 935 NativePointerCallback callBack, void *data) 936 { 937 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this)); 938 object->SetNativePointerField(index, nativePointer, callBack, data); 939 } 940 941 // ----------------------------------- FunctionRef -------------------------------------- New(EcmaVM * vm,FunctionCallback nativeFunc,void * data)942 Local<FunctionRef> FunctionRef::New(EcmaVM *vm, FunctionCallback nativeFunc, void *data) 943 { 944 JSThread *thread = vm->GetJSThread(); 945 ObjectFactory *factory = vm->GetFactory(); 946 JSHandle<GlobalEnv> env = vm->GetGlobalEnv(); 947 JSHandle<JSFunction> current(factory->NewJSFunction(env, reinterpret_cast<void *>(Callback::RegisterCallback))); 948 JSHandle<JSNativePointer> extraInfo = 949 factory->NewJSNativePointer(reinterpret_cast<void *>(nativeFunc), nullptr, data); 950 current->SetFunctionExtraInfo(thread, extraInfo.GetTaggedValue()); 951 return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current)); 952 } 953 New(EcmaVM * vm,FunctionCallback nativeFunc,Deleter deleter,void * data)954 Local<FunctionRef> FunctionRef::New(EcmaVM *vm, FunctionCallback nativeFunc, Deleter deleter, void *data) 955 { 956 JSThread *thread = vm->GetJSThread(); 957 ObjectFactory *factory = vm->GetFactory(); 958 JSHandle<GlobalEnv> env = vm->GetGlobalEnv(); 959 JSHandle<JSFunction> current(factory->NewJSFunction(env, reinterpret_cast<void *>(Callback::RegisterCallback))); 960 JSHandle<JSNativePointer> extraInfo = 961 factory->NewJSNativePointer(reinterpret_cast<void *>(nativeFunc), deleter, data); 962 vm->PushToArrayDataList(*extraInfo); 963 current->SetFunctionExtraInfo(thread, extraInfo.GetTaggedValue()); 964 return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current)); 965 } 966 NewWithProperty(EcmaVM * vm,FunctionCallback nativeFunc,void * data)967 Local<FunctionRef> FunctionRef::NewWithProperty(EcmaVM *vm, FunctionCallback nativeFunc, void *data) 968 { 969 JSThread *thread = vm->GetJSThread(); 970 ObjectFactory *factory = vm->GetFactory(); 971 JSHandle<GlobalEnv> env = vm->GetGlobalEnv(); 972 JSHandle<JSFunction> current = 973 factory->NewJSFunction(env, reinterpret_cast<void *>(Callback::RegisterCallbackWithProperty)); 974 JSHandle<JSNativePointer> extraInfo = 975 factory->NewJSNativePointer(reinterpret_cast<void *>(nativeFunc), nullptr, data); 976 current->SetFunctionExtraInfo(thread, extraInfo.GetTaggedValue()); 977 return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current)); 978 } 979 NewClassFunction(EcmaVM * vm,FunctionCallbackWithNewTarget nativeFunc,Deleter deleter,void * data)980 Local<FunctionRef> FunctionRef::NewClassFunction(EcmaVM *vm, FunctionCallbackWithNewTarget nativeFunc, Deleter deleter, 981 void *data) 982 { 983 JSThread *thread = vm->GetJSThread(); 984 ObjectFactory *factory = vm->GetFactory(); 985 JSHandle<GlobalEnv> env = vm->GetGlobalEnv(); 986 JSHandle<JSHClass> dynclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutName()); 987 JSMethod *method = 988 vm->GetMethodForNativeFunction(reinterpret_cast<void *>(Callback::RegisterCallbackWithNewTarget)); 989 JSHandle<JSFunction> current = 990 factory->NewJSFunctionByDynClass(method, dynclass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR); 991 992 auto globalConst = thread->GlobalConstants(); 993 JSHandle<JSTaggedValue> accessor = globalConst->GetHandledFunctionPrototypeAccessor(); 994 current->SetPropertyInlinedProps(thread, JSFunction::CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX, 995 accessor.GetTaggedValue()); 996 997 JSHandle<JSNativePointer> extraInfo = 998 factory->NewJSNativePointer(reinterpret_cast<void *>(nativeFunc), deleter, data); 999 if (deleter != nullptr) { 1000 vm->PushToArrayDataList(*extraInfo); 1001 } 1002 current->SetFunctionExtraInfo(thread, extraInfo.GetTaggedValue()); 1003 1004 JSHandle<JSObject> clsPrototype = JSFunction::NewJSFunctionPrototype(thread, factory, current); 1005 clsPrototype.GetTaggedValue().GetTaggedObject()->GetClass()->SetClassPrototype(true); 1006 JSHandle<JSTaggedValue>::Cast(current)->GetTaggedObject()->GetClass()->SetClassConstructor(true); 1007 current->SetClassConstructor(true); 1008 JSHandle<JSTaggedValue> parent = env->GetFunctionPrototype(); 1009 JSObject::SetPrototype(thread, JSHandle<JSObject>::Cast(current), parent); 1010 current->SetHomeObject(thread, clsPrototype); 1011 return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current)); 1012 } 1013 Call(const EcmaVM * vm,Local<JSValueRef> thisObj,const Local<JSValueRef> argv[],int32_t length)1014 Local<JSValueRef> FunctionRef::Call(const EcmaVM *vm, Local<JSValueRef> thisObj, 1015 const Local<JSValueRef> argv[], // NOLINTNEXTLINE(modernize-avoid-c-arrays) 1016 int32_t length) 1017 { 1018 JSThread *thread = vm->GetJSThread(); 1019 if (!IsFunction()) { 1020 return JSValueRef::Undefined(vm); 1021 } 1022 JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this); 1023 JSHandle<JSTaggedValue> thisValue = JSNApiHelper::ToJSHandle(thisObj); 1024 ObjectFactory *factory = vm->GetFactory(); 1025 JSHandle<TaggedArray> arguments = factory->NewTaggedArray(length); 1026 Span<const Local<JSValueRef>> sp(argv, length); 1027 for (int i = 0; i < length; ++i) { 1028 arguments->Set(thread, i, JSNApiHelper::ToJSHandle(sp[i])); 1029 } 1030 InternalCallParams *args = thread->GetInternalCallParams(); 1031 args->MakeArgList(*arguments); 1032 JSTaggedValue result = JSFunction::Call(thread, func, thisValue, arguments->GetLength(), args->GetArgv()); 1033 RETURN_VALUE_IF_ABRUPT_NOT_CLEAR_EXCEPTION(thread, JSValueRef::Exception(vm)); 1034 JSHandle<JSTaggedValue> resultValue(thread, result); 1035 1036 vm->ExecutePromisePendingJob(); 1037 RETURN_VALUE_IF_ABRUPT_NOT_CLEAR_EXCEPTION(thread, JSValueRef::Exception(vm)); 1038 1039 return JSNApiHelper::ToLocal<JSValueRef>(resultValue); 1040 } 1041 Constructor(const EcmaVM * vm,const Local<JSValueRef> argv[],int32_t length)1042 Local<JSValueRef> FunctionRef::Constructor(const EcmaVM *vm, 1043 const Local<JSValueRef> argv[], // NOLINTNEXTLINE(modernize-avoid-c-arrays) 1044 int32_t length) 1045 { 1046 JSThread *thread = vm->GetJSThread(); 1047 if (!IsFunction()) { 1048 return JSValueRef::Undefined(vm); 1049 } 1050 JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this); 1051 JSHandle<JSTaggedValue> newTarget = func; 1052 ObjectFactory *factory = vm->GetFactory(); 1053 JSHandle<TaggedArray> arguments = factory->NewTaggedArray(length); 1054 Span<const Local<JSValueRef>> sp(argv, length); 1055 for (int i = 0; i < length; ++i) { 1056 arguments->Set(thread, i, JSNApiHelper::ToJSHandle(sp[i])); 1057 } 1058 ecmascript::InternalCallParams *params = thread->GetInternalCallParams(); 1059 params->MakeArgList(*arguments); 1060 JSTaggedValue result = JSFunction::Construct(thread, func, length, params->GetArgv(), newTarget); 1061 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1062 JSHandle<JSTaggedValue> resultValue(vm->GetJSThread(), result); 1063 return JSNApiHelper::ToLocal<JSValueRef>(resultValue); 1064 } 1065 GetFunctionPrototype(const EcmaVM * vm)1066 Local<JSValueRef> FunctionRef::GetFunctionPrototype(const EcmaVM *vm) 1067 { 1068 JSThread *thread = vm->GetJSThread(); 1069 JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this); 1070 JSHandle<JSTaggedValue> prototype(thread, JSHandle<JSFunction>(func)->GetFunctionPrototype()); 1071 return JSNApiHelper::ToLocal<JSValueRef>(prototype); 1072 } 1073 Inherit(const EcmaVM * vm,Local<FunctionRef> parent)1074 bool FunctionRef::Inherit(const EcmaVM *vm, Local<FunctionRef> parent) 1075 { 1076 JSThread *thread = vm->GetJSThread(); 1077 JSHandle<JSTaggedValue> parentValue = JSNApiHelper::ToJSHandle(parent); 1078 JSHandle<JSObject> parentHandle = JSHandle<JSObject>::Cast(parentValue); 1079 JSHandle<JSObject> thisHandle = JSHandle<JSObject>::Cast(JSNApiHelper::ToJSHandle(this)); 1080 // Set this.__proto__ to parent 1081 bool res = JSObject::SetPrototype(thread, thisHandle, parentValue); 1082 if (!res) { 1083 return false; 1084 } 1085 // Set this.Prototype.__proto__ to parent.Prototype 1086 JSHandle<JSTaggedValue> parentProtoType(thread, JSFunction::PrototypeGetter(thread, parentHandle)); 1087 JSHandle<JSTaggedValue> thisProtoType(thread, JSFunction::PrototypeGetter(thread, thisHandle)); 1088 return JSObject::SetPrototype(thread, JSHandle<JSObject>::Cast(thisProtoType), parentProtoType); 1089 } 1090 SetName(const EcmaVM * vm,Local<StringRef> name)1091 void FunctionRef::SetName(const EcmaVM *vm, Local<StringRef> name) 1092 { 1093 JSThread *thread = vm->GetJSThread(); 1094 JSFunction *func = JSFunction::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject()); 1095 JSTaggedValue key = JSNApiHelper::ToJSTaggedValue(*name); 1096 JSFunction::SetFunctionNameNoPrefix(thread, func, key); 1097 } 1098 GetName(const EcmaVM * vm)1099 Local<StringRef> FunctionRef::GetName(const EcmaVM *vm) 1100 { 1101 JSThread *thread = vm->GetJSThread(); 1102 JSHandle<JSFunctionBase> func = JSHandle<JSFunctionBase>(thread, JSNApiHelper::ToJSTaggedValue(this)); 1103 JSHandle<JSTaggedValue> name = JSFunctionBase::GetFunctionName(thread, func); 1104 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1105 return JSNApiHelper::ToLocal<StringRef>(name); 1106 } 1107 IsNative(const EcmaVM * vm)1108 bool FunctionRef::IsNative(const EcmaVM *vm) 1109 { 1110 JSThread *thread = vm->GetJSThread(); 1111 JSHandle<JSFunctionBase> func = JSHandle<JSFunctionBase>(thread, JSNApiHelper::ToJSTaggedValue(this)); 1112 JSMethod *method = func->GetMethod(); 1113 return method->IsNative(); 1114 } 1115 1116 // ----------------------------------- ArrayRef ---------------------------------------- New(const EcmaVM * vm,int32_t length)1117 Local<ArrayRef> ArrayRef::New(const EcmaVM *vm, int32_t length) 1118 { 1119 JSThread *thread = vm->GetJSThread(); 1120 JSTaggedNumber arrayLen(length); 1121 JSHandle<JSTaggedValue> array = JSArray::ArrayCreate(thread, arrayLen); 1122 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1123 return JSNApiHelper::ToLocal<ArrayRef>(array); 1124 } 1125 Length(const EcmaVM * vm)1126 int32_t ArrayRef::Length([[maybe_unused]] const EcmaVM *vm) 1127 { 1128 return JSArray::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetArrayLength(); 1129 } 1130 1131 GetValueAt(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index)1132 Local<JSValueRef> ArrayRef::GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index) 1133 { 1134 JSThread *thread = vm->GetJSThread(); 1135 JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(obj); 1136 JSHandle<JSTaggedValue> result = JSArray::FastGetPropertyByValue(thread, object, index); 1137 return JSNApiHelper::ToLocal<JSValueRef>(result); 1138 } 1139 SetValueAt(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index,Local<JSValueRef> value)1140 bool ArrayRef::SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value) 1141 { 1142 JSThread *thread = vm->GetJSThread(); 1143 JSHandle<JSTaggedValue> objectHandle = JSNApiHelper::ToJSHandle(obj); 1144 JSHandle<JSTaggedValue> valueHandle = JSNApiHelper::ToJSHandle(value); 1145 return JSArray::FastSetPropertyByValue(thread, objectHandle, index, valueHandle); 1146 } 1147 // ---------------------------------- Promise -------------------------------------- New(const EcmaVM * vm)1148 Local<PromiseCapabilityRef> PromiseCapabilityRef::New(const EcmaVM *vm) 1149 { 1150 JSThread *thread = vm->GetJSThread(); 1151 JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv(); 1152 JSHandle<JSTaggedValue> constructor(globalEnv->GetPromiseFunction()); 1153 JSHandle<JSTaggedValue> capability(JSPromise::NewPromiseCapability(thread, constructor)); 1154 return JSNApiHelper::ToLocal<PromiseCapabilityRef>(capability); 1155 } 1156 GetPromise(const EcmaVM * vm)1157 Local<PromiseRef> PromiseCapabilityRef::GetPromise(const EcmaVM *vm) 1158 { 1159 JSThread *thread = vm->GetJSThread(); 1160 JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this)); 1161 return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, capacity->GetPromise())); 1162 } 1163 Resolve(const EcmaVM * vm,Local<JSValueRef> value)1164 bool PromiseCapabilityRef::Resolve(const EcmaVM *vm, Local<JSValueRef> value) 1165 { 1166 JSThread *thread = vm->GetJSThread(); 1167 const GlobalEnvConstants *constants = thread->GlobalConstants(); 1168 1169 JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(value); 1170 JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this)); 1171 JSHandle<JSTaggedValue> resolve(thread, capacity->GetResolve()); 1172 JSHandle<JSTaggedValue> undefined(thread, constants->GetUndefined()); 1173 InternalCallParams *arguments = thread->GetInternalCallParams(); 1174 arguments->MakeArgv(arg); 1175 JSFunction::Call(thread, resolve, undefined, 1, arguments->GetArgv()); 1176 RETURN_VALUE_IF_ABRUPT(thread, false); 1177 1178 vm->ExecutePromisePendingJob(); 1179 RETURN_VALUE_IF_ABRUPT(thread, false); 1180 return true; 1181 } 1182 Reject(const EcmaVM * vm,Local<JSValueRef> reason)1183 bool PromiseCapabilityRef::Reject(const EcmaVM *vm, Local<JSValueRef> reason) 1184 { 1185 JSThread *thread = vm->GetJSThread(); 1186 const GlobalEnvConstants *constants = thread->GlobalConstants(); 1187 1188 JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(reason); 1189 JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this)); 1190 JSHandle<JSTaggedValue> reject(thread, capacity->GetReject()); 1191 JSHandle<JSTaggedValue> undefined(thread, constants->GetUndefined()); 1192 InternalCallParams *arguments = thread->GetInternalCallParams(); 1193 arguments->MakeArgv(arg); 1194 JSFunction::Call(thread, reject, undefined, 1, arguments->GetArgv()); 1195 RETURN_VALUE_IF_ABRUPT(thread, false); 1196 1197 vm->ExecutePromisePendingJob(); 1198 RETURN_VALUE_IF_ABRUPT(thread, false); 1199 return true; 1200 } 1201 Catch(const EcmaVM * vm,Local<FunctionRef> handler)1202 Local<PromiseRef> PromiseRef::Catch(const EcmaVM *vm, Local<FunctionRef> handler) 1203 { 1204 JSThread *thread = vm->GetJSThread(); 1205 const GlobalEnvConstants *constants = thread->GlobalConstants(); 1206 1207 JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this); 1208 JSHandle<JSTaggedValue> catchKey(thread, constants->GetPromiseCatchString()); 1209 JSHandle<JSTaggedValue> reject = JSNApiHelper::ToJSHandle(handler); 1210 ecmascript::InternalCallParams *arguments = thread->GetInternalCallParams(); 1211 arguments->MakeArgv(reject); 1212 JSTaggedValue result = JSFunction::Invoke(thread, promise, catchKey, 1, arguments->GetArgv()); 1213 1214 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1215 return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result)); 1216 } 1217 Then(const EcmaVM * vm,Local<FunctionRef> handler)1218 Local<PromiseRef> PromiseRef::Then(const EcmaVM *vm, Local<FunctionRef> handler) 1219 { 1220 JSThread *thread = vm->GetJSThread(); 1221 const GlobalEnvConstants *constants = thread->GlobalConstants(); 1222 1223 JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this); 1224 JSHandle<JSTaggedValue> thenKey(thread, constants->GetPromiseThenString()); 1225 JSHandle<JSTaggedValue> resolver = JSNApiHelper::ToJSHandle(handler); 1226 ecmascript::InternalCallParams *arguments = thread->GetInternalCallParams(); 1227 arguments->MakeArgv(resolver.GetTaggedValue(), constants->GetUndefined()); 1228 JSTaggedValue result = JSFunction::Invoke(thread, promise, thenKey, 2, arguments->GetArgv()); // 2: two args 1229 1230 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1231 return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result)); 1232 } 1233 Then(const EcmaVM * vm,Local<FunctionRef> onFulfilled,Local<FunctionRef> onRejected)1234 Local<PromiseRef> PromiseRef::Then(const EcmaVM *vm, Local<FunctionRef> onFulfilled, Local<FunctionRef> onRejected) 1235 { 1236 JSThread *thread = vm->GetJSThread(); 1237 const GlobalEnvConstants *constants = thread->GlobalConstants(); 1238 1239 JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this); 1240 JSHandle<JSTaggedValue> thenKey(thread, constants->GetPromiseThenString()); 1241 JSHandle<JSTaggedValue> resolver = JSNApiHelper::ToJSHandle(onFulfilled); 1242 JSHandle<JSTaggedValue> reject = JSNApiHelper::ToJSHandle(onRejected); 1243 ecmascript::InternalCallParams *arguments = thread->GetInternalCallParams(); 1244 arguments->MakeArgv(resolver, reject); 1245 JSTaggedValue result = JSFunction::Invoke(thread, promise, thenKey, 2, arguments->GetArgv()); // 2: two args 1246 1247 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1248 return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result)); 1249 } 1250 // ---------------------------------- Promise ------------------------------------- 1251 1252 // ---------------------------------- Buffer ----------------------------------- New(const EcmaVM * vm,int32_t length)1253 Local<ArrayBufferRef> ArrayBufferRef::New(const EcmaVM *vm, int32_t length) 1254 { 1255 JSThread *thread = vm->GetJSThread(); 1256 ObjectFactory *factory = vm->GetFactory(); 1257 1258 JSHandle<JSArrayBuffer> arrayBuffer = factory->NewJSArrayBuffer(length); 1259 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1260 return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer)); 1261 } 1262 New(const EcmaVM * vm,void * buffer,int32_t length,const Deleter & deleter,void * data)1263 Local<ArrayBufferRef> ArrayBufferRef::New( 1264 const EcmaVM *vm, void *buffer, int32_t length, const Deleter &deleter, void *data) 1265 { 1266 JSThread *thread = vm->GetJSThread(); 1267 ObjectFactory *factory = vm->GetFactory(); 1268 1269 JSHandle<JSArrayBuffer> arrayBuffer = 1270 factory->NewJSArrayBuffer(buffer, length, reinterpret_cast<ecmascript::DeleteEntryPoint>(deleter), data); 1271 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1272 return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer)); 1273 } 1274 ByteLength(const EcmaVM * vm)1275 int32_t ArrayBufferRef::ByteLength(const EcmaVM *vm) 1276 { 1277 JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this)); 1278 return arrayBuffer->GetArrayBufferByteLength(); 1279 } 1280 GetBuffer()1281 void *ArrayBufferRef::GetBuffer() 1282 { 1283 JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this)); 1284 JSTaggedValue bufferData = arrayBuffer->GetArrayBufferData(); 1285 if (!bufferData.IsJSNativePointer()) { 1286 return nullptr; 1287 } 1288 return JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer(); 1289 } 1290 // ---------------------------------- Buffer ----------------------------------- 1291 1292 // ---------------------------------- DataView ----------------------------------- New(const EcmaVM * vm,Local<ArrayBufferRef> arrayBuffer,uint32_t byteOffset,uint32_t byteLength)1293 Local<DataViewRef> DataViewRef::New( 1294 const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, uint32_t byteOffset, uint32_t byteLength) 1295 { 1296 JSThread *thread = vm->GetJSThread(); 1297 ObjectFactory *factory = vm->GetFactory(); 1298 1299 JSHandle<JSArrayBuffer> buffer(JSNApiHelper::ToJSHandle(arrayBuffer)); 1300 JSHandle<JSDataView> dataView = factory->NewJSDataView(buffer, byteOffset, byteLength); 1301 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1302 return JSNApiHelper::ToLocal<DataViewRef>(JSHandle<JSTaggedValue>(dataView)); 1303 } 1304 ByteLength()1305 uint32_t DataViewRef::ByteLength() 1306 { 1307 JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this)); 1308 return dataView->GetByteLength(); 1309 } 1310 ByteOffset()1311 uint32_t DataViewRef::ByteOffset() 1312 { 1313 JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this)); 1314 return dataView->GetByteOffset(); 1315 } 1316 GetArrayBuffer(const EcmaVM * vm)1317 Local<ArrayBufferRef> DataViewRef::GetArrayBuffer(const EcmaVM *vm) 1318 { 1319 JSThread *thread = vm->GetJSThread(); 1320 JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this)); 1321 JSHandle<JSTaggedValue> arrayBuffer(thread, dataView->GetViewedArrayBuffer()); 1322 return JSNApiHelper::ToLocal<ArrayBufferRef>(arrayBuffer); 1323 } 1324 // ---------------------------------- DataView ----------------------------------- 1325 1326 // ---------------------------------- TypedArray ----------------------------------- ByteLength(const EcmaVM * vm)1327 int32_t TypedArrayRef::ByteLength(const EcmaVM *vm) 1328 { 1329 JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this)); 1330 JSTaggedValue length = typedArray->GetByteLength(); 1331 if (!length.IsNumber()) { 1332 return 0; 1333 } 1334 return length.GetNumber(); 1335 } 1336 ByteOffset(const EcmaVM * vm)1337 int32_t TypedArrayRef::ByteOffset(const EcmaVM *vm) 1338 { 1339 JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this)); 1340 JSTaggedValue length = typedArray->GetByteOffset(); 1341 if (!length.IsNumber()) { 1342 return 0; 1343 } 1344 return length.GetNumber(); 1345 } 1346 ArrayLength(const EcmaVM * vm)1347 int32_t TypedArrayRef::ArrayLength(const EcmaVM *vm) 1348 { 1349 JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this)); 1350 JSTaggedValue length = typedArray->GetArrayLength(); 1351 if (!length.IsNumber()) { 1352 return 0; 1353 } 1354 return length.GetNumber(); 1355 } 1356 GetArrayBuffer(const EcmaVM * vm)1357 Local<ArrayBufferRef> TypedArrayRef::GetArrayBuffer(const EcmaVM *vm) 1358 { 1359 JSThread *thread = vm->GetJSThread(); 1360 JSHandle<JSObject> typeArray(JSNApiHelper::ToJSHandle(this)); 1361 JSHandle<JSTaggedValue> arrayBuffer(thread, JSTypedArray::Cast(*typeArray)->GetViewedArrayBuffer()); 1362 return JSNApiHelper::ToLocal<ArrayBufferRef>(arrayBuffer); 1363 } 1364 1365 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 1366 #define TYPED_ARRAY_NEW(Type) \ 1367 Local<Type##Ref> Type##Ref::New( \ 1368 const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length) \ 1369 { \ 1370 JSThread *thread = vm->GetJSThread(); \ 1371 JSHandle<GlobalEnv> env = vm->GetGlobalEnv(); \ 1372 \ 1373 JSHandle<JSTaggedValue> func = env->Get##Type##Function(); \ 1374 JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(buffer)); \ 1375 ecmascript::InternalCallParams *argv = thread->GetInternalCallParams(); \ 1376 argv->MakeArgv(arrayBuffer.GetTaggedValue(), JSTaggedValue(byteOffset), JSTaggedValue(length)); \ 1377 uint32_t argc = 3; \ 1378 JSTaggedValue result = JSFunction::Construct(thread, func, argc, argv->GetArgv(), func); \ 1379 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); \ 1380 JSHandle<JSTaggedValue> resultHandle(thread, result); \ 1381 return JSNApiHelper::ToLocal<Type##Ref>(resultHandle); \ 1382 } 1383 1384 TYPED_ARRAY_ALL(TYPED_ARRAY_NEW) 1385 1386 #undef TYPED_ARRAY_NEW 1387 // ---------------------------------- TypedArray ----------------------------------- 1388 1389 // ---------------------------------- Error --------------------------------------- 1390 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 1391 #define EXCEPTION_ERROR_NEW(name, type) \ 1392 Local<JSValueRef> Exception::name(const EcmaVM *vm, Local<StringRef> message) \ 1393 { \ 1394 JSThread *thread = vm->GetJSThread(); \ 1395 ObjectFactory *factory = vm->GetFactory(); \ 1396 \ 1397 JSHandle<EcmaString> messageValue(JSNApiHelper::ToJSHandle(message)); \ 1398 JSHandle<JSTaggedValue> result(factory->NewJSError(ErrorType::type, messageValue)); \ 1399 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); \ 1400 return JSNApiHelper::ToLocal<JSValueRef>(result); \ 1401 } 1402 EXCEPTION_ERROR_ALL(EXCEPTION_ERROR_NEW)1403 EXCEPTION_ERROR_ALL(EXCEPTION_ERROR_NEW) 1404 1405 #undef EXCEPTION_ERROR_NEW 1406 // ---------------------------------- Error --------------------------------------- 1407 1408 // ---------------------------------- JSON ------------------------------------------ 1409 Local<JSValueRef> JSON::Parse(const EcmaVM *vm, Local<StringRef> string) 1410 { 1411 JSThread *thread = vm->GetJSThread(); 1412 auto ecmaStr = EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(*string).GetTaggedObject()); 1413 JSHandle<JSTaggedValue> result; 1414 if (ecmaStr->IsUtf8()) { 1415 JsonParser<uint8_t> parser(thread); 1416 result = parser.ParseUtf8(EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(*string).GetTaggedObject())); 1417 } else { 1418 JsonParser<uint16_t> parser(thread); 1419 result = parser.ParseUtf16(EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(*string).GetTaggedObject())); 1420 } 1421 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1422 return JSNApiHelper::ToLocal<JSValueRef>(result); 1423 } 1424 Stringify(const EcmaVM * vm,Local<JSValueRef> json)1425 Local<JSValueRef> JSON::Stringify(const EcmaVM *vm, Local<JSValueRef> json) 1426 { 1427 JSThread *thread = vm->GetJSThread(); 1428 auto constants = thread->GlobalConstants(); 1429 JsonStringifier stringifier(thread); 1430 JSHandle<JSTaggedValue> str = stringifier.Stringify( 1431 JSNApiHelper::ToJSHandle(json), constants->GetHandledUndefined(), constants->GetHandledUndefined()); 1432 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1433 return JSNApiHelper::ToLocal<JSValueRef>(str); 1434 } 1435 GetOriginalSource(const EcmaVM * vm)1436 Local<StringRef> RegExpRef::GetOriginalSource(const EcmaVM *vm) 1437 { 1438 JSThread *thread = vm->GetJSThread(); 1439 JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this)); 1440 JSTaggedValue source = regExp->GetOriginalSource(); 1441 if (!source.IsString()) { 1442 auto constants = thread->GlobalConstants(); 1443 return JSNApiHelper::ToLocal<StringRef>(constants->GetHandledEmptyString()); 1444 } 1445 JSHandle<JSTaggedValue> sourceHandle(thread, source); 1446 return JSNApiHelper::ToLocal<StringRef>(sourceHandle); 1447 } 1448 New(const EcmaVM * vm,double time)1449 Local<DateRef> DateRef::New(const EcmaVM *vm, double time) 1450 { 1451 JSThread *thread = vm->GetJSThread(); 1452 ObjectFactory *factory = vm->GetFactory(); 1453 JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv(); 1454 JSHandle<JSTaggedValue> dateFunction = globalEnv->GetDateFunction(); 1455 JSHandle<JSDate> dateObject = 1456 JSHandle<JSDate>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(dateFunction), dateFunction)); 1457 dateObject->SetTimeValue(thread, JSTaggedValue(time)); 1458 return JSNApiHelper::ToLocal<DateRef>(JSHandle<JSTaggedValue>(dateObject)); 1459 } 1460 ToString(const EcmaVM * vm)1461 Local<StringRef> DateRef::ToString(const EcmaVM *vm) 1462 { 1463 JSThread *thread = vm->GetJSThread(); 1464 JSHandle<JSDate> date(JSNApiHelper::ToJSHandle(this)); 1465 JSTaggedValue dateStr = date->ToString(thread); 1466 if (!dateStr.IsString()) { 1467 auto constants = thread->GlobalConstants(); 1468 return JSNApiHelper::ToLocal<StringRef>(constants->GetHandledEmptyString()); 1469 } 1470 JSHandle<JSTaggedValue> dateStrHandle(thread, dateStr); 1471 return JSNApiHelper::ToLocal<StringRef>(dateStrHandle); 1472 } 1473 GetTime()1474 double DateRef::GetTime() 1475 { 1476 JSHandle<JSDate> date(JSNApiHelper::ToJSHandle(this)); 1477 if (!date->IsDate()) { 1478 LOG(ERROR, RUNTIME) << "Not a Date Object"; 1479 } 1480 return date->GetTime().GetDouble(); 1481 } 1482 GetSize()1483 int32_t MapRef::GetSize() 1484 { 1485 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this)); 1486 return map->GetSize(); 1487 } 1488 GetSize()1489 int32_t SetRef::GetSize() 1490 { 1491 JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this)); 1492 return set->GetSize(); 1493 } 1494 1495 // ----------------------------------- FunctionCallback --------------------------------- RegisterCallback(ecmascript::EcmaRuntimeCallInfo * info)1496 JSTaggedValue Callback::RegisterCallback(ecmascript::EcmaRuntimeCallInfo *info) 1497 { 1498 // Constructor 1499 JSThread *thread = info->GetThread(); 1500 JSHandle<JSTaggedValue> constructor = BuiltinsBase::GetConstructor(info); 1501 if (!constructor->IsJSFunction()) { 1502 return JSTaggedValue::False(); 1503 } 1504 JSHandle<JSFunction> function(constructor); 1505 JSHandle<JSTaggedValue> extraInfoValue(thread, function->GetFunctionExtraInfo()); 1506 if (!extraInfoValue->IsJSNativePointer()) { 1507 return JSTaggedValue::False(); 1508 } 1509 JSHandle<JSNativePointer> extraInfo(extraInfoValue); 1510 // vm 1511 Region *region = Region::ObjectAddressToRange(extraInfo.GetTaggedValue().GetTaggedObject()); 1512 if (region == nullptr) { 1513 return JSTaggedValue::False(); 1514 } 1515 EcmaVM *vm = thread->GetEcmaVM(); 1516 // data 1517 void *data = extraInfo->GetData(); 1518 // callBack 1519 FunctionCallback nativeFunc = reinterpret_cast<FunctionCallback>(extraInfo->GetExternalPointer()); 1520 1521 // this 1522 JSHandle<JSTaggedValue> thisValue(BuiltinsBase::GetThis(info)); 1523 1524 // arguments 1525 std::vector<Local<JSValueRef>> arguments; 1526 uint32_t length = info->GetArgsNumber(); 1527 for (uint32_t i = 0; i < length; ++i) { 1528 arguments.emplace_back(JSNApiHelper::ToLocal<JSValueRef>(BuiltinsBase::GetCallArg(info, i))); 1529 } 1530 1531 Local<JSValueRef> result = nativeFunc(vm, 1532 JSNApiHelper::ToLocal<JSValueRef>(thisValue), 1533 arguments.data(), 1534 arguments.size(), 1535 data); 1536 return JSNApiHelper::ToJSHandle(result).GetTaggedValue(); 1537 } 1538 RegisterCallbackWithProperty(ecmascript::EcmaRuntimeCallInfo * info)1539 JSTaggedValue Callback::RegisterCallbackWithProperty(ecmascript::EcmaRuntimeCallInfo *info) 1540 { 1541 // Constructor 1542 JSThread *thread = info->GetThread(); 1543 JSHandle<JSTaggedValue> constructor = BuiltinsBase::GetConstructor(info); 1544 if (!constructor->IsJSFunction()) { 1545 return JSTaggedValue::False(); 1546 } 1547 JSHandle<JSFunction> function(constructor); 1548 JSHandle<JSTaggedValue> extraInfoValue(thread, function->GetFunctionExtraInfo()); 1549 if (!extraInfoValue->IsJSNativePointer()) { 1550 return JSTaggedValue::False(); 1551 } 1552 JSHandle<JSNativePointer> extraInfo(extraInfoValue); 1553 // vm 1554 Region *region = Region::ObjectAddressToRange(extraInfo.GetTaggedValue().GetTaggedObject()); 1555 if (region == nullptr) { 1556 return JSTaggedValue::False(); 1557 } 1558 EcmaVM *vm = thread->GetEcmaVM(); 1559 // data 1560 void *data = extraInfo->GetData(); 1561 // callBack 1562 FunctionCallback nativeFunc = reinterpret_cast<FunctionCallback>(extraInfo->GetExternalPointer()); 1563 1564 // constructor 1565 JSHandle<JSTaggedValue> thisValue(BuiltinsBase::GetConstructor(info)); 1566 1567 // arguments 1568 std::vector<Local<JSValueRef>> arguments; 1569 uint32_t length = info->GetArgsNumber(); 1570 for (uint32_t i = 0; i < length; ++i) { 1571 arguments.emplace_back(JSNApiHelper::ToLocal<JSValueRef>(BuiltinsBase::GetCallArg(info, i))); 1572 } 1573 1574 Local<JSValueRef> result = nativeFunc(vm, 1575 JSNApiHelper::ToLocal<JSValueRef>(thisValue), 1576 arguments.data(), 1577 arguments.size(), 1578 data); 1579 return JSNApiHelper::ToJSHandle(result).GetTaggedValue(); 1580 } 1581 RegisterCallbackWithNewTarget(ecmascript::EcmaRuntimeCallInfo * info)1582 JSTaggedValue Callback::RegisterCallbackWithNewTarget(ecmascript::EcmaRuntimeCallInfo *info) 1583 { 1584 // Constructor 1585 JSThread *thread = info->GetThread(); 1586 JSHandle<JSTaggedValue> constructor = BuiltinsBase::GetConstructor(info); 1587 if (!constructor->IsJSFunction()) { 1588 return JSTaggedValue::False(); 1589 } 1590 JSHandle<JSFunction> function(constructor); 1591 JSHandle<JSTaggedValue> extraInfoValue(thread, function->GetFunctionExtraInfo()); 1592 if (!extraInfoValue->IsJSNativePointer()) { 1593 return JSTaggedValue::False(); 1594 } 1595 JSHandle<JSNativePointer> extraInfo(extraInfoValue); 1596 // vm 1597 Region *region = Region::ObjectAddressToRange(extraInfo.GetTaggedValue().GetTaggedObject()); 1598 if (region == nullptr) { 1599 return JSTaggedValue::False(); 1600 } 1601 EcmaVM *vm = thread->GetEcmaVM(); 1602 // data 1603 void *data = extraInfo->GetData(); 1604 // callBack 1605 FunctionCallbackWithNewTarget nativeFunc = 1606 reinterpret_cast<FunctionCallbackWithNewTarget>(extraInfo->GetExternalPointer()); 1607 1608 // newTarget 1609 JSHandle<JSTaggedValue> newTarget(BuiltinsBase::GetNewTarget(info)); 1610 1611 // this 1612 JSHandle<JSTaggedValue> thisValue(BuiltinsBase::GetThis(info)); 1613 1614 // arguments 1615 std::vector<Local<JSValueRef>> arguments; 1616 uint32_t length = info->GetArgsNumber(); 1617 for (uint32_t i = 0; i < length; ++i) { 1618 arguments.emplace_back(JSNApiHelper::ToLocal<JSValueRef>(BuiltinsBase::GetCallArg(info, i))); 1619 } 1620 1621 Local<JSValueRef> result = nativeFunc(vm, 1622 JSNApiHelper::ToLocal<JSValueRef>(thisValue), 1623 JSNApiHelper::ToLocal<JSValueRef>(newTarget), 1624 arguments.data(), 1625 arguments.size(), 1626 data); 1627 return JSNApiHelper::ToJSHandle(result).GetTaggedValue(); 1628 } 1629 1630 // ------------------------------------- JSExecutionScope ------------------------------ JSExecutionScope(const EcmaVM * vm)1631 JSExecutionScope::JSExecutionScope(const EcmaVM *vm) 1632 { 1633 (void)vm; 1634 } 1635 ~JSExecutionScope()1636 JSExecutionScope::~JSExecutionScope() 1637 { 1638 last_current_thread_ = nullptr; 1639 is_revert_ = false; 1640 } 1641 1642 // ----------------------------------- JSValueRef -------------------------------------- Undefined(const EcmaVM * vm)1643 Local<PrimitiveRef> JSValueRef::Undefined(const EcmaVM *vm) 1644 { 1645 return JSNApiHelper::ToLocal<PrimitiveRef>(JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::Undefined())); 1646 } 1647 Null(const EcmaVM * vm)1648 Local<PrimitiveRef> JSValueRef::Null(const EcmaVM *vm) 1649 { 1650 return JSNApiHelper::ToLocal<PrimitiveRef>(JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::Null())); 1651 } 1652 True(const EcmaVM * vm)1653 Local<PrimitiveRef> JSValueRef::True(const EcmaVM *vm) 1654 { 1655 return JSNApiHelper::ToLocal<PrimitiveRef>(JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::True())); 1656 } 1657 False(const EcmaVM * vm)1658 Local<PrimitiveRef> JSValueRef::False(const EcmaVM *vm) 1659 { 1660 return JSNApiHelper::ToLocal<PrimitiveRef>(JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::False())); 1661 } 1662 Exception(const EcmaVM * vm)1663 Local<JSValueRef> JSValueRef::Exception(const EcmaVM *vm) 1664 { 1665 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::Exception())); 1666 } 1667 ToObject(const EcmaVM * vm)1668 Local<ObjectRef> JSValueRef::ToObject(const EcmaVM *vm) 1669 { 1670 JSThread *thread = vm->GetJSThread(); 1671 if (IsUndefined() || IsNull()) { 1672 return Exception(vm); 1673 } 1674 JSHandle<JSTaggedValue> obj(JSTaggedValue::ToObject(thread, JSNApiHelper::ToJSHandle(this))); 1675 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1676 return JSNApiHelper::ToLocal<ObjectRef>(obj); 1677 } 1678 ToString(const EcmaVM * vm)1679 Local<StringRef> JSValueRef::ToString(const EcmaVM *vm) 1680 { 1681 JSThread *thread = vm->GetJSThread(); 1682 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 1683 if (!obj->IsString()) { 1684 obj = JSHandle<JSTaggedValue>(JSTaggedValue::ToString(thread, obj)); 1685 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1686 } 1687 return JSNApiHelper::ToLocal<StringRef>(obj); 1688 } 1689 ToNativePointer(const EcmaVM * vm)1690 Local<NativePointerRef> JSValueRef::ToNativePointer(const EcmaVM *vm) 1691 { 1692 JSThread *thread = vm->GetJSThread(); 1693 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 1694 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1695 return JSNApiHelper::ToLocal<NativePointerRef>(obj); 1696 } 1697 BooleaValue()1698 bool JSValueRef::BooleaValue() 1699 { 1700 return JSNApiHelper::ToJSTaggedValue(this).ToBoolean(); 1701 } 1702 IntegerValue(const EcmaVM * vm)1703 int64_t JSValueRef::IntegerValue(const EcmaVM *vm) 1704 { 1705 JSThread *thread = vm->GetJSThread(); 1706 JSTaggedNumber number = JSTaggedValue::ToInteger(thread, JSNApiHelper::ToJSHandle(this)); 1707 RETURN_VALUE_IF_ABRUPT(thread, 0); 1708 return number.GetNumber(); 1709 } 1710 Uint32Value(const EcmaVM * vm)1711 uint32_t JSValueRef::Uint32Value(const EcmaVM *vm) 1712 { 1713 JSThread *thread = vm->GetJSThread(); 1714 uint32_t number = JSTaggedValue::ToUint32(thread, JSNApiHelper::ToJSHandle(this)); 1715 RETURN_VALUE_IF_ABRUPT(thread, 0); 1716 return number; 1717 } 1718 Int32Value(const EcmaVM * vm)1719 int32_t JSValueRef::Int32Value(const EcmaVM *vm) 1720 { 1721 JSThread *thread = vm->GetJSThread(); 1722 int32_t number = JSTaggedValue::ToInt32(thread, JSNApiHelper::ToJSHandle(this)); 1723 RETURN_VALUE_IF_ABRUPT(thread, 0); 1724 return number; 1725 } 1726 ToBoolean(const EcmaVM * vm)1727 Local<BooleanRef> JSValueRef::ToBoolean(const EcmaVM *vm) 1728 { 1729 JSThread *thread = vm->GetJSThread(); 1730 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 1731 JSHandle<JSTaggedValue> booleanObj = JSHandle<JSTaggedValue>(thread, JSTaggedValue(obj->ToBoolean())); 1732 return JSNApiHelper::ToLocal<BooleanRef>(booleanObj); 1733 } 1734 ToNumber(const EcmaVM * vm)1735 Local<NumberRef> JSValueRef::ToNumber(const EcmaVM *vm) 1736 { 1737 JSThread *thread = vm->GetJSThread(); 1738 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 1739 JSHandle<JSTaggedValue> number(thread, JSTaggedValue::ToNumber(thread, obj)); 1740 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Exception(vm)); 1741 return JSNApiHelper::ToLocal<NumberRef>(number); 1742 } 1743 IsStrictEquals(const EcmaVM * vm,Local<JSValueRef> value)1744 bool JSValueRef::IsStrictEquals(const EcmaVM *vm, Local<JSValueRef> value) 1745 { 1746 JSThread *thread = vm->GetJSThread(); 1747 JSHandle<JSTaggedValue> xValue = JSNApiHelper::ToJSHandle(this); 1748 JSHandle<JSTaggedValue> yValue = JSNApiHelper::ToJSHandle(value); 1749 return JSTaggedValue::StrictEqual(thread, xValue, yValue); 1750 } 1751 Typeof(const EcmaVM * vm)1752 Local<StringRef> JSValueRef::Typeof(const EcmaVM *vm) 1753 { 1754 JSThread *thread = vm->GetJSThread(); 1755 JSTaggedValue value = FastRuntimeStub::FastTypeOf(thread, JSNApiHelper::ToJSTaggedValue(this)); 1756 return JSNApiHelper::ToLocal<StringRef>(JSHandle<JSTaggedValue>(thread, value)); 1757 } 1758 InstanceOf(const EcmaVM * vm,Local<JSValueRef> value)1759 bool JSValueRef::InstanceOf(const EcmaVM *vm, Local<JSValueRef> value) 1760 { 1761 JSThread *thread = vm->GetJSThread(); 1762 JSHandle<JSTaggedValue> origin = JSNApiHelper::ToJSHandle(this); 1763 JSHandle<JSTaggedValue> target = JSNApiHelper::ToJSHandle(value); 1764 bool result = JSObject::InstanceOf(thread, origin, target); 1765 RETURN_VALUE_IF_ABRUPT(thread, false); 1766 return result; 1767 } 1768 IsUndefined()1769 bool JSValueRef::IsUndefined() 1770 { 1771 return JSNApiHelper::ToJSTaggedValue(this).IsUndefined(); 1772 } 1773 IsNull()1774 bool JSValueRef::IsNull() 1775 { 1776 return JSNApiHelper::ToJSTaggedValue(this).IsNull(); 1777 } 1778 IsHole()1779 bool JSValueRef::IsHole() 1780 { 1781 return JSNApiHelper::ToJSTaggedValue(this).IsHole(); 1782 } 1783 IsTrue()1784 bool JSValueRef::IsTrue() 1785 { 1786 return JSNApiHelper::ToJSTaggedValue(this).IsTrue(); 1787 } 1788 IsFalse()1789 bool JSValueRef::IsFalse() 1790 { 1791 return JSNApiHelper::ToJSTaggedValue(this).IsFalse(); 1792 } 1793 IsNumber()1794 bool JSValueRef::IsNumber() 1795 { 1796 return JSNApiHelper::ToJSTaggedValue(this).IsNumber(); 1797 } 1798 IsBigInt()1799 bool JSValueRef::IsBigInt() 1800 { 1801 return JSNApiHelper::ToJSTaggedValue(this).IsBigInt(); 1802 } 1803 IsInt()1804 bool JSValueRef::IsInt() 1805 { 1806 return JSNApiHelper::ToJSTaggedValue(this).IsInt(); 1807 } 1808 WithinInt32()1809 bool JSValueRef::WithinInt32() 1810 { 1811 return JSNApiHelper::ToJSTaggedValue(this).WithinInt32(); 1812 } 1813 IsBoolean()1814 bool JSValueRef::IsBoolean() 1815 { 1816 return JSNApiHelper::ToJSTaggedValue(this).IsBoolean(); 1817 } 1818 IsString()1819 bool JSValueRef::IsString() 1820 { 1821 return JSNApiHelper::ToJSTaggedValue(this).IsString(); 1822 } 1823 IsSymbol()1824 bool JSValueRef::IsSymbol() 1825 { 1826 return JSNApiHelper::ToJSTaggedValue(this).IsSymbol(); 1827 } 1828 IsObject()1829 bool JSValueRef::IsObject() 1830 { 1831 return JSNApiHelper::ToJSTaggedValue(this).IsECMAObject(); 1832 } 1833 IsArray(const EcmaVM * vm)1834 bool JSValueRef::IsArray(const EcmaVM *vm) 1835 { 1836 JSThread *thread = vm->GetJSThread(); 1837 return JSNApiHelper::ToJSTaggedValue(this).IsArray(thread); 1838 } 1839 IsConstructor()1840 bool JSValueRef::IsConstructor() 1841 { 1842 JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this); 1843 return value.IsHeapObject() && value.IsConstructor(); 1844 } 1845 IsFunction()1846 bool JSValueRef::IsFunction() 1847 { 1848 JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this); 1849 return value.IsHeapObject() && value.IsCallable(); 1850 } 1851 IsProxy()1852 bool JSValueRef::IsProxy() 1853 { 1854 return JSNApiHelper::ToJSTaggedValue(this).IsJSProxy(); 1855 } 1856 IsException()1857 bool JSValueRef::IsException() 1858 { 1859 return JSNApiHelper::ToJSTaggedValue(this).IsException(); 1860 } 1861 IsPromise()1862 bool JSValueRef::IsPromise() 1863 { 1864 return JSNApiHelper::ToJSTaggedValue(this).IsJSPromise(); 1865 } 1866 IsDataView()1867 bool JSValueRef::IsDataView() 1868 { 1869 return JSNApiHelper::ToJSTaggedValue(this).IsDataView(); 1870 } 1871 IsTypedArray()1872 bool JSValueRef::IsTypedArray() 1873 { 1874 return JSNApiHelper::ToJSTaggedValue(this).IsTypedArray(); 1875 } 1876 IsNativePointer()1877 bool JSValueRef::IsNativePointer() 1878 { 1879 return JSNApiHelper::ToJSTaggedValue(this).IsJSNativePointer(); 1880 } 1881 IsDate()1882 bool JSValueRef::IsDate() 1883 { 1884 return JSNApiHelper::ToJSTaggedValue(this).IsDate(); 1885 } 1886 IsError()1887 bool JSValueRef::IsError() 1888 { 1889 return JSNApiHelper::ToJSTaggedValue(this).IsJSError(); 1890 } 1891 IsMap()1892 bool JSValueRef::IsMap() 1893 { 1894 return JSNApiHelper::ToJSTaggedValue(this).IsJSMap(); 1895 } 1896 IsSet()1897 bool JSValueRef::IsSet() 1898 { 1899 return JSNApiHelper::ToJSTaggedValue(this).IsJSSet(); 1900 } 1901 IsWeakMap()1902 bool JSValueRef::IsWeakMap() 1903 { 1904 return JSNApiHelper::ToJSTaggedValue(this).IsJSWeakMap(); 1905 } 1906 IsWeakSet()1907 bool JSValueRef::IsWeakSet() 1908 { 1909 return JSNApiHelper::ToJSTaggedValue(this).IsJSWeakSet(); 1910 } 1911 IsRegExp()1912 bool JSValueRef::IsRegExp() 1913 { 1914 return JSNApiHelper::ToJSTaggedValue(this).IsJSRegExp(); 1915 } 1916 IsArrayIterator()1917 bool JSValueRef::IsArrayIterator() 1918 { 1919 return JSNApiHelper::ToJSTaggedValue(this).IsJSArrayIterator(); 1920 } 1921 IsStringIterator()1922 bool JSValueRef::IsStringIterator() 1923 { 1924 return JSNApiHelper::ToJSTaggedValue(this).IsStringIterator(); 1925 } 1926 IsSetIterator()1927 bool JSValueRef::IsSetIterator() 1928 { 1929 return JSNApiHelper::ToJSTaggedValue(this).IsJSSetIterator(); 1930 } 1931 IsMapIterator()1932 bool JSValueRef::IsMapIterator() 1933 { 1934 return JSNApiHelper::ToJSTaggedValue(this).IsJSMapIterator(); 1935 } 1936 IsArrayBuffer()1937 bool JSValueRef::IsArrayBuffer() 1938 { 1939 return JSNApiHelper::ToJSTaggedValue(this).IsArrayBuffer(); 1940 } 1941 IsUint8Array()1942 bool JSValueRef::IsUint8Array() 1943 { 1944 return JSNApiHelper::ToJSTaggedValue(this).IsJSUint8Array(); 1945 } 1946 IsInt8Array()1947 bool JSValueRef::IsInt8Array() 1948 { 1949 return JSNApiHelper::ToJSTaggedValue(this).IsJSInt8Array(); 1950 } 1951 IsUint8ClampedArray()1952 bool JSValueRef::IsUint8ClampedArray() 1953 { 1954 return JSNApiHelper::ToJSTaggedValue(this).IsJSUint8ClampedArray(); 1955 } 1956 IsInt16Array()1957 bool JSValueRef::IsInt16Array() 1958 { 1959 return JSNApiHelper::ToJSTaggedValue(this).IsJSInt16Array(); 1960 } 1961 IsUint16Array()1962 bool JSValueRef::IsUint16Array() 1963 { 1964 return JSNApiHelper::ToJSTaggedValue(this).IsJSUint16Array(); 1965 } 1966 IsInt32Array()1967 bool JSValueRef::IsInt32Array() 1968 { 1969 return JSNApiHelper::ToJSTaggedValue(this).IsJSInt32Array(); 1970 } 1971 IsUint32Array()1972 bool JSValueRef::IsUint32Array() 1973 { 1974 return JSNApiHelper::ToJSTaggedValue(this).IsJSUint32Array(); 1975 } 1976 IsFloat32Array()1977 bool JSValueRef::IsFloat32Array() 1978 { 1979 return JSNApiHelper::ToJSTaggedValue(this).IsJSFloat32Array(); 1980 } 1981 IsFloat64Array()1982 bool JSValueRef::IsFloat64Array() 1983 { 1984 return JSNApiHelper::ToJSTaggedValue(this).IsJSFloat64Array(); 1985 } 1986 IsJSPrimitiveRef()1987 bool JSValueRef::IsJSPrimitiveRef() 1988 { 1989 return JSNApiHelper::ToJSTaggedValue(this).IsJSPrimitiveRef(); 1990 } 1991 IsJSPrimitiveNumber()1992 bool JSValueRef::IsJSPrimitiveNumber() 1993 { 1994 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 1995 return JSPrimitiveRef::Cast(obj->GetHeapObject())->IsNumber(); 1996 } 1997 IsJSPrimitiveInt()1998 bool JSValueRef::IsJSPrimitiveInt() 1999 { 2000 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 2001 return JSPrimitiveRef::Cast(obj->GetHeapObject())->IsInt(); 2002 } 2003 IsJSPrimitiveBoolean()2004 bool JSValueRef::IsJSPrimitiveBoolean() 2005 { 2006 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 2007 return JSPrimitiveRef::Cast(obj->GetHeapObject())->IsBoolean(); 2008 } 2009 IsJSPrimitiveString()2010 bool JSValueRef::IsJSPrimitiveString() 2011 { 2012 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 2013 return JSPrimitiveRef::Cast(obj->GetHeapObject())->IsString(); 2014 } 2015 IsJSPrimitiveSymbol()2016 bool JSValueRef::IsJSPrimitiveSymbol() 2017 { 2018 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 2019 return JSPrimitiveRef::Cast(obj->GetHeapObject())->IsSymbol(); 2020 } 2021 IsGeneratorObject()2022 bool JSValueRef::IsGeneratorObject() 2023 { 2024 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 2025 bool rst = obj->IsGeneratorObject(); 2026 return rst; 2027 } 2028 IsAsyncFunction()2029 bool JSValueRef::IsAsyncFunction() 2030 { 2031 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 2032 bool rst = obj->IsJSAsyncFunction(); 2033 return rst; 2034 } 2035 IsArgumentsObject()2036 bool JSValueRef::IsArgumentsObject() 2037 { 2038 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 2039 bool rst = obj->IsArguments(); 2040 return rst; 2041 } 2042 IsGeneratorFunction()2043 bool JSValueRef::IsGeneratorFunction() 2044 { 2045 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this); 2046 bool rst = obj->IsGeneratorFunction(); 2047 return rst; 2048 } StartCpuProfiler(const EcmaVM * vm,const std::string & fileName)2049 void JSNApi::StartCpuProfiler(const EcmaVM *vm, const std::string &fileName) 2050 { 2051 panda::ecmascript::CpuProfiler* singleton = panda::ecmascript::CpuProfiler::GetInstance(); 2052 singleton->StartCpuProfiler(vm, fileName); 2053 } 2054 StopCpuProfiler()2055 void JSNApi::StopCpuProfiler() 2056 { 2057 panda::ecmascript::CpuProfiler* singleton = panda::ecmascript::CpuProfiler::GetInstance(); 2058 singleton->StopCpuProfiler(); 2059 if (singleton != nullptr) { 2060 delete singleton; 2061 singleton = nullptr; 2062 } 2063 } 2064 SuspendVM(const EcmaVM * vm)2065 bool JSNApi::SuspendVM(const EcmaVM *vm) 2066 { 2067 ecmascript::JSThread* thread = vm->GetJSThreadNoCheck(); 2068 return thread->NotifyVMThreadSuspension(); 2069 } 2070 ResumeVM(const EcmaVM * vm)2071 void JSNApi::ResumeVM(const EcmaVM *vm) 2072 { 2073 ecmascript::JSThread* thread = vm->GetJSThreadNoCheck(); 2074 thread->ResumeVM(); 2075 } 2076 IsSuspended(const EcmaVM * vm)2077 bool JSNApi::IsSuspended(const EcmaVM *vm) 2078 { 2079 ecmascript::JSThread* thread = vm->GetJSThreadNoCheck(); 2080 return thread->IsSuspended(); 2081 } 2082 CheckSafepoint(const EcmaVM * vm)2083 bool JSNApi::CheckSafepoint(const EcmaVM *vm) 2084 { 2085 ecmascript::JSThread* thread = vm->GetJSThread(); 2086 return thread->CheckSafepoint(); 2087 } 2088 } // namespace panda 2089