• 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