• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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/mem/mem_common.h"
32 
33 #ifndef NDEBUG
34 #include "libpandabase/utils/debug.h"
35 #endif
36 
37 #ifdef ERROR
38 #undef ERROR
39 #endif
40 
41 namespace panda {
42 class JSNApiHelper;
43 class EscapeLocalScope;
44 class PromiseRejectInfo;
45 template<typename T>
46 class CopyableGlobal;
47 template<typename T>
48 class Global;
49 class JSNApi;
50 class SymbolRef;
51 template<typename T>
52 class Local;
53 class JSValueRef;
54 class PrimitiveRef;
55 class ArrayRef;
56 class BigIntRef;
57 class StringRef;
58 class ObjectRef;
59 class FunctionRef;
60 class NumberRef;
61 class MapIteratorRef;
62 class BooleanRef;
63 class NativePointerRef;
64 class JsiRuntimeCallInfo;
65 class RuntimeOption;
66 namespace test {
67 class JSNApiTests;
68 }  // namespace test
69 class BufferRef;
70 namespace ecmascript {
71 class EcmaVM;
72 class JSTaggedValue;
73 class EcmaContext;
74 class JSRuntimeOptions;
75 class JSThread;
76 struct EcmaRuntimeCallInfo;
77 namespace base {
78 template<size_t ElementAlign, typename... Ts>
79 struct AlignedStruct;
80 struct AlignedPointer;
81 }
82 }  // namespace ecmascript
83 
84 struct HmsMap {
85     std::string originalPath;
86     std::string targetPath;
87     uint32_t sinceVersion;
88 };
89 
90 using Deleter = void (*)(void *nativePointer, void *data);
91 using WeakRefClearCallBack = void (*)(void *);
92 using EcmaVM = ecmascript::EcmaVM;
93 using EcmaContext = ecmascript::EcmaContext;
94 using JSThread = ecmascript::JSThread;
95 using JSTaggedType = uint64_t;
96 using ConcurrentCallback = void (*)(Local<JSValueRef> result, bool success, void *taskInfo, void *data);
97 using SourceMapCallback = std::function<std::string(const std::string& rawStack)>;
98 using SourceMapTranslateCallback = std::function<bool(std::string& url, int& line, int& column)>;
99 using DeviceDisconnectCallback = std::function<bool()>;
100 
101 #define ECMA_DISALLOW_COPY(className)      \
102     className(const className &) = delete; \
103     className &operator=(const className &) = delete
104 
105 #define ECMA_DISALLOW_MOVE(className) \
106     className(className &&) = delete; \
107     className &operator=(className &&) = delete
108 
109 #ifdef PANDA_TARGET_WINDOWS
110 #define ECMA_PUBLIC_API __declspec(dllexport)
111 #else
112 #define ECMA_PUBLIC_API __attribute__((visibility ("default")))
113 #endif
114 
115 #ifndef NDEBUG
116 #define ECMA_ASSERT(cond) \
117     if (!(cond)) { \
118         panda::debug::AssertionFail(#cond, __FILE__, __LINE__, __FUNCTION__); \
119     }
120 #else
121 #define ECMA_ASSERT(cond) static_cast<void>(0)
122 #endif
123 
124 template<typename T>
125 class ECMA_PUBLIC_API Local {  // NOLINT(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
126 public:
127     inline Local() = default;
128 
129     template<typename S>
Local(const Local<S> & current)130     inline Local(const Local<S> &current) : address_(reinterpret_cast<uintptr_t>(*current))
131     {
132         // Check
133     }
134 
135     Local(const EcmaVM *vm, const Global<T> &current);
136 
137     Local(const EcmaVM *vm, const CopyableGlobal<T> &current);
138 
139     ~Local() = default;
140 
141     inline T *operator*() const
142     {
143         return GetAddress();
144     }
145 
146     inline T *operator->() const
147     {
148         return GetAddress();
149     }
150 
IsEmpty()151     inline bool IsEmpty() const
152     {
153         return GetAddress() == nullptr;
154     }
155 
Empty()156     inline void Empty()
157     {
158         address_ = 0;
159     }
160 
IsNull()161     inline bool IsNull() const
162     {
163         return IsEmpty() || GetAddress()->IsHole();
164     }
165 
Local(uintptr_t addr)166     explicit inline Local(uintptr_t addr) : address_(addr) {}
167 
168 private:
GetAddress()169     inline T *GetAddress() const
170     {
171         return reinterpret_cast<T *>(address_);
172     };
173     uintptr_t address_ = 0U;
174     friend JSNApiHelper;
175     friend EscapeLocalScope;
176     friend JsiRuntimeCallInfo;
177 };
178 
179 /**
180  * A Copyable global handle, keeps a separate global handle for each CopyableGlobal.
181  *
182  * Support Copy Constructor and Assign, Move Constructor And Assign.
183  *
184  * If destructed, the global handle held will be automatically released.
185  *
186  * Usage: It Can be used as heap object assign to another variable, a value passing parameter, or
187  *        a value passing return value and so on.
188  */
189 template<typename T>
190 class ECMA_PUBLIC_API CopyableGlobal {
191 public:
192     inline CopyableGlobal() = default;
~CopyableGlobal()193     ~CopyableGlobal()
194     {
195         Free();
196     }
197 
CopyableGlobal(const CopyableGlobal & that)198     inline CopyableGlobal(const CopyableGlobal &that)
199     {
200         Copy(that);
201     }
202 
203     inline CopyableGlobal &operator=(const CopyableGlobal &that)
204     {
205         Copy(that);
206         return *this;
207     }
208 
CopyableGlobal(CopyableGlobal && that)209     inline CopyableGlobal(CopyableGlobal &&that)
210     {
211         Move(that);
212     }
213 
214     inline CopyableGlobal &operator=(CopyableGlobal &&that)
215     {
216         Move(that);
217         return *this;
218     }
219 
220     template<typename S>
221     CopyableGlobal(const EcmaVM *vm, const Local<S> &current);
222 
223     CopyableGlobal(const EcmaVM *vm, const Local<T> &current);
224 
225     template<typename S>
CopyableGlobal(const CopyableGlobal<S> & that)226     CopyableGlobal(const CopyableGlobal<S> &that)
227     {
228         Copy(that);
229     }
230 
Reset()231     void Reset()
232     {
233         Free();
234     }
235 
ToLocal()236     Local<T> ToLocal() const
237     {
238         if (IsEmpty()) {
239             return Local<T>();
240         }
241         return Local<T>(vm_, *this);
242     }
243 
Empty()244     void Empty()
245     {
246         address_ = 0;
247     }
248 
249     inline T *operator*() const
250     {
251         return GetAddress();
252     }
253 
254     inline T *operator->() const
255     {
256         return GetAddress();
257     }
258 
IsEmpty()259     inline bool IsEmpty() const
260     {
261         return GetAddress() == nullptr;
262     }
263 
264     void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
265                          WeakRefClearCallBack nativeFinalizeCallback);
266     void SetWeak();
267 
268     void ClearWeak();
269 
270     bool IsWeak() const;
271 
GetEcmaVM()272     const EcmaVM *GetEcmaVM() const
273     {
274         return vm_;
275     }
276 
277 private:
GetAddress()278     inline T *GetAddress() const
279     {
280         return reinterpret_cast<T *>(address_);
281     };
282     inline void Copy(const CopyableGlobal &that);
283     template<typename S>
284     inline void Copy(const CopyableGlobal<S> &that);
285     inline void Move(CopyableGlobal &that);
286     inline void Free();
287     uintptr_t address_ = 0U;
288     const EcmaVM *vm_ {nullptr};
289 };
290 
291 template<typename T>
292 class ECMA_PUBLIC_API Global {  // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions
293 public:
294     inline Global() = default;
295 
Global(const Global & that)296     inline Global(const Global &that)
297     {
298         Update(that);
299     }
300 
301     inline Global &operator=(const Global &that)
302     {
303         Update(that);
304         return *this;
305     }
306 
Global(Global && that)307     inline Global(Global &&that)
308     {
309         Update(that);
310     }
311 
312     inline Global &operator=(Global &&that)
313     {
314         Update(that);
315         return *this;
316     }
317 
318     template<typename S>
319     Global(const EcmaVM *vm, const Local<S> &current);
320     template<typename S>
321     Global(const EcmaVM *vm, const Global<S> &current);
322 
323     ~Global() = default;
324 
ToLocal()325     Local<T> ToLocal() const
326     {
327         if (IsEmpty()) {
328             return Local<T>();
329         }
330         return Local<T>(vm_, *this);
331     }
332 
ToLocal(const EcmaVM * vm)333     Local<T> ToLocal(const EcmaVM *vm) const
334     {
335         return Local<T>(vm, *this);
336     }
337 
Empty()338     void Empty()
339     {
340         address_ = 0;
341     }
342 
343     // This method must be called before Global is released.
344     void FreeGlobalHandleAddr();
345 
346     inline T *operator*() const
347     {
348         return GetAddress();
349     }
350 
351     inline T *operator->() const
352     {
353         return GetAddress();
354     }
355 
IsEmpty()356     inline bool IsEmpty() const
357     {
358         return GetAddress() == nullptr;
359     }
360 
361     void SetWeak();
362 
363     void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack,
364                          WeakRefClearCallBack nativeFinalizeCallback);
365 
366     void ClearWeak();
367 
368     bool IsWeak() const;
369 
370 private:
GetAddress()371     inline T *GetAddress() const
372     {
373         return reinterpret_cast<T *>(address_);
374     };
375     inline void Update(const Global &that);
376     uintptr_t address_ = 0U;
377     const EcmaVM *vm_ {nullptr};
378 };
379 
380 class ECMA_PUBLIC_API JSValueRef {
381 public:
382     static Local<PrimitiveRef> Undefined(const EcmaVM *vm);
383     static Local<PrimitiveRef> Null(const EcmaVM *vm);
384     static Local<PrimitiveRef> True(const EcmaVM *vm);
385     static Local<PrimitiveRef> False(const EcmaVM *vm);
386 
387     bool BooleaValue();
388     int64_t IntegerValue(const EcmaVM *vm);
389     uint32_t Uint32Value(const EcmaVM *vm);
390     int32_t Int32Value(const EcmaVM *vm);
391 
392     Local<NumberRef> ToNumber(const EcmaVM *vm);
393     Local<BooleanRef> ToBoolean(const EcmaVM *vm);
394     Local<BigIntRef> ToBigInt(const EcmaVM *vm);
395     Local<StringRef> ToString(const EcmaVM *vm);
396     Local<ObjectRef> ToObject(const EcmaVM *vm);
397     Local<NativePointerRef> ToNativePointer(const EcmaVM *vm);
398 
399     bool IsUndefined();
400     bool IsNull();
401     bool IsHole();
402     bool IsTrue();
403     bool IsFalse();
404     bool IsNumber();
405     bool IsBigInt();
406     bool IsInt();
407     bool WithinInt32();
408     bool IsBoolean();
409     bool IsString();
410     bool IsSymbol();
411     bool IsObject();
412     bool IsArray(const EcmaVM *vm);
413     bool IsJSArray(const EcmaVM *vm);
414     bool IsConstructor();
415     bool IsFunction();
416     bool IsJSFunction();
417     bool IsProxy();
418     bool IsPromise();
419     bool IsDataView();
420     bool IsTypedArray();
421     bool IsNativePointer();
422     bool IsDate();
423     bool IsError();
424     bool IsMap();
425     bool IsSet();
426     bool IsWeakRef();
427     bool IsWeakMap();
428     bool IsWeakSet();
429     bool IsRegExp();
430     bool IsArrayIterator();
431     bool IsStringIterator();
432     bool IsSetIterator();
433     bool IsMapIterator();
434     bool IsArrayBuffer();
435     bool IsBuffer();
436     bool IsUint8Array();
437     bool IsInt8Array();
438     bool IsUint8ClampedArray();
439     bool IsInt16Array();
440     bool IsUint16Array();
441     bool IsInt32Array();
442     bool IsUint32Array();
443     bool IsFloat32Array();
444     bool IsFloat64Array();
445     bool IsBigInt64Array();
446     bool IsBigUint64Array();
447     bool IsJSPrimitiveRef();
448     bool IsJSPrimitiveNumber();
449     bool IsJSPrimitiveInt();
450     bool IsJSPrimitiveBoolean();
451     bool IsJSPrimitiveString();
452 
453     bool IsGeneratorObject();
454     bool IsJSPrimitiveSymbol();
455 
456     bool IsArgumentsObject();
457     bool IsGeneratorFunction();
458     bool IsAsyncFunction();
459     bool IsJSLocale();
460     bool IsJSDateTimeFormat();
461     bool IsJSRelativeTimeFormat();
462     bool IsJSIntl();
463     bool IsJSNumberFormat();
464     bool IsJSCollator();
465     bool IsJSPluralRules();
466     bool IsJSListFormat();
467     bool IsAsyncGeneratorFunction();
468     bool IsAsyncGeneratorObject();
469 
470     bool IsModuleNamespaceObject();
471     bool IsSharedArrayBuffer();
472 
473     bool IsStrictEquals(const EcmaVM *vm, Local<JSValueRef> value);
474     Local<StringRef> Typeof(const EcmaVM *vm);
475     bool InstanceOf(const EcmaVM *vm, Local<JSValueRef> value);
476 
477     bool IsArrayList();
478     bool IsDeque();
479     bool IsHashMap();
480     bool IsHashSet();
481     bool IsLightWeightMap();
482     bool IsLightWeightSet();
483     bool IsLinkedList();
484     bool IsLinkedListIterator();
485     bool IsList();
486     bool IsPlainArray();
487     bool IsQueue();
488     bool IsStack();
489     bool IsTreeMap();
490     bool IsTreeSet();
491     bool IsVector();
492     bool IsSharedObject();
493 
494 private:
495     JSTaggedType value_;
496     friend JSNApi;
497     template<typename T>
498     friend class Global;
499     template<typename T>
500     friend class Local;
501 };
502 
503 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
504 class ECMA_PUBLIC_API PropertyAttribute {
505 public:
Default()506     static PropertyAttribute Default()
507     {
508         return PropertyAttribute();
509     }
510     PropertyAttribute() = default;
PropertyAttribute(Local<JSValueRef> value,bool w,bool e,bool c)511     PropertyAttribute(Local<JSValueRef> value, bool w, bool e, bool c)
512         : value_(value),
513           writable_(w),
514           enumerable_(e),
515           configurable_(c),
516           hasWritable_(true),
517           hasEnumerable_(true),
518           hasConfigurable_(true)
519     {}
520     ~PropertyAttribute() = default;
521 
IsWritable()522     bool IsWritable() const
523     {
524         return writable_;
525     }
SetWritable(bool flag)526     void SetWritable(bool flag)
527     {
528         writable_ = flag;
529         hasWritable_ = true;
530     }
IsEnumerable()531     bool IsEnumerable() const
532     {
533         return enumerable_;
534     }
SetEnumerable(bool flag)535     void SetEnumerable(bool flag)
536     {
537         enumerable_ = flag;
538         hasEnumerable_ = true;
539     }
IsConfigurable()540     bool IsConfigurable() const
541     {
542         return configurable_;
543     }
SetConfigurable(bool flag)544     void SetConfigurable(bool flag)
545     {
546         configurable_ = flag;
547         hasConfigurable_ = true;
548     }
HasWritable()549     bool HasWritable() const
550     {
551         return hasWritable_;
552     }
HasConfigurable()553     bool HasConfigurable() const
554     {
555         return hasConfigurable_;
556     }
HasEnumerable()557     bool HasEnumerable() const
558     {
559         return hasEnumerable_;
560     }
GetValue(const EcmaVM * vm)561     Local<JSValueRef> GetValue(const EcmaVM *vm) const
562     {
563         if (value_.IsEmpty()) {
564             return JSValueRef::Undefined(vm);
565         }
566         return value_;
567     }
SetValue(Local<JSValueRef> value)568     void SetValue(Local<JSValueRef> value)
569     {
570         value_ = value;
571     }
HasValue()572     inline bool HasValue() const
573     {
574         return !value_.IsEmpty();
575     }
GetGetter(const EcmaVM * vm)576     Local<JSValueRef> GetGetter(const EcmaVM *vm) const
577     {
578         if (getter_.IsEmpty()) {
579             return JSValueRef::Undefined(vm);
580         }
581         return getter_;
582     }
SetGetter(Local<JSValueRef> value)583     void SetGetter(Local<JSValueRef> value)
584     {
585         getter_ = value;
586     }
HasGetter()587     bool HasGetter() const
588     {
589         return !getter_.IsEmpty();
590     }
GetSetter(const EcmaVM * vm)591     Local<JSValueRef> GetSetter(const EcmaVM *vm) const
592     {
593         if (setter_.IsEmpty()) {
594             return JSValueRef::Undefined(vm);
595         }
596         return setter_;
597     }
SetSetter(Local<JSValueRef> value)598     void SetSetter(Local<JSValueRef> value)
599     {
600         setter_ = value;
601     }
HasSetter()602     bool HasSetter() const
603     {
604         return !setter_.IsEmpty();
605     }
606 
607 private:
608     Local<JSValueRef> value_;
609     Local<JSValueRef> getter_;
610     Local<JSValueRef> setter_;
611     bool writable_ = false;
612     bool enumerable_ = false;
613     bool configurable_ = false;
614     bool hasWritable_ = false;
615     bool hasEnumerable_ = false;
616     bool hasConfigurable_ = false;
617 };
618 
619 using NativePointerCallback = void (*)(void* value, void* hint);
620 class ECMA_PUBLIC_API NativePointerRef : public JSValueRef {
621 public:
622     static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, size_t nativeBindingsize = 0);
623     static Local<NativePointerRef> New(const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack,
624                                        void *data, size_t nativeBindingsize = 0);
625     void *Value();
626 };
627 
628 class ECMA_PUBLIC_API ObjectRef : public JSValueRef {
629 public:
630     static constexpr int MAX_PROPERTIES_ON_STACK = 32;
Cast(JSValueRef * value)631     static inline ObjectRef *Cast(JSValueRef *value)
632     {
633         return static_cast<ObjectRef *>(value);
634     }
635     static Local<ObjectRef> New(const EcmaVM *vm);
636     static Local<ObjectRef> NewWithProperties(const EcmaVM *vm, size_t propertyCount, const Local<JSValueRef> *keys,
637                                               const PropertyAttribute *attributes);
638     static Local<ObjectRef> NewWithNamedProperties(const EcmaVM *vm, size_t propertyCount, const char **keys,
639                                                    const Local<JSValueRef> *values);
640     static Local<ObjectRef> CreateAccessorData(const EcmaVM *vm, Local<FunctionRef> getter, Local<FunctionRef> setter);
641     bool ConvertToNativeBindingObject(const EcmaVM *vm, Local<NativePointerRef> value);
642     bool Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
643     bool Set(const EcmaVM *vm, uint32_t key, Local<JSValueRef> value);
644     bool SetAccessorProperty(const EcmaVM *vm, Local<JSValueRef> key, Local<FunctionRef> getter,
645                              Local<FunctionRef> setter, PropertyAttribute attribute = PropertyAttribute::Default());
646     Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
647     Local<JSValueRef> Get(const EcmaVM *vm, int32_t key);
648 
649     bool GetOwnProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute &property);
650     Local<ArrayRef> GetOwnPropertyNames(const EcmaVM *vm);
651     Local<ArrayRef> GetAllPropertyNames(const EcmaVM *vm, uint32_t filter);
652     Local<ArrayRef> GetOwnEnumerablePropertyNames(const EcmaVM *vm);
653     Local<JSValueRef> GetPrototype(const EcmaVM *vm);
654     bool SetPrototype(const EcmaVM *vm, Local<ObjectRef> prototype);
655 
656     bool DefineProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute attribute);
657 
658     bool Has(const EcmaVM *vm, Local<JSValueRef> key);
659     bool Has(const EcmaVM *vm, uint32_t key);
660 
661     bool Delete(const EcmaVM *vm, Local<JSValueRef> key);
662     bool Delete(const EcmaVM *vm, uint32_t key);
663 
664     Local<JSValueRef> Freeze(const EcmaVM *vm);
665     Local<JSValueRef> Seal(const EcmaVM *vm);
666 
667     void SetNativePointerFieldCount(const EcmaVM *vm, int32_t count);
668     int32_t GetNativePointerFieldCount();
669     void *GetNativePointerField(int32_t index);
670     void SetNativePointerField(const EcmaVM *vm,
671                                int32_t index,
672                                void *nativePointer = nullptr,
673                                NativePointerCallback callBack = nullptr,
674                                void *data = nullptr, size_t nativeBindingsize = 0);
675 };
676 
677 using FunctionCallback = Local<JSValueRef>(*)(JsiRuntimeCallInfo*);
678 using InternalFunctionCallback = JSValueRef(*)(JsiRuntimeCallInfo*);
679 class ECMA_PUBLIC_API FunctionRef : public ObjectRef {
680 public:
681     static Local<FunctionRef> New(EcmaVM *vm, FunctionCallback nativeFunc, Deleter deleter = nullptr,
682         void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0);
683     static Local<FunctionRef> New(EcmaVM *vm, InternalFunctionCallback nativeFunc, Deleter deleter,
684         void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0);
685     static Local<FunctionRef> NewClassFunction(EcmaVM *vm, FunctionCallback nativeFunc, Deleter deleter,
686         void *data, bool callNapi = false, size_t nativeBindingsize = 0);
687     static Local<FunctionRef> NewClassFunction(EcmaVM *vm, InternalFunctionCallback nativeFunc, Deleter deleter,
688         void *data, bool callNapi = false, size_t nativeBindingsize = 0);
689     JSValueRef* CallForNapi(const EcmaVM *vm, JSValueRef *thisObj, JSValueRef *const argv[],
690         int32_t length);
691     Local<JSValueRef> Call(const EcmaVM *vm, Local<JSValueRef> thisObj, const Local<JSValueRef> argv[],
692         int32_t length);
693     Local<JSValueRef> Constructor(const EcmaVM *vm, const Local<JSValueRef> argv[], int32_t length);
694     JSValueRef* ConstructorOptimize(const EcmaVM *vm, JSValueRef* argv[], int32_t length);
695 
696     Local<JSValueRef> GetFunctionPrototype(const EcmaVM *vm);
697     bool Inherit(const EcmaVM *vm, Local<FunctionRef> parent);
698     void SetName(const EcmaVM *vm, Local<StringRef> name);
699     Local<StringRef> GetName(const EcmaVM *vm);
700     Local<StringRef> GetSourceCode(const EcmaVM *vm, int lineNumber);
701     bool IsNative(const EcmaVM *vm);
702     void SetData(const EcmaVM *vm, void *data, Deleter deleter = nullptr, bool callNapi = false);
703     void* GetData(const EcmaVM *vm);
704 };
705 
706 class ECMA_PUBLIC_API PrimitiveRef : public JSValueRef {
707 public:
708     Local<JSValueRef> GetValue(const EcmaVM *vm);
709 };
710 
711 class ECMA_PUBLIC_API SymbolRef : public PrimitiveRef {
712 public:
713     static Local<SymbolRef> New(const EcmaVM *vm, Local<StringRef> description = Local<StringRef>());
714     Local<StringRef> GetDescription(const EcmaVM *vm);
715 };
716 
717 class ECMA_PUBLIC_API BooleanRef : public PrimitiveRef {
718 public:
719     static Local<BooleanRef> New(const EcmaVM *vm, bool input);
720     bool Value();
721 };
722 
723 class ECMA_PUBLIC_API StringRef : public PrimitiveRef {
724 public:
Cast(JSValueRef * value)725     static inline StringRef *Cast(JSValueRef *value)
726     {
727         // check
728         return static_cast<StringRef *>(value);
729     }
730     static Local<StringRef> NewFromUtf8(const EcmaVM *vm, const char *utf8, int length = -1);
731     static Local<StringRef> NewFromUtf16(const EcmaVM *vm, const char16_t *utf16, int length = -1);
732     std::string ToString();
733     std::string DebuggerToString();
734     uint32_t Length();
735     int32_t Utf8Length(const EcmaVM *vm);
736     int WriteUtf8(char *buffer, int length, bool isWriteBuffer = false);
737     int WriteUtf16(char16_t *buffer, int length);
738     int WriteLatin1(char *buffer, int length);
739     static Local<StringRef> GetNapiWrapperString(const EcmaVM *vm);
740 };
741 
742 class ECMA_PUBLIC_API PromiseRejectInfo {
743 public:
744     enum class ECMA_PUBLIC_API PROMISE_REJECTION_EVENT : uint32_t { REJECT = 0, HANDLE };
745     PromiseRejectInfo(Local<JSValueRef> promise, Local<JSValueRef> reason,
746                       PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data);
~PromiseRejectInfo()747     ~PromiseRejectInfo() {}
748     Local<JSValueRef> GetPromise() const;
749     Local<JSValueRef> GetReason() const;
750     PromiseRejectInfo::PROMISE_REJECTION_EVENT GetOperation() const;
751     void* GetData() const;
752 
753 private:
754     Local<JSValueRef> promise_ {};
755     Local<JSValueRef> reason_ {};
756     PROMISE_REJECTION_EVENT operation_ = PROMISE_REJECTION_EVENT::REJECT;
757     void* data_ {nullptr};
758 };
759 
760 /**
761  * An external exception handler.
762  */
763 class ECMA_PUBLIC_API TryCatch {
764 public:
TryCatch(const EcmaVM * ecmaVm)765     explicit TryCatch(const EcmaVM *ecmaVm) : ecmaVm_(ecmaVm) {};
766 
767     /**
768      * Consumes the exception by default if not rethrow explicitly.
769      */
770     ~TryCatch();
771 
772     bool HasCaught() const;
773     void Rethrow();
774     Local<ObjectRef> GetAndClearException();
775     Local<ObjectRef> GetException();
776     void ClearException();
777 
778     ECMA_DISALLOW_COPY(TryCatch);
779     ECMA_DISALLOW_MOVE(TryCatch);
780 
getrethrow_()781     bool getrethrow_()
782     {
783         return rethrow_;
784     }
785 
786 private:
787     // Disable dynamic allocation
788     void* operator new(size_t size) = delete;
789     void operator delete(void*, size_t) = delete;
790     void* operator new[](size_t size) = delete;
791     void operator delete[](void*, size_t) = delete;
792 
793     const EcmaVM *ecmaVm_ {nullptr};
794     bool rethrow_ {false};
795 };
796 
797 class ECMA_PUBLIC_API BigIntRef : public PrimitiveRef {
798 public:
799     static Local<BigIntRef> New(const EcmaVM *vm, uint64_t input);
800     static Local<BigIntRef> New(const EcmaVM *vm, int64_t input);
801     static Local<JSValueRef> CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words);
802     void BigIntToInt64(const EcmaVM *vm, int64_t *value, bool *lossless);
803     void BigIntToUint64(const EcmaVM *vm, uint64_t *value, bool *lossless);
804     void GetWordsArray(bool* signBit, size_t wordCount, uint64_t* words);
805     uint32_t GetWordsArraySize();
806 };
807 
808 // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions)
809 class ECMA_PUBLIC_API LocalScope {
810 public:
811     explicit LocalScope(const EcmaVM *vm);
812     virtual ~LocalScope();
813 
814 protected:
815     inline LocalScope(const EcmaVM *vm, JSTaggedType value);
816 
817 private:
818     void *prevNext_ = nullptr;
819     void *prevEnd_ = nullptr;
820     int prevHandleStorageIndex_ {-1};
821     void *thread_ = nullptr;
822 };
823 
824 class ECMA_PUBLIC_API EscapeLocalScope final : public LocalScope {
825 public:
826     explicit EscapeLocalScope(const EcmaVM *vm);
827     ~EscapeLocalScope() override = default;
828 
829     ECMA_DISALLOW_COPY(EscapeLocalScope);
830     ECMA_DISALLOW_MOVE(EscapeLocalScope);
831 
832     template<typename T>
Escape(Local<T> current)833     inline Local<T> Escape(Local<T> current)
834     {
835         ECMA_ASSERT(!alreadyEscape_);
836         alreadyEscape_ = true;
837         *(reinterpret_cast<T *>(escapeHandle_)) = **current;
838         return Local<T>(escapeHandle_);
839     }
840 
841 private:
842     bool alreadyEscape_ = false;
843     uintptr_t escapeHandle_ = 0U;
844 };
845 
846 class ECMA_PUBLIC_API IntegerRef : public PrimitiveRef {
847 public:
848     static Local<IntegerRef> New(const EcmaVM *vm, int input);
849     static Local<IntegerRef> NewFromUnsigned(const EcmaVM *vm, unsigned int input);
850     int Value();
851 };
852 
853 class ECMA_PUBLIC_API ArrayBufferRef : public ObjectRef {
854 public:
855     static Local<ArrayBufferRef> New(const EcmaVM *vm, int32_t length);
856     static Local<ArrayBufferRef> New(const EcmaVM *vm, void *buffer, int32_t length, const Deleter &deleter,
857                                      void *data);
858 
859     int32_t ByteLength(const EcmaVM *vm);
860     void *GetBuffer();
861 
862     void Detach(const EcmaVM *vm);
863     bool IsDetach();
864 };
865 
866 class ECMA_PUBLIC_API DateRef : public ObjectRef {
867 public:
868     static Local<DateRef> New(const EcmaVM *vm, double time);
869     Local<StringRef> ToString(const EcmaVM *vm);
870     double GetTime();
871 };
872 
873 class ECMA_PUBLIC_API TypedArrayRef : public ObjectRef {
874 public:
875     uint32_t ByteLength(const EcmaVM *vm);
876     uint32_t ByteOffset(const EcmaVM *vm);
877     uint32_t ArrayLength(const EcmaVM *vm);
878     Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
879 };
880 
881 class ECMA_PUBLIC_API ArrayRef : public ObjectRef {
882 public:
883     static Local<ArrayRef> New(const EcmaVM *vm, uint32_t length = 0);
884     uint32_t Length(const EcmaVM *vm);
885     static bool SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value);
886     static Local<JSValueRef> GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index);
887 };
888 
889 class ECMA_PUBLIC_API Int8ArrayRef : public TypedArrayRef {
890 public:
891     static Local<Int8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
892 };
893 
894 class ECMA_PUBLIC_API Uint8ArrayRef : public TypedArrayRef {
895 public:
896     static Local<Uint8ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
897 };
898 
899 class ECMA_PUBLIC_API Uint8ClampedArrayRef : public TypedArrayRef {
900 public:
901     static Local<Uint8ClampedArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
902                                            int32_t length);
903 };
904 
905 class ECMA_PUBLIC_API Int16ArrayRef : public TypedArrayRef {
906 public:
907     static Local<Int16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
908 };
909 
910 class ECMA_PUBLIC_API Uint16ArrayRef : public TypedArrayRef {
911 public:
912     static Local<Uint16ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
913                                      int32_t length);
914 };
915 
916 class ECMA_PUBLIC_API Int32ArrayRef : public TypedArrayRef {
917 public:
918     static Local<Int32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length);
919 };
920 
921 class ECMA_PUBLIC_API Uint32ArrayRef : public TypedArrayRef {
922 public:
923     static Local<Uint32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
924                                      int32_t length);
925 };
926 
927 class ECMA_PUBLIC_API Float32ArrayRef : public TypedArrayRef {
928 public:
929     static Local<Float32ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
930                                       int32_t length);
931 };
932 
933 class ECMA_PUBLIC_API Float64ArrayRef : public TypedArrayRef {
934 public:
935     static Local<Float64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
936                                       int32_t length);
937 };
938 
939 class ECMA_PUBLIC_API BigInt64ArrayRef : public TypedArrayRef {
940 public:
941     static Local<BigInt64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
942                                       int32_t length);
943 };
944 
945 class ECMA_PUBLIC_API BigUint64ArrayRef : public TypedArrayRef {
946 public:
947     static Local<BigUint64ArrayRef> New(const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset,
948                                       int32_t length);
949 };
950 
951 class ECMA_PUBLIC_API Exception {
952 public:
953     static Local<JSValueRef> Error(const EcmaVM *vm, Local<StringRef> message);
954     static Local<JSValueRef> RangeError(const EcmaVM *vm, Local<StringRef> message);
955     static Local<JSValueRef> ReferenceError(const EcmaVM *vm, Local<StringRef> message);
956     static Local<JSValueRef> SyntaxError(const EcmaVM *vm, Local<StringRef> message);
957     static Local<JSValueRef> TypeError(const EcmaVM *vm, Local<StringRef> message);
958     static Local<JSValueRef> AggregateError(const EcmaVM *vm, Local<StringRef> message);
959     static Local<JSValueRef> EvalError(const EcmaVM *vm, Local<StringRef> message);
960     static Local<JSValueRef> OOMError(const EcmaVM *vm, Local<StringRef> message);
961     static Local<JSValueRef> TerminationError(const EcmaVM *vm, Local<StringRef> message);
962 };
963 
964 class ECMA_PUBLIC_API FunctionCallScope {
965 public:
966     FunctionCallScope(EcmaVM *vm);
967     ~FunctionCallScope();
968 
969 private:
970     EcmaVM *vm_;
971 };
972 
973 class ECMA_PUBLIC_API JSExecutionScope {
974 public:
975     explicit JSExecutionScope(const EcmaVM *vm);
976     ~JSExecutionScope();
977     ECMA_DISALLOW_COPY(JSExecutionScope);
978     ECMA_DISALLOW_MOVE(JSExecutionScope);
979 
980 private:
981     void *lastCurrentThread_ = nullptr;
982     bool isRevert_ = false;
983 };
984 
985 /**
986  * JsiRuntimeCallInfo is used for ace_engine and napi, is same to ark EcamRuntimeCallInfo except data.
987  */
988 class ECMA_PUBLIC_API JsiRuntimeCallInfo
989     : public ecmascript::base::AlignedStruct<ecmascript::base::AlignedPointer::Size(),
990                                              ecmascript::base::AlignedPointer,
991                                              ecmascript::base::AlignedPointer,
992                                              ecmascript::base::AlignedPointer> {
993     enum class Index : size_t {
994         ThreadIndex = 0,
995         NumArgsIndex,
996         StackArgsIndex,
997         NumOfMembers
998     };
999 public:
1000     JsiRuntimeCallInfo() = default;
1001     ~JsiRuntimeCallInfo() = default;
1002 
GetThread()1003     inline JSThread *GetThread() const
1004     {
1005         return thread_;
1006     }
1007 
1008     EcmaVM *GetVM() const;
1009 
GetArgsNumber()1010     inline uint32_t GetArgsNumber() const
1011     {
1012         return numArgs_ - FIRST_ARGS_INDEX;
1013     }
1014 
1015     void* GetData();
1016 
GetFunctionRef()1017     inline Local<JSValueRef> GetFunctionRef() const
1018     {
1019         return GetArgRef(FUNC_INDEX);
1020     }
1021 
GetNewTargetRef()1022     inline Local<JSValueRef> GetNewTargetRef() const
1023     {
1024         return GetArgRef(NEW_TARGET_INDEX);
1025     }
1026 
GetThisRef()1027     inline Local<JSValueRef> GetThisRef() const
1028     {
1029         return GetArgRef(THIS_INDEX);
1030     }
1031 
GetCallArgRef(uint32_t idx)1032     inline Local<JSValueRef> GetCallArgRef(uint32_t idx) const
1033     {
1034         return GetArgRef(FIRST_ARGS_INDEX + idx);
1035     }
1036 
1037 private:
1038     enum ArgsIndex : uint8_t { FUNC_INDEX = 0, NEW_TARGET_INDEX, THIS_INDEX, FIRST_ARGS_INDEX };
1039 
GetArgRef(uint32_t idx)1040     Local<JSValueRef> GetArgRef(uint32_t idx) const
1041     {
1042         return Local<JSValueRef>(GetArgAddress(idx));
1043     }
1044 
GetArgAddress(uint32_t idx)1045     uintptr_t GetArgAddress(uint32_t idx) const
1046     {
1047         if (idx < GetArgsNumber() + FIRST_ARGS_INDEX) {
1048             return reinterpret_cast<uintptr_t>(&stackArgs_[idx]);
1049         }
1050         return 0U;
1051     }
1052 
1053 private:
1054     alignas(sizeof(JSTaggedType)) JSThread *thread_ {nullptr};
1055     alignas(sizeof(JSTaggedType))  uint32_t numArgs_ = 0;
1056     __extension__ alignas(sizeof(JSTaggedType)) JSTaggedType stackArgs_[0];
1057     friend class FunctionRef;
1058 };
1059 
1060 class ECMA_PUBLIC_API MapRef : public ObjectRef {
1061 public:
1062     int32_t GetSize();
1063     int32_t GetTotalElements();
1064     Local<JSValueRef> Get(const EcmaVM *vm, Local<JSValueRef> key);
1065     Local<JSValueRef> GetKey(const EcmaVM *vm, int entry);
1066     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1067     static Local<MapRef> New(const EcmaVM *vm);
1068     void Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value);
1069 };
1070 
1071 class ECMA_PUBLIC_API BufferRef : public ObjectRef {
1072 public:
1073     static Local<BufferRef> New(const EcmaVM *vm, int32_t length);
1074     static Local<BufferRef> New(const EcmaVM *vm, void *buffer, int32_t length, const Deleter &deleter,
1075                                 void *data);
1076 
1077     int32_t ByteLength(const EcmaVM *vm);
1078     void *GetBuffer();
1079     static ecmascript::JSTaggedValue BufferToStringCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo);
1080 };
1081 
1082 class ECMA_PUBLIC_API PromiseRef : public ObjectRef {
1083 public:
1084     Local<PromiseRef> Catch(const EcmaVM *vm, Local<FunctionRef> handler);
1085     Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> handler);
1086     Local<PromiseRef> Finally(const EcmaVM *vm, Local<FunctionRef> handler);
1087     Local<PromiseRef> Then(const EcmaVM *vm, Local<FunctionRef> onFulfilled, Local<FunctionRef> onRejected);
1088 
1089     Local<JSValueRef> GetPromiseState(const EcmaVM *vm);
1090     Local<JSValueRef> GetPromiseResult(const EcmaVM *vm);
1091 };
1092 
1093 class ECMA_PUBLIC_API PromiseCapabilityRef : public ObjectRef {
1094 public:
1095     static Local<PromiseCapabilityRef> New(const EcmaVM *vm);
1096     bool Resolve(const EcmaVM *vm, Local<JSValueRef> value);
1097     bool Reject(const EcmaVM *vm, Local<JSValueRef> reason);
1098     Local<PromiseRef> GetPromise(const EcmaVM *vm);
1099 };
1100 
1101 class ECMA_PUBLIC_API NumberRef : public PrimitiveRef {
1102 public:
1103     static Local<NumberRef> New(const EcmaVM *vm, double input);
1104     static Local<NumberRef> New(const EcmaVM *vm, int32_t input);
1105     static Local<NumberRef> New(const EcmaVM *vm, uint32_t input);
1106     static Local<NumberRef> New(const EcmaVM *vm, int64_t input);
1107 
1108     double Value();
1109 };
1110 
1111 class ECMA_PUBLIC_API DataViewRef : public ObjectRef {
1112 public:
1113     static Local<DataViewRef> New(const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, uint32_t byteOffset,
1114                                   uint32_t byteLength);
1115     uint32_t ByteLength();
1116     uint32_t ByteOffset();
1117     Local<ArrayBufferRef> GetArrayBuffer(const EcmaVM *vm);
1118 };
1119 
1120 class ECMA_PUBLIC_API MapIteratorRef : public ObjectRef {
1121 public:
1122     int32_t GetIndex();
1123     Local<JSValueRef> GetKind(const EcmaVM *vm);
1124     static Local<MapIteratorRef> New(const EcmaVM *vm, Local<MapRef> map);
1125     ecmascript::EcmaRuntimeCallInfo* GetEcmaRuntimeCallInfo(const EcmaVM *vm);
1126     static Local<ArrayRef> Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo* ecmaRuntimeCallInfo);
1127 };
1128 
1129 class ECMA_PUBLIC_API JSNApi {
1130 public:
1131     struct DebugOption {
1132         const char *libraryPath;
1133         bool isDebugMode = false;
1134         int port = -1;
1135     };
1136     using DebuggerPostTask = std::function<void(std::function<void()>&&)>;
1137 
1138     using UncatchableErrorHandler = std::function<void(panda::TryCatch&)>;
1139 
1140     struct NativeBindingInfo {
CreateNewInstanceNativeBindingInfo1141         static NativeBindingInfo* CreateNewInstance() { return new(std::nothrow) NativeBindingInfo(); }
1142         void *env = nullptr;
1143         void *nativeValue = nullptr;
1144         void *attachFunc = nullptr;
1145         void *attachData = nullptr;
1146         void *detachFunc = nullptr;
1147         void *detachData = nullptr;
1148         void *hint = nullptr;
1149     };
1150 
1151     // JSVM
1152     // fixme: Rename SEMI_GC to YOUNG_GC
1153     enum class ECMA_PUBLIC_API TRIGGER_GC_TYPE : uint8_t { SEMI_GC, OLD_GC, FULL_GC };
1154 
1155     enum class PatchErrorCode : uint8_t {
1156         SUCCESS = 0,
1157         PATCH_HAS_LOADED,
1158         PATCH_NOT_LOADED,
1159         FILE_NOT_EXECUTED,
1160         FILE_NOT_FOUND,
1161         PACKAGE_NOT_ESMODULE,
1162         MODIFY_IMPORT_EXPORT_NOT_SUPPORT,
1163         INTERNAL_ERROR
1164     };
1165 
1166     static EcmaVM *CreateJSVM(const RuntimeOption &option);
1167     static void DestroyJSVM(EcmaVM *ecmaVm);
1168     static void RegisterUncatchableErrorHandler(EcmaVM *ecmaVm, const UncatchableErrorHandler &handler);
1169 
1170     // aot load
1171     static void LoadAotFile(EcmaVM *vm, const std::string &moduleName);
1172     // context
1173     static EcmaContext *CreateJSContext(EcmaVM *vm);
1174     static void SwitchCurrentContext(EcmaVM *vm, EcmaContext *context);
1175     static void DestroyJSContext(EcmaVM *vm, EcmaContext *context);
1176 
1177     // context execute
1178     static bool ExecuteInContext(EcmaVM *vm, const std::string &fileName, const std::string &entry,
1179                                  bool needUpdate = false);
1180     // JS code
1181     static bool Execute(EcmaVM *vm, const std::string &fileName, const std::string &entry, bool needUpdate = false);
1182     static bool Execute(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &entry,
1183                         const std::string &filename = "", bool needUpdate = false);
1184     // merge abc, execute module buffer
1185     static bool ExecuteModuleBuffer(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &filename = "",
1186                                     bool needUpdate = false);
1187     static bool ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file);
1188     static Local<ObjectRef> GetExportObject(EcmaVM *vm, const std::string &file, const std::string &key);
1189     static Local<ObjectRef> GetExportObjectFromBuffer(EcmaVM *vm, const std::string &file, const std::string &key);
1190     static Local<ObjectRef> ExecuteNativeModule(EcmaVM *vm, const std::string &key);
1191     // secure memory check
1192     static bool CheckSecureMem(uintptr_t mem);
1193 
1194     /*
1195      * Execute panda file from secure mem. secure memory lifecycle managed externally.
1196      * The data parameter needs to be created externally by an external caller and managed externally
1197      * by the external caller. The size parameter is the size of the data memory. The entry parameter
1198      * is the name of the entry function. The filename parameter is used to uniquely identify this
1199      * memory internally.
1200      */
1201     static bool ExecuteSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &entry,
1202                                 const std::string &filename = "", bool needUpdate = false);
1203     /*
1204      * Execute panda file(merge abc) from secure mem. secure memory lifecycle managed externally.
1205      * The data parameter needs to be created externally by an external caller and managed externally
1206      * by the external caller. The size parameter is the size of the data memory. The filename parameter
1207      * is used to uniquely identify this memory internally.
1208      */
1209     static bool ExecuteModuleBufferSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &filename = "",
1210                                           bool needUpdate = false);
1211 
1212     // ObjectRef Operation
1213     static Local<ObjectRef> GetGlobalObject(const EcmaVM *vm);
1214     static void ExecutePendingJob(const EcmaVM *vm);
1215 
1216     // Memory
1217     // fixme: Rename SEMI_GC to YOUNG_GC
1218     static void TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC);
1219     // Exception
1220     static void ThrowException(const EcmaVM *vm, Local<JSValueRef> error);
1221     static void PrintExceptionInfo(const EcmaVM *vm);
1222     static Local<ObjectRef> GetAndClearUncaughtException(const EcmaVM *vm);
1223     static Local<ObjectRef> GetUncaughtException(const EcmaVM *vm);
1224     static bool IsExecutingPendingJob(const EcmaVM *vm);
1225     static bool HasPendingException(const EcmaVM *vm);
1226     static bool HasPendingJob(const EcmaVM *vm);
1227     static void EnableUserUncaughtErrorHandler(EcmaVM *vm);
1228     // prevewer debugger.
1229     static bool StartDebugger(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0,
1230         const DebuggerPostTask &debuggerPostTask = {});
1231     // To be compatible with the old process.
1232     static bool StartDebuggerForOldProcess(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0,
1233         const DebuggerPostTask &debuggerPostTask = {});
1234     // socketpair process in ohos platform.
1235     static bool StartDebuggerForSocketPair(int tid, int socketfd = -1);
1236     static bool StopDebugger(int tid);
1237     static bool NotifyDebugMode(int tid, EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0,
1238                                 const DebuggerPostTask &debuggerPostTask = {}, bool debugApp = false);
1239     static bool StoreDebugInfo(
1240         int tid, EcmaVM *vm, const DebugOption &option, const DebuggerPostTask &debuggerPostTask, bool debugApp);
1241     static bool StopDebugger(EcmaVM *vm);
1242     static bool IsMixedDebugEnabled(const EcmaVM *vm);
1243     static void NotifyNativeCalling(const EcmaVM *vm, const void *nativeAddress);
1244     static void NotifyNativeReturn(const EcmaVM *vm, const void *nativeAddress);
1245     static void NotifyLoadModule(const EcmaVM *vm);
1246     static void SetDeviceDisconnectCallback(EcmaVM *vm, DeviceDisconnectCallback cb);
1247     // Serialize & Deserialize.
1248     static void* SerializeValue(const EcmaVM *vm, Local<JSValueRef> data, Local<JSValueRef> transfer,
1249                                 Local<JSValueRef> cloneList,
1250                                 bool defaultTransfer = false,
1251                                 bool defaultCloneShared = true);
1252     static Local<JSValueRef> DeserializeValue(const EcmaVM *vm, void *recoder, void *hint);
1253     static void DeleteSerializationData(void *data);
1254     static void SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data);
1255     static void SetHostResolveBufferTracker(EcmaVM *vm,
1256         std::function<bool(std::string dirPath, uint8_t **buff, size_t *buffSize)> cb);
1257     static void SetUnloadNativeModuleCallback(EcmaVM *vm, const std::function<bool(const std::string &moduleKey)> &cb);
1258     static void SetNativePtrGetter(EcmaVM *vm, void* cb);
1259     static void SetSourceMapCallback(EcmaVM *vm, SourceMapCallback cb);
1260     static void SetSourceMapTranslateCallback(EcmaVM *vm, SourceMapTranslateCallback cb);
1261     static void SetHostEnqueueJob(const EcmaVM* vm, Local<JSValueRef> cb);
1262     static void InitializeIcuData(const ecmascript::JSRuntimeOptions &options);
1263     static void InitializeMemMapAllocator();
1264     static void InitializePGOProfiler(const ecmascript::JSRuntimeOptions &options);
1265     static void DestroyAnDataManager();
1266     static void DestroyMemMapAllocator();
1267     static void DestroyPGOProfiler();
1268     static EcmaVM* CreateEcmaVM(const ecmascript::JSRuntimeOptions &options);
1269     static void PreFork(EcmaVM *vm);
1270     static void PostFork(EcmaVM *vm, const RuntimeOption &option);
1271     static void AddWorker(EcmaVM *hostVm, EcmaVM *workerVm);
1272     static bool DeleteWorker(EcmaVM *hostVm, EcmaVM *workerVm);
1273     static void GetStackBeforeCallNapiSuccess(EcmaVM *vm, bool &getStackBeforeCallNapiSuccess);
1274     static void GetStackAfterCallNapi(EcmaVM *vm);
1275 
1276     static PatchErrorCode LoadPatch(EcmaVM *vm, const std::string &patchFileName, const std::string &baseFileName);
1277     static PatchErrorCode LoadPatch(EcmaVM *vm,
1278                                     const std::string &patchFileName, const void *patchBuffer, size_t patchSize,
1279                                     const std::string &baseFileName, const void *baseBuffer, size_t baseSize);
1280     static PatchErrorCode UnloadPatch(EcmaVM *vm, const std::string &patchFileName);
1281     // check whether the exception is caused by quickfix methods.
1282     static bool IsQuickFixCausedException(EcmaVM *vm, Local<ObjectRef> exception, const std::string &patchFileName);
1283     // register quickfix query function.
1284     static void RegisterQuickFixQueryFunc(EcmaVM *vm, std::function<bool(std::string baseFileName,
1285                         std::string &patchFileName,
1286                         void **patchBuffer,
1287                         size_t &patchSize)> callBack);
1288     static bool IsBundle(EcmaVM *vm);
1289     static void SetBundle(EcmaVM *vm, bool value);
1290     static void SetAssetPath(EcmaVM *vm, const std::string &assetPath);
1291     static void SetMockModuleList(EcmaVM *vm, const std::map<std::string, std::string> &list);
1292     static void SetHmsModuleList(EcmaVM *vm, const std::vector<panda::HmsMap> &list);
1293     static void SetModuleInfo(EcmaVM *vm, const std::string &assetPath, const std::string &entryPoint);
1294 
1295     static void SetLoop(EcmaVM *vm, void *loop);
1296     static std::string GetAssetPath(EcmaVM *vm);
1297     static bool InitForConcurrentThread(EcmaVM *vm, ConcurrentCallback cb, void *data);
1298     static bool InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> func, void *taskInfo);
1299     static void* GetCurrentTaskInfo(const EcmaVM *vm);
1300     static void SetBundleName(EcmaVM *vm, const std::string &bundleName);
1301     static std::string GetBundleName(EcmaVM *vm);
1302     static void SetModuleName(EcmaVM *vm, const std::string &moduleName);
1303     static std::string GetModuleName(EcmaVM *vm);
1304     static std::pair<std::string, std::string> GetCurrentModuleInfo(EcmaVM *vm, bool needRecordName = false);
1305     static void AllowCrossThreadExecution(EcmaVM *vm);
1306     static void SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM);
1307     static bool IsProfiling(EcmaVM *vm);
1308     static void SetProfilerState(const EcmaVM *vm, bool value);
1309     static void SetRequestAotCallback(EcmaVM *vm, const std::function<int32_t(const std::string &bundleName,
1310                     const std::string &moduleName,
1311                     int32_t triggerMode)> &cb);
1312     static void SetSearchHapPathTracker(EcmaVM *vm, std::function<bool(const std::string moduleName,
1313                     std::string &hapPath)> cb);
1314 
1315 private:
1316     static int vmCount_;
1317     static bool initialize_;
1318     static bool CreateRuntime(const RuntimeOption &option);
1319     static bool DestroyRuntime();
1320 
1321     static uintptr_t GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress);
1322     static uintptr_t GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress);
1323     static uintptr_t SetWeak(const EcmaVM *vm, uintptr_t localAddress);
1324     static uintptr_t SetWeakCallback(const EcmaVM *vm, uintptr_t localAddress, void *ref,
1325                                      WeakRefClearCallBack freeGlobalCallBack,
1326                                      WeakRefClearCallBack nativeFinalizeCallback);
1327     static uintptr_t ClearWeak(const EcmaVM *vm, uintptr_t localAddress);
1328     static bool IsWeak(const EcmaVM *vm, uintptr_t localAddress);
1329     static void DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr);
1330     template<typename T>
1331     friend class Global;
1332     template<typename T>
1333     friend class CopyableGlobal;
1334     template<typename T>
1335     friend class Local;
1336     friend class test::JSNApiTests;
1337 };
1338 
1339 class ECMA_PUBLIC_API ProxyRef : public ObjectRef {
1340 public:
1341     Local<JSValueRef> GetHandler(const EcmaVM *vm);
1342     Local<JSValueRef> GetTarget(const EcmaVM *vm);
1343     bool IsRevoked();
1344 };
1345 
1346 class ECMA_PUBLIC_API WeakMapRef : public ObjectRef {
1347 public:
1348     int32_t GetSize();
1349     int32_t GetTotalElements();
1350     Local<JSValueRef> GetKey(const EcmaVM *vm, int entry);
1351     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1352     static Local<WeakMapRef> New(const EcmaVM *vm);
1353     void Set(const EcmaVM *vm, const Local<JSValueRef> &key, const Local<JSValueRef> &value);
1354     bool Has(const EcmaVM *vm, Local<JSValueRef> key);
1355 };
1356 
1357 class ECMA_PUBLIC_API SetRef : public ObjectRef {
1358 public:
1359     int32_t GetSize();
1360     int32_t GetTotalElements();
1361     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1362     static Local<SetRef> New(const EcmaVM *vm);
1363     void Add(const EcmaVM *vm, Local<JSValueRef> value);
1364 };
1365 
1366 class ECMA_PUBLIC_API WeakSetRef : public ObjectRef {
1367 public:
1368     int32_t GetSize();
1369     int32_t GetTotalElements();
1370     Local<JSValueRef> GetValue(const EcmaVM *vm, int entry);
1371     static Local<WeakSetRef> New(const EcmaVM *vm);
1372     void Add(const EcmaVM *vm, Local<JSValueRef> value);
1373 };
1374 
1375 class ECMA_PUBLIC_API SetIteratorRef : public ObjectRef {
1376 public:
1377     int32_t GetIndex();
1378     Local<JSValueRef> GetKind(const EcmaVM *vm);
1379     static Local<SetIteratorRef> New(const EcmaVM *vm, Local<SetRef> set);
1380     ecmascript::EcmaRuntimeCallInfo *GetEcmaRuntimeCallInfo(const EcmaVM *vm);
1381     static Local<ArrayRef> Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo);
1382 };
1383 }
1384 #endif