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