• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 #ifndef ECMASCRIPT_NAPI_INCLUDE_JSNAPI_EXPO_H
17 #define ECMASCRIPT_NAPI_INCLUDE_JSNAPI_EXPO_H
18 
19 #include <cassert>
20 #include <cstdint>
21 #include <functional>
22 #include <memory>
23 #include <map>
24 #include <shared_mutex>
25 #include <string>
26 #include <unordered_map>
27 #include <vector>
28 
29 #include "ecmascript/base/aligned_struct.h"
30 #include "ecmascript/base/config.h"
31 #include "ecmascript/common.h"
32 #include "ecmascript/cross_vm/jsnapi_expo_hybrid.h"
33 #include "ecmascript/module/js_module_execute_type.h"
34 #include "ecmascript/napi/include/jsnapi_internals.h"
35 
36 #ifndef NDEBUG
37 #include "libpandabase/utils/debug.h"
38 #endif
39 
40 #ifdef ERROR
41 #undef ERROR
42 #endif
43 namespace panda {
44 class JSNApiHelper;
45 class EscapeLocalScope;
46 class PromiseRejectInfo;
47 template<typename T>
48 class CopyableGlobal;
49 template<typename T>
50 class Global;
51 class JSNApi;
52 class SymbolRef;
53 template<typename T>
54 class Local;
55 class JSValueRef;
56 class PrimitiveRef;
57 class ArrayRef;
58 class BigIntRef;
59 class StringRef;
60 class ObjectRef;
61 class FunctionRef;
62 class NumberRef;
63 class MapIteratorRef;
64 class SendableMapIteratorRef;
65 class BooleanRef;
66 class NativePointerRef;
67 class TypedArrayRef;
68 class JsiRuntimeCallInfo;
69 class RuntimeOption;
70 namespace test {
71 class JSNApiTests;
72 }  // namespace test
73 class BufferRef;
74 namespace ecmascript {
75 class EcmaVM;
76 class JSTaggedValue;
77 class JSRuntimeOptions;
78 class EcmaContext;
79 class JSThread;
80 struct EcmaRuntimeCallInfo;
81 namespace base {
82 template<size_t ElementAlign, typename... Ts>
83 struct AlignedStruct;
84 struct AlignedPointer;
85 }
86 namespace job {
87 enum class QueueType : uint8_t {
88     QUEUE_PROMISE,
89     QUEUE_SCRIPT,
90 };
91 }
92 }  // namespace ecmascript
93 
94 enum class ForHybridApp {
95     Normal,
96     Hybrid
97 };
98 
99 struct HmsMap {
100     std::string originalPath;
101     std::string targetPath;
102     uint32_t sinceVersion;
103 };
104 
105 struct StackInfo {
106     size_t stackStart;
107     size_t stackSize;
108 };
109 
110 using WeakRefClearCallBack = void (*)(void *);
111 using WeakFinalizeTaskCallback = std::function<void()>;
112 using NativePointerCallbackFinishNotify = std::function<void(size_t totalBindSize_)>;
113 using NativePointerCallbackData = std::pair<NativePointerCallback, std::tuple<void*, void*, void*>>;
114 using TriggerGCData = std::pair<void*, uint8_t>;
115 using TriggerGCTaskCallback = std::function<void(TriggerGCData& data)>;
116 using StartIdleMonitorCallback = std::function<void()>;
117 using EcmaVM = ecmascript::EcmaVM;
118 using JSThread = ecmascript::JSThread;
119 using JSTaggedType = uint64_t;
120 using ConcurrentCallback = void (*)(Local<JSValueRef> result, bool success, void *taskInfo, void *data);
121 using SourceMapCallback = std::function<std::string(const std::string& rawStack)>;
122 using TimerCallbackFunc = void (*)(void *data);
123 using TimerTaskCallback = void* (*)(EcmaVM *vm, void *data, TimerCallbackFunc func, uint64_t timeout, bool repeat);
124 using CancelTimerCallback = void (*)(void *timerCallbackInfo);
125 using ReleaseSecureMemCallback = std::function<void(void* fileMapper)>;
126 using SourceMapTranslateCallback = std::function<bool(std::string& url, int& line, int& column,
127     std::string& packageName)>;
128 using DeviceDisconnectCallback = std::function<bool()>;
129 using QueueType = ecmascript::job::QueueType;
130 using OnErrorCallback = std::function<void(Local<ObjectRef> value, void *data)>;
131 using StopPreLoadSoCallback = std::function<void()>;
132 
133 #define ECMA_DISALLOW_COPY(className)      \
134     className(const className &) = delete; \
135     className &operator=(const className &) = delete
136 
137 #define ECMA_DISALLOW_MOVE(className) \
138     className(className &&) = delete; \
139     className &operator=(className &&) = delete
140 
141 #ifndef NDEBUG
142 #define ECMA_ASSERT(cond) \
143     if (!(cond)) { \
144         panda::debug::AssertionFail(#cond, __FILE__, __LINE__, __FUNCTION__); \
145     }
146 #else
147 #define ECMA_ASSERT(cond) static_cast<void>(0)
148 #endif
149 
150 #define INIT_CRASH_HOLDER(holder, tag) \
151     ArkCrashHolder holder(tag, __FUNCTION__)
152 
153 class PUBLIC_API ArkCrashHolder {
154 public:
ArkCrashHolder(const std::string & tag,const std::string & info)155     ArkCrashHolder(const std::string& tag, const std::string& info)
156     {
157         SetCrashObj(tag.c_str(), info.c_str());
158     }
159 
ArkCrashHolder(const char * tag,const char * info)160     ArkCrashHolder(const char* tag, const char* info)
161     {
162         SetCrashObj(tag, info);
163     }
164 
165     ~ArkCrashHolder();
166 
167 void UpdateCallbackPtr(uintptr_t addr);
168 
169 private:
170     void SetCrashObj(const char* tag, const char* info);
171 
172     uintptr_t handle_ {0};
173 
174     char* data_ {nullptr};
175     size_t size_ {0};
176 };
177 
178 class PUBLIC_API AsyncNativeCallbacksPack {
179 public:
180     AsyncNativeCallbacksPack() = default;
181     ~AsyncNativeCallbacksPack() = default;
182     AsyncNativeCallbacksPack(AsyncNativeCallbacksPack&&) = default;
183     AsyncNativeCallbacksPack& operator=(AsyncNativeCallbacksPack&&) = default;
184     AsyncNativeCallbacksPack(const AsyncNativeCallbacksPack &) = default;
185     AsyncNativeCallbacksPack &operator=(const AsyncNativeCallbacksPack &) = default;
186 
Clear()187     void Clear()
188     {
189         callBacks_.clear();
190         totalBindingSize_ = 0;
191         notify_ = nullptr;
192     }
193 
TotallyEmpty()194     bool TotallyEmpty() const
195     {
196         return callBacks_.empty() && totalBindingSize_ == 0 && notify_ == nullptr;
197     }
198 
Empty()199     bool Empty() const
200     {
201         return callBacks_.empty();
202     }
203 
RegisterFinishNotify(NativePointerCallbackFinishNotify notify)204     void RegisterFinishNotify(NativePointerCallbackFinishNotify notify)
205     {
206         notify_ = notify;
207     }
208 
GetNumCallBacks()209     size_t GetNumCallBacks() const
210     {
211         return callBacks_.size();
212     }
213 
ProcessAll(const char * tag)214     void ProcessAll(const char* tag)
215     {
216         INIT_CRASH_HOLDER(holder, tag);
217         for (auto &iter : callBacks_) {
218             NativePointerCallback callback = iter.first;
219             std::tuple<void*, void*, void*> &param = iter.second;
220             if (callback != nullptr) {
221                 holder.UpdateCallbackPtr(reinterpret_cast<uintptr_t>(callback));
222                 callback(std::get<0>(param), std::get<1>(param), std::get<2>(param)); // 2 is the param.
223             }
224         }
225         NotifyFinish();
226     }
227 
GetTotalBindingSize()228     size_t GetTotalBindingSize() const
229     {
230         return totalBindingSize_;
231     }
232 
AddCallback(NativePointerCallbackData callback,size_t bindingSize)233     void AddCallback(NativePointerCallbackData callback, size_t bindingSize)
234     {
235         callBacks_.emplace_back(callback);
236         totalBindingSize_ += bindingSize;
237     }
238 private:
NotifyFinish()239     void NotifyFinish() const
240     {
241         if (notify_ != nullptr) {
242             notify_(totalBindingSize_);
243         }
244     }
245 
246     std::vector<NativePointerCallbackData> callBacks_ {};
247     size_t totalBindingSize_ {0};
248     NativePointerCallbackFinishNotify notify_ {nullptr};
249 };
250 using NativePointerTaskCallback = std::function<void(AsyncNativeCallbacksPack *callbacksPack)>;
251 
252 template<typename T>
253 class PUBLIC_API Local {  // NOLINT(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
254 public:
255     inline Local() = default;
256 
257     template<typename S>
Local(const Local<S> & current)258     inline Local(const Local<S> &current) : address_(reinterpret_cast<uintptr_t>(*current))
259     {
260         // Check
261     }
262 
263     Local(const EcmaVM *vm, const Global<T> &current);
264 
265     Local(const EcmaVM *vm, const CopyableGlobal<T> &current);
266 
267     ~Local() = default;
268 
269     inline T *operator*() const
270     {
271         return GetAddress();
272     }
273 
274     inline T *operator->() const
275     {
276         return GetAddress();
277     }
278 
IsEmpty()279     inline bool IsEmpty() const
280     {
281         return GetAddress() == nullptr;
282     }
283 
Empty()284     inline void Empty()
285     {
286         address_ = 0;
287     }
288 
IsNull()289     inline bool IsNull() const
290     {
291         return IsEmpty() || GetAddress()->IsHole();
292     }
293 
Local(uintptr_t addr)294     explicit inline Local(uintptr_t addr) : address_(addr) {}
295 
296     inline bool operator==(const Local<T> &other) const
297     {
298         return *reinterpret_cast<JSTaggedType *>(GetAddress()) ==
299             *reinterpret_cast<JSTaggedType *>(other.GetAddress());
300     }
301 
302 private:
GetAddress()303     inline T *GetAddress() const
304     {
305         return reinterpret_cast<T *>(address_);
306     };
307     uintptr_t address_ = 0U;
308     friend JSNApiHelper;
309     friend EscapeLocalScope;
310     friend JsiRuntimeCallInfo;
311 };
312 
313 /**
314  * A Copyable global handle, keeps a separate global handle for each CopyableGlobal.
315  *
316  * Support Copy Constructor and Assign, Move Constructor And Assign.
317  *
318  * If destructed, the global handle held will be automatically released.
319  *
320  * Usage: It Can be used as heap object assign to another variable, a value passing parameter, or
321  *        a value passing return value and so on.
322  */
323 template<typename T>
324 class PUBLIC_API CopyableGlobal {
325 public:
326     inline CopyableGlobal() = default;
~CopyableGlobal()327     ~CopyableGlobal()
328     {
329         Free();
330     }
331 
CopyableGlobal(const CopyableGlobal & that)332     inline CopyableGlobal(const CopyableGlobal &that)
333     {
334         Copy(that);
335     }
336 
337     inline CopyableGlobal &operator=(const CopyableGlobal &that)
338     {
339         Copy(that);
340         return *this;
341     }
342 
CopyableGlobal(CopyableGlobal && that)343     inline CopyableGlobal(CopyableGlobal &&that)
344     {
345         Move(that);
346     }
347 
348     inline CopyableGlobal &operator=(CopyableGlobal &&that)
349     {
350         Move(that);
351         return *this;
352     }
353 
354     template<typename S>
355     CopyableGlobal(const EcmaVM *vm, const Local<S> &current);
356 
357     CopyableGlobal(const EcmaVM *vm, const Local<T> &current);
358 
359     template<typename S>
CopyableGlobal(const CopyableGlobal<S> & that)360     CopyableGlobal(const CopyableGlobal<S> &that)
361     {
362         Copy(that);
363     }
364 
Reset()365     void Reset()
366     {
367         Free();
368     }
369 
ToLocal()370     Local<T> ToLocal() const
371     {
372         if (IsEmpty()) {
373             return Local<T>();
374         }
375         return Local<T>(vm_, *this);
376     }
377 
Empty()378     void Empty()
379     {
380         address_ = 0;
381     }
382 
383     inline T *operator*() const
384     {
385         return GetAddress();
386     }
387 
388     inline T *operator->() const
389     {
390         return GetAddress();
391     }
392 
IsEmpty()393     inline bool IsEmpty() const
394     {
395         return GetAddress() == nullptr;
396     }
397 
398     void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
399                          WeakRefClearCallBack nativeFinalizeCallback);
400     void SetWeak();
401 
402     void ClearWeak();
403 
404     bool IsWeak() const;
405 
GetEcmaVM()406     const EcmaVM *GetEcmaVM() const
407     {
408         return vm_;
409     }
410 
411 private:
GetAddress()412     inline T *GetAddress() const
413     {
414         return reinterpret_cast<T *>(address_);
415     };
416     inline void Copy(const CopyableGlobal &that);
417     template<typename S>
418     inline void Copy(const CopyableGlobal<S> &that);
419     inline void Move(CopyableGlobal &that);
420     inline void Free();
421     uintptr_t address_ = 0U;
422     const EcmaVM *vm_ {nullptr};
423 };
424 
425 template<typename T>
426 class PUBLIC_API Global {  // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions
427 public:
428     inline Global() = default;
429 
Global(const Global & that)430     inline Global(const Global &that)
431     {
432         Update(that);
433     }
434 
435     inline Global &operator=(const Global &that)
436     {
437         Update(that);
438         return *this;
439     }
440 
Global(Global && that)441     inline Global(Global &&that)
442     {
443         Update(that);
444     }
445 
446     inline Global &operator=(Global &&that)
447     {
448         Update(that);
449         return *this;
450     }
451 
452     template<typename S>
453     Global(const EcmaVM *vm, const Local<S> &current);
454     template<typename S>
455     Global(const EcmaVM *vm, const Global<S> &current);
456 
457     ~Global() = default;
458 
ToLocal()459     Local<T> ToLocal() const
460     {
461         if (IsEmpty()) {
462             return Local<T>();
463         }
464         return Local<T>(vm_, *this);
465     }
466 
ToLocal(const EcmaVM * vm)467     Local<T> ToLocal(const EcmaVM *vm) const
468     {
469         return Local<T>(vm, *this);
470     }
471 
Empty()472     void Empty()
473     {
474         address_ = 0;
475     }
476 
477     inline T *operator*() const
478     {
479         return GetAddress();
480     }
481 
482     inline T *operator->() const
483     {
484         return GetAddress();
485     }
486 
IsEmpty()487     inline bool IsEmpty() const
488     {
489         return GetAddress() == nullptr;
490     }
491 
492     void SetWeak();
493 
494     void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
495                          WeakRefClearCallBack nativeFinalizeCallback);
496 
497     void ClearWeak();
498 
499     bool IsWeak() const;
500 
GetEcmaVM()501     const EcmaVM *GetEcmaVM() const
502     {
503         return vm_;
504     }
505 
506     // This method must be called before Global is released.
507     GLOBAL_PUBLIC_HYBRID_EXTENSION();
508 private:
GetAddress()509     inline T *GetAddress() const
510     {
511         return reinterpret_cast<T *>(address_);
512     };
513     inline void Update(const Global &that);
514     uintptr_t address_ = 0U;
515     const EcmaVM *vm_ {nullptr};
516 };
517 
518 class PUBLIC_API JSValueRef {
519 public:
520     static Local<PrimitiveRef> Undefined(const EcmaVM *vm);
521     static Local<PrimitiveRef> Null(const EcmaVM *vm);
522     static Local<PrimitiveRef> Hole(const EcmaVM *vm);
523     static Local<PrimitiveRef> True(const EcmaVM *vm);
524     static Local<PrimitiveRef> False(const EcmaVM *vm);
525 
526     bool BooleaValue(const EcmaVM *vm);
527     int64_t IntegerValue(const EcmaVM *vm);
528     uint32_t Uint32Value(const EcmaVM *vm);
529     int32_t Int32Value(const EcmaVM *vm);
530     double GetValueDouble(bool &isNumber);
531     int32_t GetValueInt32(bool &isNumber);
532     uint32_t GetValueUint32(bool &isNumber);
533     int64_t GetValueInt64(bool &isNumber);
534     bool GetValueBool(bool &isBool);
535 
536     Local<NumberRef> ToNumber(const EcmaVM *vm);
537     Local<BooleanRef> ToBoolean(const EcmaVM *vm);
538     Local<BigIntRef> ToBigInt(const EcmaVM *vm);
539     Local<StringRef> ToString(const EcmaVM *vm);
540     Local<ObjectRef> ToObject(const EcmaVM *vm);
541     Local<ObjectRef> ToEcmaObject(const EcmaVM *vm);
542     Local<ObjectRef> ToEcmaObjectWithoutSwitchState(const EcmaVM *vm);
543     Local<NativePointerRef> ToNativePointer(const EcmaVM *vm);
544 
545     bool IsUndefined();
546     bool IsNull();
547     bool IsHole();
548     bool IsTrue();
549     bool IsFalse();
550     bool IsNumber();
551     bool IsBigInt(const EcmaVM *vm);
552     bool IsInt();
553     bool WithinInt32();
554     bool IsBoolean();
555     bool IsString(const EcmaVM *vm);
556     bool IsStringWithoutSwitchState(const EcmaVM *vm);
557     bool IsSymbol(const EcmaVM *vm);
558     bool IsObject(const EcmaVM *vm);
559     bool IsObjectWithoutSwitchState(const EcmaVM *vm);
560     bool IsNativeBindingObject(const EcmaVM *vm);
561     bool IsArray(const EcmaVM *vm);
562     bool IsJSArray(const EcmaVM *vm);
563     bool IsConstructor(const EcmaVM *vm);
564     bool IsFunction(const EcmaVM *vm);
565 
566     bool IsJSFunction(const EcmaVM *vm);
567     bool IsProxy(const EcmaVM *vm);
568     bool IsPromise(const EcmaVM *vm);
569     bool IsDataView(const EcmaVM *vm);
570     bool IsTypedArray(const EcmaVM *vm);
571     bool IsNativePointer(const EcmaVM *vm);
572     bool IsDate(const EcmaVM *vm);
573     bool IsError(const EcmaVM *vm);
574     bool IsMap(const EcmaVM *vm);
575     bool IsSet(const EcmaVM *vm);
576     bool IsWeakRef(const EcmaVM *vm);
577     bool IsWeakMap(const EcmaVM *vm);
578     bool IsWeakSet(const EcmaVM *vm);
579     bool IsRegExp(const EcmaVM *vm);
580     bool IsArrayIterator(const EcmaVM *vm);
581     bool IsStringIterator(const EcmaVM *vm);
582     bool IsSetIterator(const EcmaVM *vm);
583     bool IsMapIterator(const EcmaVM *vm);
584     bool IsArrayBuffer(const EcmaVM *vm);
585     bool IsBuffer(const EcmaVM *vm);
586     bool IsUint8Array(const EcmaVM *vm);
587     bool IsInt8Array(const EcmaVM *vm);
588     bool IsUint8ClampedArray(const EcmaVM *vm);
589     bool IsInt16Array(const EcmaVM *vm);
590     bool IsUint16Array(const EcmaVM *vm);
591     bool IsInt32Array(const EcmaVM *vm);
592     bool IsUint32Array(const EcmaVM *vm);
593     bool IsFloat32Array(const EcmaVM *vm);
594     bool IsFloat64Array(const EcmaVM *vm);
595     bool IsBigInt64Array(const EcmaVM *vm);
596     bool IsBigUint64Array(const EcmaVM *vm);
597     bool IsJSPrimitiveRef(const EcmaVM *vm);
598     bool IsJSPrimitiveNumber(const EcmaVM *vm);
599     bool IsJSPrimitiveInt(const EcmaVM *vm);
600     bool IsJSPrimitiveBoolean(const EcmaVM *vm);
601     bool IsJSPrimitiveString(const EcmaVM *vm);
602 
603     bool IsJSSharedInt8Array(const EcmaVM *vm);
604     bool IsJSSharedUint8Array(const EcmaVM *vm);
605     bool IsJSSharedUint8ClampedArray(const EcmaVM *vm);
606     bool IsJSSharedInt16Array(const EcmaVM *vm);
607     bool IsJSSharedUint16Array(const EcmaVM *vm);
608     bool IsJSSharedInt32Array(const EcmaVM *vm);
609     bool IsJSSharedUint32Array(const EcmaVM *vm);
610     bool IsJSSharedFloat32Array(const EcmaVM *vm);
611 
612     bool IsGeneratorObject(const EcmaVM *vm);
613     bool IsJSPrimitiveSymbol(const EcmaVM *vm);
614 
615     bool IsArgumentsObject(const EcmaVM *vm);
616     bool IsGeneratorFunction(const EcmaVM *vm);
617     bool IsAsyncFunction(const EcmaVM *vm);
618     bool IsConcurrentFunction(const EcmaVM *vm);
619     bool IsJSLocale(const EcmaVM *vm);
620     bool IsJSDateTimeFormat(const EcmaVM *vm);
621     bool IsJSRelativeTimeFormat(const EcmaVM *vm);
622     bool IsJSIntl(const EcmaVM *vm);
623     bool IsJSNumberFormat(const EcmaVM *vm);
624     bool IsJSCollator(const EcmaVM *vm);
625     bool IsJSPluralRules(const EcmaVM *vm);
626     bool IsJSListFormat(const EcmaVM *vm);
627     bool IsAsyncGeneratorFunction(const EcmaVM *vm);
628     bool IsAsyncGeneratorObject(const EcmaVM *vm);
629 
630     bool IsModuleNamespaceObject(const EcmaVM *vm);
631     bool IsNativeModuleFailureInfoObject(const EcmaVM *vm);
632     bool IsSharedArrayBuffer(const EcmaVM *vm);
633     bool IsSendableArrayBuffer(const EcmaVM *vm);
634 
635     bool IsStrictEquals(const EcmaVM *vm, Local<JSValueRef> value);
636     Local<StringRef> Typeof(const EcmaVM *vm);
637     bool InstanceOf(const EcmaVM *vm, Local<JSValueRef> value);
638 
639     bool IsArrayList(const EcmaVM *vm);
640     bool IsDeque(const EcmaVM *vm);
641     bool IsHashMap(const EcmaVM *vm);
642     bool IsHashSet(const EcmaVM *vm);
643     bool IsLightWeightMap(const EcmaVM *vm);
644     bool IsLightWeightSet(const EcmaVM *vm);
645     bool IsLinkedList(const EcmaVM *vm);
646     bool IsLinkedListIterator(const EcmaVM *vm);
647     bool IsList(const EcmaVM *vm);
648     bool IsPlainArray(const EcmaVM *vm);
649     bool IsQueue(const EcmaVM *vm);
650     bool IsStack(const EcmaVM *vm);
651     bool IsTreeMap(const EcmaVM *vm);
652     bool IsTreeSet(const EcmaVM *vm);
653     bool IsVector(const EcmaVM *vm);
654     bool IsBitVector(const EcmaVM *vm);
655     bool IsSendableObject(const EcmaVM *vm);
656     bool IsJSShared(const EcmaVM *vm);
657     bool IsSharedArray(const EcmaVM *vm);
658     bool IsSharedTypedArray(const EcmaVM *vm);
659     bool IsSharedSet(const EcmaVM *vm);
660     bool IsSharedMap(const EcmaVM *vm);
661     bool IsSharedMapIterator(const EcmaVM *vm);
662     bool IsHeapObject();
663     void *GetNativePointerValue(const EcmaVM *vm, bool &isNativePointer);
664     bool IsDetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer);
665     void DetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer);
666     void GetDataViewInfo(const EcmaVM *vm,
667                          bool &isDataView,
668                          size_t *byteLength,
669                          void **data,
670                          JSValueRef **arrayBuffer,
671                          size_t *byteOffset);
672     void TryGetArrayLength(const EcmaVM *vm, bool *isPendingException,
673         bool *isArrayOrSharedArray, uint32_t *arrayLength);
674     bool IsJsGlobalEnv(const EcmaVM *vm);
675 
676 private:
677     JSTaggedType value_;
678     friend JSNApi;
679     template<typename T>
680     friend class Global;
681     template<typename T>
682     friend class Local;
683     void *GetNativePointerValueImpl(const EcmaVM *vm, bool &isNativePointer);
684 };
685 
686 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
687 class PUBLIC_API PropertyAttribute {
688 public:
Default()689     static PropertyAttribute Default()
690     {
691         return PropertyAttribute();
692     }
693     PropertyAttribute() = default;
PropertyAttribute(Local<JSValueRef> value,bool w,bool e,bool c)694     PropertyAttribute(Local<JSValueRef> value, bool w, bool e, bool c)
695         : value_(value),
696           writable_(w),
697           enumerable_(e),
698           configurable_(c),
699           hasWritable_(true),
700           hasEnumerable_(true),
701           hasConfigurable_(true)
702     {}
703     ~PropertyAttribute() = default;
704 
IsWritable()705     bool IsWritable() const
706     {
707         return writable_;
708     }
SetWritable(bool flag)709     void SetWritable(bool flag)
710     {
711         writable_ = flag;
712         hasWritable_ = true;
713     }
IsEnumerable()714     bool IsEnumerable() const
715     {
716         return enumerable_;
717     }
SetEnumerable(bool flag)718     void SetEnumerable(bool flag)
719     {
720         enumerable_ = flag;
721         hasEnumerable_ = true;
722     }
IsConfigurable()723     bool IsConfigurable() const
724     {
725         return configurable_;
726     }
SetConfigurable(bool flag)727     void SetConfigurable(bool flag)
728     {
729         configurable_ = flag;
730         hasConfigurable_ = true;
731     }
HasWritable()732     bool HasWritable() const
733     {
734         return hasWritable_;
735     }
HasConfigurable()736     bool HasConfigurable() const
737     {
738         return hasConfigurable_;
739     }
HasEnumerable()740     bool HasEnumerable() const
741     {
742         return hasEnumerable_;
743     }
GetValue(const EcmaVM * vm)744     Local<JSValueRef> GetValue(const EcmaVM *vm) const
745     {
746         if (value_.IsEmpty()) {
747             return JSValueRef::Undefined(vm);
748         }
749         return value_;
750     }
SetValue(Local<JSValueRef> value)751     void SetValue(Local<JSValueRef> value)
752     {
753         value_ = value;
754     }
HasValue()755     inline bool HasValue() const
756     {
757         return !value_.IsEmpty();
758     }
GetGetter(const EcmaVM * vm)759     Local<JSValueRef> GetGetter(const EcmaVM *vm) const
760     {
761         if (getter_.IsEmpty()) {
762             return JSValueRef::Undefined(vm);
763         }
764         return getter_;
765     }
SetGetter(Local<JSValueRef> value)766     void SetGetter(Local<JSValueRef> value)
767     {
768         getter_ = value;
769     }
HasGetter()770     bool HasGetter() const
771     {
772         return !getter_.IsEmpty();
773     }
GetSetter(const EcmaVM * vm)774     Local<JSValueRef> GetSetter(const EcmaVM *vm) const
775     {
776         if (setter_.IsEmpty()) {
777             return JSValueRef::Undefined(vm);
778         }
779         return setter_;
780     }
SetSetter(Local<JSValueRef> value)781     void SetSetter(Local<JSValueRef> value)
782     {
783         setter_ = value;
784     }
HasSetter()785     bool HasSetter() const
786     {
787         return !setter_.IsEmpty();
788     }
789 
790 private:
791     Local<JSValueRef> value_;
792     Local<JSValueRef> getter_;
793     Local<JSValueRef> setter_;
794     bool writable_ = false;
795     bool enumerable_ = false;
796     bool configurable_ = false;
797     bool hasWritable_ = false;
798     bool hasEnumerable_ = false;
799     bool hasConfigurable_ = false;
800 };
801 
802 class PUBLIC_API NativePointerRef : public JSValueRef {
803 public:
804     static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, size_t nativeBindingsize = 0);
805     static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack,
806                                        void *data, size_t nativeBindingsize = 0);
807     static Local<NativePointerRef> NewConcurrent(const EcmaVM *vm, void *nativePointer,
808                                                  NativePointerCallback callBack,
809                                                  void *data, size_t nativeBindingsize = 0);
810     static Local<NativePointerRef> NewSendable(const EcmaVM *vm,
811                                                void *nativePointer,
812                                                NativePointerCallback callBack = nullptr,
813                                                void *data = nullptr,
814                                                size_t nativeBindingsize = 0);
815     void *Value();
816 };
817 
818 class PUBLIC_API ObjectRef : public JSValueRef {
819 public:
820     enum class SendableType {
821         NONE,
822         OBJECT,
823         GENERIC,
824     };
825     struct SendablePropertiesInfo {
826         std::vector<Local<JSValueRef>> keys;
827         std::vector<SendableType> types;
828         std::vector<PropertyAttribute> attributes;
829     };
830     static constexpr int MAX_PROPERTIES_ON_STACK = 32;
Cast(JSValueRef * value)831     static inline ObjectRef *Cast(JSValueRef *value)
832     {
833         return static_cast<ObjectRef *>(value);
834     }
835     static Local<ObjectRef> New(const EcmaVM *vm);
836     static uintptr_t NewObject(const EcmaVM *vm);
837     static Local<ObjectRef> NewS(const EcmaVM *vm);
838     static Local<ObjectRef> NewWithProperties(const EcmaVM *vm, size_t propertyCount, const Local<JSValueRef> *keys,
839                                               const PropertyAttribute *attributes);
840     static Local<ObjectRef> NewSWithProperties(const EcmaVM *vm, SendablePropertiesInfo &info);
841     static Local<ObjectRef> NewWithNamedProperties(const EcmaVM *vm, size_t propertyCount, const char **keys,
842                                                    const Local<JSValueRef> *values);
843     static Local<ObjectRef> CreateNativeModuleFailureInfo(const EcmaVM *vm, const std::string &failureInfo);
844     static Local<ObjectRef> CreateAccessorData(const EcmaVM *vm, Local<FunctionRef> getter, Local<FunctionRef> setter);
845     static Local<ObjectRef> CreateSendableAccessorData(const EcmaVM *vm,
846                                                        Local<FunctionRef> getter,
847                                                        Local<FunctionRef> setter);
848     bool ConvertToNativeBindingObject(const EcmaVM *vm, Local<NativePointerRef> value);
849     Local<NativePointerRef> GetNativeBindingPointer(const EcmaVM *vm);
850     bool Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
851     bool Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value);
852     bool Set(const EcmaVM *vm, uint32_t key, Local<JSValueRef> value);
853     bool SetWithoutSwitchState(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value);
854     bool SetAccessorProperty(const EcmaVM *vm, Local<JSValueRef> key, Local<FunctionRef> getter,
855                              Local<FunctionRef> setter, PropertyAttribute attribute = PropertyAttribute::Default());
856     Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
857     Local<JSValueRef> Get(const EcmaVM *vm, const char *utf8);
858     Local<JSValueRef> Get(const EcmaVM *vm, int32_t key);
859 
860     bool GetOwnProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute &property);
861     Local<ArrayRef> GetOwnPropertyNames(const EcmaVM *vm);
862     Local<ArrayRef> GetAllPropertyNames(const EcmaVM *vm, uint32_t filter);
863     Local<ArrayRef> GetOwnEnumerablePropertyNames(const EcmaVM *vm);
864     Local<JSValueRef> GetPrototype(const EcmaVM *vm);
865     bool SetPrototype(const EcmaVM *vm, Local<ObjectRef> prototype);
866 
867     bool DefineProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute attribute);
868 
869     bool Has(const EcmaVM *vm, Local<JSValueRef> key);
870     bool Has(const EcmaVM *vm, uint32_t key);
871 
872     bool HasOwnProperty(const EcmaVM *vm, Local<JSValueRef> key);
873 
874     bool Delete(const EcmaVM *vm, Local<JSValueRef> key);
875     bool Delete(const EcmaVM *vm, uint32_t key);
876 
877     Local<JSValueRef> Freeze(const EcmaVM *vm);
878     Local<JSValueRef> Seal(const EcmaVM *vm);
879     void SetNativePointerFieldCount(const EcmaVM *vm, int32_t count);
880     int32_t GetNativePointerFieldCount(const EcmaVM *vm);
881     void *GetNativePointerField(const EcmaVM *vm, int32_t index);
882     void SetNativePointerField(const EcmaVM *vm,
883                                int32_t index,
884                                void *nativePointer = nullptr,
885                                NativePointerCallback callBack = nullptr,
886                                void *data = nullptr, size_t nativeBindingsize = 0);
887     void SetConcurrentNativePointerField(const EcmaVM *vm,
888                                          int32_t index,
889                                          void *nativePointer = nullptr,
890                                          NativePointerCallback callBack = nullptr,
891                                          void *data = nullptr, size_t nativeBindingsize = 0);
892     OBJECTREF_PUBLIC_HYBRID_EXTENSION();
893 };
894 
895 using FunctionCallback = Local<JSValueRef>(*)(JsiRuntimeCallInfo*);
896 using InternalFunctionCallback = JSValueRef(*)(JsiRuntimeCallInfo*);
897 class PUBLIC_API FunctionRef : public ObjectRef {
898 public:
899     struct SendablePropertiesInfos {
900         SendablePropertiesInfo instancePropertiesInfo;
901         SendablePropertiesInfo staticPropertiesInfo;
902         SendablePropertiesInfo nonStaticPropertiesInfo;
903     };
904     static Local<FunctionRef> New(EcmaVM *vm, FunctionCallback nativeFunc, NativePointerCallback deleter = nullptr,
905         void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0);
906     static Local<FunctionRef> New(EcmaVM *vm, const Local<JSValueRef> &context, FunctionCallback nativeFunc,
907         NativePointerCallback deleter = nullptr, void *data = nullptr, bool callNapi = false,
908         size_t nativeBindingsize = 0);
909     static Local<FunctionRef> NewConcurrent(EcmaVM *vm,
910                                             FunctionCallback nativeFunc,
911                                             NativePointerCallback deleter = nullptr,
912                                             void *data = nullptr,
913                                             bool callNapi = false,
914                                             size_t nativeBindingsize = 0);
915     static Local<FunctionRef> NewConcurrent(EcmaVM *vm,
916                                             const Local<JSValueRef> &context,
917                                             FunctionCallback nativeFunc,
918                                             NativePointerCallback deleter = nullptr,
919                                             void *data = nullptr,
920                                             bool callNapi = false,
921                                             size_t nativeBindingsize = 0);
922     static Local<FunctionRef> New(EcmaVM *vm, InternalFunctionCallback nativeFunc, NativePointerCallback deleter,
923         void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0);
924     static Local<FunctionRef> New(EcmaVM *vm, const Local<JSValueRef> &context, InternalFunctionCallback nativeFunc,
925         NativePointerCallback deleter, void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0);
926     static Local<FunctionRef> NewConcurrent(EcmaVM *vm,
927                                             const Local<JSValueRef> &context,
928                                             InternalFunctionCallback nativeFunc,
929                                             NativePointerCallback deleter,
930                                             void *data = nullptr,
931                                             bool callNapi = false,
932                                             size_t nativeBindingsize = 0);
933     static Local<FunctionRef> NewConcurrent(EcmaVM *vm,
934                                             InternalFunctionCallback nativeFunc,
935                                             NativePointerCallback deleter,
936                                             void *data = nullptr,
937                                             bool callNapi = false,
938                                             size_t nativeBindingsize = 0);
939     static Local<FunctionRef> NewConcurrentWithName(EcmaVM *vm, const Local<JSValueRef> &context,
940                                                     InternalFunctionCallback nativeFunc, NativePointerCallback deleter,
941                                                     const char *name, void *data = nullptr, bool callNapi = false,
942                                                     size_t nativeBindingsize = 0);
943     static Local<FunctionRef> NewSendable(EcmaVM *vm,
944                                           InternalFunctionCallback nativeFunc,
945                                           NativePointerCallback deleter,
946                                           void *data = nullptr,
947                                           bool callNapi = false,
948                                           size_t nativeBindingsize = 0);
949     static Local<FunctionRef> NewClassFunction(EcmaVM *vm, FunctionCallback nativeFunc, NativePointerCallback deleter,
950         void *data, bool callNapi = false, size_t nativeBindingsize = 0);
951     static Local<FunctionRef> NewClassFunction(EcmaVM *vm, const Local<JSValueRef> &context,
952         FunctionCallback nativeFunc, NativePointerCallback deleter, void *data, bool callNapi = false,
953         size_t nativeBindingsize = 0);
954     static Local<FunctionRef> NewConcurrentClassFunction(EcmaVM *vm,
955                                                          InternalFunctionCallback nativeFunc,
956                                                          NativePointerCallback deleter,
957                                                          void *data,
958                                                          bool callNapi = false,
959                                                          size_t nativeBindingsize = 0);
960     static Local<FunctionRef> NewConcurrentClassFunction(EcmaVM *vm,
961                                                          const Local<JSValueRef> &context,
962                                                          InternalFunctionCallback nativeFunc,
963                                                          NativePointerCallback deleter,
964                                                          void *data,
965                                                          bool callNapi = false,
966                                                          size_t nativeBindingsize = 0);
967     static Local<FunctionRef> NewConcurrentClassFunctionWithName(const EcmaVM *vm, const Local<JSValueRef> &context,
968                                                                  InternalFunctionCallback nativeFunc,
969                                                                  NativePointerCallback deleter, const char *name,
970                                                                  void *data, bool callNapi = false,
971                                                                  size_t propertyCount = 0,
972                                                                  size_t staticPropCount = 0,
973                                                                  Local<panda::JSValueRef> *keys = nullptr,
974                                                                  PropertyAttribute *attrs = nullptr,
975                                                                  size_t nativeBindingsize = 0);
976 
977     static Local<FunctionRef> NewClassFunction(EcmaVM *vm,
978                                                InternalFunctionCallback nativeFunc,
979                                                NativePointerCallback deleter,
980                                                void *data,
981                                                bool callNapi = false,
982                                                size_t nativeBindingsize = 0);
983     static Local<FunctionRef> NewClassFunction(EcmaVM *vm,
984                                                const Local<JSValueRef> &context,
985                                                InternalFunctionCallback nativeFunc,
986                                                NativePointerCallback deleter,
987                                                void *data,
988                                                bool callNapi = false,
989                                                size_t nativeBindingsize = 0);
990     static Local<FunctionRef> NewSendableClassFunction(const EcmaVM *vm,
991                                                        InternalFunctionCallback nativeFunc,
992                                                        NativePointerCallback deleter,
993                                                        void *data,
994                                                        Local<StringRef> name,
995                                                        SendablePropertiesInfos &infos,
996                                                        Local<FunctionRef> parent,
997                                                        bool callNapi = false,
998                                                        size_t nativeBindingsize = 0);
999     JSValueRef* CallForNapi(const EcmaVM *vm, JSValueRef *thisObj, JSValueRef *const argv[],
1000         int32_t length);
1001     Local<JSValueRef> Call(const EcmaVM *vm, Local<JSValueRef> thisObj, const Local<JSValueRef> argv[],
1002         int32_t length);
1003     Local<JSValueRef> Constructor(const EcmaVM *vm, const Local<JSValueRef> argv[], int32_t length);
1004     JSValueRef* ConstructorOptimize(const EcmaVM *vm, JSValueRef* argv[], int32_t length);
1005 
1006     Local<JSValueRef> GetFunctionPrototype(const EcmaVM *vm);
1007     bool Inherit(const EcmaVM *vm, Local<FunctionRef> parent);
1008     void SetName(const EcmaVM *vm, Local<StringRef> name);
1009     Local<StringRef> GetName(const EcmaVM *vm);
1010     Local<StringRef> GetSourceCode(const EcmaVM *vm, int lineNumber);
1011     bool IsNative(const EcmaVM *vm);
1012     void SetData(const EcmaVM *vm, void *data, NativePointerCallback deleter = nullptr, bool callNapi = false);
1013     void* GetData(const EcmaVM *vm);
1014 };
1015 
1016 class PUBLIC_API PrimitiveRef : public JSValueRef {
1017 public:
1018     Local<JSValueRef> GetValue(const EcmaVM *vm);
1019 };
1020 
1021 class PUBLIC_API SymbolRef : public PrimitiveRef {
1022 public:
1023     static Local<SymbolRef> New(const EcmaVM *vm, Local<StringRef> description = Local<StringRef>());
1024     Local<StringRef> GetDescription(const EcmaVM *vm);
1025 };
1026 
1027 class PUBLIC_API BooleanRef : public PrimitiveRef {
1028 public:
1029     static Local<BooleanRef> New(const EcmaVM *vm, bool input);
1030     bool Value();
1031 };
1032 
1033 class PUBLIC_API StringRef : public PrimitiveRef {
1034 public:
Cast(JSValueRef * value)1035     static inline StringRef *Cast(JSValueRef *value)
1036     {
1037         // check
1038         return static_cast<StringRef *>(value);
1039     }
1040     static Local<StringRef> NewFromUtf8WithoutStringTable(const EcmaVM *vm, const char *utf8, int length = -1);
1041     static Local<StringRef> NewFromUtf8(const EcmaVM *vm, const char *utf8, int length = -1);
1042     static Local<StringRef> NewFromUtf16WithoutStringTable(const EcmaVM *vm, const char16_t *utf16, int length = -1);
1043     static Local<StringRef> NewFromUtf16(const EcmaVM *vm, const char16_t *utf16, int length = -1);
1044     std::string ToString(const EcmaVM *vm);
1045     std::string DebuggerToString(const EcmaVM *vm);
1046     uint32_t Length(const EcmaVM *vm);
1047     bool IsCompressed(const EcmaVM *vm);
1048     size_t Utf8Length(const EcmaVM *vm, bool isGetBufferSize = false);
1049     uint32_t WriteUtf8(const EcmaVM *vm, char *buffer, uint32_t length, bool isWriteBuffer = false);
1050     uint32_t WriteUtf16(const EcmaVM *vm, char16_t *buffer, uint32_t length);
1051     uint32_t WriteLatin1(const EcmaVM *vm, char *buffer, uint32_t length);
1052     uint32_t WriteLatin1WithoutSwitchState(const EcmaVM *vm, char *buffer, uint32_t length);
1053     static Local<StringRef> GetNapiWrapperString(const EcmaVM *vm);
1054     Local<TypedArrayRef> EncodeIntoUint8Array(const EcmaVM *vm);
1055     STRINGREF_PUBLIC_HYBRID_EXTENSION();
1056 };
1057 
1058 class PUBLIC_API PromiseRejectInfo {
1059 public:
1060     enum class PUBLIC_API PROMISE_REJECTION_EVENT : uint32_t { REJECT = 0, HANDLE };
1061     PromiseRejectInfo(Local<JSValueRef> promise, Local<JSValueRef> reason,
1062                       PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data);
~PromiseRejectInfo()1063     ~PromiseRejectInfo() {}
1064     Local<JSValueRef> GetPromise() const;
1065     Local<JSValueRef> GetReason() const;
1066     PromiseRejectInfo::PROMISE_REJECTION_EVENT GetOperation() const;
1067     void* GetData() const;
1068 
1069 private:
1070     Local<JSValueRef> promise_ {};
1071     Local<JSValueRef> reason_ {};
1072     PROMISE_REJECTION_EVENT operation_ = PROMISE_REJECTION_EVENT::REJECT;
1073     void* data_ {nullptr};
1074 };
1075 
1076 /**
1077  * An external exception handler.
1078  */
1079 class PUBLIC_API TryCatch {
1080 public:
TryCatch(const EcmaVM * ecmaVm)1081     explicit TryCatch(const EcmaVM *ecmaVm) : ecmaVm_(ecmaVm) {};
1082 
1083     /**
1084      * Consumes the exception by default if not rethrow explicitly.
1085      */
1086     ~TryCatch();
1087 
1088     bool HasCaught() const;
1089     void Rethrow();
1090     Local<ObjectRef> GetAndClearException();
1091     Local<ObjectRef> GetException();
1092     void ClearException();
1093 
1094     ECMA_DISALLOW_COPY(TryCatch);
1095     ECMA_DISALLOW_MOVE(TryCatch);
1096 
getrethrow_()1097     bool getrethrow_()
1098     {
1099         return rethrow_;
1100     }
1101 
1102 private:
1103     // Disable dynamic allocation
1104     void* operator new(size_t size) = delete;
1105     void operator delete(void*, size_t) = delete;
1106     void* operator new[](size_t size) = delete;
1107     void operator delete[](void*, size_t) = delete;
1108 
1109     const EcmaVM *ecmaVm_ {nullptr};
1110     bool rethrow_ {false};
1111 };
1112 
1113 class PUBLIC_API BigIntRef : public PrimitiveRef {
1114 public:
1115     static Local<BigIntRef> New(const EcmaVM *vm, uint64_t input);
1116     static Local<BigIntRef> New(const EcmaVM *vm, int64_t input);
1117     static Local<JSValueRef> CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words);
1118     void BigIntToInt64(const EcmaVM *vm, int64_t *value, bool *lossless);
1119     void BigIntToUint64(const EcmaVM *vm, uint64_t *value, bool *lossless);
1120     void GetWordsArray(const EcmaVM *vm, bool* signBit, size_t wordCount, uint64_t* words);
1121     uint32_t GetWordsArraySize(const EcmaVM *vm);
1122 };
1123 
1124 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
1125 class PUBLIC_API LocalScope {
1126 public:
1127     explicit LocalScope(const EcmaVM *vm);
1128     virtual ~LocalScope();
1129 
1130 protected:
1131     inline LocalScope(const EcmaVM *vm, JSTaggedType value);
1132 
1133 private:
1134     void *prevNext_ = nullptr;
1135     void *prevEnd_ = nullptr;
1136     int32_t prevHandleStorageIndex_ {-1};
1137     int32_t prevPrimitiveStorageIndex_ {-1};
1138     void *prevPrimitiveNext_ = nullptr;
1139     void *prevPrimitiveEnd_ = nullptr;
1140     void *thread_ = nullptr;
1141 };
1142 
1143 class PUBLIC_API EscapeLocalScope final : public LocalScope {
1144 public:
1145     explicit EscapeLocalScope(const EcmaVM *vm);
1146     ~EscapeLocalScope() override = default;
1147 
1148     ECMA_DISALLOW_COPY(EscapeLocalScope);
1149     ECMA_DISALLOW_MOVE(EscapeLocalScope);
1150 
1151     template<typename T>
Escape(Local<T> current)1152     inline Local<T> Escape(Local<T> current)
1153     {
1154         ECMA_ASSERT(!alreadyEscape_);
1155         alreadyEscape_ = true;
1156         *(reinterpret_cast<T *>(escapeHandle_)) = **current;
1157         return Local<T>(escapeHandle_);
1158     }
1159 
1160 private:
1161     bool alreadyEscape_ = false;
1162     uintptr_t escapeHandle_ = 0U;
1163 };
1164 
1165 class PUBLIC_API IntegerRef : public PrimitiveRef {
1166 public:
1167     static Local<IntegerRef> New(const EcmaVM *vm, int input);
1168     static Local<IntegerRef> NewFromUnsigned(const EcmaVM *vm, unsigned int input);
1169     int Value();
1170 };
1171 
1172 class PUBLIC_API ArrayBufferRef : public ObjectRef {
1173 public:
1174     static Local<ArrayBufferRef> New(const EcmaVM *vm, int32_t length);
1175     static Local<ArrayBufferRef> New(const EcmaVM *vm, void *buffer, int32_t length,
1176                                      const NativePointerCallback &deleter, void *data);
1177 
1178     int32_t ByteLength(const EcmaVM *vm);
1179     void *GetBuffer(const EcmaVM *vm);
1180     void *GetBufferAndLength(const EcmaVM *vm, int32_t *length);
1181     void Detach(const EcmaVM *vm);
1182     bool IsDetach(const EcmaVM *vm);
1183 };
1184 
1185 class PUBLIC_API SendableArrayBufferRef : public ObjectRef {
1186 public:
1187     static Local<SendableArrayBufferRef> New(const EcmaVM *vm, int32_t length);
1188     static Local<SendableArrayBufferRef> New(const EcmaVM *vm, void *buffer, int32_t length,
1189                                              const NativePointerCallback &deleter, void *data);
1190 
1191     int32_t ByteLength(const EcmaVM *vm);
1192     void *GetBuffer(const EcmaVM *vm);
1193 
1194     void Detach(const EcmaVM *vm);
1195     bool IsDetach(const EcmaVM *vm);
1196 };
1197 
1198 class PUBLIC_API DateRef : public ObjectRef {
1199 public:
1200     static Local<DateRef> New(const EcmaVM *vm, double time);
1201     Local<StringRef> ToString(const EcmaVM *vm);
1202     double GetTime(const EcmaVM *vm);
1203 };
1204 
1205 class PUBLIC_API TypedArrayRef : public ObjectRef {
1206 public:
1207     uint32_t ByteLength(const EcmaVM *vm);
1208     uint32_t ByteOffset(const EcmaVM *vm);
1209     uint32_t ArrayLength(const EcmaVM *vm);
1210     Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
1211 };
1212 
1213 class PUBLIC_API SendableTypedArrayRef : public ObjectRef {
1214 public:
1215     uint32_t ByteLength(const EcmaVM *vm);
1216     uint32_t ByteOffset(const EcmaVM *vm);
1217     uint32_t ArrayLength(const EcmaVM *vm);
1218     Local<SendableArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
1219 };
1220 
1221 class PUBLIC_API ArrayRef : public ObjectRef {
1222 public:
1223     static Local<ArrayRef> New(const EcmaVM *vm, uint32_t length = 0);
1224     uint32_t Length(const EcmaVM *vm);
1225     static bool SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value);
1226     static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index);
1227 };
1228 
1229 class PUBLIC_API SendableArrayRef : public ObjectRef {
1230 public:
1231     static Local<SendableArrayRef> New(const EcmaVM *vm, uint32_t length = 0);
1232     uint32_t Length(const EcmaVM *vm);
1233     static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index);
1234     static bool SetProperty(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value);
1235 };
1236 
1237 class PUBLIC_API Int8ArrayRef : public TypedArrayRef {
1238 public:
1239     static Local<Int8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
1240 };
1241 
1242 class PUBLIC_API SharedInt8ArrayRef : public SendableTypedArrayRef {
1243 public:
1244     static Local<SharedInt8ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1245                                          int32_t byteOffset, int32_t length);
1246 };
1247 
1248 class PUBLIC_API Uint8ArrayRef : public TypedArrayRef {
1249 public:
1250     static Local<Uint8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
1251 };
1252 
1253 class PUBLIC_API SharedUint8ArrayRef : public SendableTypedArrayRef {
1254 public:
1255     static Local<SharedUint8ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1256                                           int32_t byteOffset, int32_t length);
1257 };
1258 
1259 class PUBLIC_API Uint8ClampedArrayRef : public TypedArrayRef {
1260 public:
1261     static Local<Uint8ClampedArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1262                                            int32_t length);
1263 };
1264 
1265 class PUBLIC_API Int16ArrayRef : public TypedArrayRef {
1266 public:
1267     static Local<Int16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
1268 };
1269 
1270 class PUBLIC_API SharedInt16ArrayRef : public SendableTypedArrayRef {
1271 public:
1272     static Local<SharedInt16ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1273                                           int32_t byteOffset, int32_t length);
1274 };
1275 
1276 class PUBLIC_API Uint16ArrayRef : public TypedArrayRef {
1277 public:
1278     static Local<Uint16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1279                                      int32_t length);
1280 };
1281 
1282 class PUBLIC_API SharedUint16ArrayRef : public SendableTypedArrayRef {
1283 public:
1284     static Local<SharedUint16ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1285                                            int32_t byteOffset, int32_t length);
1286 };
1287 
1288 class PUBLIC_API Int32ArrayRef : public TypedArrayRef {
1289 public:
1290     static Local<Int32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
1291 };
1292 
1293 class PUBLIC_API SharedInt32ArrayRef : public SendableTypedArrayRef {
1294 public:
1295     static Local<SharedInt32ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1296                                           int32_t byteOffset, int32_t length);
1297 };
1298 
1299 class PUBLIC_API SharedFloat32ArrayRef : public SendableTypedArrayRef {
1300 public:
1301     static Local<SharedFloat32ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1302                                             int32_t byteOffset, int32_t length);
1303 };
1304 
1305 class PUBLIC_API SharedUint8ClampedArrayRef : public SendableTypedArrayRef {
1306 public:
1307     static Local<SharedUint8ClampedArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1308                                                  int32_t byteOffset, int32_t length);
1309 };
1310 
1311 class PUBLIC_API Uint32ArrayRef : public TypedArrayRef {
1312 public:
1313     static Local<Uint32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1314                                      int32_t length);
1315 };
1316 
1317 class PUBLIC_API SharedUint32ArrayRef : public SendableTypedArrayRef {
1318 public:
1319     static Local<SharedUint32ArrayRef> New(const EcmaVM *vm, Local<SendableArrayBufferRef> buffer,
1320                                            int32_t byteOffset, int32_t length);
1321 };
1322 
1323 class PUBLIC_API Float32ArrayRef : public TypedArrayRef {
1324 public:
1325     static Local<Float32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1326                                       int32_t length);
1327 };
1328 
1329 class PUBLIC_API Float64ArrayRef : public TypedArrayRef {
1330 public:
1331     static Local<Float64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1332                                       int32_t length);
1333 };
1334 
1335 class PUBLIC_API BigInt64ArrayRef : public TypedArrayRef {
1336 public:
1337     static Local<BigInt64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1338                                       int32_t length);
1339 };
1340 
1341 class PUBLIC_API BigUint64ArrayRef : public TypedArrayRef {
1342 public:
1343     static Local<BigUint64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
1344                                       int32_t length);
1345 };
1346 
1347 class PUBLIC_API Exception {
1348 public:
1349     static Local<JSValueRef> Error(const EcmaVM *vm, Local<StringRef> message);
1350     static Local<JSValueRef> RangeError(const EcmaVM *vm, Local<StringRef> message);
1351     static Local<JSValueRef> ReferenceError(const EcmaVM *vm, Local<StringRef> message);
1352     static Local<JSValueRef> SyntaxError(const EcmaVM *vm, Local<StringRef> message);
1353     static Local<JSValueRef> TypeError(const EcmaVM *vm, Local<StringRef> message);
1354     static Local<JSValueRef> AggregateError(const EcmaVM *vm, Local<StringRef> message);
1355     static Local<JSValueRef> EvalError(const EcmaVM *vm, Local<StringRef> message);
1356     static Local<JSValueRef> OOMError(const EcmaVM *vm, Local<StringRef> message);
1357     static Local<JSValueRef> TerminationError(const EcmaVM *vm, Local<StringRef> message);
1358 };
1359 
1360 class PUBLIC_API FunctionCallScope {
1361 public:
1362     FunctionCallScope(EcmaVM *vm);
1363     ~FunctionCallScope();
1364 
1365 private:
1366     EcmaVM *vm_;
1367 };
1368 
1369 class PUBLIC_API JSExecutionScope {
1370 public:
1371     explicit JSExecutionScope(const EcmaVM *vm);
1372     ~JSExecutionScope();
1373     ECMA_DISALLOW_COPY(JSExecutionScope);
1374     ECMA_DISALLOW_MOVE(JSExecutionScope);
1375 
1376 private:
1377     void *lastCurrentThread_ = nullptr;
1378     bool isRevert_ = false;
1379 };
1380 
1381 class PUBLIC_API JsiNativeScope {
1382 public:
1383     explicit JsiNativeScope(const EcmaVM *vm);
1384     ~JsiNativeScope();
1385     ECMA_DISALLOW_COPY(JsiNativeScope);
1386     ECMA_DISALLOW_MOVE(JsiNativeScope);
1387 
1388 private:
1389     JSThread *thread_;
1390     uint16_t oldThreadState_ {0};
1391     uint32_t isEnableCMCGC_ {0};
1392     uint32_t hasSwitchState_ {0};
1393 };
1394 
1395 class PUBLIC_API JsiFastNativeScope {
1396 public:
1397     explicit JsiFastNativeScope(const EcmaVM *vm);
1398     ~JsiFastNativeScope();
1399     ECMA_DISALLOW_COPY(JsiFastNativeScope);
1400     ECMA_DISALLOW_MOVE(JsiFastNativeScope);
1401 
1402 private:
1403     JSThread *thread_ {nullptr};
1404     uint16_t oldThreadState_ {0};
1405     uint32_t isEnableCMCGC_ {0};
1406     uint32_t hasSwitchState_ {0};
1407 };
1408 
1409 /**
1410  * JsiRuntimeCallInfo is used for ace_engine and napi, is same to ark EcamRuntimeCallInfo except data.
1411  */
1412 class PUBLIC_API JsiRuntimeCallInfo
1413     : public ecmascript::base::AlignedStruct<ecmascript::base::AlignedPointer::Size(),
1414                                              ecmascript::base::AlignedPointer,
1415                                              ecmascript::base::AlignedPointer,
1416                                              ecmascript::base::AlignedPointer> {
1417     enum class Index : size_t {
1418         ThreadIndex = 0,
1419         NumArgsIndex,
1420         StackArgsIndex,
1421         NumOfMembers
1422     };
1423 public:
1424     JsiRuntimeCallInfo() = default;
1425     ~JsiRuntimeCallInfo() = default;
1426 
GetThread()1427     inline JSThread *GetThread() const
1428     {
1429         return thread_;
1430     }
1431 
1432     EcmaVM *GetVM() const;
1433 
GetArgsNumber()1434     inline uint32_t GetArgsNumber() const
1435     {
1436         ECMA_ASSERT(numArgs_ >= FIRST_ARGS_INDEX);
1437         return numArgs_ - FIRST_ARGS_INDEX;
1438     }
1439 
1440     void* GetData();
1441 
GetFunctionRef()1442     inline Local<JSValueRef> GetFunctionRef() const
1443     {
1444         return GetArgRef(FUNC_INDEX);
1445     }
1446 
GetNewTargetRef()1447     inline Local<JSValueRef> GetNewTargetRef() const
1448     {
1449         return GetArgRef(NEW_TARGET_INDEX);
1450     }
1451 
GetThisRef()1452     inline Local<JSValueRef> GetThisRef() const
1453     {
1454         return GetArgRef(THIS_INDEX);
1455     }
1456 
GetCallArgRef(uint32_t idx)1457     inline Local<JSValueRef> GetCallArgRef(uint32_t idx) const
1458     {
1459         return GetArgRef(FIRST_ARGS_INDEX + idx);
1460     }
1461 
1462 private:
1463     enum ArgsIndex : uint8_t { FUNC_INDEX = 0, NEW_TARGET_INDEX, THIS_INDEX, FIRST_ARGS_INDEX };
1464 
GetArgRef(uint32_t idx)1465     Local<JSValueRef> GetArgRef(uint32_t idx) const
1466     {
1467         return Local<JSValueRef>(GetArgAddress(idx));
1468     }
1469 
GetArgAddress(uint32_t idx)1470     uintptr_t GetArgAddress(uint32_t idx) const
1471     {
1472         if (idx < GetArgsNumber() + FIRST_ARGS_INDEX) {
1473             return reinterpret_cast<uintptr_t>(&stackArgs_[idx]);
1474         }
1475         return 0U;
1476     }
1477 
1478 private:
1479     alignas(sizeof(JSTaggedType)) JSThread *thread_ {nullptr};
1480     alignas(sizeof(JSTaggedType))  uint32_t numArgs_ = 0;
1481     __extension__ alignas(sizeof(JSTaggedType)) JSTaggedType stackArgs_[0];
1482     friend class FunctionRef;
1483 };
1484 
1485 class PUBLIC_API MapRef : public ObjectRef {
1486 public:
1487     int32_t GetSize(const EcmaVM *vm);
1488     int32_t GetTotalElements(const EcmaVM *vm);
1489     Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
1490     Local<JSValueRef> Get(const EcmaVM *vm, const char *utf8);
1491     Local<JSValueRef> GetKey(const EcmaVM *vm, int entry);
1492     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1493     static Local<MapRef> New(const EcmaVM *vm);
1494     void Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
1495     void Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value);
1496     bool Has(const EcmaVM *vm, Local<JSValueRef> key);
1497     bool Has(const EcmaVM *vm, const char *utf8);
1498     void Delete(const EcmaVM *vm, Local<JSValueRef> key);
1499     void Clear(const EcmaVM *vm);
1500     Local<MapIteratorRef> GetEntries(const EcmaVM *vm);
1501     Local<MapIteratorRef> GetKeys(const EcmaVM *vm);
1502     Local<MapIteratorRef> GetValues(const EcmaVM *vm);
1503 };
1504 
1505 class PUBLIC_API SendableMapRef : public ObjectRef {
1506 public:
1507     static Local<SendableMapRef> New(const EcmaVM *vm);
1508     uint32_t GetSize(const EcmaVM *vm);
1509     uint32_t GetTotalElements(const EcmaVM *vm);
1510     Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
1511     Local<JSValueRef> Get(const EcmaVM *vm, const char *utf8);
1512     Local<JSValueRef> GetKey(const EcmaVM *vm, int entry);
1513     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1514     void Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
1515     void Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value);
1516     bool Has(const EcmaVM *vm, Local<JSValueRef> key);
1517     bool Has(const EcmaVM *vm, const char *utf8);
1518     void Delete(const EcmaVM *vm, Local<JSValueRef> key);
1519     void Clear(const EcmaVM *vm);
1520     Local<SendableMapIteratorRef> GetEntries(const EcmaVM *vm);
1521     Local<SendableMapIteratorRef> GetKeys(const EcmaVM *vm);
1522     Local<SendableMapIteratorRef> GetValues(const EcmaVM *vm);
1523 };
1524 
1525 class PUBLIC_API SendableSetRef : public ObjectRef {
1526 public:
1527     static Local<SendableSetRef> New(const EcmaVM *vm);
1528     uint32_t GetSize(const EcmaVM *vm);
1529     uint32_t GetTotalElements(const EcmaVM *vm);
1530     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1531     void Add(const EcmaVM *vm, Local<JSValueRef> value);
1532 };
1533 
1534 class PUBLIC_API BufferRef : public ObjectRef {
1535 public:
1536     static Local<BufferRef> New(const EcmaVM *vm, int32_t length);
1537     static Local<BufferRef> New(const EcmaVM *vm, const Local<JSValueRef> &context, int32_t length);
1538     static Local<BufferRef> New(const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter,
1539                                 void *data);
1540     static Local<BufferRef> New(const EcmaVM *vm, const Local<JSValueRef> &context, void *buffer, int32_t length,
1541                                 const NativePointerCallback &deleter, void *data);
1542 
1543     int32_t ByteLength(const EcmaVM *vm);
1544     void *GetBuffer(const EcmaVM *vm);
1545     static ecmascript::JSTaggedValue BufferToStringCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo);
1546 };
1547 
1548 class PUBLIC_API PromiseRef : public ObjectRef {
1549 public:
1550     Local<PromiseRef> Catch(const EcmaVM *vm, Local<FunctionRef> handler);
1551     Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> handler);
1552     Local<PromiseRef> Finally(const EcmaVM *vm, Local<FunctionRef> handler);
1553     Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> onFulfilled, Local<FunctionRef> onRejected);
1554 
1555     Local<JSValueRef> GetPromiseState(const EcmaVM *vm);
1556     Local<JSValueRef> GetPromiseResult(const EcmaVM *vm);
1557 };
1558 
1559 class PUBLIC_API PromiseCapabilityRef : public ObjectRef {
1560 public:
1561     static Local<PromiseCapabilityRef> New(const EcmaVM *vm);
1562     bool Resolve(const EcmaVM *vm, uintptr_t value);
1563     bool Resolve(const EcmaVM *vm, Local<JSValueRef> value);
1564     bool Reject(const EcmaVM *vm, uintptr_t reason);
1565     bool Reject(const EcmaVM *vm, Local<JSValueRef> reason);
1566     Local<PromiseRef> GetPromise(const EcmaVM *vm);
1567 };
1568 
1569 class PUBLIC_API NumberRef : public PrimitiveRef {
1570 public:
1571     static Local<NumberRef> New(const EcmaVM *vm, double input);
1572     static Local<NumberRef> New(const EcmaVM *vm, int32_t input);
1573     static Local<NumberRef> New(const EcmaVM *vm, uint32_t input);
1574     static Local<NumberRef> New(const EcmaVM *vm, int64_t input);
1575 
1576     double Value();
1577 };
1578 
1579 class PUBLIC_API DataViewRef : public ObjectRef {
1580 public:
1581     static Local<DataViewRef> New(const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, uint32_t byteOffset,
1582                                   uint32_t byteLength);
1583     static Local<DataViewRef> NewWithoutSwitchState(const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer,
1584                                                     uint32_t byteOffset, uint32_t byteLength);
1585     uint32_t ByteLength();
1586     uint32_t ByteOffset();
1587     Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
1588 };
1589 
1590 class PUBLIC_API MapIteratorRef : public ObjectRef {
1591 public:
1592     int32_t GetIndex();
1593     Local<JSValueRef> GetKind(const EcmaVM *vm);
1594     static Local<MapIteratorRef> New(const EcmaVM *vm, Local<MapRef> map);
1595     ecmascript::EcmaRuntimeCallInfo* GetEcmaRuntimeCallInfo(const EcmaVM *vm);
1596     static Local<ArrayRef> Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo* ecmaRuntimeCallInfo);
1597     Local<JSValueRef> Next(const EcmaVM *vm);
1598 };
1599 
1600 class PUBLIC_API SendableMapIteratorRef : public ObjectRef {
1601 public:
1602     Local<JSValueRef> Next(const EcmaVM *vm);
1603 };
1604 
1605 class PUBLIC_API JSNApi {
1606 public:
1607     struct DebugOption {
1608         const char *libraryPath;
1609         bool isDebugMode = false;
1610         int port = -1;
1611         bool isFaApp = false;
1612     };
1613     using DebuggerPostTask = std::function<void(std::function<void()>&&)>;
1614     using PatchErrorCode = panda::PatchErrorCode;
1615     using UncatchableErrorHandler = std::function<void(panda::TryCatch&)>;
1616 
1617     struct NativeBindingInfo {
CreateNewInstanceNativeBindingInfo1618         static NativeBindingInfo* CreateNewInstance() { return new(std::nothrow) NativeBindingInfo(); }
1619         void *env = nullptr;
1620         void *nativeValue = nullptr;
1621         void *attachFunc = nullptr;
1622         void *attachData = nullptr;
1623         void *detachFunc = nullptr;
1624         void *detachData = nullptr;
1625         void *hint = nullptr;
1626         void *detachedFinalizer = nullptr;
1627         void *detachedHint = nullptr;
1628     };
1629 
1630     struct XRefBindingInfo {
CreateNewInstanceXRefBindingInfo1631         static XRefBindingInfo* CreateNewInstance() { return new(std::nothrow) XRefBindingInfo(); }
1632         void *attachXRefFunc = nullptr;
1633         void *attachXRefData = nullptr;
1634     };
1635 
1636     // JSVM
1637     // fixme: Rename SEMI_GC to YOUNG_GC
1638     enum class PUBLIC_API TRIGGER_GC_TYPE : uint8_t {
1639         SEMI_GC,
1640         OLD_GC,
1641         FULL_GC,
1642         SHARED_GC,
1643         SHARED_FULL_GC
1644     };
1645 
1646     enum class PUBLIC_API TRIGGER_IDLE_GC_TYPE : uint8_t {
1647         LOCAL_CONCURRENT_YOUNG_MARK = 1,
1648         LOCAL_CONCURRENT_FULL_MARK = 1 << 1,
1649         LOCAL_REMARK = 1 << 2,
1650         FULL_GC = 1 << 3,
1651         SHARED_CONCURRENT_MARK = 1 << 4,
1652         SHARED_CONCURRENT_PARTIAL_MARK = 1 << 5,
1653         SHARED_FULL_GC = 1 << 6,
1654     };
1655 
1656     enum class PUBLIC_API MemoryReduceDegree : uint8_t {
1657         LOW = 0,
1658         MIDDLE,
1659         HIGH,
1660     };
1661 
1662     enum class PUBLIC_API PandaFileType : int8_t {
1663         FILE_FORMAT_INVALID = -1,
1664         FILE_DYNAMIC = 0,
1665         FILE_STATIC = 1,
1666     };
1667 
1668     static EcmaVM *CreateJSVM(const RuntimeOption &option);
1669     static void DestroyJSVM(EcmaVM *ecmaVm);
1670     static void IgnoreFinalizeCallback(EcmaVM *ecmaVm);
1671     static void RegisterUncatchableErrorHandler(EcmaVM *ecmaVm, const UncatchableErrorHandler &handler);
1672 
1673     // aot load
1674     static void LoadAotFile(EcmaVM *vm, const std::string &moduleName);
1675 #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM)
1676     static void LoadAotFile(EcmaVM *vm, [[maybe_unused]] const std::string &bundleName,
1677                             const std::string &moduleName,
1678                             std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)> cb);
1679 #endif
1680     // JS code
1681     static bool ExecuteForAbsolutePath(const EcmaVM *vm, const std::string &fileName,
1682                                        const std::string &entry, bool needUpdate = false,
1683                                        const ecmascript::ExecuteTypes &executeType = ecmascript::ExecuteTypes::STATIC);
1684     static bool Execute(const EcmaVM *vm, const std::string &fileName,
1685                         const std::string &entry, bool needUpdate = false,
1686                         const ecmascript::ExecuteTypes &executeType = ecmascript::ExecuteTypes::STATIC);
1687     static bool Execute(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &entry,
1688                         const std::string &filename = "", bool needUpdate = false,
1689                         [[maybe_unused]] void* fileMapper = nullptr);
1690     static int ExecuteWithSingletonPatternFlag(EcmaVM *vm, const std::string &bundleName,
1691         const std::string &moduleName, const std::string &ohmurl, bool isSingletonPattern);
1692     static bool IsExecuteModuleInAbcFile(EcmaVM *vm, const std::string &bundleName,
1693         const std::string &moduleName, const std::string &ohmurl);
1694     // merge abc, execute module buffer
1695     static bool ExecuteModuleBuffer(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &filename = "",
1696                                     bool needUpdate = false);
1697     static bool ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file);
1698     /**
1699      * @brief Return the abc file type
1700      * @param[in] data : begin pos of abc file
1701      * @param[in] size : length of abc file
1702      * @return -1 indicates the abc file format invalid
1703      *         0 indicates the abc file is dynamic
1704      *         1 indicates the abc file is static
1705      */
1706     static PandaFileType GetFileType(const uint8_t *data, int32_t size);
1707     static Local<ObjectRef> GetExportObject(EcmaVM *vm, const std::string &file, const std::string &key);
1708     static Local<ObjectRef> GetExportObjectFromBuffer(EcmaVM *vm, const std::string &file, const std::string &key);
1709     static Local<ObjectRef> GetExportObjectFromOhmUrl(EcmaVM *vm, const std::string &ohmUrl, const std::string &key);
1710     static Local<ObjectRef> ExecuteNativeModule(EcmaVM *vm, const std::string &key);
1711     static Local<ObjectRef> GetModuleNameSpaceFromFile(EcmaVM *vm, const std::string &file);
1712     template<ForHybridApp isHybrid = ForHybridApp::Normal>
1713     static Local<ObjectRef> GetModuleNameSpaceWithModuleInfo(EcmaVM *vm, const std::string &file,
1714                                                              const std::string &module_path);
1715     static Local<ObjectRef> GetModuleNameSpaceWithModuleInfoForNormalApp(EcmaVM *vm, const std::string &file,
1716                                                              const std::string &module_path);
1717     static Local<ObjectRef> GetModuleNameSpaceWithModuleInfoForHybridApp(EcmaVM *vm, const std::string &file,
1718                                                              const std::string &module_path);
1719 
1720     /*
1721      * Execute panda file from secure mem. secure memory lifecycle managed externally.
1722      * The data parameter needs to be created externally by an external caller and managed externally
1723      * by the external caller. The size parameter is the size of the data memory. The entry parameter
1724      * is the name of the entry function. The filename parameter is used to uniquely identify this
1725      * memory internally.
1726      */
1727     static bool ExecuteSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &entry,
1728                               const std::string &filename = "", bool needUpdate = false, void* fileMapper = nullptr);
1729     /*
1730      * Execute panda file(merge abc) from secure mem. secure memory lifecycle managed externally.
1731      * The data parameter needs to be created externally by an external caller and managed externally
1732      * by the external caller. The size parameter is the size of the data memory. The filename parameter
1733      * is used to uniquely identify this memory internally.
1734      */
1735     static bool ExecuteModuleBufferSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &filename = "",
1736                                           bool needUpdate = false);
1737 
1738     static bool ExecuteSecureWithOhmUrl(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &srcFilename,
1739                                         const std::string &ohmUrl);
1740 
1741     // ObjectRef Operation
1742     static Local<ObjectRef> GetGlobalObject(const EcmaVM *vm);
1743     static Local<ObjectRef> GetGlobalObject(const EcmaVM *vm, const Local<JSValueRef> &context);
1744     static void ExecutePendingJob(const EcmaVM *vm);
1745 
1746     // Memory
1747     // fixme: Rename SEMI_GC to YOUNG_GC
1748     static void TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC);
1749     static void TriggerGC(const EcmaVM *vm, ecmascript::GCReason reason,
1750         TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC);
1751     static void HintGC(const EcmaVM *vm, MemoryReduceDegree degree, ecmascript::GCReason reason);
1752     static void TriggerIdleGC(const EcmaVM *vm, TRIGGER_IDLE_GC_TYPE gcType);
1753     static void SetStartIdleMonitorCallback(const StartIdleMonitorCallback& callback);
1754     static StartIdleMonitorCallback GetStartIdleMonitorCallback();
1755     // Exception
1756     static void ThrowException(const EcmaVM *vm, Local<JSValueRef> error);
1757     static void PrintExceptionInfo(const EcmaVM *vm);
1758     static void SetOnErrorCallback(EcmaVM *vm, OnErrorCallback cb, void* data);
1759     static Local<ObjectRef> GetAndClearUncaughtException(const EcmaVM *vm);
1760     static Local<ObjectRef> GetUncaughtException(const EcmaVM *vm);
1761     static bool IsExecutingPendingJob(const EcmaVM *vm);
1762     static bool HasPendingException(const EcmaVM *vm);
1763     static bool HasPendingJob(const EcmaVM *vm);
1764     static void EnableUserUncaughtErrorHandler(EcmaVM *vm);
1765     // prevewer debugger.
1766     static bool StartDebuggerCheckParameters(EcmaVM *vm, const DebugOption &option, int32_t instanceId,
1767                                              const DebuggerPostTask &debuggerPostTask);
1768     static bool StartDebugger(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0,
1769         const DebuggerPostTask &debuggerPostTask = {});
1770     // To be compatible with the old process.
1771     static bool StartDebuggerForOldProcess(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0,
1772         const DebuggerPostTask &debuggerPostTask = {});
1773     // socketpair process in ohos platform.
1774     static bool StartDebuggerForSocketPair(int tid, int socketfd = -1);
1775     static bool StopDebugger(int tid);
1776     static bool NotifyDebugMode(int tid, EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0,
1777                                 const DebuggerPostTask &debuggerPostTask = {}, bool debugApp = false);
1778     static bool StoreDebugInfo(
1779         int tid, EcmaVM *vm, const DebugOption &option, const DebuggerPostTask &debuggerPostTask, bool debugApp);
1780     static bool StopDebugger(EcmaVM *vm);
1781     static bool IsMixedDebugEnabled(const EcmaVM *vm);
1782     static bool IsDebugModeEnabled(const EcmaVM *vm);
1783     static void NotifyNativeCalling(const EcmaVM *vm, const void *nativeAddress);
1784     static void NotifyNativeReturn(const EcmaVM *vm, const void *nativeAddress);
1785     static void NotifyLoadModule(const EcmaVM *vm);
1786     static void NotifyUIIdle(const EcmaVM *vm, int idleTime);
1787     static bool NotifyLooperIdleStart(const EcmaVM *vm, int64_t timestamp, int idleTime);
1788     static void NotifyLooperIdleEnd(const EcmaVM *vm, int64_t timestamp);
1789     static bool IsJSMainThreadOfEcmaVM(const EcmaVM *vm);
1790     static void SetDeviceDisconnectCallback(EcmaVM *vm, DeviceDisconnectCallback cb);
1791     // Serialize & Deserialize.
1792     static void* SerializeValue(const EcmaVM *vm, Local<JSValueRef> data, Local<JSValueRef> transfer,
1793                                 Local<JSValueRef> cloneList,
1794                                 bool defaultTransfer = false,
1795                                 bool defaultCloneShared = true);
1796     static void* SerializeValueWithError(const EcmaVM *vm, Local<JSValueRef> data, Local<JSValueRef> transfer,
1797                                          Local<JSValueRef> cloneList, std::string &error, bool defaultTransfer = false,
1798                                          bool defaultCloneShared = true);
1799     static Local<JSValueRef> DeserializeValue(const EcmaVM *vm, void *recoder, void *hint);
1800     // InterOp Serialize & Deserialize.
1801     static void* InterOpSerializeValue(const EcmaVM *vm, Local<JSValueRef> data, Local<JSValueRef> transfer,
1802         Local<JSValueRef> cloneList, bool defaultTransfer = false, bool defaultCloneShared = true);
1803     static Local<JSValueRef> InterOpDeserializeValue(const EcmaVM *vm, void *recoder, void *hint);
1804     static void DeleteSerializationData(void *data);
1805     static void SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data);
1806     static void SetTimerTaskCallback(EcmaVM *vm, TimerTaskCallback callback);
1807     static void SetCancelTimerCallback(EcmaVM *vm, CancelTimerCallback callback);
1808     static void NotifyEnvInitialized(EcmaVM *vm);
1809     static void SetReleaseSecureMemCallback(ReleaseSecureMemCallback releaseSecureMemFunc);
1810     static void PandaFileSerialize(const EcmaVM *vm);
1811     static void ModuleSerialize(const EcmaVM *vm);
1812     static void ModuleDeserialize(EcmaVM *vm, const uint32_t appVersion);
1813     static void SetHostResolveBufferTrackerForHybridApp(EcmaVM *vm, std::function<bool(std::string dirPath,
1814                                             uint8_t **buff, size_t *buffSize, std::string &errorMsg)> cb);
1815     static void SetUnloadNativeModuleCallback(EcmaVM *vm, const std::function<bool(const std::string &moduleKey)> &cb);
1816     static void SetNativePtrGetter(EcmaVM *vm, void* cb);
1817     static void SetSourceMapCallback(EcmaVM *vm, SourceMapCallback cb);
1818     static void SetSourceMapTranslateCallback(EcmaVM *vm, SourceMapTranslateCallback cb);
1819     static void SetHostEnqueueJob(const EcmaVM* vm, Local<JSValueRef> cb,
1820                                 QueueType queueType = QueueType::QUEUE_PROMISE);
1821     static EcmaVM* CreateEcmaVM(const ecmascript::JSRuntimeOptions &options);
1822     static void PreFork(EcmaVM *vm);
1823     static void PostFork(EcmaVM *vm, const RuntimeOption &option);
1824     static void AddWorker(EcmaVM *hostVm, EcmaVM *workerVm);
1825     static bool DeleteWorker(EcmaVM *hostVm, EcmaVM *workerVm);
1826     static void GetStackBeforeCallNapiSuccess(EcmaVM *vm, bool &getStackBeforeCallNapiSuccess);
1827     static void GetStackAfterCallNapi(EcmaVM *vm);
1828     static PatchErrorCode LoadPatch(EcmaVM *vm, const std::string &patchFileName, const std::string &baseFileName);
1829     static PatchErrorCode LoadPatch(EcmaVM *vm,
1830                                     const std::string &patchFileName, uint8_t *patchBuffer, size_t patchSize,
1831                                     const std::string &baseFileName, uint8_t *baseBuffer, size_t baseSize);
1832     static PatchErrorCode UnloadPatch(EcmaVM *vm, const std::string &patchFileName);
1833     // check whether the exception is caused by quickfix methods.
1834     static bool IsQuickFixCausedException(EcmaVM *vm, Local<ObjectRef> exception, const std::string &patchFileName);
1835     // register quickfix query function.
1836     static void RegisterQuickFixQueryFunc(EcmaVM *vm, std::function<bool(std::string baseFileName,
1837                         std::string &patchFileName,
1838                         uint8_t **patchBuffer,
1839                         size_t &patchSize)> callBack);
1840     static bool IsBundle(EcmaVM *vm);
1841     static void SetBundle(EcmaVM *vm, bool value);
1842     static bool IsNormalizedOhmUrlPack(EcmaVM *vm);
1843     static bool IsOhmUrl(const std::string &srcName);
1844     static void SetAssetPath(EcmaVM *vm, const std::string &assetPath);
1845     static void SetMockModuleList(EcmaVM *vm, const std::map<std::string, std::string> &list);
1846     static void SetPkgNameList(EcmaVM *vm, const std::map<std::string, std::string> &list);
1847     static void UpdatePkgNameList(EcmaVM *vm, const std::map<std::string, std::string> &list);
1848     static std::string GetPkgName(EcmaVM *vm, const std::string &moduleName);
1849     static void SetPkgAliasList(EcmaVM *vm, const std::map<std::string, std::string> &list);
1850     static void UpdatePkgAliasList(EcmaVM *vm, const std::map<std::string, std::string> &list);
1851     static void SetHmsModuleList(EcmaVM *vm, const std::vector<panda::HmsMap> &list);
1852     static void SetModuleInfo(EcmaVM *vm, const std::string &assetPath, const std::string &entryPoint);
1853     static void SetpkgContextInfoList(EcmaVM *vm, const std::map<std::string,
1854         std::vector<std::vector<std::string>>> &list);
1855     static void UpdatePkgContextInfoList(EcmaVM *vm,
1856         const std::map<std::string, std::vector<std::vector<std::string>>> &list);
1857     static void SetExecuteBufferMode(const EcmaVM *vm);
1858     // Stop preloading so task callback.
1859     static void SetStopPreLoadSoCallback(EcmaVM *vm, const StopPreLoadSoCallback &callback);
1860     static void SetLoop(EcmaVM *vm, void *loop);
1861     static void SetWeakFinalizeTaskCallback(EcmaVM *vm, const WeakFinalizeTaskCallback &callback);
1862     static void SetAsyncCleanTaskCallback(EcmaVM *vm, const NativePointerTaskCallback &callback);
1863     static void SetTriggerGCTaskCallback(EcmaVM *vm, const TriggerGCTaskCallback& callback);
1864     static void SetStartIdleMonitorCallback(EcmaVM *vm, const StartIdleMonitorCallback& callback);
1865     static std::string GetAssetPath(EcmaVM *vm);
1866     static bool InitForConcurrentThread(EcmaVM *vm, ConcurrentCallback cb, void *data);
1867     static bool InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> func, void *taskInfo);
1868     static void* GetCurrentTaskInfo(const EcmaVM *vm);
1869     static void ClearCurrentTaskInfo(const EcmaVM *vm);
1870     static void SetBundleName(EcmaVM *vm, const std::string &bundleName);
1871     static std::string GetBundleName(EcmaVM *vm);
1872     static void SetModuleName(EcmaVM *vm, const std::string &moduleName);
1873     static std::string GetModuleName(EcmaVM *vm);
1874     static void SetLargeHeap(bool isLargeHeap);
1875     static std::pair<std::string, std::string> GetCurrentModuleInfo(EcmaVM *vm, bool needRecordName = false);
1876     static std::string NormalizePath(const std::string &string);
1877     static void AllowCrossThreadExecution(EcmaVM *vm);
1878     static bool CheckAndSetAllowCrossThreadExecution(EcmaVM *vm);
1879     static void SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM);
1880     static bool IsProfiling(EcmaVM *vm);
1881     static void SetProfilerState(const EcmaVM *vm, bool value);
1882     static void SetRequestAotCallback(EcmaVM *vm, const std::function<int32_t(const std::string &bundleName,
1883                     const std::string &moduleName,
1884                     int32_t triggerMode)> &cb);
1885     static void SetSearchHapPathTracker(EcmaVM *vm, std::function<bool(const std::string moduleName,
1886                     std::string &hapPath)> cb);
1887     static void *GetEnv(EcmaVM *vm);
1888     static void SetEnv(EcmaVM *vm, void *env);
1889     static void SetMultiThreadCheck(bool multiThreadCheck = true);
1890     static void SetErrorInfoEnhance(bool errorInfoEnhance = true);
1891 
1892     // Napi Heavy Logics fast path
1893     static Local<JSValueRef> NapiHasProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key);
1894     static Local<JSValueRef> NapiHasOwnProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key);
1895     static Local<JSValueRef> NapiGetProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key);
1896     static Local<JSValueRef> NapiDeleteProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key);
1897     static Local<JSValueRef> NapiGetNamedProperty(const EcmaVM *vm, uintptr_t nativeObj, const char* utf8Key);
1898     static Local<JSValueRef> CreateLocal(const EcmaVM *vm, JSValueRef src);
1899 
1900     // Napi helper function
1901     static bool KeyIsNumber(const char* utf8);
1902     static int GetStartRealTime(const EcmaVM *vm);
1903     static void NotifyTaskBegin(const EcmaVM *vm);
1904     static void NotifyTaskFinished(const EcmaVM *vm);
1905     static bool IsMultiThreadCheckEnabled(const EcmaVM *vm);
1906     static uint32_t GetCurrentThreadId();
1907 
1908     //set VM apiVersion
1909     static void SetVMAPIVersion(EcmaVM *vm, const int32_t apiVersion);
1910 
1911     // Napi Update SubStackInfo
1912     static void UpdateStackInfo(EcmaVM *vm, void *currentStackInfo, uint32_t opKind);
1913 
1914     static Local<JSValueRef> CreateContext(const EcmaVM *vm);
1915 
1916     static Local<JSValueRef> GetCurrentContext(const EcmaVM *vm);
1917 
1918     static void SwitchContext(const EcmaVM *vm, const Local<JSValueRef> &context);
1919     // 1.2runtime interface info
1920     static Local<JSValueRef> GetImplements(const EcmaVM *vm, Local<JSValueRef> instance);
1921 
1922     JSNAPI_PUBLIC_HYBRID_EXTENSION();
1923 private:
1924     static bool isForked_;
1925     static bool CreateRuntime(const RuntimeOption &option);
1926     static bool DestroyRuntime();
1927     static StartIdleMonitorCallback startIdleMonitorCallback_;
1928 
1929     static uintptr_t GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress);
1930     static uintptr_t GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress);
1931     static uintptr_t SetWeak(const EcmaVM *vm, uintptr_t localAddress);
1932     static uintptr_t SetWeakCallback(const EcmaVM *vm, uintptr_t localAddress, void *ref,
1933                                      WeakRefClearCallBack freeGlobalCallBack,
1934                                      WeakRefClearCallBack nativeFinalizeCallback);
1935     static uintptr_t ClearWeak(const EcmaVM *vm, uintptr_t localAddress);
1936     static bool IsWeak(const EcmaVM *vm, uintptr_t localAddress);
1937     static void DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr);
1938 
1939     static bool IsSerializationTimeoutCheckEnabled(const EcmaVM *vm);
1940     static void GenerateTimeoutTraceIfNeeded(const EcmaVM *vm, std::chrono::system_clock::time_point &start,
1941                                      std::chrono::system_clock::time_point &end, bool isSerialization);
1942     static void UpdateAOTCompileStatus(ecmascript::JSRuntimeOptions &jsOption, const RuntimeOption &option);
1943     template<typename T>
1944     friend class Global;
1945     template<typename T>
1946     friend class CopyableGlobal;
1947     template<typename T>
1948     friend class Local;
1949     friend class test::JSNApiTests;
1950     JSNAPI_PRIVATE_HYBRID_EXTENSION();
1951 #ifdef PANDA_JS_ETS_HYBRID_MODE
1952     JSNAPI_PRIVATE_HYBRID_MODE_EXTENSION();
1953 #endif // PANDA_JS_ETS_HYBRID_MODE
1954 };
1955 
1956 class PUBLIC_API ProxyRef : public ObjectRef {
1957 public:
1958     Local<JSValueRef> GetHandler(const EcmaVM *vm);
1959     Local<JSValueRef> GetTarget(const EcmaVM *vm);
1960     bool IsRevoked();
1961 };
1962 
1963 class PUBLIC_API WeakMapRef : public ObjectRef {
1964 public:
1965     int32_t GetSize(const EcmaVM *vm);
1966     int32_t GetTotalElements(const EcmaVM *vm);
1967     Local<JSValueRef> GetKey(const EcmaVM *vm, int entry);
1968     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1969     static Local<WeakMapRef> New(const EcmaVM *vm);
1970     void Set(const EcmaVM *vm, const Local<JSValueRef> &key, const Local<JSValueRef> &value);
1971     bool Has(const EcmaVM *vm, Local<JSValueRef> key);
1972 };
1973 
1974 class PUBLIC_API SetRef : public ObjectRef {
1975 public:
1976     int32_t GetSize(const EcmaVM *vm);
1977     int32_t GetTotalElements(const EcmaVM *vm);
1978     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1979     static Local<SetRef> New(const EcmaVM *vm);
1980     void Add(const EcmaVM *vm, Local<JSValueRef> value);
1981 };
1982 
1983 class PUBLIC_API WeakSetRef : public ObjectRef {
1984 public:
1985     int32_t GetSize(const EcmaVM *vm);
1986     int32_t GetTotalElements(const EcmaVM *vm);
1987     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1988     static Local<WeakSetRef> New(const EcmaVM *vm);
1989     void Add(const EcmaVM *vm, Local<JSValueRef> value);
1990 };
1991 
1992 class PUBLIC_API SetIteratorRef : public ObjectRef {
1993 public:
1994     int32_t GetIndex();
1995     Local<JSValueRef> GetKind(const EcmaVM *vm);
1996     static Local<SetIteratorRef> New(const EcmaVM *vm, Local<SetRef> set);
1997     ecmascript::EcmaRuntimeCallInfo *GetEcmaRuntimeCallInfo(const EcmaVM *vm);
1998     static Local<ArrayRef> Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo);
1999 };
2000 
2001 /* Attention pls, ExternalStringCache only can be utilized in main thread. Threads of Worker or Taskpool call
2002  * functions of this class will cause data race.
2003  */
2004 class PUBLIC_API ExternalStringCache final {
2005 public:
2006     static bool RegisterStringCacheTable(const EcmaVM *vm, uint32_t size);
2007     static bool SetCachedString(const EcmaVM *vm, const char *name, uint32_t propertyIndex);
2008     static bool HasCachedString(const EcmaVM *vm, uint32_t propertyIndex);
2009     static Local<StringRef> GetCachedString(const EcmaVM *vm, uint32_t propertyIndex);
2010 };
2011 
2012 template<typename T>
2013 template<typename S>
Global(const EcmaVM * vm,const Local<S> & current)2014 Global<T>::Global(const EcmaVM *vm, const Local<S> &current) : vm_(vm)
2015 {
2016     if (!current.IsEmpty()) {
2017         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
2018     }
2019 }
2020 
2021 template<typename T>
2022 template<typename S>
Global(const EcmaVM * vm,const Global<S> & current)2023 Global<T>::Global(const EcmaVM *vm, const Global<S> &current) : vm_(vm)
2024 {
2025     if (!current.IsEmpty()) {
2026         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
2027     }
2028 }
2029 
2030 template<typename T>
CopyableGlobal(const EcmaVM * vm,const Local<T> & current)2031 CopyableGlobal<T>::CopyableGlobal(const EcmaVM *vm, const Local<T> &current) : vm_(vm)
2032 {
2033     if (!current.IsEmpty()) {
2034         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
2035     }
2036 }
2037 
2038 template<typename T>
2039 template<typename S>
CopyableGlobal(const EcmaVM * vm,const Local<S> & current)2040 CopyableGlobal<T>::CopyableGlobal(const EcmaVM *vm, const Local<S> &current) : vm_(vm)
2041 {
2042     if (!current.IsEmpty()) {
2043         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*current));
2044     }
2045 }
2046 
2047 template<typename T>
Copy(const CopyableGlobal & that)2048 void CopyableGlobal<T>::Copy(const CopyableGlobal &that)
2049 {
2050     Free();
2051     vm_ = that.vm_;
2052     if (!that.IsEmpty()) {
2053         ECMA_ASSERT(vm_ != nullptr);
2054         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*that));
2055     }
2056 }
2057 
2058 template<typename T>
2059 template<typename S>
Copy(const CopyableGlobal<S> & that)2060 void CopyableGlobal<T>::Copy(const CopyableGlobal<S> &that)
2061 {
2062     Free();
2063     vm_ = that.GetEcmaVM();
2064     if (!that.IsEmpty()) {
2065         ECMA_ASSERT(vm_ != nullptr);
2066         address_ = JSNApi::GetGlobalHandleAddr(vm_, reinterpret_cast<uintptr_t>(*that));
2067     }
2068 }
2069 
2070 template<typename T>
Move(CopyableGlobal & that)2071 void CopyableGlobal<T>::Move(CopyableGlobal &that)
2072 {
2073     Free();
2074     vm_ = that.vm_;
2075     address_ = that.address_;
2076     that.vm_ = nullptr;
2077     that.address_ = 0U;
2078 }
2079 
2080 template<typename T>
Free()2081 inline void CopyableGlobal<T>::Free()
2082 {
2083     if (!IsEmpty()) {
2084         JSNApi::DisposeGlobalHandleAddr(vm_, address_);
2085         address_ = 0U;
2086     }
2087 }
2088 
2089 template <typename T>
SetWeakCallback(void * ref,WeakRefClearCallBack freeGlobalCallBack,WeakRefClearCallBack nativeFinalizeCallback)2090 void CopyableGlobal<T>::SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
2091                                         WeakRefClearCallBack nativeFinalizeCallback)
2092 {
2093     address_ = JSNApi::SetWeakCallback(vm_, address_, ref, freeGlobalCallBack, nativeFinalizeCallback);
2094 }
2095 
2096 template<typename T>
SetWeak()2097 void CopyableGlobal<T>::SetWeak()
2098 {
2099     address_ = JSNApi::SetWeak(vm_, address_);
2100 }
2101 
2102 template<typename T>
ClearWeak()2103 void CopyableGlobal<T>::ClearWeak()
2104 {
2105     address_ = JSNApi::ClearWeak(vm_, address_);
2106 }
2107 
2108 template<typename T>
IsWeak()2109 bool CopyableGlobal<T>::IsWeak() const
2110 {
2111     return JSNApi::IsWeak(vm_, address_);
2112 }
2113 
2114 template<typename T>
Update(const Global & that)2115 void Global<T>::Update(const Global &that)
2116 {
2117     if (address_ != 0) {
2118         JSNApi::DisposeGlobalHandleAddr(vm_, address_);
2119     }
2120     address_ = that.address_;
2121     vm_ = that.vm_;
2122 }
2123 
2124 template<typename T>
FreeGlobalHandleAddr()2125 void Global<T>::FreeGlobalHandleAddr()
2126 {
2127     if (address_ == 0) {
2128         return;
2129     }
2130     JSNApi::DisposeGlobalHandleAddr(vm_, address_);
2131     address_ = 0;
2132 }
2133 
2134 template<typename T>
SetWeak()2135 void Global<T>::SetWeak()
2136 {
2137     address_ = JSNApi::SetWeak(vm_, address_);
2138 }
2139 
2140 template <typename T>
SetWeakCallback(void * ref,WeakRefClearCallBack freeGlobalCallBack,WeakRefClearCallBack nativeFinalizeCallback)2141 void Global<T>::SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
2142                                 WeakRefClearCallBack nativeFinalizeCallback)
2143 {
2144     address_ = JSNApi::SetWeakCallback(vm_, address_, ref, freeGlobalCallBack, nativeFinalizeCallback);
2145 }
2146 
2147 template<typename T>
ClearWeak()2148 void Global<T>::ClearWeak()
2149 {
2150     address_ = JSNApi::ClearWeak(vm_, address_);
2151 }
2152 
2153 template<typename T>
IsWeak()2154 bool Global<T>::IsWeak() const
2155 {
2156     return JSNApi::IsWeak(vm_, address_);
2157 }
2158 
2159 // ---------------------------------- Local --------------------------------------------
2160 template<typename T>
Local(const EcmaVM * vm,const CopyableGlobal<T> & current)2161 Local<T>::Local(const EcmaVM *vm, const CopyableGlobal<T> &current)
2162 {
2163     address_ = JSNApi::GetHandleAddr(vm, reinterpret_cast<uintptr_t>(*current));
2164 }
2165 
2166 template<typename T>
Local(const EcmaVM * vm,const Global<T> & current)2167 Local<T>::Local(const EcmaVM *vm, const Global<T> &current)
2168 {
2169     address_ = JSNApi::GetHandleAddr(vm, reinterpret_cast<uintptr_t>(*current));
2170 }
2171 GLOBAL_PUBLIC_DEF_HYBRID_EXTENSION();
2172 #ifdef PANDA_JS_ETS_HYBRID_MODE
2173     GLOBAL_PUBLIC_DEF_HYBRID_MODE_EXTENSION();
2174 #endif // PANDA_JS_ETS_HYBRID_MODE
2175 }  // namespace panda
2176 #endif
2177