• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.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/path_helper.h"
25 #include "ecmascript/base/string_helper.h"
26 #include "ecmascript/base/typed_array_helper-inl.h"
27 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
28 #include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
29 #endif
30 #include "ecmascript/debugger/js_debugger_manager.h"
31 #include "ecmascript/ecma_global_storage.h"
32 #include "ecmascript/ecma_runtime_call_info.h"
33 #include "ecmascript/ecma_string.h"
34 #include "ecmascript/ecma_vm.h"
35 #include "ecmascript/aot_file_manager.h"
36 #include "ecmascript/global_env.h"
37 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
38 #include "ecmascript/jobs/micro_job_queue.h"
39 #include "ecmascript/jspandafile/debug_info_extractor.h"
40 #include "ecmascript/jspandafile/js_pandafile_executor.h"
41 #include "ecmascript/jspandafile/js_pandafile_manager.h"
42 #include "ecmascript/jspandafile/quick_fix_manager.h"
43 #include "ecmascript/js_array.h"
44 #include "ecmascript/js_arraybuffer.h"
45 #include "ecmascript/js_bigint.h"
46 #include "ecmascript/js_collator.h"
47 #include "ecmascript/js_dataview.h"
48 #include "ecmascript/byte_array.h"
49 #include "ecmascript/js_date_time_format.h"
50 #include "ecmascript/js_file_path.h"
51 #include "ecmascript/js_function.h"
52 #include "ecmascript/js_generator_object.h"
53 #include "ecmascript/js_iterator.h"
54 #include "ecmascript/js_map.h"
55 #include "ecmascript/js_map_iterator.h"
56 #include "ecmascript/js_number_format.h"
57 #include "ecmascript/js_primitive_ref.h"
58 #include "ecmascript/js_promise.h"
59 #include "ecmascript/js_regexp.h"
60 #include "ecmascript/js_runtime_options.h"
61 #include "ecmascript/js_serializer.h"
62 #include "ecmascript/js_set.h"
63 #include "ecmascript/js_set_iterator.h"
64 #include "ecmascript/js_tagged_number.h"
65 #include "ecmascript/js_thread.h"
66 #include "ecmascript/js_typed_array.h"
67 #include "ecmascript/linked_hash_table.h"
68 #include "ecmascript/log.h"
69 #include "ecmascript/mem/mem.h"
70 #include "ecmascript/mem/mem_map_allocator.h"
71 #include "ecmascript/mem/region.h"
72 #include "ecmascript/module/js_module_manager.h"
73 #include "ecmascript/module/js_module_source_text.h"
74 #include "ecmascript/object_factory.h"
75 #include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
76 #include "ecmascript/platform/file.h"
77 #include "ecmascript/tagged_array.h"
78 #include "ecmascript/regexp/regexp_parser.h"
79 
80 #include "ohos/init_data.h"
81 
82 #include "os/mutex.h"
83 
84 #if defined(PANDA_TARGET_IOS)
85 namespace OHOS::ArkCompiler::Toolchain {
86 using DebuggerPostTask = std::function<void(std::function<void()> &&)>;
87 extern "C" {
88     bool StartDebug(const std::string& componentName, void* vm, bool isDebugMode, int32_t instanceId,
89         const DebuggerPostTask& debuggerPostTask);
90     void StopDebug(const std::string& componentName);
91 }
92 } // namespace OHOS::ArkCompiler::Toolchain
93 const std::string DEBUGGER_NAME = "PandaDebugger";
94 #endif
95 
96 namespace panda {
97 using ecmascript::ECMAObject;
98 using ecmascript::EcmaString;
99 using ecmascript::EcmaStringAccessor;
100 using ecmascript::ErrorType;
101 using ecmascript::FastRuntimeStub;
102 using ecmascript::GlobalEnv;
103 using ecmascript::GlobalEnvConstants;
104 using ecmascript::EcmaRuntimeCallInfo;
105 using ecmascript::JSArray;
106 using ecmascript::JSArrayBuffer;
107 using ecmascript::JSDataView;
108 using ecmascript::ByteArray;
109 using ecmascript::JSDate;
110 using ecmascript::JSFunction;
111 using ecmascript::JSFunctionBase;
112 using ecmascript::JSHClass;
113 using ecmascript::JSMap;
114 using ecmascript::Method;
115 using ecmascript::JSNativePointer;
116 using ecmascript::JSObject;
117 using ecmascript::JSPandaFile;
118 using ecmascript::JSPandaFileManager;
119 using ecmascript::JSPrimitiveRef;
120 using ecmascript::JSPromise;
121 using ecmascript::JSRegExp;
122 using ecmascript::JSSerializer;
123 using ecmascript::JSSet;
124 using ecmascript::JSSymbol;
125 using ecmascript::JSTaggedNumber;
126 using ecmascript::JSTaggedType;
127 using ecmascript::JSTaggedValue;
128 using ecmascript::JSThread;
129 using ecmascript::LinkedHashMap;
130 using ecmascript::LinkedHashSet;
131 using ecmascript::ObjectFactory;
132 using ecmascript::PromiseCapability;
133 using ecmascript::PropertyDescriptor;
134 using ecmascript::OperationResult;
135 using ecmascript::Region;
136 using ecmascript::TaggedArray;
137 using ecmascript::JSTypedArray;
138 using ecmascript::base::BuiltinsBase;
139 using ecmascript::base::JsonParser;
140 using ecmascript::base::JsonStringifier;
141 using ecmascript::base::StringHelper;
142 using ecmascript::base::TypedArrayHelper;
143 using ecmascript::job::MicroJobQueue;
144 using ecmascript::job::QueueType;
145 using ecmascript::JSRuntimeOptions;
146 using ecmascript::BigInt;
147 using ecmascript::MemMapAllocator;
148 using ecmascript::JSMapIterator;
149 using ecmascript::JSSetIterator;
150 using ecmascript::IterationKind;
151 using ecmascript::JSGeneratorState;
152 using ecmascript::JSIterator;
153 using ecmascript::JSGeneratorFunction;
154 using ecmascript::JSGeneratorObject;
155 using ecmascript::GeneratorContext;
156 using ecmascript::JSCollator;
157 using ecmascript::JSDateTimeFormat;
158 using ecmascript::JSNumberFormat;
159 using ecmascript::RegExpParser;
160 using ecmascript::DebugInfoExtractor;
161 using ecmascript::base::NumberHelper;
162 template<typename T>
163 using JSHandle = ecmascript::JSHandle<T>;
164 
165 template<typename T>
166 using JSMutableHandle = ecmascript::JSMutableHandle<T>;
167 
168 using PathHelper = ecmascript::base::PathHelper;
169 namespace {
170 // NOLINTNEXTLINE(fuchsia-statically-constructed-objects)
171 constexpr std::string_view ENTRY_POINTER = "_GLOBAL::func_main_0";
172 }
173 int JSNApi::vmCount_ = 0;
174 bool JSNApi::initialize_ = false;
175 static os::memory::Mutex mutex;
176 
177 // ------------------------------------ Panda -----------------------------------------------
CreateJSVM(const RuntimeOption & option)178 EcmaVM *JSNApi::CreateJSVM(const RuntimeOption &option)
179 {
180     JSRuntimeOptions runtimeOptions;
181     runtimeOptions.SetArkProperties(option.GetArkProperties());
182     runtimeOptions.SetArkBundleName(option.GetArkBundleName());
183     runtimeOptions.SetLongPauseTime(option.GetLongPauseTime());
184     runtimeOptions.SetGcThreadNum(option.GetGcThreadNum());
185     runtimeOptions.SetIsWorker(option.GetIsWorker());
186     // Mem
187     runtimeOptions.SetHeapSizeLimit(option.GetGcPoolSize());
188 // Disable the asm-interpreter of ark-engine for ios-platform temporarily.
189 #if !defined(PANDA_TARGET_IOS) && !defined(DISABLE_ASM_INTERPRETER)
190     // asmInterpreter
191     runtimeOptions.SetEnableAsmInterpreter(option.GetEnableAsmInterpreter());
192 #else
193     runtimeOptions.SetEnableAsmInterpreter(false);
194 #endif
195     runtimeOptions.SetAsmOpcodeDisableRange(option.GetAsmOpcodeDisableRange());
196     // aot
197     runtimeOptions.SetEnableAOT(option.GetEnableAOT());
198     runtimeOptions.SetEnablePGOProfiler(option.GetEnableProfile());
199     runtimeOptions.SetPGOProfilerPath(option.GetProfileDir());
200 
201     // Dfx
202     runtimeOptions.SetLogLevel(option.GetLogLevel());
203     runtimeOptions.SetEnableArkTools(option.GetEnableArkTools());
204     return CreateEcmaVM(runtimeOptions);
205 }
206 
CreateEcmaVM(const JSRuntimeOptions & options)207 EcmaVM *JSNApi::CreateEcmaVM(const JSRuntimeOptions &options)
208 {
209     {
210         os::memory::LockHolder lock(mutex);
211         vmCount_++;
212         if (!initialize_) {
213             ecmascript::Log::Initialize(options);
214             InitializeIcuData(options);
215             InitializeMemMapAllocator();
216             InitializePGOProfiler(options);
217             initialize_ = true;
218         }
219     }
220     auto config = ecmascript::EcmaParamConfiguration(options.IsWorker(),
221         MemMapAllocator::GetInstance()->GetCapacity());
222     LOG_ECMA(INFO) << " [NAPI]: CreateEcmaVM, isWorker = " << options.IsWorker() << ", vmCount = " << vmCount_;
223     MemMapAllocator::GetInstance()->IncreaseAndCheckReserved(config.GetMaxHeapSize());
224     return EcmaVM::Create(options, config);
225 }
226 
DestroyJSVM(EcmaVM * ecmaVm)227 void JSNApi::DestroyJSVM(EcmaVM *ecmaVm)
228 {
229     os::memory::LockHolder lock(mutex);
230     if (!initialize_) {
231         return;
232     }
233     auto &config = ecmaVm->GetEcmaParamConfiguration();
234     MemMapAllocator::GetInstance()->DecreaseReserved(config.GetMaxHeapSize());
235     EcmaVM::Destroy(ecmaVm);
236     vmCount_--;
237     if (vmCount_ <= 0) {
238         DestoryAnDataManager();
239         DestroyMemMapAllocator();
240         DestroyPGOProfiler();
241         initialize_ = false;
242     }
243 }
244 
CleanJSVMCache()245 void JSNApi::CleanJSVMCache()
246 {
247     JSPandaFileManager::GetInstance()->ClearCache();
248 }
249 
TriggerGC(const EcmaVM * vm,TRIGGER_GC_TYPE gcType)250 void JSNApi::TriggerGC(const EcmaVM *vm,  TRIGGER_GC_TYPE gcType)
251 {
252     if (vm->GetJSThread() != nullptr && vm->IsInitialized()) {
253         switch (gcType) {
254             case TRIGGER_GC_TYPE::SEMI_GC:
255                 vm->CollectGarbage(ecmascript::TriggerGCType::YOUNG_GC);
256                 break;
257             case TRIGGER_GC_TYPE::OLD_GC:
258                 vm->CollectGarbage(ecmascript::TriggerGCType::OLD_GC);
259                 break;
260             case TRIGGER_GC_TYPE::FULL_GC:
261                 vm->CollectGarbage(ecmascript::TriggerGCType::FULL_GC);
262                 break;
263             default:
264                 break;
265         }
266     }
267 }
268 
ThrowException(const EcmaVM * vm,Local<JSValueRef> error)269 void JSNApi::ThrowException(const EcmaVM *vm, Local<JSValueRef> error)
270 {
271     auto thread = vm->GetJSThread();
272     thread->SetException(JSNApiHelper::ToJSTaggedValue(*error));
273 }
274 
275 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
276 #if !defined(PANDA_TARGET_IOS)
StartDebugger(const char * libraryPath,EcmaVM * vm,bool isDebugMode,int32_t instanceId,const DebuggerPostTask & debuggerPostTask)277 bool JSNApi::StartDebugger(const char *libraryPath, EcmaVM *vm, bool isDebugMode, int32_t instanceId,
278     const DebuggerPostTask &debuggerPostTask)
279 {
280     const auto &handler = vm->GetJsDebuggerManager()->GetDebugLibraryHandle();
281     if (handler.IsValid()) {
282         return false;
283     }
284 
285     auto handle = panda::os::library_loader::Load(std::string(libraryPath));
286     if (!handle) {
287         return false;
288     }
289 
290     using StartDebugger = bool (*)(const std::string &, EcmaVM *, bool, int32_t, const DebuggerPostTask &);
291 
292     auto sym = panda::os::library_loader::ResolveSymbol(handle.Value(), "StartDebug");
293     if (!sym) {
294         LOG_ECMA(ERROR) << sym.Error().ToString();
295         return false;
296     }
297 
298     bool ret = reinterpret_cast<StartDebugger>(sym.Value())("PandaDebugger", vm, isDebugMode, instanceId,
299         debuggerPostTask);
300     if (ret) {
301         vm->GetJsDebuggerManager()->SetDebugMode(isDebugMode);
302         vm->GetJsDebuggerManager()->SetDebugLibraryHandle(std::move(handle.Value()));
303     }
304     return ret;
305 }
306 
StopDebugger(EcmaVM * vm)307 bool JSNApi::StopDebugger(EcmaVM *vm)
308 {
309     if (vm == nullptr) {
310         return false;
311     }
312     const auto &handle = vm->GetJsDebuggerManager()->GetDebugLibraryHandle();
313 
314     using StopDebug = void (*)(const std::string &);
315 
316     auto sym = panda::os::library_loader::ResolveSymbol(handle, "StopDebug");
317     if (!sym) {
318         LOG_ECMA(ERROR) << sym.Error().ToString();
319         return false;
320     }
321 
322     reinterpret_cast<StopDebug>(sym.Value())("PandaDebugger");
323     vm->GetJsDebuggerManager()->SetDebugMode(false);
324     return true;
325 }
326 #else
StartDebugger(EcmaVM * vm,bool isDebugMode,int32_t instanceId,const DebuggerPostTask & debuggerPostTask)327 bool JSNApi::StartDebugger(EcmaVM *vm, bool isDebugMode, int32_t instanceId, const DebuggerPostTask &debuggerPostTask)
328 {
329     bool ret = OHOS::ArkCompiler::Toolchain::StartDebug(DEBUGGER_NAME, vm, isDebugMode, instanceId, debuggerPostTask);
330     if (ret) {
331         vm->GetJsDebuggerManager()->SetDebugMode(isDebugMode);
332     }
333     return ret;
334 }
335 
StopDebugger(EcmaVM * vm)336 bool JSNApi::StopDebugger(EcmaVM *vm)
337 {
338     if (vm == nullptr) {
339         return false;
340     }
341 
342     OHOS::ArkCompiler::Toolchain::StopDebug(DEBUGGER_NAME);
343     vm->GetJsDebuggerManager()->SetDebugMode(false);
344     return true;
345 }
346 #endif
347 
IsMixedDebugEnabled(const EcmaVM * vm)348 bool JSNApi::IsMixedDebugEnabled(const EcmaVM *vm)
349 {
350     return vm->GetJsDebuggerManager()->IsMixedDebugEnabled();
351 }
352 
NotifyNativeCalling(const EcmaVM * vm,const void * nativeAddress)353 void JSNApi::NotifyNativeCalling(const EcmaVM *vm, const void *nativeAddress)
354 {
355     vm->GetJsDebuggerManager()->GetNotificationManager()->NativeCallingEvent(nativeAddress);
356 }
357 #endif
358 
LoadAotFile(EcmaVM * vm,const std::string & hapPath)359 void JSNApi::LoadAotFile(EcmaVM *vm, const std::string &hapPath)
360 {
361     if (!ecmascript::AnFileDataManager::GetInstance()->IsEnable()) {
362         return;
363     }
364     std::string aotFileName = ecmascript::AnFileDataManager::GetInstance()->GetDir();
365     aotFileName += ecmascript::JSFilePath::GetFileName(hapPath);
366     LOG_ECMA(INFO) << "start to load aot file: " << aotFileName;
367     vm->LoadAOTFiles(aotFileName);
368 }
369 
Execute(EcmaVM * vm,const std::string & fileName,const std::string & entry,bool needUpdate)370 bool JSNApi::Execute(EcmaVM *vm, const std::string &fileName, const std::string &entry, bool needUpdate)
371 {
372     LOG_ECMA(DEBUG) << "start to execute ark file: " << fileName;
373     JSThread *thread = vm->GetAssociatedJSThread();
374     if (!ecmascript::JSPandaFileExecutor::ExecuteFromFile(thread, fileName.c_str(), entry, needUpdate)) {
375         LOG_ECMA(ERROR) << "Cannot execute ark file '" << fileName
376                         << "' with entry '" << entry << "'" << std::endl;
377         return false;
378     }
379     return true;
380 }
381 
Execute(EcmaVM * vm,const uint8_t * data,int32_t size,const std::string & entry,const std::string & filename,bool needUpdate)382 bool JSNApi::Execute(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &entry,
383                      const std::string &filename, bool needUpdate)
384 {
385     LOG_ECMA(DEBUG) << "start to execute ark buffer: " << filename;
386     JSThread *thread = vm->GetAssociatedJSThread();
387     if (!ecmascript::JSPandaFileExecutor::ExecuteFromBuffer(
388             thread, data, size, entry, filename.c_str(), needUpdate)) {
389         LOG_ECMA(ERROR) << "Cannot execute ark buffer file '" << filename
390                         << "' with entry '" << entry << "'" << std::endl;
391         return false;
392     }
393     return true;
394 }
395 
ExecuteModuleBuffer(EcmaVM * vm,const uint8_t * data,int32_t size,const std::string & filename,bool needUpdate)396 bool JSNApi::ExecuteModuleBuffer(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &filename,
397                                  bool needUpdate)
398 {
399     LOG_ECMA(DEBUG) << "start to execute module buffer: " << filename;
400     JSThread *thread = vm->GetAssociatedJSThread();
401     if (!ecmascript::JSPandaFileExecutor::ExecuteModuleBuffer(thread, data, size, filename.c_str(), needUpdate)) {
402         LOG_ECMA(ERROR) << "Cannot execute module buffer file '" << filename;
403         return false;
404     }
405     return true;
406 }
407 
PreFork(EcmaVM * vm)408 void JSNApi::PreFork(EcmaVM *vm)
409 {
410     vm->PreFork();
411 }
412 
PostFork(EcmaVM * vm,const RuntimeOption & option)413 void JSNApi::PostFork(EcmaVM *vm, const RuntimeOption &option)
414 {
415     JSRuntimeOptions &jsOption = vm->GetJSOptions();
416     LOG_ECMA(INFO) << "asmint: " << jsOption.GetEnableAsmInterpreter()
417                     << ", aot: " << jsOption.GetEnableAOT()
418                     << ", bundle name: " <<  option.GetBundleName();
419     jsOption.SetEnablePGOProfiler(option.GetEnableProfile());
420     vm->ResetPGOProfiler();
421 
422     if (jsOption.GetEnableAOT() && option.GetAnDir().size()) {
423         ecmascript::AnFileDataManager::GetInstance()->SetDir(option.GetAnDir());
424         ecmascript::AnFileDataManager::GetInstance()->SetEnable(true);
425     }
426 
427     vm->PostFork();
428 }
429 
addWorker(EcmaVM * hostVm,EcmaVM * workerVm)430 void JSNApi::addWorker(EcmaVM *hostVm, EcmaVM *workerVm)
431 {
432     if (hostVm != nullptr && workerVm != nullptr) {
433         hostVm->WorkersetInfo(hostVm, workerVm);
434     }
435 }
436 
DeleteWorker(EcmaVM * hostVm,EcmaVM * workerVm)437 bool JSNApi::DeleteWorker(EcmaVM *hostVm, EcmaVM *workerVm)
438 {
439     if (hostVm != nullptr && workerVm != nullptr) {
440         return hostVm->DeleteWorker(hostVm, workerVm);
441     }
442     return false;
443 }
444 
GetUncaughtException(const EcmaVM * vm)445 Local<ObjectRef> JSNApi::GetUncaughtException(const EcmaVM *vm)
446 {
447     return JSNApiHelper::ToLocal<ObjectRef>(vm->GetEcmaUncaughtException());
448 }
449 
GetAndClearUncaughtException(const EcmaVM * vm)450 Local<ObjectRef> JSNApi::GetAndClearUncaughtException(const EcmaVM *vm)
451 {
452     return JSNApiHelper::ToLocal<ObjectRef>(vm->GetAndClearEcmaUncaughtException());
453 }
454 
HasPendingException(const EcmaVM * vm)455 bool JSNApi::HasPendingException(const EcmaVM *vm)
456 {
457     return vm->GetJSThread()->HasPendingException();
458 }
459 
EnableUserUncaughtErrorHandler(EcmaVM * vm)460 void JSNApi::EnableUserUncaughtErrorHandler(EcmaVM *vm)
461 {
462     return vm->EnableUserUncaughtErrorHandler();
463 }
464 
GetGlobalObject(const EcmaVM * vm)465 Local<ObjectRef> JSNApi::GetGlobalObject(const EcmaVM *vm)
466 {
467     JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
468     JSHandle<JSTaggedValue> global(vm->GetJSThread(), globalEnv->GetGlobalObject());
469     return JSNApiHelper::ToLocal<ObjectRef>(global);
470 }
471 
ExecutePendingJob(const EcmaVM * vm)472 void JSNApi::ExecutePendingJob(const EcmaVM *vm)
473 {
474     EcmaVM::ConstCast(vm)->ExecutePromisePendingJob();
475 }
476 
GetHandleAddr(const EcmaVM * vm,uintptr_t localAddress)477 uintptr_t JSNApi::GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress)
478 {
479     if (localAddress == 0) {
480         return 0;
481     }
482     JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(localAddress));
483     return ecmascript::EcmaHandleScope::NewHandle(vm->GetJSThread(), value);
484 }
485 
GetGlobalHandleAddr(const EcmaVM * vm,uintptr_t localAddress)486 uintptr_t JSNApi::GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress)
487 {
488     if (localAddress == 0) {
489         return 0;
490     }
491     JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(localAddress));
492     return vm->GetJSThread()->NewGlobalHandle(value);
493 }
494 
SetWeak(const EcmaVM * vm,uintptr_t localAddress)495 uintptr_t JSNApi::SetWeak(const EcmaVM *vm, uintptr_t localAddress)
496 {
497     if (localAddress == 0) {
498         return 0;
499     }
500     return vm->GetJSThread()->SetWeak(localAddress);
501 }
502 
SetWeakCallback(const EcmaVM * vm,uintptr_t localAddress,void * ref,WeakRefClearCallBack firstCallback,WeakRefClearCallBack secondCallback)503 uintptr_t JSNApi::SetWeakCallback(const EcmaVM *vm, uintptr_t localAddress, void *ref,
504                                   WeakRefClearCallBack firstCallback, WeakRefClearCallBack secondCallback)
505 {
506     if (localAddress == 0) {
507         return 0;
508     }
509     return vm->GetJSThread()->SetWeak(localAddress, ref, firstCallback, secondCallback);
510 }
511 
ClearWeak(const EcmaVM * vm,uintptr_t localAddress)512 uintptr_t JSNApi::ClearWeak(const EcmaVM *vm, uintptr_t localAddress)
513 {
514     if (localAddress == 0) {
515         return 0;
516     }
517     if (JSTaggedValue(reinterpret_cast<ecmascript::Node *>(localAddress)->GetObject())
518         .IsUndefined()) {
519         LOG_ECMA(ERROR) << "The object of weak reference has been recycled!";
520         return 0;
521     }
522     return vm->GetJSThread()->ClearWeak(localAddress);
523 }
524 
IsWeak(const EcmaVM * vm,uintptr_t localAddress)525 bool JSNApi::IsWeak(const EcmaVM *vm, uintptr_t localAddress)
526 {
527     if (localAddress == 0) {
528         return false;
529     }
530     return vm->GetJSThread()->IsWeak(localAddress);
531 }
532 
DisposeGlobalHandleAddr(const EcmaVM * vm,uintptr_t addr)533 void JSNApi::DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr)
534 {
535     if (addr == 0 || !reinterpret_cast<ecmascript::Node *>(addr)->IsUsing()) {
536         return;
537     }
538     vm->GetJSThread()->DisposeGlobalHandle(addr);
539 }
540 
SerializeValue(const EcmaVM * vm,Local<JSValueRef> value,Local<JSValueRef> transfer)541 void *JSNApi::SerializeValue(const EcmaVM *vm, Local<JSValueRef> value, Local<JSValueRef> transfer)
542 {
543     ecmascript::JSThread *thread = vm->GetJSThread();
544     ecmascript::Serializer serializer(thread);
545     JSHandle<JSTaggedValue> arkValue = JSNApiHelper::ToJSHandle(value);
546     JSHandle<JSTaggedValue> arkTransfer = JSNApiHelper::ToJSHandle(transfer);
547     std::unique_ptr<ecmascript::SerializationData> data;
548     if (serializer.WriteValue(thread, arkValue, arkTransfer)) {
549         data = serializer.Release();
550     }
551     if (data == nullptr) {
552         return nullptr;
553     } else {
554         return reinterpret_cast<void *>(data.release());
555     }
556 }
557 
DeserializeValue(const EcmaVM * vm,void * recoder,void * hint)558 Local<JSValueRef> JSNApi::DeserializeValue(const EcmaVM *vm, void *recoder, void *hint)
559 {
560     ecmascript::JSThread *thread = vm->GetJSThread();
561     std::unique_ptr<ecmascript::SerializationData> data(reinterpret_cast<ecmascript::SerializationData *>(recoder));
562     ecmascript::Deserializer deserializer(thread, data.release(), hint);
563     JSHandle<JSTaggedValue> result = deserializer.ReadValue();
564     return JSNApiHelper::ToLocal<ObjectRef>(result);
565 }
566 
DeleteSerializationData(void * data)567 void JSNApi::DeleteSerializationData(void *data)
568 {
569     ecmascript::SerializationData *value = reinterpret_cast<ecmascript::SerializationData *>(data);
570     delete value;
571     value = nullptr;
572 }
573 
HostPromiseRejectionTracker(const EcmaVM * vm,const JSHandle<JSPromise> promise,const JSHandle<JSTaggedValue> reason,const ecmascript::PromiseRejectionEvent operation,void * data)574 void HostPromiseRejectionTracker(const EcmaVM *vm,
575                                  const JSHandle<JSPromise> promise,
576                                  const JSHandle<JSTaggedValue> reason,
577                                  const ecmascript::PromiseRejectionEvent operation,
578                                  void* data)
579 {
580     ecmascript::PromiseRejectCallback promiseRejectCallback = vm->GetPromiseRejectCallback();
581     if (promiseRejectCallback != nullptr) {
582         Local<JSValueRef> promiseVal = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>::Cast(promise));
583         PromiseRejectInfo promiseRejectInfo(promiseVal, JSNApiHelper::ToLocal<JSValueRef>(reason),
584                               static_cast<PromiseRejectInfo::PROMISE_REJECTION_EVENT>(operation), data);
585         promiseRejectCallback(reinterpret_cast<void*>(&promiseRejectInfo));
586     }
587 }
588 
SetHostPromiseRejectionTracker(EcmaVM * vm,void * cb,void * data)589 void JSNApi::SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data)
590 {
591     vm->SetHostPromiseRejectionTracker(HostPromiseRejectionTracker);
592     vm->SetPromiseRejectCallback(reinterpret_cast<ecmascript::PromiseRejectCallback>(cb));
593     vm->SetData(data);
594 }
595 
SetHostResolveBufferTracker(EcmaVM * vm,std::function<std::vector<uint8_t> (std::string dirPath,std::string requestPath)> cb)596 void JSNApi::SetHostResolveBufferTracker(EcmaVM *vm,
597     std::function<std::vector<uint8_t>(std::string dirPath, std::string requestPath)> cb)
598 {
599     vm->SetResolveBufferCallback(cb);
600 }
601 
SetNativePtrGetter(EcmaVM * vm,void * cb)602 void JSNApi::SetNativePtrGetter(EcmaVM *vm, void* cb)
603 {
604     vm->SetNativePtrGetter(reinterpret_cast<ecmascript::NativePtrGetter>(cb));
605 }
606 
SetHostEnqueueJob(const EcmaVM * vm,Local<JSValueRef> cb)607 void JSNApi::SetHostEnqueueJob(const EcmaVM *vm, Local<JSValueRef> cb)
608 {
609     JSHandle<JSFunction> fun = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(cb));
610     JSHandle<TaggedArray> array = vm->GetFactory()->EmptyArray();
611     JSHandle<MicroJobQueue> job = vm->GetMicroJobQueue();
612     MicroJobQueue::EnqueueJob(vm->GetJSThread(), job, QueueType::QUEUE_PROMISE, fun, array);
613 }
614 
PromiseRejectInfo(Local<JSValueRef> promise,Local<JSValueRef> reason,PromiseRejectInfo::PROMISE_REJECTION_EVENT operation,void * data)615 PromiseRejectInfo::PromiseRejectInfo(Local<JSValueRef> promise, Local<JSValueRef> reason,
616                                      PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data)
617     : promise_(promise), reason_(reason), operation_(operation), data_(data) {}
618 
GetPromise() const619 Local<JSValueRef> PromiseRejectInfo::GetPromise() const
620 {
621     return promise_;
622 }
623 
GetReason() const624 Local<JSValueRef> PromiseRejectInfo::GetReason() const
625 {
626     return reason_;
627 }
628 
GetOperation() const629 PromiseRejectInfo::PROMISE_REJECTION_EVENT PromiseRejectInfo::GetOperation() const
630 {
631     return operation_;
632 }
633 
GetData() const634 void* PromiseRejectInfo::GetData() const
635 {
636     return data_;
637 }
638 
ExecuteModuleFromBuffer(EcmaVM * vm,const void * data,int32_t size,const std::string & file)639 bool JSNApi::ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file)
640 {
641     JSThread *thread = vm->GetAssociatedJSThread();
642     if (!ecmascript::JSPandaFileExecutor::ExecuteFromBuffer(thread, data, size, ENTRY_POINTER, file.c_str())) {
643         std::cerr << "Cannot execute panda file from memory" << std::endl;
644         return false;
645     }
646     return true;
647 }
648 
GetExportObject(EcmaVM * vm,const std::string & file,const std::string & key)649 Local<ObjectRef> JSNApi::GetExportObject(EcmaVM *vm, const std::string &file, const std::string &key)
650 {
651     ecmascript::CString entry = file.c_str();
652     JSThread *thread = vm->GetJSThread();
653     ecmascript::CString name = vm->GetAssetPath();
654     if (!vm->IsBundlePack()) {
655         entry = PathHelper::ParseOhmUrl(vm, entry, name);
656         const JSPandaFile *jsPandaFile =
657             JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, name, entry.c_str(), false);
658         if (jsPandaFile == nullptr) {
659             JSHandle<JSTaggedValue> exportObj(thread, JSTaggedValue::Null());
660             return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
661         }
662         if (!jsPandaFile->IsRecordWithBundleName()) {
663             PathHelper::CroppingRecord(entry);
664         }
665     }
666     ecmascript::ModuleManager *moduleManager = vm->GetModuleManager();
667     JSHandle<ecmascript::SourceTextModule> ecmaModule = moduleManager->HostGetImportedModule(entry);
668     if (ecmaModule->GetIsNewBcVersion()) {
669         int index = ecmascript::ModuleManager::GetExportObjectIndex(vm, ecmaModule, key);
670         JSTaggedValue result = ecmaModule->GetModuleValue(thread, index, false);
671         JSHandle<JSTaggedValue> exportObj(thread, result);
672         return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
673     }
674     ObjectFactory *factory = vm->GetFactory();
675     JSHandle<EcmaString> keyHandle = factory->NewFromASCII(key.c_str());
676 
677     JSTaggedValue result = ecmaModule->GetModuleValue(thread, keyHandle.GetTaggedValue(), false);
678     JSHandle<JSTaggedValue> exportObj(thread, result);
679     return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
680 }
681 
GetExportObjectFromBuffer(EcmaVM * vm,const std::string & file,const std::string & key)682 Local<ObjectRef> JSNApi::GetExportObjectFromBuffer(EcmaVM *vm, const std::string &file,
683                                                    const std::string &key)
684 {
685     ecmascript::ModuleManager *moduleManager = vm->GetModuleManager();
686     JSThread *thread = vm->GetJSThread();
687     JSHandle<ecmascript::SourceTextModule> ecmaModule = moduleManager->HostGetImportedModule(file.c_str());
688 
689     if (ecmaModule->GetIsNewBcVersion()) {
690         int index = ecmascript::ModuleManager::GetExportObjectIndex(vm, ecmaModule, key);
691         JSTaggedValue result = ecmaModule->GetModuleValue(thread, index, false);
692         JSHandle<JSTaggedValue> exportObj(thread, result);
693         return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
694     }
695 
696     ObjectFactory *factory = vm->GetFactory();
697     JSHandle<EcmaString> keyHandle = factory->NewFromASCII(key.c_str());
698     JSTaggedValue result = ecmaModule->GetModuleValue(thread, keyHandle.GetTaggedValue(), false);
699     JSHandle<JSTaggedValue> exportObj(thread, result);
700     return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
701 }
702 
703  // Initialize IcuData Path
InitializeIcuData(const JSRuntimeOptions & options)704 void JSNApi::InitializeIcuData(const JSRuntimeOptions &options)
705 {
706     std::string icuPath = options.GetIcuDataPath();
707     if (icuPath == "default") {
708 #if !WIN_OR_MAC_OR_IOS_PLATFORM && !defined(PANDA_TARGET_LINUX)
709         SetHwIcuDirectory();
710 #endif
711     } else {
712         std::string absPath;
713         if (ecmascript::RealPath(icuPath, absPath)) {
714             u_setDataDirectory(absPath.c_str());
715         }
716     }
717 }
718 
InitializeMemMapAllocator()719 void JSNApi::InitializeMemMapAllocator()
720 {
721     MemMapAllocator::GetInstance()->Initialize(ecmascript::DEFAULT_REGION_SIZE);
722 }
723 
DestroyMemMapAllocator()724 void JSNApi::DestroyMemMapAllocator()
725 {
726     MemMapAllocator::GetInstance()->Finalize();
727 }
728 
InitializePGOProfiler(const ecmascript::JSRuntimeOptions & options)729 void JSNApi::InitializePGOProfiler(const ecmascript::JSRuntimeOptions &options)
730 {
731     ecmascript::PGOProfilerManager::GetInstance()->Initialize(
732         options.GetPGOProfilerPath(), options.GetPGOHotnessThreshold());
733 }
734 
DestroyPGOProfiler()735 void JSNApi::DestroyPGOProfiler()
736 {
737     ecmascript::PGOProfilerManager::GetInstance()->Destroy();
738 }
739 
DestoryAnDataManager()740 void JSNApi::DestoryAnDataManager()
741 {
742     ecmascript::AnFileDataManager::GetInstance()->SafeDestoryAllData();
743 }
744 
745 // ----------------------------------- HandleScope -------------------------------------
LocalScope(const EcmaVM * vm)746 LocalScope::LocalScope(const EcmaVM *vm) : thread_(vm->GetJSThread())
747 {
748     auto thread = reinterpret_cast<JSThread *>(thread_);
749     prevNext_ = thread->GetHandleScopeStorageNext();
750     prevEnd_ = thread->GetHandleScopeStorageEnd();
751     prevHandleStorageIndex_ = thread->GetCurrentHandleStorageIndex();
752     thread->HandleScopeCountAdd();
753 }
754 
LocalScope(const EcmaVM * vm,JSTaggedType value)755 LocalScope::LocalScope(const EcmaVM *vm, JSTaggedType value) : thread_(vm->GetJSThread())
756 {
757     auto thread = reinterpret_cast<JSThread *>(thread_);
758     ecmascript::EcmaHandleScope::NewHandle(thread, value);
759     prevNext_ = thread->GetHandleScopeStorageNext();
760     prevEnd_ = thread->GetHandleScopeStorageEnd();
761     prevHandleStorageIndex_ = thread->GetCurrentHandleStorageIndex();
762     thread->HandleScopeCountAdd();
763 }
764 
~LocalScope()765 LocalScope::~LocalScope()
766 {
767     auto thread = reinterpret_cast<JSThread *>(thread_);
768     thread->HandleScopeCountDec();
769     thread->SetHandleScopeStorageNext(static_cast<JSTaggedType *>(prevNext_));
770     if (thread->GetHandleScopeStorageEnd() != prevEnd_) {
771         thread->SetHandleScopeStorageEnd(static_cast<JSTaggedType *>(prevEnd_));
772         thread->ShrinkHandleStorage(prevHandleStorageIndex_);
773     }
774 }
775 
776 // ----------------------------------- EscapeLocalScope ------------------------------
EscapeLocalScope(const EcmaVM * vm)777 EscapeLocalScope::EscapeLocalScope(const EcmaVM *vm) : LocalScope(vm, JSTaggedValue::Undefined().GetRawData())
778 {
779     auto thread = vm->GetJSThread();
780     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
781     escapeHandle_ = ToUintPtr(thread->GetHandleScopeStorageNext() - 1);
782 }
783 
784 // ----------------------------------- PritimitiveRef ---------------------------------------
GetValue(const EcmaVM * vm)785 Local<JSValueRef> PrimitiveRef::GetValue(const EcmaVM *vm)
786 {
787     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
788     if (obj->IsJSPrimitiveRef()) {
789         JSTaggedValue primitiveValue = JSPrimitiveRef::Cast(obj->GetTaggedObject())->GetValue();
790         JSHandle<JSTaggedValue> value = JSHandle<JSTaggedValue>(vm->GetJSThread(), primitiveValue);
791         return JSNApiHelper::ToLocal<JSValueRef>(value);
792     }
793     return Local<JSValueRef>();
794 }
795 
796 // ----------------------------------- NumberRef ---------------------------------------
New(const EcmaVM * vm,double input)797 Local<NumberRef> NumberRef::New(const EcmaVM *vm, double input)
798 {
799     JSThread *thread = vm->GetJSThread();
800     if (std::isnan(input)) {
801         input = ecmascript::base::NAN_VALUE;
802     }
803     JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input));
804     return JSNApiHelper::ToLocal<NumberRef>(number);
805 }
806 
New(const EcmaVM * vm,int32_t input)807 Local<NumberRef> NumberRef::New(const EcmaVM *vm, int32_t input)
808 {
809     JSThread *thread = vm->GetJSThread();
810     JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input));
811     return JSNApiHelper::ToLocal<NumberRef>(number);
812 }
813 
New(const EcmaVM * vm,uint32_t input)814 Local<NumberRef> NumberRef::New(const EcmaVM *vm, uint32_t input)
815 {
816     JSThread *thread = vm->GetJSThread();
817     JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input));
818     return JSNApiHelper::ToLocal<NumberRef>(number);
819 }
820 
New(const EcmaVM * vm,int64_t input)821 Local<NumberRef> NumberRef::New(const EcmaVM *vm, int64_t input)
822 {
823     JSThread *thread = vm->GetJSThread();
824     JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input));
825     return JSNApiHelper::ToLocal<NumberRef>(number);
826 }
827 
Value()828 double NumberRef::Value()
829 {
830     return JSTaggedNumber(JSNApiHelper::ToJSTaggedValue(this)).GetNumber();
831 }
832 
833 // ----------------------------------- BigIntRef ---------------------------------------
New(const EcmaVM * vm,uint64_t input)834 Local<BigIntRef> BigIntRef::New(const EcmaVM *vm, uint64_t input)
835 {
836     JSThread *thread = vm->GetJSThread();
837     JSHandle<BigInt> big = BigInt::Uint64ToBigInt(thread, input);
838     JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big);
839     return JSNApiHelper::ToLocal<BigIntRef>(bigint);
840 }
841 
New(const EcmaVM * vm,int64_t input)842 Local<BigIntRef> BigIntRef::New(const EcmaVM *vm, int64_t input)
843 {
844     JSThread *thread = vm->GetJSThread();
845     JSHandle<BigInt> big = BigInt::Int64ToBigInt(thread, input);
846     JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big);
847     return JSNApiHelper::ToLocal<BigIntRef>(bigint);
848 }
849 
CreateBigWords(const EcmaVM * vm,bool sign,uint32_t size,const uint64_t * words)850 Local<JSValueRef> BigIntRef::CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words)
851 {
852     JSThread *thread = vm->GetJSThread();
853     JSHandle<BigInt> big = BigInt::CreateBigWords(thread, sign, size, words);
854     JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big);
855     return JSNApiHelper::ToLocal<JSValueRef>(bigint);
856 }
857 
BigIntToInt64(const EcmaVM * vm,int64_t * cValue,bool * lossless)858 void BigIntRef::BigIntToInt64(const EcmaVM *vm, int64_t *cValue, bool *lossless)
859 {
860     JSThread *thread = vm->GetJSThread();
861     JSHandle<JSTaggedValue> bigintVal(JSNApiHelper::ToJSHandle(this));
862     BigInt::BigIntToInt64(thread, bigintVal, cValue, lossless);
863 }
864 
BigIntToUint64(const EcmaVM * vm,uint64_t * cValue,bool * lossless)865 void BigIntRef::BigIntToUint64(const EcmaVM *vm, uint64_t *cValue, bool *lossless)
866 {
867     JSThread *thread = vm->GetJSThread();
868     JSHandle<JSTaggedValue> bigintVal(JSNApiHelper::ToJSHandle(this));
869     BigInt::BigIntToUint64(thread, bigintVal, cValue, lossless);
870 }
871 
GetWordsArray(bool * signBit,size_t wordCount,uint64_t * words)872 void BigIntRef::GetWordsArray(bool* signBit, size_t wordCount, uint64_t* words)
873 {
874     JSHandle<BigInt> bigintVal(JSNApiHelper::ToJSHandle(this));
875     uint32_t len = bigintVal->GetLength();
876     uint32_t count = 0;
877     uint32_t index = 0;
878     for (; index < wordCount - 1; ++index) {
879         words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
880         words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits
881     }
882     if (len % 2 == 0) { // 2 : len is odd or even
883         words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
884         words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits
885     } else {
886         words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
887     }
888     *signBit = bigintVal->GetSign();
889 }
890 
GetWordsArraySize()891 uint32_t BigIntRef::GetWordsArraySize()
892 {
893     JSHandle<BigInt> bigintVal(JSNApiHelper::ToJSHandle(this));
894     uint32_t len = bigintVal->GetLength();
895     return len % 2 != 0 ? len / 2 + 1 : len / 2; // 2 : len is odd or even
896 }
897 
898 // ----------------------------------- BooleanRef ---------------------------------------
New(const EcmaVM * vm,bool input)899 Local<BooleanRef> BooleanRef::New(const EcmaVM *vm, bool input)
900 {
901     JSThread *thread = vm->GetJSThread();
902     JSHandle<JSTaggedValue> boolean(thread, JSTaggedValue(input));
903     return JSNApiHelper::ToLocal<BooleanRef>(boolean);
904 }
905 
Value()906 bool BooleanRef::Value()
907 {
908     return JSNApiHelper::ToJSTaggedValue(this).IsTrue();
909 }
910 
911 // ----------------------------------- IntegerRef ---------------------------------------
New(const EcmaVM * vm,int input)912 Local<IntegerRef> IntegerRef::New(const EcmaVM *vm, int input)
913 {
914     JSThread *thread = vm->GetJSThread();
915     JSHandle<JSTaggedValue> integer(thread, JSTaggedValue(input));
916     return JSNApiHelper::ToLocal<IntegerRef>(integer);
917 }
918 
NewFromUnsigned(const EcmaVM * vm,unsigned int input)919 Local<IntegerRef> IntegerRef::NewFromUnsigned(const EcmaVM *vm, unsigned int input)
920 {
921     JSThread *thread = vm->GetJSThread();
922     JSHandle<JSTaggedValue> integer(thread, JSTaggedValue(input));
923     return JSNApiHelper::ToLocal<IntegerRef>(integer);
924 }
925 
Value()926 int IntegerRef::Value()
927 {
928     return JSNApiHelper::ToJSTaggedValue(this).GetInt();
929 }
930 
931 // ----------------------------------- StringRef ----------------------------------------
NewFromUtf8(const EcmaVM * vm,const char * utf8,int length)932 Local<StringRef> StringRef::NewFromUtf8(const EcmaVM *vm, const char *utf8, int length)
933 {
934     ObjectFactory *factory = vm->GetFactory();
935     if (length < 0) {
936         JSHandle<JSTaggedValue> current(factory->NewFromUtf8(utf8));
937         return JSNApiHelper::ToLocal<StringRef>(current);
938     }
939     JSHandle<JSTaggedValue> current(factory->NewFromUtf8(reinterpret_cast<const uint8_t *>(utf8), length));
940     return JSNApiHelper::ToLocal<StringRef>(current);
941 }
942 
ToString()943 std::string StringRef::ToString()
944 {
945     return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this)).ToStdString();
946 }
947 
Length()948 int32_t StringRef::Length()
949 {
950     return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this)).GetLength();
951 }
952 
Utf8Length()953 int32_t StringRef::Utf8Length()
954 {
955     return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this)).GetUtf8Length();
956 }
957 
WriteUtf8(char * buffer,int length)958 int StringRef::WriteUtf8(char *buffer, int length)
959 {
960     return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this))
961         .WriteToFlatUtf8(reinterpret_cast<uint8_t *>(buffer), length);
962 }
963 
GetNapiWrapperString(const EcmaVM * vm)964 Local<StringRef> StringRef::GetNapiWrapperString(const EcmaVM *vm)
965 {
966     JSHandle<JSTaggedValue> napiWapperString = vm->GetJSThread()->GlobalConstants()->GetHandledNapiWrapperString();
967     return JSNApiHelper::ToLocal<StringRef>(napiWapperString);
968 }
969 
970 // ----------------------------------- SymbolRef -----------------------------------------
New(const EcmaVM * vm,Local<StringRef> description)971 Local<SymbolRef> SymbolRef::New(const EcmaVM *vm, Local<StringRef> description)
972 {
973     ObjectFactory *factory = vm->GetFactory();
974     JSHandle<JSSymbol> symbol = factory->NewJSSymbol();
975     JSTaggedValue desc = JSNApiHelper::ToJSTaggedValue(*description);
976     symbol->SetDescription(vm->GetJSThread(), desc);
977     return JSNApiHelper::ToLocal<SymbolRef>(JSHandle<JSTaggedValue>(symbol));
978 }
979 
GetDescription(const EcmaVM * vm)980 Local<StringRef> SymbolRef::GetDescription(const EcmaVM *vm)
981 {
982     JSTaggedValue description = JSSymbol::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetDescription();
983     if (!description.IsString()) {
984         auto constants = vm->GetJSThread()->GlobalConstants();
985         return JSNApiHelper::ToLocal<StringRef>(constants->GetHandledEmptyString());
986     }
987     JSHandle<JSTaggedValue> descriptionHandle(vm->GetJSThread(), description);
988     return JSNApiHelper::ToLocal<StringRef>(descriptionHandle);
989 }
990 
991 // -------------------------------- NativePointerRef ------------------------------------
New(const EcmaVM * vm,void * nativePointer,size_t nativeBindingsize)992 Local<NativePointerRef> NativePointerRef::New(const EcmaVM *vm, void *nativePointer, size_t nativeBindingsize)
993 {
994     ObjectFactory *factory = vm->GetFactory();
995     JSHandle<JSNativePointer> obj = factory->NewJSNativePointer(nativePointer, nullptr, nullptr,
996         false, nativeBindingsize);
997     return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
998 }
999 
New(const EcmaVM * vm,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)1000 Local<NativePointerRef> NativePointerRef::New(
1001     const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, void *data, size_t nativeBindingsize)
1002 {
1003     ObjectFactory *factory = vm->GetFactory();
1004     JSHandle<JSNativePointer> obj = factory->NewJSNativePointer(nativePointer, callBack, data,
1005         false, nativeBindingsize);
1006     return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
1007 }
1008 
Value()1009 void *NativePointerRef::Value()
1010 {
1011     JSHandle<JSTaggedValue> nativePointer = JSNApiHelper::ToJSHandle(this);
1012     return JSHandle<JSNativePointer>(nativePointer)->GetExternalPointer();
1013 }
1014 
1015 // ----------------------------------- ObjectRef ----------------------------------------
New(const EcmaVM * vm)1016 Local<ObjectRef> ObjectRef::New(const EcmaVM *vm)
1017 {
1018     ObjectFactory *factory = vm->GetFactory();
1019     JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
1020     JSHandle<JSFunction> constructor(globalEnv->GetObjectFunction());
1021     JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(constructor));
1022     return JSNApiHelper::ToLocal<ObjectRef>(object);
1023 }
1024 
New(const EcmaVM * vm,void * detach,void * attach)1025 Local<ObjectRef> ObjectRef::New(const EcmaVM *vm, void *detach, void *attach)
1026 {
1027     ObjectFactory *factory = vm->GetFactory();
1028     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1029     JSHandle<JSFunction> constructor(env->GetObjectFunction());
1030     JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(constructor));
1031     JSHandle<JSTaggedValue> detachKey = env->GetDetachSymbol();
1032     JSHandle<JSTaggedValue> attachKey = env->GetAttachSymbol();
1033     JSHandle<JSTaggedValue> detachValue = JSNApiHelper::ToJSHandle(NativePointerRef::New(vm, detach));
1034     JSHandle<JSTaggedValue> attachValue = JSNApiHelper::ToJSHandle(NativePointerRef::New(vm, attach));
1035     JSTaggedValue::SetProperty(vm->GetJSThread(), object, detachKey, detachValue);
1036     JSTaggedValue::SetProperty(vm->GetJSThread(), object, attachKey, attachValue);
1037     RETURN_VALUE_IF_ABRUPT(vm->GetJSThread(), JSValueRef::Undefined(vm));
1038     return JSNApiHelper::ToLocal<ObjectRef>(object);
1039 }
1040 
Set(const EcmaVM * vm,void * detach,void * attach)1041 bool ObjectRef::Set(const EcmaVM *vm, void *detach, void *attach)
1042 {
1043     [[maybe_unused]] LocalScope scope(vm);
1044     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1045     JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(this);
1046     JSHandle<JSTaggedValue> detachKey = env->GetDetachSymbol();
1047     JSHandle<JSTaggedValue> attachKey = env->GetAttachSymbol();
1048     JSHandle<JSTaggedValue> detachValue = JSNApiHelper::ToJSHandle(NativePointerRef::New(vm, detach));
1049     JSHandle<JSTaggedValue> attachValue = JSNApiHelper::ToJSHandle(NativePointerRef::New(vm, attach));
1050     bool detachResult = JSTaggedValue::SetProperty(vm->GetJSThread(), object, detachKey, detachValue);
1051     bool attachResult = JSTaggedValue::SetProperty(vm->GetJSThread(), object, attachKey, attachValue);
1052     RETURN_VALUE_IF_ABRUPT(vm->GetJSThread(), false);
1053     return detachResult && attachResult;
1054 }
1055 
Set(const EcmaVM * vm,Local<JSValueRef> key,Local<JSValueRef> value)1056 bool ObjectRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value)
1057 {
1058     [[maybe_unused]] LocalScope scope(vm);
1059     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
1060     JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
1061     JSHandle<JSTaggedValue> valueValue = JSNApiHelper::ToJSHandle(value);
1062     bool result = JSTaggedValue::SetProperty(vm->GetJSThread(), obj, keyValue, valueValue);
1063     RETURN_VALUE_IF_ABRUPT(vm->GetJSThread(), false);
1064     return result;
1065 }
1066 
Set(const EcmaVM * vm,uint32_t key,Local<JSValueRef> value)1067 bool ObjectRef::Set(const EcmaVM *vm, uint32_t key, Local<JSValueRef> value)
1068 {
1069     [[maybe_unused]] LocalScope scope(vm);
1070     Local<JSValueRef> keyValue = NumberRef::New(vm, key);
1071     return Set(vm, keyValue, value);
1072 }
1073 
SetAccessorProperty(const EcmaVM * vm,Local<JSValueRef> key,Local<FunctionRef> getter,Local<FunctionRef> setter,PropertyAttribute attribute)1074 bool ObjectRef::SetAccessorProperty(const EcmaVM *vm, Local<JSValueRef> key, Local<FunctionRef> getter,
1075     Local<FunctionRef> setter, PropertyAttribute attribute)
1076 {
1077     [[maybe_unused]] LocalScope scope(vm);
1078     JSThread *thread = vm->GetJSThread();
1079     JSHandle<JSTaggedValue> getterValue = JSNApiHelper::ToJSHandle(getter);
1080     JSHandle<JSTaggedValue> setterValue = JSNApiHelper::ToJSHandle(setter);
1081     PropertyDescriptor desc(thread, attribute.IsWritable(), attribute.IsEnumerable(), attribute.IsConfigurable());
1082     desc.SetValue(JSNApiHelper::ToJSHandle(attribute.GetValue(vm)));
1083     desc.SetSetter(setterValue);
1084     desc.SetGetter(getterValue);
1085     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
1086     JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
1087     bool result = JSTaggedValue::DefineOwnProperty(thread, obj, keyValue, desc);
1088     RETURN_VALUE_IF_ABRUPT(thread, false);
1089     return result;
1090 }
1091 
Get(const EcmaVM * vm,Local<JSValueRef> key)1092 Local<JSValueRef> ObjectRef::Get(const EcmaVM *vm, Local<JSValueRef> key)
1093 {
1094     EscapeLocalScope scope(vm);
1095     JSThread *thread = vm->GetJSThread();
1096     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
1097     JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
1098     OperationResult ret = JSTaggedValue::GetProperty(thread, obj, keyValue);
1099     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1100     if (!ret.GetPropertyMetaData().IsFound()) {
1101         return JSValueRef::Undefined(vm);
1102     }
1103     return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(ret.GetValue()));
1104 }
1105 
Get(const EcmaVM * vm,int32_t key)1106 Local<JSValueRef> ObjectRef::Get(const EcmaVM *vm, int32_t key)
1107 {
1108     Local<JSValueRef> keyValue = IntegerRef::New(vm, key);
1109     return Get(vm, keyValue);
1110 }
1111 
GetOwnProperty(const EcmaVM * vm,Local<JSValueRef> key,PropertyAttribute & property)1112 bool ObjectRef::GetOwnProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute &property)
1113 {
1114     JSThread *thread = vm->GetJSThread();
1115     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
1116     JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
1117     PropertyDescriptor desc(thread);
1118     bool ret = JSObject::GetOwnProperty(thread, JSHandle<JSObject>(obj), keyValue, desc);
1119     if (!ret) {
1120         return false;
1121     }
1122     property.SetValue(JSNApiHelper::ToLocal<JSValueRef>(desc.GetValue()));
1123     if (desc.HasGetter()) {
1124         property.SetGetter(JSNApiHelper::ToLocal<JSValueRef>(desc.GetGetter()));
1125     }
1126     if (desc.HasSetter()) {
1127         property.SetSetter(JSNApiHelper::ToLocal<JSValueRef>(desc.GetSetter()));
1128     }
1129     if (desc.HasWritable()) {
1130         property.SetWritable(desc.IsWritable());
1131     }
1132     if (desc.HasEnumerable()) {
1133         property.SetEnumerable(desc.IsEnumerable());
1134     }
1135     if (desc.HasConfigurable()) {
1136         property.SetConfigurable(desc.IsConfigurable());
1137     }
1138 
1139     return true;
1140 }
1141 
GetOwnPropertyNames(const EcmaVM * vm)1142 Local<ArrayRef> ObjectRef::GetOwnPropertyNames(const EcmaVM *vm)
1143 {
1144     JSThread *thread = vm->GetJSThread();
1145     JSHandle<JSTaggedValue> obj(JSNApiHelper::ToJSHandle(this));
1146     JSHandle<TaggedArray> array(JSTaggedValue::GetOwnPropertyKeys(thread, obj));
1147     JSHandle<JSTaggedValue> jsArray(JSArray::CreateArrayFromList(thread, array));
1148     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1149     return JSNApiHelper::ToLocal<ArrayRef>(jsArray);
1150 }
1151 
GetOwnEnumerablePropertyNames(const EcmaVM * vm)1152 Local<ArrayRef> ObjectRef::GetOwnEnumerablePropertyNames(const EcmaVM *vm)
1153 {
1154     JSThread *thread = vm->GetJSThread();
1155     JSHandle<JSObject> obj(JSNApiHelper::ToJSHandle(this));
1156     JSHandle<TaggedArray> array(JSObject::EnumerableOwnNames(thread, obj));
1157     JSHandle<JSTaggedValue> jsArray(JSArray::CreateArrayFromList(thread, array));
1158     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1159     return JSNApiHelper::ToLocal<ArrayRef>(jsArray);
1160 }
1161 
GetPrototype(const EcmaVM * vm)1162 Local<JSValueRef> ObjectRef::GetPrototype(const EcmaVM *vm)
1163 {
1164     JSThread *thread = vm->GetJSThread();
1165     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
1166     JSHandle<JSTaggedValue> prototype(thread, JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(object)));
1167     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1168     return JSNApiHelper::ToLocal<JSValueRef>(prototype);
1169 }
1170 
DefineProperty(const EcmaVM * vm,Local<JSValueRef> key,PropertyAttribute attribute)1171 bool ObjectRef::DefineProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute attribute)
1172 {
1173     JSThread *thread = vm->GetJSThread();
1174     JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
1175     JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key));
1176     PropertyDescriptor desc(thread, attribute.IsWritable(), attribute.IsEnumerable(), attribute.IsConfigurable());
1177     desc.SetValue(JSNApiHelper::ToJSHandle(attribute.GetValue(vm)));
1178     bool result = object->DefinePropertyOrThrow(thread, object, keyValue, desc);
1179     RETURN_VALUE_IF_ABRUPT(thread, false);
1180     return result;
1181 }
1182 
Has(const EcmaVM * vm,Local<JSValueRef> key)1183 bool ObjectRef::Has(const EcmaVM *vm, Local<JSValueRef> key)
1184 {
1185     JSThread *thread = vm->GetJSThread();
1186     JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
1187     JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key));
1188     bool result = object->HasProperty(thread, object, keyValue);
1189     RETURN_VALUE_IF_ABRUPT(thread, false);
1190     return result;
1191 }
1192 
Has(const EcmaVM * vm,uint32_t key)1193 bool ObjectRef::Has(const EcmaVM *vm, uint32_t key)
1194 {
1195     JSThread *thread = vm->GetJSThread();
1196     JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
1197     bool result = object->HasProperty(thread, object, key);
1198     RETURN_VALUE_IF_ABRUPT(thread, false);
1199     return result;
1200 }
1201 
Delete(const EcmaVM * vm,Local<JSValueRef> key)1202 bool ObjectRef::Delete(const EcmaVM *vm, Local<JSValueRef> key)
1203 {
1204     JSThread *thread = vm->GetJSThread();
1205     JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
1206     JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key));
1207     bool result = object->DeleteProperty(thread, object, keyValue);
1208     RETURN_VALUE_IF_ABRUPT(thread, false);
1209     return result;
1210 }
1211 
Delete(const EcmaVM * vm,uint32_t key)1212 bool ObjectRef::Delete(const EcmaVM *vm, uint32_t key)
1213 {
1214     JSThread *thread = vm->GetJSThread();
1215     JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
1216     JSHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue(key));
1217     bool result = object->DeleteProperty(thread, object, keyHandle);
1218     RETURN_VALUE_IF_ABRUPT(thread, false);
1219     return result;
1220 }
1221 
SetNativePointerFieldCount(int32_t count)1222 void ObjectRef::SetNativePointerFieldCount(int32_t count)
1223 {
1224     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
1225     object->SetNativePointerFieldCount(count);
1226 }
1227 
GetNativePointerFieldCount()1228 int32_t ObjectRef::GetNativePointerFieldCount()
1229 {
1230     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
1231     return object->GetNativePointerFieldCount();
1232 }
1233 
GetNativePointerField(int32_t index)1234 void *ObjectRef::GetNativePointerField(int32_t index)
1235 {
1236     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
1237     return object->GetNativePointerField(index);
1238 }
1239 
SetNativePointerField(int32_t index,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)1240 void ObjectRef::SetNativePointerField(int32_t index, void *nativePointer,
1241     NativePointerCallback callBack, void *data, size_t nativeBindingsize)
1242 {
1243     JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
1244     object->SetNativePointerField(index, nativePointer, callBack, data, nativeBindingsize);
1245 }
1246 
1247 // ----------------------------------- FunctionRef --------------------------------------
New(EcmaVM * vm,FunctionCallback nativeFunc,Deleter deleter,void * data,bool callNapi,size_t nativeBindingsize)1248 Local<FunctionRef> FunctionRef::New(EcmaVM *vm, FunctionCallback nativeFunc,
1249     Deleter deleter, void *data, bool callNapi, size_t nativeBindingsize)
1250 {
1251     JSThread *thread = vm->GetJSThread();
1252     ObjectFactory *factory = vm->GetFactory();
1253     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1254     JSHandle<JSFunction> current(factory->NewJSFunction(env, reinterpret_cast<void *>(Callback::RegisterCallback)));
1255     current->SetFunctionExtraInfo(thread, reinterpret_cast<void *>(nativeFunc), deleter, data, nativeBindingsize);
1256     current->SetCallNapi(callNapi);
1257     return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
1258 }
1259 
NewClassFunction(EcmaVM * vm,FunctionCallback nativeFunc,Deleter deleter,void * data,bool callNapi,size_t nativeBindingsize)1260 Local<FunctionRef> FunctionRef::NewClassFunction(EcmaVM *vm, FunctionCallback nativeFunc,
1261     Deleter deleter, void *data, bool callNapi, size_t nativeBindingsize)
1262 {
1263     EscapeLocalScope scope(vm);
1264     JSThread *thread = vm->GetJSThread();
1265     ObjectFactory *factory = vm->GetFactory();
1266     JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1267     JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutName());
1268     JSHandle<JSFunction> current =
1269         factory->NewJSFunctionByHClass(reinterpret_cast<void *>(Callback::RegisterCallback),
1270         hclass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR);
1271 
1272     auto globalConst = thread->GlobalConstants();
1273     JSHandle<JSTaggedValue> accessor = globalConst->GetHandledFunctionPrototypeAccessor();
1274     current->SetPropertyInlinedProps(thread, JSFunction::CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX,
1275                                      accessor.GetTaggedValue());
1276 
1277     current->SetFunctionExtraInfo(thread, reinterpret_cast<void *>(nativeFunc), deleter, data, nativeBindingsize);
1278 
1279     JSHandle<JSObject> clsPrototype = JSFunction::NewJSFunctionPrototype(thread, factory, current);
1280     clsPrototype.GetTaggedValue().GetTaggedObject()->GetClass()->SetClassPrototype(true);
1281     JSHandle<JSTaggedValue>::Cast(current)->GetTaggedObject()->GetClass()->SetClassConstructor(true);
1282     current->SetClassConstructor(true);
1283     JSHandle<JSTaggedValue> parent = env->GetFunctionPrototype();
1284     JSObject::SetPrototype(thread, JSHandle<JSObject>::Cast(current), parent);
1285     current->SetHomeObject(thread, clsPrototype);
1286     current->SetCallNapi(callNapi);
1287     Local<FunctionRef> result = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
1288     return scope.Escape(result);
1289 }
1290 
Call(const EcmaVM * vm,Local<JSValueRef> thisObj,const Local<JSValueRef> argv[],int32_t length)1291 Local<JSValueRef> FunctionRef::Call(const EcmaVM *vm, Local<JSValueRef> thisObj,
1292     const Local<JSValueRef> argv[],  // NOLINTNEXTLINE(modernize-avoid-c-arrays)
1293     int32_t length)
1294 {
1295     EscapeLocalScope scope(vm);
1296     JSThread *thread = vm->GetJSThread();
1297     if (!IsFunction()) {
1298         return JSValueRef::Undefined(vm);
1299     }
1300     vm->GetJsDebuggerManager()->ClearSingleStepper();
1301     JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this);
1302     JSHandle<JSTaggedValue> thisValue = JSNApiHelper::ToJSHandle(thisObj);
1303     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
1304     EcmaRuntimeCallInfo *info =
1305         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, thisValue, undefined, length);
1306     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1307     for (int32_t i = 0; i < length; i++) {
1308         JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(argv[i]);
1309         info->SetCallArg(i, arg.GetTaggedValue());
1310     }
1311     JSTaggedValue result = JSFunction::Call(info);
1312     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1313     JSHandle<JSTaggedValue> resultValue(thread, result);
1314 
1315     EcmaVM::ConstCast(vm)->ExecutePromisePendingJob();
1316     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1317     vm->GetHeap()->ClearKeptObjects();
1318 
1319     return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(resultValue));
1320 }
1321 
Constructor(const EcmaVM * vm,const Local<JSValueRef> argv[],int32_t length)1322 Local<JSValueRef> FunctionRef::Constructor(const EcmaVM *vm,
1323     const Local<JSValueRef> argv[],  // NOLINTNEXTLINE(modernize-avoid-c-arrays)
1324     int32_t length)
1325 {
1326     JSThread *thread = vm->GetJSThread();
1327     if (!IsFunction()) {
1328         return JSValueRef::Undefined(vm);
1329     }
1330     JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this);
1331     JSHandle<JSTaggedValue> newTarget = func;
1332     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
1333     EcmaRuntimeCallInfo *info =
1334         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, newTarget, length);
1335     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1336     for (int32_t i = 0; i < length; i++) {
1337         JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(argv[i]);
1338         info->SetCallArg(i, arg.GetTaggedValue());
1339     }
1340     JSTaggedValue result = JSFunction::Construct(info);
1341 
1342     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1343     JSHandle<JSTaggedValue> resultValue(thread, result);
1344     return JSNApiHelper::ToLocal<JSValueRef>(resultValue);
1345 }
1346 
GetFunctionPrototype(const EcmaVM * vm)1347 Local<JSValueRef> FunctionRef::GetFunctionPrototype(const EcmaVM *vm)
1348 {
1349     JSThread *thread = vm->GetJSThread();
1350     JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this);
1351     JSHandle<JSTaggedValue> prototype(thread, JSHandle<JSFunction>(func)->GetFunctionPrototype());
1352     return JSNApiHelper::ToLocal<JSValueRef>(prototype);
1353 }
1354 
Inherit(const EcmaVM * vm,Local<FunctionRef> parent)1355 bool FunctionRef::Inherit(const EcmaVM *vm, Local<FunctionRef> parent)
1356 {
1357     [[maybe_unused]] LocalScope scope(vm);
1358     JSThread *thread = vm->GetJSThread();
1359     JSHandle<JSTaggedValue> parentValue = JSNApiHelper::ToJSHandle(parent);
1360     JSHandle<JSObject> parentHandle = JSHandle<JSObject>::Cast(parentValue);
1361     JSHandle<JSObject> thisHandle = JSHandle<JSObject>::Cast(JSNApiHelper::ToJSHandle(this));
1362     // Set this.__proto__ to parent
1363     bool res = JSObject::SetPrototype(thread, thisHandle, parentValue);
1364     if (!res) {
1365         return false;
1366     }
1367     // Set this.Prototype.__proto__ to parent.Prototype
1368     JSHandle<JSTaggedValue> parentProtoType(thread, JSFunction::PrototypeGetter(thread, parentHandle));
1369     JSHandle<JSTaggedValue> thisProtoType(thread, JSFunction::PrototypeGetter(thread, thisHandle));
1370     return JSObject::SetPrototype(thread, JSHandle<JSObject>::Cast(thisProtoType), parentProtoType);
1371 }
1372 
SetName(const EcmaVM * vm,Local<StringRef> name)1373 void FunctionRef::SetName(const EcmaVM *vm, Local<StringRef> name)
1374 {
1375     [[maybe_unused]] LocalScope scope(vm);
1376     JSThread *thread = vm->GetJSThread();
1377     JSFunction *func = JSFunction::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject());
1378     JSTaggedValue key = JSNApiHelper::ToJSTaggedValue(*name);
1379     JSFunction::SetFunctionNameNoPrefix(thread, func, key);
1380 }
1381 
GetName(const EcmaVM * vm)1382 Local<StringRef> FunctionRef::GetName(const EcmaVM *vm)
1383 {
1384     EscapeLocalScope scope(vm);
1385     JSThread *thread = vm->GetJSThread();
1386     JSHandle<JSFunctionBase> func = JSHandle<JSFunctionBase>(thread, JSNApiHelper::ToJSTaggedValue(this));
1387     JSHandle<JSTaggedValue> name = JSFunctionBase::GetFunctionName(thread, func);
1388     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1389     return scope.Escape(JSNApiHelper::ToLocal<StringRef>(name));
1390 }
1391 
GetSourceCode(const EcmaVM * vm,int lineNumber)1392 Local<StringRef> FunctionRef::GetSourceCode(const EcmaVM *vm, int lineNumber)
1393 {
1394     EscapeLocalScope scope(vm);
1395     JSThread *thread = vm->GetJSThread();
1396     JSHandle<JSFunctionBase> func = JSHandle<JSFunctionBase>(thread, JSNApiHelper::ToJSTaggedValue(this));
1397     JSHandle<Method> method = JSHandle<Method>(thread, func->GetMethod());
1398     const JSPandaFile *jsPandaFile = method->GetJSPandaFile();
1399     DebugInfoExtractor *debugExtractor = JSPandaFileManager::GetInstance()->GetJSPtExtractor(jsPandaFile);
1400     ecmascript::CString entry = JSPandaFile::ENTRY_FUNCTION_NAME;
1401     if (!jsPandaFile->IsBundlePack()) {
1402         JSFunction *function = JSFunction::Cast(func.GetTaggedValue().GetTaggedObject());
1403         JSTaggedValue recordName = function->GetRecordName();
1404         ASSERT(!recordName.IsHole());
1405         entry = ConvertToString(recordName);
1406     }
1407 
1408     uint32_t mainMethodIndex = jsPandaFile->GetMainMethodIndex(entry);
1409     JSMutableHandle<JSTaggedValue> sourceCodeHandle(thread, BuiltinsBase::GetTaggedString(thread, ""));
1410     if (mainMethodIndex == 0) {
1411         return scope.Escape(JSNApiHelper::ToLocal<StringRef>(sourceCodeHandle));
1412     }
1413 
1414     const std::string &allSourceCode = debugExtractor->GetSourceCode(panda_file::File::EntityId(mainMethodIndex));
1415     std::string sourceCode = StringHelper::GetSpecifiedLine(allSourceCode, lineNumber);
1416     uint32_t codeLen = sourceCode.length();
1417     if (codeLen == 0) {
1418         return scope.Escape(JSNApiHelper::ToLocal<StringRef>(sourceCodeHandle));
1419     }
1420 
1421     if (sourceCode[codeLen - 1] == '\r') {
1422         sourceCode = sourceCode.substr(0, codeLen - 1);
1423     }
1424     sourceCodeHandle.Update(BuiltinsBase::GetTaggedString(thread, sourceCode.c_str()));
1425     return scope.Escape(JSNApiHelper::ToLocal<StringRef>(sourceCodeHandle));
1426 }
1427 
IsNative(const EcmaVM * vm)1428 bool FunctionRef::IsNative(const EcmaVM *vm)
1429 {
1430     JSThread *thread = vm->GetJSThread();
1431     JSHandle<JSFunctionBase> func = JSHandle<JSFunctionBase>(thread, JSNApiHelper::ToJSTaggedValue(this));
1432     JSHandle<Method> method = JSHandle<Method>(thread, func->GetMethod());
1433     return method->IsNativeWithCallField();
1434 }
1435 
1436 // ----------------------------------- ArrayRef ----------------------------------------
New(const EcmaVM * vm,uint32_t length)1437 Local<ArrayRef> ArrayRef::New(const EcmaVM *vm, uint32_t length)
1438 {
1439     JSThread *thread = vm->GetJSThread();
1440     JSTaggedNumber arrayLen(length);
1441     JSHandle<JSTaggedValue> array = JSArray::ArrayCreate(thread, arrayLen);
1442     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1443     return JSNApiHelper::ToLocal<ArrayRef>(array);
1444 }
1445 
Length(const EcmaVM * vm)1446 int32_t ArrayRef::Length([[maybe_unused]] const EcmaVM *vm)
1447 {
1448     return JSArray::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetArrayLength();
1449 }
1450 
1451 
GetValueAt(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index)1452 Local<JSValueRef> ArrayRef::GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index)
1453 {
1454     JSThread *thread = vm->GetJSThread();
1455     JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(obj);
1456     JSHandle<JSTaggedValue> result = JSArray::FastGetPropertyByValue(thread, object, index);
1457     return JSNApiHelper::ToLocal<JSValueRef>(result);
1458 }
1459 
SetValueAt(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index,Local<JSValueRef> value)1460 bool ArrayRef::SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value)
1461 {
1462     JSThread *thread = vm->GetJSThread();
1463     JSHandle<JSTaggedValue> objectHandle = JSNApiHelper::ToJSHandle(obj);
1464     JSHandle<JSTaggedValue> valueHandle = JSNApiHelper::ToJSHandle(value);
1465     return JSArray::FastSetPropertyByValue(thread, objectHandle, index, valueHandle);
1466 }
1467 // ---------------------------------- Promise --------------------------------------
New(const EcmaVM * vm)1468 Local<PromiseCapabilityRef> PromiseCapabilityRef::New(const EcmaVM *vm)
1469 {
1470     JSThread *thread = vm->GetJSThread();
1471     JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
1472     JSHandle<JSTaggedValue> constructor(globalEnv->GetPromiseFunction());
1473     JSHandle<JSTaggedValue> capability(JSPromise::NewPromiseCapability(thread, constructor));
1474     return JSNApiHelper::ToLocal<PromiseCapabilityRef>(capability);
1475 }
1476 
GetPromise(const EcmaVM * vm)1477 Local<PromiseRef> PromiseCapabilityRef::GetPromise(const EcmaVM *vm)
1478 {
1479     JSThread *thread = vm->GetJSThread();
1480     JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
1481     return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, capacity->GetPromise()));
1482 }
1483 
Resolve(const EcmaVM * vm,Local<JSValueRef> value)1484 bool PromiseCapabilityRef::Resolve(const EcmaVM *vm, Local<JSValueRef> value)
1485 {
1486     JSThread *thread = vm->GetJSThread();
1487     const GlobalEnvConstants *constants = thread->GlobalConstants();
1488 
1489     JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(value);
1490     JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
1491     JSHandle<JSTaggedValue> resolve(thread, capacity->GetResolve());
1492     JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
1493     EcmaRuntimeCallInfo *info =
1494         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, resolve, undefined, undefined, 1);
1495     RETURN_VALUE_IF_ABRUPT(thread, false);
1496     info->SetCallArg(arg.GetTaggedValue());
1497     JSFunction::Call(info);
1498     RETURN_VALUE_IF_ABRUPT(thread, false);
1499 
1500     EcmaVM::ConstCast(vm)->ExecutePromisePendingJob();
1501     RETURN_VALUE_IF_ABRUPT(thread, false);
1502     vm->GetHeap()->ClearKeptObjects();
1503     return true;
1504 }
1505 
Reject(const EcmaVM * vm,Local<JSValueRef> reason)1506 bool PromiseCapabilityRef::Reject(const EcmaVM *vm, Local<JSValueRef> reason)
1507 {
1508     JSThread *thread = vm->GetJSThread();
1509     const GlobalEnvConstants *constants = thread->GlobalConstants();
1510 
1511     JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(reason);
1512     JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
1513     JSHandle<JSTaggedValue> reject(thread, capacity->GetReject());
1514     JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
1515 
1516     EcmaRuntimeCallInfo *info =
1517         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, reject, undefined, undefined, 1);
1518     RETURN_VALUE_IF_ABRUPT(thread, false);
1519     info->SetCallArg(arg.GetTaggedValue());
1520     JSFunction::Call(info);
1521     RETURN_VALUE_IF_ABRUPT(thread, false);
1522 
1523     EcmaVM::ConstCast(vm)->ExecutePromisePendingJob();
1524     RETURN_VALUE_IF_ABRUPT(thread, false);
1525     vm->GetHeap()->ClearKeptObjects();
1526     return true;
1527 }
1528 
Catch(const EcmaVM * vm,Local<FunctionRef> handler)1529 Local<PromiseRef> PromiseRef::Catch(const EcmaVM *vm, Local<FunctionRef> handler)
1530 {
1531     JSThread *thread = vm->GetJSThread();
1532     const GlobalEnvConstants *constants = thread->GlobalConstants();
1533 
1534     JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
1535     JSHandle<JSTaggedValue> catchKey(thread, constants->GetPromiseCatchString());
1536     JSHandle<JSTaggedValue> reject = JSNApiHelper::ToJSHandle(handler);
1537     JSHandle<JSTaggedValue> undefined = constants->GetHandledUndefined();
1538     EcmaRuntimeCallInfo *info =
1539         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 1);
1540     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1541     info->SetCallArg(reject.GetTaggedValue());
1542     JSTaggedValue result = JSFunction::Invoke(info, catchKey);
1543 
1544     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1545     return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
1546 }
1547 
Finally(const EcmaVM * vm,Local<FunctionRef> handler)1548 Local<PromiseRef> PromiseRef::Finally(const EcmaVM *vm, Local<FunctionRef> handler)
1549 {
1550     JSThread *thread = vm->GetJSThread();
1551     const GlobalEnvConstants *constants = thread->GlobalConstants();
1552 
1553     JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
1554     JSHandle<JSTaggedValue> finallyKey = constants->GetHandledPromiseFinallyString();
1555     JSHandle<JSTaggedValue> resolver = JSNApiHelper::ToJSHandle(handler);
1556     JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
1557     EcmaRuntimeCallInfo *info =
1558         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
1559     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1560     info->SetCallArg(resolver.GetTaggedValue(), undefined.GetTaggedValue());
1561     JSTaggedValue result = JSFunction::Invoke(info, finallyKey);
1562 
1563     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1564     return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
1565 }
1566 
Then(const EcmaVM * vm,Local<FunctionRef> handler)1567 Local<PromiseRef> PromiseRef::Then(const EcmaVM *vm, Local<FunctionRef> handler)
1568 {
1569     JSThread *thread = vm->GetJSThread();
1570     const GlobalEnvConstants *constants = thread->GlobalConstants();
1571 
1572     JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
1573     JSHandle<JSTaggedValue> thenKey(thread, constants->GetPromiseThenString());
1574     JSHandle<JSTaggedValue> resolver = JSNApiHelper::ToJSHandle(handler);
1575     JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
1576     EcmaRuntimeCallInfo *info =
1577         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
1578     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1579     info->SetCallArg(resolver.GetTaggedValue(), undefined.GetTaggedValue());
1580     JSTaggedValue result = JSFunction::Invoke(info, thenKey);
1581 
1582     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1583     return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
1584 }
1585 
Then(const EcmaVM * vm,Local<FunctionRef> onFulfilled,Local<FunctionRef> onRejected)1586 Local<PromiseRef> PromiseRef::Then(const EcmaVM *vm, Local<FunctionRef> onFulfilled, Local<FunctionRef> onRejected)
1587 {
1588     JSThread *thread = vm->GetJSThread();
1589     const GlobalEnvConstants *constants = thread->GlobalConstants();
1590 
1591     JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
1592     JSHandle<JSTaggedValue> thenKey(thread, constants->GetPromiseThenString());
1593     JSHandle<JSTaggedValue> resolver = JSNApiHelper::ToJSHandle(onFulfilled);
1594     JSHandle<JSTaggedValue> reject = JSNApiHelper::ToJSHandle(onRejected);
1595     JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
1596     EcmaRuntimeCallInfo *info =
1597         ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
1598     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1599     info->SetCallArg(resolver.GetTaggedValue(), reject.GetTaggedValue());
1600     JSTaggedValue result = JSFunction::Invoke(info, thenKey);
1601 
1602     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1603     return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
1604 }
1605 // ---------------------------------- Promise -------------------------------------
1606 
1607 // ---------------------------------- Buffer -----------------------------------
New(const EcmaVM * vm,int32_t length)1608 Local<ArrayBufferRef> ArrayBufferRef::New(const EcmaVM *vm, int32_t length)
1609 {
1610     ObjectFactory *factory = vm->GetFactory();
1611     JSHandle<JSArrayBuffer> arrayBuffer = factory->NewJSArrayBuffer(length);
1612     return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
1613 }
1614 
New(const EcmaVM * vm,void * buffer,int32_t length,const Deleter & deleter,void * data)1615 Local<ArrayBufferRef> ArrayBufferRef::New(
1616     const EcmaVM *vm, void *buffer, int32_t length, const Deleter &deleter, void *data)
1617 {
1618     ObjectFactory *factory = vm->GetFactory();
1619     JSHandle<JSArrayBuffer> arrayBuffer =
1620         factory->NewJSArrayBuffer(buffer, length, reinterpret_cast<ecmascript::DeleteEntryPoint>(deleter), data);
1621     return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
1622 }
1623 
ByteLength(const EcmaVM * vm)1624 int32_t ArrayBufferRef::ByteLength([[maybe_unused]] const EcmaVM *vm)
1625 {
1626     JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
1627     return arrayBuffer->GetArrayBufferByteLength();
1628 }
1629 
GetBuffer()1630 void *ArrayBufferRef::GetBuffer()
1631 {
1632     JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
1633     JSTaggedValue bufferData = arrayBuffer->GetArrayBufferData();
1634     if (!bufferData.IsJSNativePointer()) {
1635         return nullptr;
1636     }
1637     return JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
1638 }
1639 // ---------------------------------- Buffer -----------------------------------
1640 
1641 // ---------------------------------- DataView -----------------------------------
New(const EcmaVM * vm,Local<ArrayBufferRef> arrayBuffer,uint32_t byteOffset,uint32_t byteLength)1642 Local<DataViewRef> DataViewRef::New(
1643     const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, uint32_t byteOffset, uint32_t byteLength)
1644 {
1645     JSThread *thread = vm->GetJSThread();
1646     ObjectFactory *factory = vm->GetFactory();
1647 
1648     JSHandle<JSArrayBuffer> buffer(JSNApiHelper::ToJSHandle(arrayBuffer));
1649     JSHandle<JSDataView> dataView = factory->NewJSDataView(buffer, byteOffset, byteLength);
1650     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1651     return JSNApiHelper::ToLocal<DataViewRef>(JSHandle<JSTaggedValue>(dataView));
1652 }
1653 
ByteLength()1654 uint32_t DataViewRef::ByteLength()
1655 {
1656     JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this));
1657     return dataView->GetByteLength();
1658 }
1659 
ByteOffset()1660 uint32_t DataViewRef::ByteOffset()
1661 {
1662     JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this));
1663     return dataView->GetByteOffset();
1664 }
1665 
GetArrayBuffer(const EcmaVM * vm)1666 Local<ArrayBufferRef> DataViewRef::GetArrayBuffer(const EcmaVM *vm)
1667 {
1668     JSThread *thread = vm->GetJSThread();
1669     JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this));
1670     JSHandle<JSTaggedValue> arrayBuffer(thread, dataView->GetViewedArrayBuffer());
1671     return JSNApiHelper::ToLocal<ArrayBufferRef>(arrayBuffer);
1672 }
1673 // ---------------------------------- DataView -----------------------------------
1674 
1675 // ---------------------------------- TypedArray -----------------------------------
ByteLength(const EcmaVM * vm)1676 uint32_t TypedArrayRef::ByteLength([[maybe_unused]] const EcmaVM *vm)
1677 {
1678     JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
1679     return typedArray->GetByteLength();
1680 }
1681 
ByteOffset(const EcmaVM * vm)1682 uint32_t TypedArrayRef::ByteOffset([[maybe_unused]] const EcmaVM *vm)
1683 {
1684     JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
1685     return typedArray->GetByteOffset();
1686 }
1687 
ArrayLength(const EcmaVM * vm)1688 uint32_t TypedArrayRef::ArrayLength([[maybe_unused]] const EcmaVM *vm)
1689 {
1690     JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
1691     return typedArray->GetArrayLength();
1692 }
1693 
GetArrayBuffer(const EcmaVM * vm)1694 Local<ArrayBufferRef> TypedArrayRef::GetArrayBuffer(const EcmaVM *vm)
1695 {
1696     JSThread *thread = vm->GetJSThread();
1697     JSHandle<JSTypedArray> typeArray(JSNApiHelper::ToJSHandle(this));
1698     JSHandle<JSTaggedValue> arrayBuffer(thread, JSTypedArray::GetOffHeapBuffer(thread, typeArray));
1699     return JSNApiHelper::ToLocal<ArrayBufferRef>(arrayBuffer);
1700 }
1701 
1702 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
1703 #define TYPED_ARRAY_NEW(Type)                                                                            \
1704     Local<Type##Ref> Type##Ref::New(                                                                     \
1705         const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length)              \
1706     {                                                                                                    \
1707         JSThread *thread = vm->GetJSThread();                                                            \
1708         JSHandle<GlobalEnv> env = vm->GetGlobalEnv();                                                    \
1709                                                                                                          \
1710         JSHandle<JSTaggedValue> func = env->Get##Type##Function();                                       \
1711         JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(buffer));                           \
1712         JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();            \
1713         const int32_t argsLength = 3;                                                                    \
1714         EcmaRuntimeCallInfo *info =                                                                      \
1715             ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, func, argsLength);  \
1716         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));                                       \
1717         info->SetCallArg(arrayBuffer.GetTaggedValue(), JSTaggedValue(byteOffset), JSTaggedValue(length)); \
1718         JSTaggedValue result = JSFunction::Construct(info);                                              \
1719         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));                                       \
1720         JSHandle<JSTaggedValue> resultHandle(thread, result);                                            \
1721         return JSNApiHelper::ToLocal<Type##Ref>(resultHandle);                                           \
1722     }
1723 
1724 TYPED_ARRAY_ALL(TYPED_ARRAY_NEW)
1725 
1726 #undef TYPED_ARRAY_NEW
1727 // ---------------------------------- TypedArray -----------------------------------
1728 
1729 // ---------------------------------- Error ---------------------------------------
1730 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
1731 #define EXCEPTION_ERROR_NEW(name, type)                                                     \
1732     Local<JSValueRef> Exception::name(const EcmaVM *vm, Local<StringRef> message)           \
1733     {                                                                                       \
1734         JSThread *thread = vm->GetJSThread();                                               \
1735         if (thread->HasPendingException()) {                                                \
1736             thread->ClearException();                                                       \
1737         }                                                                                   \
1738         ObjectFactory *factory = vm->GetFactory();                                          \
1739                                                                                             \
1740         JSHandle<EcmaString> messageValue(JSNApiHelper::ToJSHandle(message));               \
1741         JSHandle<JSTaggedValue> result(factory->NewJSError(ErrorType::type, messageValue)); \
1742         return JSNApiHelper::ToLocal<JSValueRef>(result);                                   \
1743     }
1744 
EXCEPTION_ERROR_ALL(EXCEPTION_ERROR_NEW)1745 EXCEPTION_ERROR_ALL(EXCEPTION_ERROR_NEW)
1746 
1747 #undef EXCEPTION_ERROR_NEW
1748 // ---------------------------------- Error ---------------------------------------
1749 
1750 // ---------------------------------- JSON ------------------------------------------
1751 Local<JSValueRef> JSON::Parse(const EcmaVM *vm, Local<StringRef> string)
1752 {
1753     JSThread *thread = vm->GetJSThread();
1754     auto ecmaStr = EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(*string).GetTaggedObject());
1755     JSHandle<JSTaggedValue> result;
1756     if (EcmaStringAccessor(ecmaStr).IsUtf8()) {
1757         JsonParser<uint8_t> parser(thread);
1758         result = parser.ParseUtf8(EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(*string).GetTaggedObject()));
1759     } else {
1760         JsonParser<uint16_t> parser(thread);
1761         result = parser.ParseUtf16(EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(*string).GetTaggedObject()));
1762     }
1763     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1764     return JSNApiHelper::ToLocal<JSValueRef>(result);
1765 }
1766 
Stringify(const EcmaVM * vm,Local<JSValueRef> json)1767 Local<JSValueRef> JSON::Stringify(const EcmaVM *vm, Local<JSValueRef> json)
1768 {
1769     JSThread *thread = vm->GetJSThread();
1770     auto constants = thread->GlobalConstants();
1771     JsonStringifier stringifier(thread);
1772     JSHandle<JSTaggedValue> str = stringifier.Stringify(
1773         JSNApiHelper::ToJSHandle(json), constants->GetHandledUndefined(), constants->GetHandledUndefined());
1774     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1775     return JSNApiHelper::ToLocal<JSValueRef>(str);
1776 }
1777 
GetOriginalSource(const EcmaVM * vm)1778 Local<StringRef> RegExpRef::GetOriginalSource(const EcmaVM *vm)
1779 {
1780     JSThread *thread = vm->GetJSThread();
1781     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
1782     JSTaggedValue source = regExp->GetOriginalSource();
1783     if (!source.IsString()) {
1784         auto constants = thread->GlobalConstants();
1785         return JSNApiHelper::ToLocal<StringRef>(constants->GetHandledEmptyString());
1786     }
1787     JSHandle<JSTaggedValue> sourceHandle(thread, source);
1788     return JSNApiHelper::ToLocal<StringRef>(sourceHandle);
1789 }
1790 
GetOriginalFlags()1791 std::string RegExpRef::GetOriginalFlags()
1792 {
1793     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
1794     JSTaggedValue regExpFlags = regExp->GetOriginalFlags();
1795     uint32_t regExpFlagsInt = static_cast<uint32_t>(regExpFlags.GetInt());
1796     std::string strFlags = "";
1797     if (regExpFlagsInt & RegExpParser::FLAG_GLOBAL) {
1798         strFlags += "g";
1799     }
1800     if (regExpFlagsInt & RegExpParser::FLAG_IGNORECASE) {
1801         strFlags += "i";
1802     }
1803     if (regExpFlagsInt & RegExpParser::FLAG_MULTILINE) {
1804         strFlags += "m";
1805     }
1806     if (regExpFlagsInt & RegExpParser::FLAG_DOTALL) {
1807         strFlags += "s";
1808     }
1809     if (regExpFlagsInt & RegExpParser::FLAG_UTF16) {
1810         strFlags += "u";
1811     }
1812     if (regExpFlagsInt & RegExpParser::FLAG_STICKY) {
1813         strFlags += "y";
1814     }
1815     std::sort(strFlags.begin(), strFlags.end());
1816     return strFlags;
1817 }
1818 
IsGlobal(const EcmaVM * vm)1819 Local<JSValueRef> RegExpRef::IsGlobal(const EcmaVM *vm)
1820 {
1821     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
1822     JSTaggedValue flags = regExp->GetOriginalFlags();
1823     bool result = flags.GetInt() & RegExpParser::FLAG_GLOBAL;
1824     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
1825     return jsValue;
1826 }
1827 
IsIgnoreCase(const EcmaVM * vm)1828 Local<JSValueRef> RegExpRef::IsIgnoreCase(const EcmaVM *vm)
1829 {
1830     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
1831     JSTaggedValue flags = regExp->GetOriginalFlags();
1832     bool result = flags.GetInt() & RegExpParser::FLAG_IGNORECASE;
1833     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
1834     return jsValue;
1835 }
1836 
IsMultiline(const EcmaVM * vm)1837 Local<JSValueRef> RegExpRef::IsMultiline(const EcmaVM *vm)
1838 {
1839     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
1840     JSTaggedValue flags = regExp->GetOriginalFlags();
1841     bool result = flags.GetInt() & RegExpParser::FLAG_MULTILINE;
1842     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
1843     return jsValue;
1844 }
1845 
IsDotAll(const EcmaVM * vm)1846 Local<JSValueRef> RegExpRef::IsDotAll(const EcmaVM *vm)
1847 {
1848     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
1849     JSTaggedValue flags = regExp->GetOriginalFlags();
1850     bool result = flags.GetInt() & RegExpParser::FLAG_DOTALL;
1851     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
1852     return jsValue;
1853 }
1854 
IsUtf16(const EcmaVM * vm)1855 Local<JSValueRef> RegExpRef::IsUtf16(const EcmaVM *vm)
1856 {
1857     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
1858     JSTaggedValue flags = regExp->GetOriginalFlags();
1859     bool result = flags.GetInt() & RegExpParser::FLAG_UTF16;
1860     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
1861     return jsValue;
1862 }
1863 
IsStick(const EcmaVM * vm)1864 Local<JSValueRef> RegExpRef::IsStick(const EcmaVM *vm)
1865 {
1866     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
1867     JSTaggedValue flags = regExp->GetOriginalFlags();
1868     bool result = flags.GetInt() & RegExpParser::FLAG_STICKY;
1869     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
1870     return jsValue;
1871 }
1872 
New(const EcmaVM * vm,double time)1873 Local<DateRef> DateRef::New(const EcmaVM *vm, double time)
1874 {
1875     JSThread *thread = vm->GetJSThread();
1876     ObjectFactory *factory = vm->GetFactory();
1877     JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
1878     JSHandle<JSFunction> dateFunction(globalEnv->GetDateFunction());
1879     JSHandle<JSDate> dateObject(factory->NewJSObjectByConstructor(dateFunction));
1880     dateObject->SetTimeValue(thread, JSTaggedValue(time));
1881     return JSNApiHelper::ToLocal<DateRef>(JSHandle<JSTaggedValue>(dateObject));
1882 }
1883 
ToString(const EcmaVM * vm)1884 Local<StringRef> DateRef::ToString(const EcmaVM *vm)
1885 {
1886     JSThread *thread = vm->GetJSThread();
1887     JSHandle<JSDate> date(JSNApiHelper::ToJSHandle(this));
1888     JSTaggedValue dateStr = date->ToString(thread);
1889     if (!dateStr.IsString()) {
1890         auto constants = thread->GlobalConstants();
1891         return JSNApiHelper::ToLocal<StringRef>(constants->GetHandledEmptyString());
1892     }
1893     JSHandle<JSTaggedValue> dateStrHandle(thread, dateStr);
1894     return JSNApiHelper::ToLocal<StringRef>(dateStrHandle);
1895 }
1896 
GetTime()1897 double DateRef::GetTime()
1898 {
1899     JSHandle<JSDate> date(JSNApiHelper::ToJSHandle(this));
1900     if (!date->IsDate()) {
1901         LOG_ECMA(ERROR) << "Not a Date Object";
1902     }
1903     return date->GetTime().GetDouble();
1904 }
1905 
Get(const EcmaVM * vm,Local<JSValueRef> key)1906 Local<JSValueRef> MapRef::Get(const EcmaVM *vm, Local<JSValueRef> key)
1907 {
1908     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1909     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(vm->GetJSThread(),
1910                 map->Get(JSNApiHelper::ToJSTaggedValue(*key))));
1911 }
1912 
Set(const EcmaVM * vm,Local<JSValueRef> key,Local<JSValueRef> value)1913 void MapRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value)
1914 {
1915     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1916     JSMap::Set(vm->GetJSThread(), map, JSNApiHelper::ToJSHandle(key), JSNApiHelper::ToJSHandle(value));
1917 }
1918 
New(const EcmaVM * vm)1919 Local<MapRef> MapRef::New(const EcmaVM *vm)
1920 {
1921     JSThread *thread = vm->GetJSThread();
1922     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1923     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1924     JSHandle<JSTaggedValue> constructor = env->GetBuiltinsMapFunction();
1925     JSHandle<JSMap> map =
1926         JSHandle<JSMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
1927     JSHandle<LinkedHashMap> hashMap = LinkedHashMap::Create(thread);
1928     map->SetLinkedMap(thread, hashMap);
1929     JSHandle<JSTaggedValue> mapTag = JSHandle<JSTaggedValue>::Cast(map);
1930     return JSNApiHelper::ToLocal<MapRef>(mapTag);
1931 }
1932 
GetSize()1933 int32_t MapRef::GetSize()
1934 {
1935     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1936     return map->GetSize();
1937 }
1938 
GetTotalElements()1939 int32_t MapRef::GetTotalElements()
1940 {
1941     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1942     return map->GetSize() + LinkedHashMap::Cast(map->GetLinkedMap().GetTaggedObject())->NumberOfDeletedElements();
1943 }
1944 
GetKey(const EcmaVM * vm,int entry)1945 Local<JSValueRef> MapRef::GetKey(const EcmaVM *vm, int entry)
1946 {
1947     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1948     JSThread *thread = vm->GetJSThread();
1949     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, map->GetKey(entry)));
1950 }
1951 
GetValue(const EcmaVM * vm,int entry)1952 Local<JSValueRef> MapRef::GetValue(const EcmaVM *vm, int entry)
1953 {
1954     JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1955     JSThread *thread = vm->GetJSThread();
1956     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, map->GetValue(entry)));
1957 }
1958 
GetSize()1959 int32_t SetRef::GetSize()
1960 {
1961     JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this));
1962     return set->GetSize();
1963 }
1964 
GetTotalElements()1965 int32_t SetRef::GetTotalElements()
1966 {
1967     JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this));
1968     return set->GetSize() + LinkedHashSet::Cast(set->GetLinkedSet().GetTaggedObject())->NumberOfDeletedElements();
1969 }
1970 
GetValue(const EcmaVM * vm,int entry)1971 Local<JSValueRef> SetRef::GetValue(const EcmaVM *vm, int entry)
1972 {
1973     JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this));
1974     JSThread *thread = vm->GetJSThread();
1975     return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, set->GetValue(entry)));
1976 }
1977 
GetIndex()1978 int32_t MapIteratorRef::GetIndex()
1979 {
1980     JSHandle<JSMapIterator> jsMapIter(JSNApiHelper::ToJSHandle(this));
1981     return jsMapIter->GetNextIndex();
1982 }
1983 
GetKind(const EcmaVM * vm)1984 Local<JSValueRef> MapIteratorRef::GetKind(const EcmaVM *vm)
1985 {
1986     JSHandle<JSMapIterator> jsMapIter(JSNApiHelper::ToJSHandle(this));
1987     IterationKind iterKind = jsMapIter->GetIterationKind();
1988     Local<JSValueRef> result;
1989     switch (iterKind) {
1990         case IterationKind::KEY:
1991             result = StringRef::NewFromUtf8(vm, "keys");
1992             break;
1993         case IterationKind::VALUE:
1994             result = StringRef::NewFromUtf8(vm, "values");
1995             break;
1996         case IterationKind::KEY_AND_VALUE:
1997             result = StringRef::NewFromUtf8(vm, "entries");
1998             break;
1999         default:
2000             break;
2001     }
2002     return result;
2003 }
2004 
GetIndex()2005 int32_t SetIteratorRef::GetIndex()
2006 {
2007     JSHandle<JSSetIterator> jsSetIter(JSNApiHelper::ToJSHandle(this));
2008     return jsSetIter->GetNextIndex();
2009 }
2010 
GetKind(const EcmaVM * vm)2011 Local<JSValueRef> SetIteratorRef::GetKind(const EcmaVM *vm)
2012 {
2013     JSHandle<JSSetIterator> jsSetIter(JSNApiHelper::ToJSHandle(this));
2014     IterationKind iterKind = jsSetIter->GetIterationKind();
2015     Local<JSValueRef> result;
2016     switch (iterKind) {
2017         case IterationKind::KEY:
2018             result = StringRef::NewFromUtf8(vm, "keys");
2019             break;
2020         case IterationKind::VALUE:
2021             result = StringRef::NewFromUtf8(vm, "values");
2022             break;
2023         case IterationKind::KEY_AND_VALUE:
2024             result = StringRef::NewFromUtf8(vm, "entries");
2025             break;
2026         default:
2027             break;
2028     }
2029     return result;
2030 }
2031 
IsGenerator()2032 bool GeneratorFunctionRef::IsGenerator()
2033 {
2034     return IsGeneratorFunction();
2035 }
2036 
GetGeneratorState(const EcmaVM * vm)2037 Local<JSValueRef> GeneratorObjectRef::GetGeneratorState(const EcmaVM *vm)
2038 {
2039     JSHandle<JSGeneratorObject> jsGenerator(JSNApiHelper::ToJSHandle(this));
2040     if (jsGenerator->GetGeneratorState() == JSGeneratorState::COMPLETED) {
2041         return StringRef::NewFromUtf8(vm, "closed");
2042     }
2043     return StringRef::NewFromUtf8(vm, "suspended");
2044 }
2045 
GetGeneratorFunction(const EcmaVM * vm)2046 Local<JSValueRef> GeneratorObjectRef::GetGeneratorFunction(const EcmaVM *vm)
2047 {
2048     JSThread *thread = vm->GetJSThread();
2049     JSHandle<JSGeneratorObject> jsGenerator(JSNApiHelper::ToJSHandle(this));
2050     JSHandle<GeneratorContext> generatorContext(thread, jsGenerator->GetGeneratorContext());
2051     JSTaggedValue jsTagValue = generatorContext->GetMethod();
2052     return JSNApiHelper::ToLocal<GeneratorFunctionRef>(JSHandle<JSTaggedValue>(thread, jsTagValue));
2053 }
2054 
GetGeneratorReceiver(const EcmaVM * vm)2055 Local<JSValueRef> GeneratorObjectRef::GetGeneratorReceiver(const EcmaVM *vm)
2056 {
2057     JSThread *thread = vm->GetJSThread();
2058     JSHandle<JSGeneratorObject> jsGenerator(JSNApiHelper::ToJSHandle(this));
2059     JSHandle<GeneratorContext> generatorContext(thread, jsGenerator->GetGeneratorContext());
2060     JSTaggedValue jsTagValue = generatorContext->GetAcc();
2061     return JSNApiHelper::ToLocal<GeneratorObjectRef>(JSHandle<JSTaggedValue>(thread, jsTagValue));
2062 }
2063 
GetCompareFunction(const EcmaVM * vm)2064 Local<JSValueRef> CollatorRef::GetCompareFunction(const EcmaVM *vm)
2065 {
2066     JSThread *thread = vm->GetJSThread();
2067     JSHandle<JSCollator> jsCollator(JSNApiHelper::ToJSHandle(this));
2068     JSTaggedValue jsTagValue = jsCollator->GetBoundCompare();
2069     return JSNApiHelper::ToLocal<CollatorRef>(JSHandle<JSTaggedValue>(thread, jsTagValue));
2070 }
2071 
GetFormatFunction(const EcmaVM * vm)2072 Local<JSValueRef> DataTimeFormatRef::GetFormatFunction(const EcmaVM *vm)
2073 {
2074     JSThread *thread = vm->GetJSThread();
2075     JSHandle<JSDateTimeFormat> jsDateTimeFormat(JSNApiHelper::ToJSHandle(this));
2076     JSTaggedValue jsTagValue = jsDateTimeFormat->GetBoundFormat();
2077     return JSNApiHelper::ToLocal<DataTimeFormatRef>(JSHandle<JSTaggedValue>(thread, jsTagValue));
2078 }
2079 
GetFormatFunction(const EcmaVM * vm)2080 Local<JSValueRef> NumberFormatRef::GetFormatFunction(const EcmaVM *vm)
2081 {
2082     JSThread *thread = vm->GetJSThread();
2083     JSHandle<JSNumberFormat> jsNumberFormat(JSNApiHelper::ToJSHandle(this));
2084     JSTaggedValue jsTagValue = jsNumberFormat->GetBoundFormat();
2085     return JSNApiHelper::ToLocal<NumberFormatRef>(JSHandle<JSTaggedValue>(thread, jsTagValue));
2086 }
2087 
2088 // ----------------------------------- FunctionCallback ---------------------------------
RegisterCallback(ecmascript::EcmaRuntimeCallInfo * ecmaRuntimeCallInfo)2089 JSTaggedValue Callback::RegisterCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo)
2090 {
2091     // Constructor
2092     JSThread *thread = ecmaRuntimeCallInfo->GetThread();
2093     JSHandle<JSTaggedValue> constructor = BuiltinsBase::GetConstructor(ecmaRuntimeCallInfo);
2094     if (!constructor->IsJSFunction()) {
2095         return JSTaggedValue::False();
2096     }
2097     [[maybe_unused]] LocalScope scope(thread->GetEcmaVM());
2098     JSHandle<JSFunction> function(constructor);
2099     JSTaggedValue extraInfoValue = function->GetFunctionExtraInfo();
2100     if (!extraInfoValue.IsJSNativePointer()) {
2101         return JSTaggedValue::False();
2102     }
2103     JSHandle<JSNativePointer> extraInfo(thread, extraInfoValue);
2104     // callBack
2105     FunctionCallback nativeFunc = reinterpret_cast<FunctionCallback>(extraInfo->GetExternalPointer());
2106 
2107     JsiRuntimeCallInfo jsiRuntimeCallInfo(ecmaRuntimeCallInfo, extraInfo->GetData());
2108 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
2109     if (thread->GetCallNapiGetStack() && function->IsCallNapi()) {
2110         thread->GetEcmaVM()->GetProfiler()->GetStackCallNapi(thread, true);
2111     }
2112 #endif
2113     Local<JSValueRef> result = nativeFunc(&jsiRuntimeCallInfo);
2114 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
2115     if (thread->GetCallNapiGetStack() && function->IsCallNapi()) {
2116         thread->GetEcmaVM()->GetProfiler()->GetStackCallNapi(thread, false);
2117     }
2118 #endif
2119     return JSNApiHelper::ToJSHandle(result).GetTaggedValue();
2120 }
2121 
2122 // -------------------------------------  JSExecutionScope ------------------------------
JSExecutionScope(const EcmaVM * vm)2123 JSExecutionScope::JSExecutionScope(const EcmaVM *vm)
2124 {
2125     (void)vm;
2126 }
2127 
~JSExecutionScope()2128 JSExecutionScope::~JSExecutionScope()
2129 {
2130     last_current_thread_ = nullptr;
2131     is_revert_ = false;
2132 }
2133 
2134 // ----------------------------------- JSValueRef --------------------------------------
Undefined(const EcmaVM * vm)2135 Local<PrimitiveRef> JSValueRef::Undefined(const EcmaVM *vm)
2136 {
2137     JSThread *thread = vm->GetJSThread();
2138     const GlobalEnvConstants *constants = thread->GlobalConstants();
2139     return JSNApiHelper::ToLocal<PrimitiveRef>(constants->GetHandledUndefined());
2140 }
2141 
Null(const EcmaVM * vm)2142 Local<PrimitiveRef> JSValueRef::Null(const EcmaVM *vm)
2143 {
2144     return JSNApiHelper::ToLocal<PrimitiveRef>(JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::Null()));
2145 }
2146 
True(const EcmaVM * vm)2147 Local<PrimitiveRef> JSValueRef::True(const EcmaVM *vm)
2148 {
2149     return JSNApiHelper::ToLocal<PrimitiveRef>(JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::True()));
2150 }
2151 
False(const EcmaVM * vm)2152 Local<PrimitiveRef> JSValueRef::False(const EcmaVM *vm)
2153 {
2154     return JSNApiHelper::ToLocal<PrimitiveRef>(JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::False()));
2155 }
2156 
ToObject(const EcmaVM * vm)2157 Local<ObjectRef> JSValueRef::ToObject(const EcmaVM *vm)
2158 {
2159     JSThread *thread = vm->GetJSThread();
2160     if (IsUndefined() || IsNull()) {
2161         return Undefined(vm);
2162     }
2163     JSHandle<JSTaggedValue> obj(JSTaggedValue::ToObject(thread, JSNApiHelper::ToJSHandle(this)));
2164     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2165     return JSNApiHelper::ToLocal<ObjectRef>(obj);
2166 }
2167 
ToString(const EcmaVM * vm)2168 Local<StringRef> JSValueRef::ToString(const EcmaVM *vm)
2169 {
2170     JSThread *thread = vm->GetJSThread();
2171     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2172     if (!obj->IsString()) {
2173         obj = JSHandle<JSTaggedValue>(JSTaggedValue::ToString(thread, obj));
2174         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2175     }
2176     return JSNApiHelper::ToLocal<StringRef>(obj);
2177 }
2178 
ToNativePointer(const EcmaVM * vm)2179 Local<NativePointerRef> JSValueRef::ToNativePointer(const EcmaVM *vm)
2180 {
2181     JSThread *thread = vm->GetJSThread();
2182     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2183     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2184     return JSNApiHelper::ToLocal<NativePointerRef>(obj);
2185 }
2186 
BooleaValue()2187 bool JSValueRef::BooleaValue()
2188 {
2189     return JSNApiHelper::ToJSTaggedValue(this).ToBoolean();
2190 }
2191 
IntegerValue(const EcmaVM * vm)2192 int64_t JSValueRef::IntegerValue(const EcmaVM *vm)
2193 {
2194     JSThread *thread = vm->GetJSThread();
2195     JSHandle<JSTaggedValue> tagged = JSNApiHelper::ToJSHandle(this);
2196     if (tagged->IsNumber()) {
2197         if (!NumberHelper::IsFinite(tagged.GetTaggedValue()) || NumberHelper::IsNaN(tagged.GetTaggedValue())) {
2198             return 0;
2199         } else {
2200             return NumberHelper::DoubleToInt64(tagged->GetNumber());
2201         }
2202     }
2203     JSTaggedNumber number = JSTaggedValue::ToInteger(thread, tagged);
2204     RETURN_VALUE_IF_ABRUPT(thread, 0);
2205     return NumberHelper::DoubleToInt64(number.GetNumber());
2206 }
2207 
Uint32Value(const EcmaVM * vm)2208 uint32_t JSValueRef::Uint32Value(const EcmaVM *vm)
2209 {
2210     JSThread *thread = vm->GetJSThread();
2211     uint32_t number = JSTaggedValue::ToUint32(thread, JSNApiHelper::ToJSHandle(this));
2212     RETURN_VALUE_IF_ABRUPT(thread, 0);
2213     return number;
2214 }
2215 
Int32Value(const EcmaVM * vm)2216 int32_t JSValueRef::Int32Value(const EcmaVM *vm)
2217 {
2218     JSThread *thread = vm->GetJSThread();
2219     int32_t number = JSTaggedValue::ToInt32(thread, JSNApiHelper::ToJSHandle(this));
2220     RETURN_VALUE_IF_ABRUPT(thread, 0);
2221     return number;
2222 }
2223 
ToBoolean(const EcmaVM * vm)2224 Local<BooleanRef> JSValueRef::ToBoolean(const EcmaVM *vm)
2225 {
2226     JSThread *thread = vm->GetJSThread();
2227     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2228     JSHandle<JSTaggedValue> booleanObj = JSHandle<JSTaggedValue>(thread, JSTaggedValue(obj->ToBoolean()));
2229     return JSNApiHelper::ToLocal<BooleanRef>(booleanObj);
2230 }
2231 
ToNumber(const EcmaVM * vm)2232 Local<NumberRef> JSValueRef::ToNumber(const EcmaVM *vm)
2233 {
2234     JSThread *thread = vm->GetJSThread();
2235     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2236     JSHandle<JSTaggedValue> number(thread, JSTaggedValue::ToNumber(thread, obj));
2237     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2238     return JSNApiHelper::ToLocal<NumberRef>(number);
2239 }
2240 
IsStrictEquals(const EcmaVM * vm,Local<JSValueRef> value)2241 bool JSValueRef::IsStrictEquals(const EcmaVM *vm, Local<JSValueRef> value)
2242 {
2243     JSThread *thread = vm->GetJSThread();
2244     JSHandle<JSTaggedValue> xValue = JSNApiHelper::ToJSHandle(this);
2245     JSHandle<JSTaggedValue> yValue = JSNApiHelper::ToJSHandle(value);
2246     return JSTaggedValue::StrictEqual(thread, xValue, yValue);
2247 }
2248 
Typeof(const EcmaVM * vm)2249 Local<StringRef> JSValueRef::Typeof(const EcmaVM *vm)
2250 {
2251     JSThread *thread = vm->GetJSThread();
2252     JSTaggedValue value = FastRuntimeStub::FastTypeOf(thread, JSNApiHelper::ToJSTaggedValue(this));
2253     return JSNApiHelper::ToLocal<StringRef>(JSHandle<JSTaggedValue>(thread, value));
2254 }
2255 
InstanceOf(const EcmaVM * vm,Local<JSValueRef> value)2256 bool JSValueRef::InstanceOf(const EcmaVM *vm, Local<JSValueRef> value)
2257 {
2258     JSThread *thread = vm->GetJSThread();
2259     JSHandle<JSTaggedValue> origin = JSNApiHelper::ToJSHandle(this);
2260     JSHandle<JSTaggedValue> target = JSNApiHelper::ToJSHandle(value);
2261     bool result = JSObject::InstanceOf(thread, origin, target);
2262     RETURN_VALUE_IF_ABRUPT(thread, false);
2263     return result;
2264 }
2265 
IsUndefined()2266 bool JSValueRef::IsUndefined()
2267 {
2268     return JSNApiHelper::ToJSTaggedValue(this).IsUndefined();
2269 }
2270 
IsNull()2271 bool JSValueRef::IsNull()
2272 {
2273     return JSNApiHelper::ToJSTaggedValue(this).IsNull();
2274 }
2275 
IsHole()2276 bool JSValueRef::IsHole()
2277 {
2278     return JSNApiHelper::ToJSTaggedValue(this).IsHole();
2279 }
2280 
IsTrue()2281 bool JSValueRef::IsTrue()
2282 {
2283     return JSNApiHelper::ToJSTaggedValue(this).IsTrue();
2284 }
2285 
IsFalse()2286 bool JSValueRef::IsFalse()
2287 {
2288     return JSNApiHelper::ToJSTaggedValue(this).IsFalse();
2289 }
2290 
IsNumber()2291 bool JSValueRef::IsNumber()
2292 {
2293     return JSNApiHelper::ToJSTaggedValue(this).IsNumber();
2294 }
2295 
IsBigInt()2296 bool JSValueRef::IsBigInt()
2297 {
2298     return JSNApiHelper::ToJSTaggedValue(this).IsBigInt();
2299 }
2300 
IsInt()2301 bool JSValueRef::IsInt()
2302 {
2303     return JSNApiHelper::ToJSTaggedValue(this).IsInt();
2304 }
2305 
WithinInt32()2306 bool JSValueRef::WithinInt32()
2307 {
2308     return JSNApiHelper::ToJSTaggedValue(this).WithinInt32();
2309 }
2310 
IsBoolean()2311 bool JSValueRef::IsBoolean()
2312 {
2313     return JSNApiHelper::ToJSTaggedValue(this).IsBoolean();
2314 }
2315 
IsString()2316 bool JSValueRef::IsString()
2317 {
2318     return JSNApiHelper::ToJSTaggedValue(this).IsString();
2319 }
2320 
IsSymbol()2321 bool JSValueRef::IsSymbol()
2322 {
2323     return JSNApiHelper::ToJSTaggedValue(this).IsSymbol();
2324 }
2325 
IsObject()2326 bool JSValueRef::IsObject()
2327 {
2328     return JSNApiHelper::ToJSTaggedValue(this).IsECMAObject();
2329 }
2330 
IsArray(const EcmaVM * vm)2331 bool JSValueRef::IsArray(const EcmaVM *vm)
2332 {
2333     JSThread *thread = vm->GetJSThread();
2334     return JSNApiHelper::ToJSTaggedValue(this).IsArray(thread);
2335 }
2336 
IsConstructor()2337 bool JSValueRef::IsConstructor()
2338 {
2339     JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
2340     return value.IsHeapObject() && value.IsConstructor();
2341 }
2342 
IsFunction()2343 bool JSValueRef::IsFunction()
2344 {
2345     JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
2346     return value.IsHeapObject() && value.IsCallable();
2347 }
2348 
IsProxy()2349 bool JSValueRef::IsProxy()
2350 {
2351     return JSNApiHelper::ToJSTaggedValue(this).IsJSProxy();
2352 }
2353 
IsPromise()2354 bool JSValueRef::IsPromise()
2355 {
2356     return JSNApiHelper::ToJSTaggedValue(this).IsJSPromise();
2357 }
2358 
IsDataView()2359 bool JSValueRef::IsDataView()
2360 {
2361     return JSNApiHelper::ToJSTaggedValue(this).IsDataView();
2362 }
2363 
IsTypedArray()2364 bool JSValueRef::IsTypedArray()
2365 {
2366     return JSNApiHelper::ToJSTaggedValue(this).IsTypedArray();
2367 }
2368 
IsNativePointer()2369 bool JSValueRef::IsNativePointer()
2370 {
2371     return JSNApiHelper::ToJSTaggedValue(this).IsJSNativePointer();
2372 }
2373 
IsDate()2374 bool JSValueRef::IsDate()
2375 {
2376     return JSNApiHelper::ToJSTaggedValue(this).IsDate();
2377 }
2378 
IsError()2379 bool JSValueRef::IsError()
2380 {
2381     return JSNApiHelper::ToJSTaggedValue(this).IsJSError();
2382 }
2383 
IsMap()2384 bool JSValueRef::IsMap()
2385 {
2386     return JSNApiHelper::ToJSTaggedValue(this).IsJSMap();
2387 }
2388 
IsSet()2389 bool JSValueRef::IsSet()
2390 {
2391     return JSNApiHelper::ToJSTaggedValue(this).IsJSSet();
2392 }
2393 
IsWeakRef()2394 bool JSValueRef::IsWeakRef()
2395 {
2396     return JSNApiHelper::ToJSTaggedValue(this).IsJSWeakRef();
2397 }
2398 
IsWeakMap()2399 bool JSValueRef::IsWeakMap()
2400 {
2401     return JSNApiHelper::ToJSTaggedValue(this).IsJSWeakMap();
2402 }
2403 
IsWeakSet()2404 bool JSValueRef::IsWeakSet()
2405 {
2406     return JSNApiHelper::ToJSTaggedValue(this).IsJSWeakSet();
2407 }
2408 
IsRegExp()2409 bool JSValueRef::IsRegExp()
2410 {
2411     return JSNApiHelper::ToJSTaggedValue(this).IsJSRegExp();
2412 }
2413 
IsArrayIterator()2414 bool JSValueRef::IsArrayIterator()
2415 {
2416     return JSNApiHelper::ToJSTaggedValue(this).IsJSArrayIterator();
2417 }
2418 
IsStringIterator()2419 bool JSValueRef::IsStringIterator()
2420 {
2421     return JSNApiHelper::ToJSTaggedValue(this).IsStringIterator();
2422 }
2423 
IsSetIterator()2424 bool JSValueRef::IsSetIterator()
2425 {
2426     return JSNApiHelper::ToJSTaggedValue(this).IsJSSetIterator();
2427 }
2428 
IsMapIterator()2429 bool JSValueRef::IsMapIterator()
2430 {
2431     return JSNApiHelper::ToJSTaggedValue(this).IsJSMapIterator();
2432 }
2433 
IsArrayBuffer()2434 bool JSValueRef::IsArrayBuffer()
2435 {
2436     return JSNApiHelper::ToJSTaggedValue(this).IsArrayBuffer();
2437 }
2438 
IsUint8Array()2439 bool JSValueRef::IsUint8Array()
2440 {
2441     return JSNApiHelper::ToJSTaggedValue(this).IsJSUint8Array();
2442 }
2443 
IsInt8Array()2444 bool JSValueRef::IsInt8Array()
2445 {
2446     return JSNApiHelper::ToJSTaggedValue(this).IsJSInt8Array();
2447 }
2448 
IsUint8ClampedArray()2449 bool JSValueRef::IsUint8ClampedArray()
2450 {
2451     return JSNApiHelper::ToJSTaggedValue(this).IsJSUint8ClampedArray();
2452 }
2453 
IsInt16Array()2454 bool JSValueRef::IsInt16Array()
2455 {
2456     return JSNApiHelper::ToJSTaggedValue(this).IsJSInt16Array();
2457 }
2458 
IsUint16Array()2459 bool JSValueRef::IsUint16Array()
2460 {
2461     return JSNApiHelper::ToJSTaggedValue(this).IsJSUint16Array();
2462 }
2463 
IsInt32Array()2464 bool JSValueRef::IsInt32Array()
2465 {
2466     return JSNApiHelper::ToJSTaggedValue(this).IsJSInt32Array();
2467 }
2468 
IsUint32Array()2469 bool JSValueRef::IsUint32Array()
2470 {
2471     return JSNApiHelper::ToJSTaggedValue(this).IsJSUint32Array();
2472 }
2473 
IsFloat32Array()2474 bool JSValueRef::IsFloat32Array()
2475 {
2476     return JSNApiHelper::ToJSTaggedValue(this).IsJSFloat32Array();
2477 }
2478 
IsFloat64Array()2479 bool JSValueRef::IsFloat64Array()
2480 {
2481     return JSNApiHelper::ToJSTaggedValue(this).IsJSFloat64Array();
2482 }
2483 
IsBigInt64Array()2484 bool JSValueRef::IsBigInt64Array()
2485 {
2486     return JSNApiHelper::ToJSTaggedValue(this).IsJSBigInt64Array();
2487 }
2488 
IsBigUint64Array()2489 bool JSValueRef::IsBigUint64Array()
2490 {
2491     return JSNApiHelper::ToJSTaggedValue(this).IsJSBigUint64Array();
2492 }
2493 
IsJSPrimitiveRef()2494 bool JSValueRef::IsJSPrimitiveRef()
2495 {
2496     return JSNApiHelper::ToJSTaggedValue(this).IsJSPrimitiveRef();
2497 }
2498 
IsJSPrimitiveNumber()2499 bool JSValueRef::IsJSPrimitiveNumber()
2500 {
2501     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2502     return JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsNumber();
2503 }
2504 
IsJSPrimitiveInt()2505 bool JSValueRef::IsJSPrimitiveInt()
2506 {
2507     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2508     return JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsInt();
2509 }
2510 
IsJSPrimitiveBoolean()2511 bool JSValueRef::IsJSPrimitiveBoolean()
2512 {
2513     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2514     return JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsBoolean();
2515 }
2516 
IsJSPrimitiveString()2517 bool JSValueRef::IsJSPrimitiveString()
2518 {
2519     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2520     return JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsString();
2521 }
2522 
IsJSPrimitiveSymbol()2523 bool JSValueRef::IsJSPrimitiveSymbol()
2524 {
2525     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2526     return JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsSymbol();
2527 }
2528 
IsGeneratorObject()2529 bool JSValueRef::IsGeneratorObject()
2530 {
2531     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2532     bool rst = obj->IsGeneratorObject();
2533     return rst;
2534 }
2535 
IsModuleNamespaceObject()2536 bool JSValueRef::IsModuleNamespaceObject()
2537 {
2538     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2539     bool rst = obj->IsModuleNamespace();
2540     return rst;
2541 }
2542 
IsSharedArrayBuffer()2543 bool JSValueRef::IsSharedArrayBuffer()
2544 {
2545     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2546     bool rst = obj->IsSharedArrayBuffer();
2547     return rst;
2548 }
2549 
IsJSLocale()2550 bool JSValueRef::IsJSLocale()
2551 {
2552     return JSNApiHelper::ToJSTaggedValue(this).IsJSLocale();
2553 }
2554 
IsJSDateTimeFormat()2555 bool JSValueRef::IsJSDateTimeFormat()
2556 {
2557     return JSNApiHelper::ToJSTaggedValue(this).IsJSDateTimeFormat();
2558 }
2559 
IsJSRelativeTimeFormat()2560 bool JSValueRef::IsJSRelativeTimeFormat()
2561 {
2562     return JSNApiHelper::ToJSTaggedValue(this).IsJSRelativeTimeFormat();
2563 }
2564 
IsJSIntl()2565 bool JSValueRef::IsJSIntl()
2566 {
2567     return JSNApiHelper::ToJSTaggedValue(this).IsJSIntl();
2568 }
2569 
IsJSNumberFormat()2570 bool JSValueRef::IsJSNumberFormat()
2571 {
2572     return JSNApiHelper::ToJSTaggedValue(this).IsJSNumberFormat();
2573 }
2574 
IsJSCollator()2575 bool JSValueRef::IsJSCollator()
2576 {
2577     return JSNApiHelper::ToJSTaggedValue(this).IsJSCollator();
2578 }
2579 
IsJSPluralRules()2580 bool JSValueRef::IsJSPluralRules()
2581 {
2582     return JSNApiHelper::ToJSTaggedValue(this).IsJSPluralRules();
2583 }
2584 
IsJSListFormat()2585 bool JSValueRef::IsJSListFormat()
2586 {
2587     return JSNApiHelper::ToJSTaggedValue(this).IsJSListFormat();
2588 }
2589 
IsAsyncGeneratorObject()2590 bool JSValueRef::IsAsyncGeneratorObject()
2591 {
2592     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2593     return obj->IsAsyncGeneratorObject();
2594 }
2595 
IsAsyncFunction()2596 bool JSValueRef::IsAsyncFunction()
2597 {
2598     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2599     bool rst  = obj->IsJSAsyncFunction();
2600     return rst;
2601 }
2602 
IsArgumentsObject()2603 bool JSValueRef::IsArgumentsObject()
2604 {
2605     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2606     bool rst  = obj->IsArguments();
2607     return rst;
2608 }
2609 
IsGeneratorFunction()2610 bool JSValueRef::IsGeneratorFunction()
2611 {
2612     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2613     bool rst  = obj->IsGeneratorFunction();
2614     return rst;
2615 }
2616 
IsAsyncGeneratorFunction()2617 bool JSValueRef::IsAsyncGeneratorFunction()
2618 {
2619     JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2620     return obj->IsAsyncGeneratorFunction();
2621 }
2622 
2623 // ------------------------------------ JsiRuntimeCallInfo -----------------------------------------------
JsiRuntimeCallInfo(ecmascript::EcmaRuntimeCallInfo * ecmaInfo,void * data)2624 JsiRuntimeCallInfo::JsiRuntimeCallInfo(ecmascript::EcmaRuntimeCallInfo* ecmaInfo, void* data)
2625     : thread_(ecmaInfo->GetThread()), numArgs_(ecmaInfo->GetArgsNumber())
2626 {
2627     stackArgs_ = ecmaInfo->GetArgs();
2628     data_ = data;
2629 }
2630 
GetVM() const2631 EcmaVM *JsiRuntimeCallInfo::GetVM() const
2632 {
2633     return thread_->GetEcmaVM();
2634 }
2635 
2636 // ---------------------------------------Hot Patch----------------------------------------------------
LoadPatch(EcmaVM * vm,const std::string & patchFileName,const std::string & baseFileName)2637 bool JSNApi::LoadPatch(EcmaVM *vm, const std::string &patchFileName, const std::string &baseFileName)
2638 {
2639     ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
2640     JSThread *thread = vm->GetJSThread();
2641     return quickFixManager->LoadPatch(thread, patchFileName, baseFileName);
2642 }
2643 
LoadPatch(EcmaVM * vm,const std::string & patchFileName,const void * patchBuffer,size_t patchSize,const std::string & baseFileName)2644 bool JSNApi::LoadPatch(EcmaVM *vm, const std::string &patchFileName, const void *patchBuffer, size_t patchSize,
2645                        const std::string &baseFileName)
2646 {
2647     ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
2648     JSThread *thread = vm->GetJSThread();
2649     return quickFixManager->LoadPatch(thread, patchFileName, patchBuffer, patchSize, baseFileName);
2650 }
2651 
UnloadPatch(EcmaVM * vm,const std::string & patchFileName)2652 bool JSNApi::UnloadPatch(EcmaVM *vm, const std::string &patchFileName)
2653 {
2654     ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
2655     JSThread *thread = vm->GetJSThread();
2656     return quickFixManager->UnloadPatch(thread, patchFileName);
2657 }
2658 
2659 /*
2660  * check whether the exception is caused by quickfix methods.
2661  */
IsQuickFixCausedException(EcmaVM * vm,Local<ObjectRef> exception,const std::string & patchFileName)2662 bool JSNApi::IsQuickFixCausedException(EcmaVM *vm, Local<ObjectRef> exception, const std::string &patchFileName)
2663 {
2664     if (exception.IsEmpty()) {
2665         return false;
2666     }
2667     ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
2668     JSThread *thread = vm->GetJSThread();
2669     JSHandle<JSTaggedValue> exceptionInfo = JSNApiHelper::ToJSHandle(exception);
2670     return quickFixManager->IsQuickFixCausedException(thread, exceptionInfo, patchFileName);
2671 }
2672 
2673 /*
2674  * register quickfix query function.
2675  */
RegisterQuickFixQueryFunc(EcmaVM * vm,QuickFixQueryCallBack callBack)2676 void JSNApi::RegisterQuickFixQueryFunc(EcmaVM *vm, QuickFixQueryCallBack callBack)
2677 {
2678     ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
2679     quickFixManager->RegisterQuickFixQueryFunc(callBack);
2680 }
2681 
IsBundle(EcmaVM * vm)2682 bool JSNApi::IsBundle(EcmaVM *vm)
2683 {
2684     return vm->IsBundlePack();
2685 }
2686 
SetBundle(EcmaVM * vm,bool value)2687 void JSNApi::SetBundle(EcmaVM *vm, bool value)
2688 {
2689     vm->SetIsBundlePack(value);
2690 }
2691 
2692 // note: The function SetAssetPath is a generic interface for previewing and physical machines.
SetAssetPath(EcmaVM * vm,const std::string & assetPath)2693 void JSNApi::SetAssetPath(EcmaVM *vm, const std::string &assetPath)
2694 {
2695     ecmascript::CString path = assetPath.c_str();
2696     vm->SetAssetPath(path);
2697 }
2698 
GetAssetPath(EcmaVM * vm)2699 std::string JSNApi::GetAssetPath(EcmaVM *vm)
2700 {
2701     return vm->GetAssetPath().c_str();
2702 }
2703 
SetBundleName(EcmaVM * vm,std::string bundleName)2704 void JSNApi::SetBundleName(EcmaVM *vm, std::string bundleName)
2705 {
2706     ecmascript::CString name = bundleName.c_str();
2707     vm->SetBundleName(name);
2708 }
2709 
GetBundleName(EcmaVM * vm)2710 std::string JSNApi::GetBundleName(EcmaVM *vm)
2711 {
2712     return vm->GetBundleName().c_str();
2713 }
2714 
SetModuleName(EcmaVM * vm,std::string moduleName)2715 void JSNApi::SetModuleName(EcmaVM *vm, std::string moduleName)
2716 {
2717     ecmascript::CString name = moduleName.c_str();
2718     vm->SetModuleName(name);
2719 }
2720 
GetModuleName(EcmaVM * vm)2721 std::string JSNApi::GetModuleName(EcmaVM *vm)
2722 {
2723     return vm->GetModuleName().c_str();
2724 }
2725 
SetLoop(EcmaVM * vm,void * loop)2726 void JSNApi::SetLoop(EcmaVM *vm, void *loop)
2727 {
2728     vm->SetLoop(loop);
2729 }
2730 
InitForConcurrentThread(EcmaVM * vm,ConcurrentCallback cb,void * data)2731 bool JSNApi::InitForConcurrentThread(EcmaVM *vm, ConcurrentCallback cb, void *data)
2732 {
2733     vm->SetConcurrentCallback(cb, data);
2734 
2735     return true;
2736 }
2737 
InitForConcurrentFunction(EcmaVM * vm,Local<JSValueRef> function)2738 bool JSNApi::InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> function)
2739 {
2740     [[maybe_unused]] LocalScope scope(vm);
2741     JSHandle<JSTaggedValue> funcVal = JSNApiHelper::ToJSHandle(function);
2742     JSHandle<JSFunction> transFunc = JSHandle<JSFunction>::Cast(funcVal);
2743     if (transFunc->GetFunctionKind() != ecmascript::FunctionKind::CONCURRENT_FUNCTION) {
2744         return false;
2745     }
2746     ecmascript::JSThread *thread = vm->GetJSThread();
2747     JSHandle<Method> method(thread, transFunc->GetMethod());
2748     const JSPandaFile *jsPandaFile = method->GetJSPandaFile();
2749     if (jsPandaFile == nullptr) {
2750         return false;
2751     }
2752 
2753     ecmascript::CString moduleName = jsPandaFile->GetJSPandaFileDesc();
2754     ecmascript::CString recordName = method->GetRecordName();
2755 
2756     // for debugger, to notify the script loaded and parsed which the concurrent function is in
2757     auto *notificationMgr = vm->GetJsDebuggerManager()->GetNotificationManager();
2758     notificationMgr->LoadModuleEvent(moduleName, recordName);
2759 
2760     bool isModule = jsPandaFile->IsModule(thread, recordName);
2761     if (isModule) {
2762         ecmascript::ModuleManager *moduleManager = vm->GetModuleManager();
2763         JSHandle<ecmascript::JSTaggedValue> moduleRecord;
2764         if (jsPandaFile->IsBundlePack()) {
2765             moduleRecord = moduleManager->HostResolveImportedModule(moduleName);
2766         } else {
2767             moduleRecord = moduleManager->HostResolveImportedModuleWithMerge(moduleName, recordName);
2768             if (ecmascript::AnFileDataManager::GetInstance()->IsEnable()) {
2769                 vm->GetAOTFileManager()->LoadAiFile(jsPandaFile);
2770             }
2771         }
2772         ecmascript::SourceTextModule::Instantiate(thread, moduleRecord);
2773         if (thread->HasPendingException()) {
2774             auto exception = thread->GetException();
2775             vm->HandleUncaughtException(exception.GetTaggedObject());
2776             return false;
2777         }
2778         JSHandle<ecmascript::SourceTextModule> module = JSHandle<ecmascript::SourceTextModule>::Cast(moduleRecord);
2779         module->SetStatus(ecmascript::ModuleStatus::INSTANTIATED);
2780         ecmascript::SourceTextModule::EvaluateForConcurrent(thread, module);
2781         transFunc->SetModule(thread, module);
2782         return true;
2783     }
2784     return false;
2785 }
2786 }  // namespace panda
2787