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