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