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