/* * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ECMASCRIPT_NAPI_INCLUDE_JSNAPI_EXPO_H #define ECMASCRIPT_NAPI_INCLUDE_JSNAPI_EXPO_H #include #include #include #include #include #include #include #include #include #include "ecmascript/base/aligned_struct.h" #include "ecmascript/base/config.h" #include "ecmascript/mem/mem_common.h" #include "ecmascript/common_enum.h" #include "ecmascript/module/js_module_execute_type.h" #ifndef NDEBUG #include "libpandabase/utils/debug.h" #endif #ifdef ERROR #undef ERROR #endif namespace panda { class JSNApiHelper; class EscapeLocalScope; class PromiseRejectInfo; template class CopyableGlobal; template class Global; class JSNApi; class SymbolRef; template class Local; class JSValueRef; class PrimitiveRef; class ArrayRef; class BigIntRef; class StringRef; class ObjectRef; class FunctionRef; class NumberRef; class MapIteratorRef; class SendableMapIteratorRef; class BooleanRef; class NativePointerRef; class TypedArrayRef; class JsiRuntimeCallInfo; class RuntimeOption; namespace test { class JSNApiTests; } // namespace test class BufferRef; namespace ecmascript { class EcmaVM; class JSTaggedValue; class EcmaContext; class JSRuntimeOptions; class JSThread; struct EcmaRuntimeCallInfo; namespace base { template struct AlignedStruct; struct AlignedPointer; } namespace job { enum class QueueType : uint8_t { QUEUE_PROMISE, QUEUE_SCRIPT, }; } } // namespace ecmascript struct HmsMap { std::string originalPath; std::string targetPath; uint32_t sinceVersion; }; using WeakRefClearCallBack = void (*)(void *); using WeakFinalizeTaskCallback = std::function; using NativePointerCallback = void (*)(void *env, void* data, void* hint); using NativePointerCallbackFinishNotify = std::function; using NativePointerCallbackData = std::pair>; using TriggerGCData = std::pair; using TriggerGCTaskCallback = std::function; using StartIdleMonitorCallback = std::function; using EcmaVM = ecmascript::EcmaVM; using EcmaContext = ecmascript::EcmaContext; using JSThread = ecmascript::JSThread; using JSTaggedType = uint64_t; using ConcurrentCallback = void (*)(Local result, bool success, void *taskInfo, void *data); using SourceMapCallback = std::function; using TimerCallbackFunc = void (*)(void *data); using TimerTaskCallback = void* (*)(EcmaVM *vm, void *data, TimerCallbackFunc func, uint64_t timeout, bool repeat); using CancelTimerCallback = void (*)(void *timerCallbackInfo); using SourceMapTranslateCallback = std::function; using DeviceDisconnectCallback = std::function; using QueueType = ecmascript::job::QueueType; using OnErrorCallback = std::function value, void *data)>; using StopPreLoadSoCallback = std::function; #define ECMA_DISALLOW_COPY(className) \ className(const className &) = delete; \ className &operator=(const className &) = delete #define ECMA_DISALLOW_MOVE(className) \ className(className &&) = delete; \ className &operator=(className &&) = delete #ifdef PANDA_TARGET_WINDOWS #define ECMA_PUBLIC_API __declspec(dllexport) #else #define ECMA_PUBLIC_API __attribute__((visibility ("default"))) #endif #ifndef NDEBUG #define ECMA_ASSERT(cond) \ if (!(cond)) { \ panda::debug::AssertionFail(#cond, __FILE__, __LINE__, __FUNCTION__); \ } #else #define ECMA_ASSERT(cond) static_cast(0) #endif #define INIT_CRASH_HOLDER(holder, tag) \ ArkCrashHolder holder(tag, __FUNCTION__) class ECMA_PUBLIC_API ArkCrashHolder { public: ArkCrashHolder(const std::string& tag, const std::string& info) { SetCrashObj(tag.c_str(), info.c_str()); } ArkCrashHolder(const char* tag, const char* info) { SetCrashObj(tag, info); } ~ArkCrashHolder(); void UpdateCallbackPtr(uintptr_t addr); private: void SetCrashObj(const char* tag, const char* info); uintptr_t handle_ {0}; char* data_ {nullptr}; size_t size_ {0}; }; class ECMA_PUBLIC_API AsyncNativeCallbacksPack { public: AsyncNativeCallbacksPack() = default; ~AsyncNativeCallbacksPack() = default; AsyncNativeCallbacksPack(AsyncNativeCallbacksPack&&) = default; AsyncNativeCallbacksPack& operator=(AsyncNativeCallbacksPack&&) = default; AsyncNativeCallbacksPack(const AsyncNativeCallbacksPack &) = default; AsyncNativeCallbacksPack &operator=(const AsyncNativeCallbacksPack &) = default; void Clear() { callBacks_.clear(); totalBindingSize_ = 0; notify_ = nullptr; } bool TotallyEmpty() const { return callBacks_.empty() && totalBindingSize_ == 0 && notify_ == nullptr; } bool Empty() const { return callBacks_.empty(); } void RegisterFinishNotify(NativePointerCallbackFinishNotify notify) { notify_ = notify; } size_t GetNumCallBacks() const { return callBacks_.size(); } void ProcessAll(const char* tag) { INIT_CRASH_HOLDER(holder, tag); for (auto &iter : callBacks_) { NativePointerCallback callback = iter.first; std::tuple ¶m = iter.second; if (callback != nullptr) { holder.UpdateCallbackPtr(reinterpret_cast(callback)); callback(std::get<0>(param), std::get<1>(param), std::get<2>(param)); // 2 is the param. } } NotifyFinish(); } size_t GetTotalBindingSize() const { return totalBindingSize_; } void AddCallback(NativePointerCallbackData callback, size_t bindingSize) { callBacks_.emplace_back(callback); totalBindingSize_ += bindingSize; } private: void NotifyFinish() const { if (notify_ != nullptr) { notify_(totalBindingSize_); } } std::vector callBacks_ {}; size_t totalBindingSize_ {0}; NativePointerCallbackFinishNotify notify_ {nullptr}; }; using NativePointerTaskCallback = std::function; template class ECMA_PUBLIC_API Local { // NOLINT(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) public: inline Local() = default; template inline Local(const Local ¤t) : address_(reinterpret_cast(*current)) { // Check } Local(const EcmaVM *vm, const Global ¤t); Local(const EcmaVM *vm, const CopyableGlobal ¤t); ~Local() = default; inline T *operator*() const { return GetAddress(); } inline T *operator->() const { return GetAddress(); } inline bool IsEmpty() const { return GetAddress() == nullptr; } inline void Empty() { address_ = 0; } inline bool IsNull() const { return IsEmpty() || GetAddress()->IsHole(); } explicit inline Local(uintptr_t addr) : address_(addr) {} private: inline T *GetAddress() const { return reinterpret_cast(address_); }; uintptr_t address_ = 0U; friend JSNApiHelper; friend EscapeLocalScope; friend JsiRuntimeCallInfo; }; /** * A Copyable global handle, keeps a separate global handle for each CopyableGlobal. * * Support Copy Constructor and Assign, Move Constructor And Assign. * * If destructed, the global handle held will be automatically released. * * Usage: It Can be used as heap object assign to another variable, a value passing parameter, or * a value passing return value and so on. */ template class ECMA_PUBLIC_API CopyableGlobal { public: inline CopyableGlobal() = default; ~CopyableGlobal() { Free(); } inline CopyableGlobal(const CopyableGlobal &that) { Copy(that); } inline CopyableGlobal &operator=(const CopyableGlobal &that) { Copy(that); return *this; } inline CopyableGlobal(CopyableGlobal &&that) { Move(that); } inline CopyableGlobal &operator=(CopyableGlobal &&that) { Move(that); return *this; } template CopyableGlobal(const EcmaVM *vm, const Local ¤t); CopyableGlobal(const EcmaVM *vm, const Local ¤t); template CopyableGlobal(const CopyableGlobal &that) { Copy(that); } void Reset() { Free(); } Local ToLocal() const { if (IsEmpty()) { return Local(); } return Local(vm_, *this); } void Empty() { address_ = 0; } inline T *operator*() const { return GetAddress(); } inline T *operator->() const { return GetAddress(); } inline bool IsEmpty() const { return GetAddress() == nullptr; } void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack, WeakRefClearCallBack nativeFinalizeCallback); void SetWeak(); void ClearWeak(); bool IsWeak() const; const EcmaVM *GetEcmaVM() const { return vm_; } private: inline T *GetAddress() const { return reinterpret_cast(address_); }; inline void Copy(const CopyableGlobal &that); template inline void Copy(const CopyableGlobal &that); inline void Move(CopyableGlobal &that); inline void Free(); uintptr_t address_ = 0U; const EcmaVM *vm_ {nullptr}; }; template class ECMA_PUBLIC_API Global { // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions public: inline Global() = default; inline Global(const Global &that) { Update(that); } inline Global &operator=(const Global &that) { Update(that); return *this; } inline Global(Global &&that) { Update(that); } inline Global &operator=(Global &&that) { Update(that); return *this; } template Global(const EcmaVM *vm, const Local ¤t); template Global(const EcmaVM *vm, const Global ¤t); ~Global() = default; Local ToLocal() const { if (IsEmpty()) { return Local(); } return Local(vm_, *this); } Local ToLocal(const EcmaVM *vm) const { return Local(vm, *this); } void Empty() { address_ = 0; } // This method must be called before Global is released. void FreeGlobalHandleAddr(); inline T *operator*() const { return GetAddress(); } inline T *operator->() const { return GetAddress(); } inline bool IsEmpty() const { return GetAddress() == nullptr; } void SetWeak(); void SetWeakCallback(void *ref, WeakRefClearCallBack freeGlobalCallBack, WeakRefClearCallBack nativeFinalizeCallback); void ClearWeak(); bool IsWeak() const; const EcmaVM *GetEcmaVM() const { return vm_; } private: inline T *GetAddress() const { return reinterpret_cast(address_); }; inline void Update(const Global &that); uintptr_t address_ = 0U; const EcmaVM *vm_ {nullptr}; }; class ECMA_PUBLIC_API JSValueRef { public: static Local Undefined(const EcmaVM *vm); static Local Null(const EcmaVM *vm); static Local Hole(const EcmaVM *vm); static Local True(const EcmaVM *vm); static Local False(const EcmaVM *vm); bool BooleaValue(const EcmaVM *vm); int64_t IntegerValue(const EcmaVM *vm); uint32_t Uint32Value(const EcmaVM *vm); int32_t Int32Value(const EcmaVM *vm); double GetValueDouble(bool &isNumber); int32_t GetValueInt32(bool &isNumber); uint32_t GetValueUint32(bool &isNumber); int64_t GetValueInt64(bool &isNumber); bool GetValueBool(bool &isBool); Local ToNumber(const EcmaVM *vm); Local ToBoolean(const EcmaVM *vm); Local ToBigInt(const EcmaVM *vm); Local ToString(const EcmaVM *vm); Local ToObject(const EcmaVM *vm); Local ToEcmaObject(const EcmaVM *vm); Local ToNativePointer(const EcmaVM *vm); bool IsUndefined(); bool IsNull(); bool IsHole(); bool IsTrue(); bool IsFalse(); bool IsNumber(); bool IsBigInt(const EcmaVM *vm); bool IsInt(); bool WithinInt32(); bool IsBoolean(); bool IsString(const EcmaVM *vm); bool IsSymbol(const EcmaVM *vm); bool IsObject(const EcmaVM *vm); bool IsNativeBindingObject(const EcmaVM *vm); bool IsArray(const EcmaVM *vm); bool IsJSArray(const EcmaVM *vm); bool IsConstructor(const EcmaVM *vm); bool IsFunction(const EcmaVM *vm); bool IsJSFunction(const EcmaVM *vm); bool IsProxy(const EcmaVM *vm); bool IsPromise(const EcmaVM *vm); bool IsDataView(const EcmaVM *vm); bool IsTypedArray(const EcmaVM *vm); bool IsNativePointer(const EcmaVM *vm); bool IsDate(const EcmaVM *vm); bool IsError(const EcmaVM *vm); bool IsMap(const EcmaVM *vm); bool IsSet(const EcmaVM *vm); bool IsWeakRef(const EcmaVM *vm); bool IsWeakMap(const EcmaVM *vm); bool IsWeakSet(const EcmaVM *vm); bool IsRegExp(const EcmaVM *vm); bool IsArrayIterator(const EcmaVM *vm); bool IsStringIterator(const EcmaVM *vm); bool IsSetIterator(const EcmaVM *vm); bool IsMapIterator(const EcmaVM *vm); bool IsArrayBuffer(const EcmaVM *vm); bool IsBuffer(const EcmaVM *vm); bool IsUint8Array(const EcmaVM *vm); bool IsInt8Array(const EcmaVM *vm); bool IsUint8ClampedArray(const EcmaVM *vm); bool IsInt16Array(const EcmaVM *vm); bool IsUint16Array(const EcmaVM *vm); bool IsInt32Array(const EcmaVM *vm); bool IsUint32Array(const EcmaVM *vm); bool IsFloat32Array(const EcmaVM *vm); bool IsFloat64Array(const EcmaVM *vm); bool IsBigInt64Array(const EcmaVM *vm); bool IsBigUint64Array(const EcmaVM *vm); bool IsJSPrimitiveRef(const EcmaVM *vm); bool IsJSPrimitiveNumber(const EcmaVM *vm); bool IsJSPrimitiveInt(const EcmaVM *vm); bool IsJSPrimitiveBoolean(const EcmaVM *vm); bool IsJSPrimitiveString(const EcmaVM *vm); bool IsJSSharedInt8Array(const EcmaVM *vm); bool IsJSSharedUint8Array(const EcmaVM *vm); bool IsJSSharedUint8ClampedArray(const EcmaVM *vm); bool IsJSSharedInt16Array(const EcmaVM *vm); bool IsJSSharedUint16Array(const EcmaVM *vm); bool IsJSSharedInt32Array(const EcmaVM *vm); bool IsJSSharedUint32Array(const EcmaVM *vm); bool IsJSSharedFloat32Array(const EcmaVM *vm); bool IsJSSharedFloat64Array(const EcmaVM *vm); bool IsJSSharedBigInt64Array(const EcmaVM *vm); bool IsJSSharedBigUint64Array(const EcmaVM *vm); bool IsGeneratorObject(const EcmaVM *vm); bool IsJSPrimitiveSymbol(const EcmaVM *vm); bool IsArgumentsObject(const EcmaVM *vm); bool IsGeneratorFunction(const EcmaVM *vm); bool IsAsyncFunction(const EcmaVM *vm); bool IsConcurrentFunction(const EcmaVM *vm); bool IsJSLocale(const EcmaVM *vm); bool IsJSDateTimeFormat(const EcmaVM *vm); bool IsJSRelativeTimeFormat(const EcmaVM *vm); bool IsJSIntl(const EcmaVM *vm); bool IsJSNumberFormat(const EcmaVM *vm); bool IsJSCollator(const EcmaVM *vm); bool IsJSPluralRules(const EcmaVM *vm); bool IsJSListFormat(const EcmaVM *vm); bool IsAsyncGeneratorFunction(const EcmaVM *vm); bool IsAsyncGeneratorObject(const EcmaVM *vm); bool IsModuleNamespaceObject(const EcmaVM *vm); bool IsNativeModuleFailureInfoObject(const EcmaVM *vm); bool IsSharedArrayBuffer(const EcmaVM *vm); bool IsSendableArrayBuffer(const EcmaVM *vm); bool IsStrictEquals(const EcmaVM *vm, Local value); Local Typeof(const EcmaVM *vm); bool InstanceOf(const EcmaVM *vm, Local value); bool IsArrayList(const EcmaVM *vm); bool IsDeque(const EcmaVM *vm); bool IsHashMap(const EcmaVM *vm); bool IsHashSet(const EcmaVM *vm); bool IsLightWeightMap(const EcmaVM *vm); bool IsLightWeightSet(const EcmaVM *vm); bool IsLinkedList(const EcmaVM *vm); bool IsLinkedListIterator(const EcmaVM *vm); bool IsList(const EcmaVM *vm); bool IsPlainArray(const EcmaVM *vm); bool IsQueue(const EcmaVM *vm); bool IsStack(const EcmaVM *vm); bool IsTreeMap(const EcmaVM *vm); bool IsTreeSet(const EcmaVM *vm); bool IsVector(const EcmaVM *vm); bool IsBitVector(const EcmaVM *vm); bool IsSendableObject(const EcmaVM *vm); bool IsJSShared(const EcmaVM *vm); bool IsSharedArray(const EcmaVM *vm); bool IsSharedTypedArray(const EcmaVM *vm); bool IsSharedSet(const EcmaVM *vm); bool IsSharedMap(const EcmaVM *vm); bool IsSharedMapIterator(const EcmaVM *vm); bool IsHeapObject(); void *GetNativePointerValue(const EcmaVM *vm, bool &isNativePointer); bool IsDetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer); void DetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer); void GetDataViewInfo(const EcmaVM *vm, bool &isDataView, size_t *byteLength, void **data, JSValueRef **arrayBuffer, size_t *byteOffset); void TryGetArrayLength(const EcmaVM *vm, bool *isPendingException, bool *isArrayOrSharedArray, uint32_t *arrayLength); private: JSTaggedType value_; friend JSNApi; template friend class Global; template friend class Local; void *GetNativePointerValueImpl(const EcmaVM *vm, bool &isNativePointer); }; // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) class ECMA_PUBLIC_API PropertyAttribute { public: static PropertyAttribute Default() { return PropertyAttribute(); } PropertyAttribute() = default; PropertyAttribute(Local value, bool w, bool e, bool c) : value_(value), writable_(w), enumerable_(e), configurable_(c), hasWritable_(true), hasEnumerable_(true), hasConfigurable_(true) {} ~PropertyAttribute() = default; bool IsWritable() const { return writable_; } void SetWritable(bool flag) { writable_ = flag; hasWritable_ = true; } bool IsEnumerable() const { return enumerable_; } void SetEnumerable(bool flag) { enumerable_ = flag; hasEnumerable_ = true; } bool IsConfigurable() const { return configurable_; } void SetConfigurable(bool flag) { configurable_ = flag; hasConfigurable_ = true; } bool HasWritable() const { return hasWritable_; } bool HasConfigurable() const { return hasConfigurable_; } bool HasEnumerable() const { return hasEnumerable_; } Local GetValue(const EcmaVM *vm) const { if (value_.IsEmpty()) { return JSValueRef::Undefined(vm); } return value_; } void SetValue(Local value) { value_ = value; } inline bool HasValue() const { return !value_.IsEmpty(); } Local GetGetter(const EcmaVM *vm) const { if (getter_.IsEmpty()) { return JSValueRef::Undefined(vm); } return getter_; } void SetGetter(Local value) { getter_ = value; } bool HasGetter() const { return !getter_.IsEmpty(); } Local GetSetter(const EcmaVM *vm) const { if (setter_.IsEmpty()) { return JSValueRef::Undefined(vm); } return setter_; } void SetSetter(Local value) { setter_ = value; } bool HasSetter() const { return !setter_.IsEmpty(); } private: Local value_; Local getter_; Local setter_; bool writable_ = false; bool enumerable_ = false; bool configurable_ = false; bool hasWritable_ = false; bool hasEnumerable_ = false; bool hasConfigurable_ = false; }; class ECMA_PUBLIC_API NativePointerRef : public JSValueRef { public: static Local New(const EcmaVM *vm, void *nativePointer, size_t nativeBindingsize = 0); static Local New(const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, void *data, size_t nativeBindingsize = 0); static Local NewConcurrent(const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, void *data, size_t nativeBindingsize = 0); static Local NewSendable(const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack = nullptr, void *data = nullptr, size_t nativeBindingsize = 0); void *Value(); }; class ECMA_PUBLIC_API ObjectRef : public JSValueRef { public: enum class SendableType { NONE, OBJECT, GENERIC, }; struct SendablePropertiesInfo { std::vector> keys; std::vector types; std::vector attributes; }; static constexpr int MAX_PROPERTIES_ON_STACK = 32; static inline ObjectRef *Cast(JSValueRef *value) { return static_cast(value); } static Local New(const EcmaVM *vm); static uintptr_t NewObject(const EcmaVM *vm); static Local NewS(const EcmaVM *vm); static Local NewWithProperties(const EcmaVM *vm, size_t propertyCount, const Local *keys, const PropertyAttribute *attributes); static Local NewSWithProperties(const EcmaVM *vm, SendablePropertiesInfo &info); static Local NewWithNamedProperties(const EcmaVM *vm, size_t propertyCount, const char **keys, const Local *values); static Local CreateNativeModuleFailureInfo(const EcmaVM *vm, const std::string &failureInfo); static Local CreateAccessorData(const EcmaVM *vm, Local getter, Local setter); static Local CreateSendableAccessorData(const EcmaVM *vm, Local getter, Local setter); bool ConvertToNativeBindingObject(const EcmaVM *vm, Local value); Local GetNativeBindingPointer(const EcmaVM *vm); bool Set(const EcmaVM *vm, Local key, Local value); bool Set(const EcmaVM *vm, const char *utf8, Local value); bool Set(const EcmaVM *vm, uint32_t key, Local value); bool SetAccessorProperty(const EcmaVM *vm, Local key, Local getter, Local setter, PropertyAttribute attribute = PropertyAttribute::Default()); Local Get(const EcmaVM *vm, Local key); Local Get(const EcmaVM *vm, const char *utf8); Local Get(const EcmaVM *vm, int32_t key); bool GetOwnProperty(const EcmaVM *vm, Local key, PropertyAttribute &property); Local GetOwnPropertyNames(const EcmaVM *vm); Local GetAllPropertyNames(const EcmaVM *vm, uint32_t filter); Local GetOwnEnumerablePropertyNames(const EcmaVM *vm); Local GetPrototype(const EcmaVM *vm); bool SetPrototype(const EcmaVM *vm, Local prototype); bool DefineProperty(const EcmaVM *vm, Local key, PropertyAttribute attribute); bool Has(const EcmaVM *vm, Local key); bool Has(const EcmaVM *vm, uint32_t key); bool HasOwnProperty(const EcmaVM *vm, Local key); bool Delete(const EcmaVM *vm, Local key); bool Delete(const EcmaVM *vm, uint32_t key); Local Freeze(const EcmaVM *vm); Local Seal(const EcmaVM *vm); void SetNativePointerFieldCount(const EcmaVM *vm, int32_t count); int32_t GetNativePointerFieldCount(const EcmaVM *vm); void *GetNativePointerField(const EcmaVM *vm, int32_t index); void SetNativePointerField(const EcmaVM *vm, int32_t index, void *nativePointer = nullptr, NativePointerCallback callBack = nullptr, void *data = nullptr, size_t nativeBindingsize = 0); void SetConcurrentNativePointerField(const EcmaVM *vm, int32_t index, void *nativePointer = nullptr, NativePointerCallback callBack = nullptr, void *data = nullptr, size_t nativeBindingsize = 0); }; using FunctionCallback = Local(*)(JsiRuntimeCallInfo*); using InternalFunctionCallback = JSValueRef(*)(JsiRuntimeCallInfo*); class ECMA_PUBLIC_API FunctionRef : public ObjectRef { public: struct SendablePropertiesInfos { SendablePropertiesInfo instancePropertiesInfo; SendablePropertiesInfo staticPropertiesInfo; SendablePropertiesInfo nonStaticPropertiesInfo; }; static Local New(EcmaVM *vm, FunctionCallback nativeFunc, NativePointerCallback deleter = nullptr, void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0); static Local NewConcurrent(EcmaVM *vm, FunctionCallback nativeFunc, NativePointerCallback deleter = nullptr, void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0); static Local New(EcmaVM *vm, InternalFunctionCallback nativeFunc, NativePointerCallback deleter, void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0); static Local NewConcurrent(EcmaVM *vm, InternalFunctionCallback nativeFunc, NativePointerCallback deleter, void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0); static Local NewSendable(EcmaVM *vm, InternalFunctionCallback nativeFunc, NativePointerCallback deleter, void *data = nullptr, bool callNapi = false, size_t nativeBindingsize = 0); static Local NewClassFunction(EcmaVM *vm, FunctionCallback nativeFunc, NativePointerCallback deleter, void *data, bool callNapi = false, size_t nativeBindingsize = 0); static Local NewConcurrentClassFunction(EcmaVM *vm, InternalFunctionCallback nativeFunc, NativePointerCallback deleter, void *data, bool callNapi = false, size_t nativeBindingsize = 0); static Local NewClassFunction(EcmaVM *vm, InternalFunctionCallback nativeFunc, NativePointerCallback deleter, void *data, bool callNapi = false, size_t nativeBindingsize = 0); static Local NewSendableClassFunction(const EcmaVM *vm, InternalFunctionCallback nativeFunc, NativePointerCallback deleter, void *data, Local name, SendablePropertiesInfos &infos, Local parent, bool callNapi = false, size_t nativeBindingsize = 0); JSValueRef* CallForNapi(const EcmaVM *vm, JSValueRef *thisObj, JSValueRef *const argv[], int32_t length); Local Call(const EcmaVM *vm, Local thisObj, const Local argv[], int32_t length); Local Constructor(const EcmaVM *vm, const Local argv[], int32_t length); JSValueRef* ConstructorOptimize(const EcmaVM *vm, JSValueRef* argv[], int32_t length); Local GetFunctionPrototype(const EcmaVM *vm); bool Inherit(const EcmaVM *vm, Local parent); void SetName(const EcmaVM *vm, Local name); Local GetName(const EcmaVM *vm); Local GetSourceCode(const EcmaVM *vm, int lineNumber); bool IsNative(const EcmaVM *vm); void SetData(const EcmaVM *vm, void *data, NativePointerCallback deleter = nullptr, bool callNapi = false); void* GetData(const EcmaVM *vm); }; class ECMA_PUBLIC_API PrimitiveRef : public JSValueRef { public: Local GetValue(const EcmaVM *vm); }; class ECMA_PUBLIC_API SymbolRef : public PrimitiveRef { public: static Local New(const EcmaVM *vm, Local description = Local()); Local GetDescription(const EcmaVM *vm); }; class ECMA_PUBLIC_API BooleanRef : public PrimitiveRef { public: static Local New(const EcmaVM *vm, bool input); bool Value(); }; class ECMA_PUBLIC_API StringRef : public PrimitiveRef { public: static inline StringRef *Cast(JSValueRef *value) { // check return static_cast(value); } static Local NewFromUtf8WithoutStringTable(const EcmaVM *vm, const char *utf8, int length = -1); static Local NewFromUtf8(const EcmaVM *vm, const char *utf8, int length = -1); static Local NewFromUtf16WithoutStringTable(const EcmaVM *vm, const char16_t *utf16, int length = -1); static Local NewFromUtf16(const EcmaVM *vm, const char16_t *utf16, int length = -1); std::string ToString(const EcmaVM *vm); std::string DebuggerToString(const EcmaVM *vm); uint32_t Length(const EcmaVM *vm); size_t Utf8Length(const EcmaVM *vm, bool isGetBufferSize = false); uint32_t WriteUtf8(const EcmaVM *vm, char *buffer, uint32_t length, bool isWriteBuffer = false); uint32_t WriteUtf16(const EcmaVM *vm, char16_t *buffer, uint32_t length); uint32_t WriteLatin1(const EcmaVM *vm, char *buffer, uint32_t length); static Local GetNapiWrapperString(const EcmaVM *vm); Local EncodeIntoUint8Array(const EcmaVM *vm); }; class ECMA_PUBLIC_API PromiseRejectInfo { public: enum class ECMA_PUBLIC_API PROMISE_REJECTION_EVENT : uint32_t { REJECT = 0, HANDLE }; PromiseRejectInfo(Local promise, Local reason, PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data); ~PromiseRejectInfo() {} Local GetPromise() const; Local GetReason() const; PromiseRejectInfo::PROMISE_REJECTION_EVENT GetOperation() const; void* GetData() const; private: Local promise_ {}; Local reason_ {}; PROMISE_REJECTION_EVENT operation_ = PROMISE_REJECTION_EVENT::REJECT; void* data_ {nullptr}; }; /** * An external exception handler. */ class ECMA_PUBLIC_API TryCatch { public: explicit TryCatch(const EcmaVM *ecmaVm) : ecmaVm_(ecmaVm) {}; /** * Consumes the exception by default if not rethrow explicitly. */ ~TryCatch(); bool HasCaught() const; void Rethrow(); Local GetAndClearException(); Local GetException(); void ClearException(); ECMA_DISALLOW_COPY(TryCatch); ECMA_DISALLOW_MOVE(TryCatch); bool getrethrow_() { return rethrow_; } private: // Disable dynamic allocation void* operator new(size_t size) = delete; void operator delete(void*, size_t) = delete; void* operator new[](size_t size) = delete; void operator delete[](void*, size_t) = delete; const EcmaVM *ecmaVm_ {nullptr}; bool rethrow_ {false}; }; class ECMA_PUBLIC_API BigIntRef : public PrimitiveRef { public: static Local New(const EcmaVM *vm, uint64_t input); static Local New(const EcmaVM *vm, int64_t input); static Local CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words); void BigIntToInt64(const EcmaVM *vm, int64_t *value, bool *lossless); void BigIntToUint64(const EcmaVM *vm, uint64_t *value, bool *lossless); void GetWordsArray(const EcmaVM *vm, bool* signBit, size_t wordCount, uint64_t* words); uint32_t GetWordsArraySize(const EcmaVM *vm); }; // NOLINTNEXTLINE(cppcoreguidelines-special-member-functions, hicpp-special-member-functions) class ECMA_PUBLIC_API LocalScope { public: explicit LocalScope(const EcmaVM *vm); virtual ~LocalScope(); protected: inline LocalScope(const EcmaVM *vm, JSTaggedType value); private: void *prevNext_ = nullptr; void *prevEnd_ = nullptr; int prevHandleStorageIndex_ {-1}; void *prevPrimitiveNext_ = nullptr; void *prevPrimitiveEnd_ = nullptr; int prevPrimitiveStorageIndex_ {-1}; void *thread_ = nullptr; }; class ECMA_PUBLIC_API EscapeLocalScope final : public LocalScope { public: explicit EscapeLocalScope(const EcmaVM *vm); ~EscapeLocalScope() override = default; ECMA_DISALLOW_COPY(EscapeLocalScope); ECMA_DISALLOW_MOVE(EscapeLocalScope); template inline Local Escape(Local current) { ECMA_ASSERT(!alreadyEscape_); alreadyEscape_ = true; *(reinterpret_cast(escapeHandle_)) = **current; return Local(escapeHandle_); } private: bool alreadyEscape_ = false; uintptr_t escapeHandle_ = 0U; }; class ECMA_PUBLIC_API IntegerRef : public PrimitiveRef { public: static Local New(const EcmaVM *vm, int input); static Local NewFromUnsigned(const EcmaVM *vm, unsigned int input); int Value(); }; class ECMA_PUBLIC_API ArrayBufferRef : public ObjectRef { public: static Local New(const EcmaVM *vm, int32_t length); static Local New(const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter, void *data); int32_t ByteLength(const EcmaVM *vm); void *GetBuffer(const EcmaVM *vm); void Detach(const EcmaVM *vm); bool IsDetach(const EcmaVM *vm); }; class ECMA_PUBLIC_API SendableArrayBufferRef : public ObjectRef { public: static Local New(const EcmaVM *vm, int32_t length); static Local New(const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter, void *data); int32_t ByteLength(const EcmaVM *vm); void *GetBuffer(const EcmaVM *vm); void Detach(const EcmaVM *vm); bool IsDetach(const EcmaVM *vm); }; class ECMA_PUBLIC_API DateRef : public ObjectRef { public: static Local New(const EcmaVM *vm, double time); Local ToString(const EcmaVM *vm); double GetTime(const EcmaVM *vm); }; class ECMA_PUBLIC_API TypedArrayRef : public ObjectRef { public: uint32_t ByteLength(const EcmaVM *vm); uint32_t ByteOffset(const EcmaVM *vm); uint32_t ArrayLength(const EcmaVM *vm); Local GetArrayBuffer(const EcmaVM *vm); }; class ECMA_PUBLIC_API SendableTypedArrayRef : public ObjectRef { public: uint32_t ByteLength(const EcmaVM *vm); uint32_t ByteOffset(const EcmaVM *vm); uint32_t ArrayLength(const EcmaVM *vm); Local GetArrayBuffer(const EcmaVM *vm); }; class ECMA_PUBLIC_API ArrayRef : public ObjectRef { public: static Local New(const EcmaVM *vm, uint32_t length = 0); uint32_t Length(const EcmaVM *vm); static bool SetValueAt(const EcmaVM *vm, Local obj, uint32_t index, Local value); static Local GetValueAt(const EcmaVM *vm, Local obj, uint32_t index); }; class ECMA_PUBLIC_API SendableArrayRef : public ObjectRef { public: static Local New(const EcmaVM *vm, uint32_t length = 0); uint32_t Length(const EcmaVM *vm); static Local GetValueAt(const EcmaVM *vm, Local obj, uint32_t index); static bool SetProperty(const EcmaVM *vm, Local obj, uint32_t index, Local value); }; class ECMA_PUBLIC_API Int8ArrayRef : public TypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API SharedInt8ArrayRef : public SendableTypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API Uint8ArrayRef : public TypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API SharedUint8ArrayRef : public SendableTypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API Uint8ClampedArrayRef : public TypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API Int16ArrayRef : public TypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API SharedInt16ArrayRef : public SendableTypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API Uint16ArrayRef : public TypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API SharedUint16ArrayRef : public SendableTypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API Int32ArrayRef : public TypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API SharedInt32ArrayRef : public SendableTypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API SharedFloat32ArrayRef : public SendableTypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API SharedUint8ClampedArrayRef : public SendableTypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API Uint32ArrayRef : public TypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API SharedUint32ArrayRef : public SendableTypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API Float32ArrayRef : public TypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API Float64ArrayRef : public TypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API SharedFloat64ArrayRef : public SendableTypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API BigInt64ArrayRef : public TypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API SharedBigInt64ArrayRef : public SendableTypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API BigUint64ArrayRef : public TypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API SharedBigUint64ArrayRef : public SendableTypedArrayRef { public: static Local New(const EcmaVM *vm, Local buffer, int32_t byteOffset, int32_t length); }; class ECMA_PUBLIC_API Exception { public: static Local Error(const EcmaVM *vm, Local message); static Local RangeError(const EcmaVM *vm, Local message); static Local ReferenceError(const EcmaVM *vm, Local message); static Local SyntaxError(const EcmaVM *vm, Local message); static Local TypeError(const EcmaVM *vm, Local message); static Local AggregateError(const EcmaVM *vm, Local message); static Local EvalError(const EcmaVM *vm, Local message); static Local OOMError(const EcmaVM *vm, Local message); static Local TerminationError(const EcmaVM *vm, Local message); }; class ECMA_PUBLIC_API FunctionCallScope { public: FunctionCallScope(EcmaVM *vm); ~FunctionCallScope(); private: EcmaVM *vm_; }; class ECMA_PUBLIC_API JSExecutionScope { public: explicit JSExecutionScope(const EcmaVM *vm); ~JSExecutionScope(); ECMA_DISALLOW_COPY(JSExecutionScope); ECMA_DISALLOW_MOVE(JSExecutionScope); private: void *lastCurrentThread_ = nullptr; bool isRevert_ = false; }; class ECMA_PUBLIC_API JsiNativeScope { public: explicit JsiNativeScope(const EcmaVM *vm); ~JsiNativeScope(); ECMA_DISALLOW_COPY(JsiNativeScope); ECMA_DISALLOW_MOVE(JsiNativeScope); private: JSThread *thread_; uint16_t oldThreadState_; }; class ECMA_PUBLIC_API JsiFastNativeScope { public: explicit JsiFastNativeScope(const EcmaVM *vm); ~JsiFastNativeScope(); ECMA_DISALLOW_COPY(JsiFastNativeScope); ECMA_DISALLOW_MOVE(JsiFastNativeScope); private: JSThread *thread_ {nullptr}; uint16_t oldThreadState_ {0}; bool hasSwitchState_ {false}; }; /** * JsiRuntimeCallInfo is used for ace_engine and napi, is same to ark EcamRuntimeCallInfo except data. */ class ECMA_PUBLIC_API JsiRuntimeCallInfo : public ecmascript::base::AlignedStruct { enum class Index : size_t { ThreadIndex = 0, NumArgsIndex, StackArgsIndex, NumOfMembers }; public: JsiRuntimeCallInfo() = default; ~JsiRuntimeCallInfo() = default; inline JSThread *GetThread() const { return thread_; } EcmaVM *GetVM() const; inline uint32_t GetArgsNumber() const { ECMA_ASSERT(numArgs_ >= FIRST_ARGS_INDEX); return numArgs_ - FIRST_ARGS_INDEX; } void* GetData(); inline Local GetFunctionRef() const { return GetArgRef(FUNC_INDEX); } inline Local GetNewTargetRef() const { return GetArgRef(NEW_TARGET_INDEX); } inline Local GetThisRef() const { return GetArgRef(THIS_INDEX); } inline Local GetCallArgRef(uint32_t idx) const { return GetArgRef(FIRST_ARGS_INDEX + idx); } private: enum ArgsIndex : uint8_t { FUNC_INDEX = 0, NEW_TARGET_INDEX, THIS_INDEX, FIRST_ARGS_INDEX }; Local GetArgRef(uint32_t idx) const { return Local(GetArgAddress(idx)); } uintptr_t GetArgAddress(uint32_t idx) const { if (idx < GetArgsNumber() + FIRST_ARGS_INDEX) { return reinterpret_cast(&stackArgs_[idx]); } return 0U; } private: alignas(sizeof(JSTaggedType)) JSThread *thread_ {nullptr}; alignas(sizeof(JSTaggedType)) uint32_t numArgs_ = 0; __extension__ alignas(sizeof(JSTaggedType)) JSTaggedType stackArgs_[0]; friend class FunctionRef; }; class ECMA_PUBLIC_API MapRef : public ObjectRef { public: int32_t GetSize(const EcmaVM *vm); int32_t GetTotalElements(const EcmaVM *vm); Local Get(const EcmaVM *vm, Local key); Local Get(const EcmaVM *vm, const char *utf8); Local GetKey(const EcmaVM *vm, int entry); Local GetValue(const EcmaVM *vm, int entry); static Local New(const EcmaVM *vm); void Set(const EcmaVM *vm, Local key, Local value); void Set(const EcmaVM *vm, const char *utf8, Local value); bool Has(const EcmaVM *vm, Local key); bool Has(const EcmaVM *vm, const char *utf8); void Delete(const EcmaVM *vm, Local key); void Clear(const EcmaVM *vm); Local GetEntries(const EcmaVM *vm); Local GetKeys(const EcmaVM *vm); Local GetValues(const EcmaVM *vm); }; class ECMA_PUBLIC_API SendableMapRef : public ObjectRef { public: static Local New(const EcmaVM *vm); uint32_t GetSize(const EcmaVM *vm); uint32_t GetTotalElements(const EcmaVM *vm); Local Get(const EcmaVM *vm, Local key); Local Get(const EcmaVM *vm, const char *utf8); Local GetKey(const EcmaVM *vm, int entry); Local GetValue(const EcmaVM *vm, int entry); void Set(const EcmaVM *vm, Local key, Local value); void Set(const EcmaVM *vm, const char *utf8, Local value); bool Has(const EcmaVM *vm, Local key); bool Has(const EcmaVM *vm, const char *utf8); void Delete(const EcmaVM *vm, Local key); void Clear(const EcmaVM *vm); Local GetEntries(const EcmaVM *vm); Local GetKeys(const EcmaVM *vm); Local GetValues(const EcmaVM *vm); }; class ECMA_PUBLIC_API SendableSetRef : public ObjectRef { public: static Local New(const EcmaVM *vm); uint32_t GetSize(const EcmaVM *vm); uint32_t GetTotalElements(const EcmaVM *vm); Local GetValue(const EcmaVM *vm, int entry); void Add(const EcmaVM *vm, Local value); }; class ECMA_PUBLIC_API BufferRef : public ObjectRef { public: static Local New(const EcmaVM *vm, int32_t length); static Local New(const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter, void *data); int32_t ByteLength(const EcmaVM *vm); void *GetBuffer(const EcmaVM *vm); static ecmascript::JSTaggedValue BufferToStringCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo); }; class ECMA_PUBLIC_API PromiseRef : public ObjectRef { public: Local Catch(const EcmaVM *vm, Local handler); Local Then(const EcmaVM *vm, Local handler); Local Finally(const EcmaVM *vm, Local handler); Local Then(const EcmaVM *vm, Local onFulfilled, Local onRejected); Local GetPromiseState(const EcmaVM *vm); Local GetPromiseResult(const EcmaVM *vm); }; class ECMA_PUBLIC_API PromiseCapabilityRef : public ObjectRef { public: static Local New(const EcmaVM *vm); bool Resolve(const EcmaVM *vm, uintptr_t value); bool Resolve(const EcmaVM *vm, Local value); bool Reject(const EcmaVM *vm, uintptr_t reason); bool Reject(const EcmaVM *vm, Local reason); Local GetPromise(const EcmaVM *vm); }; class ECMA_PUBLIC_API NumberRef : public PrimitiveRef { public: static Local New(const EcmaVM *vm, double input); static Local New(const EcmaVM *vm, int32_t input); static Local New(const EcmaVM *vm, uint32_t input); static Local New(const EcmaVM *vm, int64_t input); double Value(); }; class ECMA_PUBLIC_API DataViewRef : public ObjectRef { public: static Local New(const EcmaVM *vm, Local arrayBuffer, uint32_t byteOffset, uint32_t byteLength); uint32_t ByteLength(); uint32_t ByteOffset(); Local GetArrayBuffer(const EcmaVM *vm); }; class ECMA_PUBLIC_API MapIteratorRef : public ObjectRef { public: int32_t GetIndex(); Local GetKind(const EcmaVM *vm); static Local New(const EcmaVM *vm, Local map); ecmascript::EcmaRuntimeCallInfo* GetEcmaRuntimeCallInfo(const EcmaVM *vm); static Local Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo* ecmaRuntimeCallInfo); Local Next(const EcmaVM *vm); }; class ECMA_PUBLIC_API SendableMapIteratorRef : public ObjectRef { public: Local Next(const EcmaVM *vm); }; class ECMA_PUBLIC_API JSNApi { public: struct DebugOption { const char *libraryPath; bool isDebugMode = false; int port = -1; bool isFaApp = false; }; using DebuggerPostTask = std::function&&)>; using UncatchableErrorHandler = std::function; struct NativeBindingInfo { static NativeBindingInfo* CreateNewInstance() { return new(std::nothrow) NativeBindingInfo(); } void *env = nullptr; void *nativeValue = nullptr; void *attachFunc = nullptr; void *attachData = nullptr; void *detachFunc = nullptr; void *detachData = nullptr; void *hint = nullptr; void *detachedFinalizer = nullptr; void *detachedHint = nullptr; }; // JSVM // fixme: Rename SEMI_GC to YOUNG_GC enum class ECMA_PUBLIC_API TRIGGER_GC_TYPE : uint8_t { SEMI_GC, OLD_GC, FULL_GC, SHARED_GC, SHARED_FULL_GC }; enum class ECMA_PUBLIC_API TRIGGER_IDLE_GC_TYPE : uint8_t { LOCAL_CONCURRENT_YOUNG_MARK = 1, LOCAL_CONCURRENT_FULL_MARK = 1 << 1, LOCAL_REMARK = 1 << 2, FULL_GC = 1 << 3, SHARED_CONCURRENT_MARK = 1 << 4, SHARED_CONCURRENT_PARTIAL_MARK = 1 << 5, SHARED_FULL_GC = 1 << 6, }; enum class ECMA_PUBLIC_API MemoryReduceDegree : uint8_t { LOW = 0, MIDDLE, HIGH, }; enum class PatchErrorCode : uint8_t { SUCCESS = 0, PATCH_HAS_LOADED, PATCH_NOT_LOADED, FILE_NOT_EXECUTED, FILE_NOT_FOUND, PACKAGE_NOT_ESMODULE, MODIFY_IMPORT_EXPORT_NOT_SUPPORT, INTERNAL_ERROR }; static EcmaVM *CreateJSVM(const RuntimeOption &option); static void DestroyJSVM(EcmaVM *ecmaVm); static void RegisterUncatchableErrorHandler(EcmaVM *ecmaVm, const UncatchableErrorHandler &handler); // aot load static void LoadAotFileInternal(EcmaVM *vm, const std::string &moduleName, std::string &aotFileName); static void LoadAotFile(EcmaVM *vm, const std::string &moduleName); #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) static void LoadAotFile(EcmaVM *vm, [[maybe_unused]] const std::string &bundleName, const std::string &moduleName, std::function cb); #endif // context static EcmaContext *CreateJSContext(EcmaVM *vm); static void SwitchCurrentContext(EcmaVM *vm, EcmaContext *context); static void DestroyJSContext(EcmaVM *vm, EcmaContext *context); // context execute static bool ExecuteInContext(EcmaVM *vm, const std::string &fileName, const std::string &entry, bool needUpdate = false); // JS code static bool ExecuteForAbsolutePath(const EcmaVM *vm, const std::string &fileName, const std::string &entry, bool needUpdate = false, const ecmascript::ExecuteTypes &executeType = ecmascript::ExecuteTypes::STATIC); static bool Execute(const EcmaVM *vm, const std::string &fileName, const std::string &entry, bool needUpdate = false, const ecmascript::ExecuteTypes &executeType = ecmascript::ExecuteTypes::STATIC); static bool Execute(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &entry, const std::string &filename = "", bool needUpdate = false); static int ExecuteWithSingletonPatternFlag(EcmaVM *vm, const std::string &bundleName, const std::string &moduleName, const std::string &ohmurl, bool isSingletonPattern); static bool IsExecuteModuleInAbcFile(EcmaVM *vm, const std::string &bundleName, const std::string &moduleName, const std::string &ohmurl); // merge abc, execute module buffer static bool ExecuteModuleBuffer(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &filename = "", bool needUpdate = false); static bool ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file); static Local GetExportObject(EcmaVM *vm, const std::string &file, const std::string &key); static Local GetExportObjectFromBuffer(EcmaVM *vm, const std::string &file, const std::string &key); static Local GetExportObjectFromOhmUrl(EcmaVM *vm, const std::string &ohmUrl, const std::string &key); static Local ExecuteNativeModule(EcmaVM *vm, const std::string &key); static Local GetModuleNameSpaceFromFile(EcmaVM *vm, const std::string &file); static Local GetModuleNameSpaceWithModuleInfo(EcmaVM *vm, const std::string &file, const std::string &module_path); /* * Execute panda file from secure mem. secure memory lifecycle managed externally. * The data parameter needs to be created externally by an external caller and managed externally * by the external caller. The size parameter is the size of the data memory. The entry parameter * is the name of the entry function. The filename parameter is used to uniquely identify this * memory internally. */ static bool ExecuteSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &entry, const std::string &filename = "", bool needUpdate = false); /* * Execute panda file(merge abc) from secure mem. secure memory lifecycle managed externally. * The data parameter needs to be created externally by an external caller and managed externally * by the external caller. The size parameter is the size of the data memory. The filename parameter * is used to uniquely identify this memory internally. */ static bool ExecuteModuleBufferSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &filename = "", bool needUpdate = false); static bool ExecuteSecureWithOhmUrl(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &srcFilename, const std::string &ohmUrl); // ObjectRef Operation static Local GetGlobalObject(const EcmaVM *vm); static void ExecutePendingJob(const EcmaVM *vm); // Memory // fixme: Rename SEMI_GC to YOUNG_GC static void TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC); static void TriggerGC(const EcmaVM *vm, ecmascript::GCReason reason, TRIGGER_GC_TYPE gcType = TRIGGER_GC_TYPE::SEMI_GC); static void HintGC(const EcmaVM *vm, MemoryReduceDegree degree, ecmascript::GCReason reason); static void TriggerIdleGC(const EcmaVM *vm, TRIGGER_IDLE_GC_TYPE gcType); static void SetStartIdleMonitorCallback(const StartIdleMonitorCallback& callback); static StartIdleMonitorCallback GetStartIdleMonitorCallback(); // Exception static void ThrowException(const EcmaVM *vm, Local error); static void PrintExceptionInfo(const EcmaVM *vm); static void SetOnErrorCallback(EcmaVM *vm, OnErrorCallback cb, void* data); static Local GetAndClearUncaughtException(const EcmaVM *vm); static Local GetUncaughtException(const EcmaVM *vm); static bool IsExecutingPendingJob(const EcmaVM *vm); static bool HasPendingException(const EcmaVM *vm); static bool HasPendingJob(const EcmaVM *vm); static void EnableUserUncaughtErrorHandler(EcmaVM *vm); // prevewer debugger. static bool StartDebuggerCheckParameters(EcmaVM *vm, const DebugOption &option, int32_t instanceId, const DebuggerPostTask &debuggerPostTask); static bool StartDebugger(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0, const DebuggerPostTask &debuggerPostTask = {}); // To be compatible with the old process. static bool StartDebuggerForOldProcess(EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0, const DebuggerPostTask &debuggerPostTask = {}); // socketpair process in ohos platform. static bool StartDebuggerForSocketPair(int tid, int socketfd = -1); static bool StopDebugger(int tid); static bool NotifyDebugMode(int tid, EcmaVM *vm, const DebugOption &option, int32_t instanceId = 0, const DebuggerPostTask &debuggerPostTask = {}, bool debugApp = false); static bool StoreDebugInfo( int tid, EcmaVM *vm, const DebugOption &option, const DebuggerPostTask &debuggerPostTask, bool debugApp); static bool StopDebugger(EcmaVM *vm); static bool IsMixedDebugEnabled(const EcmaVM *vm); static bool IsDebugModeEnabled(const EcmaVM *vm); static void NotifyNativeCalling(const EcmaVM *vm, const void *nativeAddress); static void NotifyNativeReturn(const EcmaVM *vm, const void *nativeAddress); static void NotifyLoadModule(const EcmaVM *vm); static void NotifyUIIdle(const EcmaVM *vm, int idleTime); static bool NotifyLooperIdleStart(const EcmaVM *vm, int64_t timestamp, int idleTime); static void NotifyLooperIdleEnd(const EcmaVM *vm, int64_t timestamp); static bool IsJSMainThreadOfEcmaVM(const EcmaVM *vm); static void SetDeviceDisconnectCallback(EcmaVM *vm, DeviceDisconnectCallback cb); // Serialize & Deserialize. static void* SerializeValue(const EcmaVM *vm, Local data, Local transfer, Local cloneList, bool defaultTransfer = false, bool defaultCloneShared = true); static Local DeserializeValue(const EcmaVM *vm, void *recoder, void *hint); static void DeleteSerializationData(void *data); static void SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data); static void SetTimerTaskCallback(EcmaVM *vm, TimerTaskCallback callback); static void SetCancelTimerCallback(EcmaVM *vm, CancelTimerCallback callback); static void NotifyEnvInitialized(EcmaVM *vm); static void SetHostResolveBufferTracker(EcmaVM *vm, std::function cb); static void SetUnloadNativeModuleCallback(EcmaVM *vm, const std::function &cb); static void SetNativePtrGetter(EcmaVM *vm, void* cb); static void SetSourceMapCallback(EcmaVM *vm, SourceMapCallback cb); static void SetSourceMapTranslateCallback(EcmaVM *vm, SourceMapTranslateCallback cb); static void SetHostEnqueueJob(const EcmaVM* vm, Local cb, QueueType queueType = QueueType::QUEUE_PROMISE); static EcmaVM* CreateEcmaVM(const ecmascript::JSRuntimeOptions &options); static void PreFork(EcmaVM *vm); static void PostFork(EcmaVM *vm, const RuntimeOption &option); static void AddWorker(EcmaVM *hostVm, EcmaVM *workerVm); static bool DeleteWorker(EcmaVM *hostVm, EcmaVM *workerVm); static void GetStackBeforeCallNapiSuccess(EcmaVM *vm, bool &getStackBeforeCallNapiSuccess); static void GetStackAfterCallNapi(EcmaVM *vm); static PatchErrorCode LoadPatch(EcmaVM *vm, const std::string &patchFileName, const std::string &baseFileName); static PatchErrorCode LoadPatch(EcmaVM *vm, const std::string &patchFileName, uint8_t *patchBuffer, size_t patchSize, const std::string &baseFileName, uint8_t *baseBuffer, size_t baseSize); static PatchErrorCode UnloadPatch(EcmaVM *vm, const std::string &patchFileName); // check whether the exception is caused by quickfix methods. static bool IsQuickFixCausedException(EcmaVM *vm, Local exception, const std::string &patchFileName); // register quickfix query function. static void RegisterQuickFixQueryFunc(EcmaVM *vm, std::function callBack); static bool IsBundle(EcmaVM *vm); static void SetBundle(EcmaVM *vm, bool value); static bool IsNormalizedOhmUrlPack(EcmaVM *vm); static bool IsOhmUrl(const std::string &srcName); static void SetAssetPath(EcmaVM *vm, const std::string &assetPath); static void SetMockModuleList(EcmaVM *vm, const std::map &list); static void SetPkgNameList(EcmaVM *vm, const std::map &list); static void UpdatePkgNameList(EcmaVM *vm, const std::map &list); static std::string GetPkgName(EcmaVM *vm, const std::string &moduleName); static void SetPkgAliasList(EcmaVM *vm, const std::map &list); static void UpdatePkgAliasList(EcmaVM *vm, const std::map &list); static void SetHmsModuleList(EcmaVM *vm, const std::vector &list); static void SetModuleInfo(EcmaVM *vm, const std::string &assetPath, const std::string &entryPoint); static void SetpkgContextInfoList(EcmaVM *vm, const std::map>> &list); static void UpdatePkgContextInfoList(EcmaVM *vm, const std::map>> &list); static void SetExecuteBufferMode(const EcmaVM *vm); // Stop preloading so task callback. static void SetStopPreLoadSoCallback(EcmaVM *vm, const StopPreLoadSoCallback &callback); static void SetLoop(EcmaVM *vm, void *loop); static void SetWeakFinalizeTaskCallback(EcmaVM *vm, const WeakFinalizeTaskCallback &callback); static void SetAsyncCleanTaskCallback(EcmaVM *vm, const NativePointerTaskCallback &callback); static void SetTriggerGCTaskCallback(EcmaVM *vm, const TriggerGCTaskCallback& callback); static void SetStartIdleMonitorCallback(EcmaVM *vm, const StartIdleMonitorCallback& callback); static std::string GetAssetPath(EcmaVM *vm); static bool InitForConcurrentThread(EcmaVM *vm, ConcurrentCallback cb, void *data); static bool InitForConcurrentFunction(EcmaVM *vm, Local func, void *taskInfo); static void* GetCurrentTaskInfo(const EcmaVM *vm); static void ClearCurrentTaskInfo(const EcmaVM *vm); static void SetBundleName(EcmaVM *vm, const std::string &bundleName); static std::string GetBundleName(EcmaVM *vm); static void SetModuleName(EcmaVM *vm, const std::string &moduleName); static std::string GetModuleName(EcmaVM *vm); static std::pair GetCurrentModuleInfo(EcmaVM *vm, bool needRecordName = false); static std::string NormalizePath(const std::string &string); static void AllowCrossThreadExecution(EcmaVM *vm); static bool CheckAndSetAllowCrossThreadExecution(EcmaVM *vm); static void SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM); static bool IsProfiling(EcmaVM *vm); static void SetProfilerState(const EcmaVM *vm, bool value); static void SetRequestAotCallback(EcmaVM *vm, const std::function &cb); static void SetSearchHapPathTracker(EcmaVM *vm, std::function cb); static void *GetEnv(EcmaVM *vm); static void SetEnv(EcmaVM *vm, void *env); static void SetMultiThreadCheck(bool multiThreadCheck = true); static void SetErrorInfoEnhance(bool errorInfoEnhance = true); // Napi Heavy Logics fast path static Local NapiHasProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key); static Local NapiHasOwnProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key); static Local NapiGetProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key); static Local NapiDeleteProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key); static Local NapiGetNamedProperty(const EcmaVM *vm, uintptr_t nativeObj, const char* utf8Key); static Local CreateLocal(const EcmaVM *vm, JSValueRef src); // Napi helper function static bool KeyIsNumber(const char* utf8); static int GetStartRealTime(const EcmaVM *vm); static void NotifyTaskBegin(const EcmaVM *vm); static void NotifyTaskFinished(const EcmaVM *vm); static bool IsMultiThreadCheckEnabled(const EcmaVM *vm); static uint32_t GetCurrentThreadId(); //set VM apiVersion static void SetVMAPIVersion(EcmaVM *vm, const int32_t apiVersion); // Napi Update SubStackInfo static void UpdateStackInfo(EcmaVM *vm, void *currentStackInfo, uint32_t opKind); private: static bool isForked_; static bool CreateRuntime(const RuntimeOption &option); static bool DestroyRuntime(); static StartIdleMonitorCallback startIdleMonitorCallback_; static uintptr_t GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress); static uintptr_t GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress); static uintptr_t SetWeak(const EcmaVM *vm, uintptr_t localAddress); static uintptr_t SetWeakCallback(const EcmaVM *vm, uintptr_t localAddress, void *ref, WeakRefClearCallBack freeGlobalCallBack, WeakRefClearCallBack nativeFinalizeCallback); static uintptr_t ClearWeak(const EcmaVM *vm, uintptr_t localAddress); static bool IsWeak(const EcmaVM *vm, uintptr_t localAddress); static void DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr); static bool IsSerializationTimeoutCheckEnabled(const EcmaVM *vm); static void GenerateTimeoutTraceIfNeeded(const EcmaVM *vm, std::chrono::system_clock::time_point &start, std::chrono::system_clock::time_point &end, bool isSerialization); static void UpdateAOTCompileStatus(ecmascript::JSRuntimeOptions &jsOption, const RuntimeOption &option); template friend class Global; template friend class CopyableGlobal; template friend class Local; friend class test::JSNApiTests; }; class ECMA_PUBLIC_API ProxyRef : public ObjectRef { public: Local GetHandler(const EcmaVM *vm); Local GetTarget(const EcmaVM *vm); bool IsRevoked(); }; class ECMA_PUBLIC_API WeakMapRef : public ObjectRef { public: int32_t GetSize(const EcmaVM *vm); int32_t GetTotalElements(const EcmaVM *vm); Local GetKey(const EcmaVM *vm, int entry); Local GetValue(const EcmaVM *vm, int entry); static Local New(const EcmaVM *vm); void Set(const EcmaVM *vm, const Local &key, const Local &value); bool Has(const EcmaVM *vm, Local key); }; class ECMA_PUBLIC_API SetRef : public ObjectRef { public: int32_t GetSize(const EcmaVM *vm); int32_t GetTotalElements(const EcmaVM *vm); Local GetValue(const EcmaVM *vm, int entry); static Local New(const EcmaVM *vm); void Add(const EcmaVM *vm, Local value); }; class ECMA_PUBLIC_API WeakSetRef : public ObjectRef { public: int32_t GetSize(const EcmaVM *vm); int32_t GetTotalElements(const EcmaVM *vm); Local GetValue(const EcmaVM *vm, int entry); static Local New(const EcmaVM *vm); void Add(const EcmaVM *vm, Local value); }; class ECMA_PUBLIC_API SetIteratorRef : public ObjectRef { public: int32_t GetIndex(); Local GetKind(const EcmaVM *vm); static Local New(const EcmaVM *vm, Local set); ecmascript::EcmaRuntimeCallInfo *GetEcmaRuntimeCallInfo(const EcmaVM *vm); static Local Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo); }; /* Attention pls, ExternalStringCache only can be utilized in main thread. Threads of Worker or Taskpool call * functions of this class will cause data race. */ class ECMA_PUBLIC_API ExternalStringCache final { public: static bool RegisterStringCacheTable(const EcmaVM *vm, uint32_t size); static bool SetCachedString(const EcmaVM *vm, const char *name, uint32_t propertyIndex); static bool HasCachedString(const EcmaVM *vm, uint32_t propertyIndex); static Local GetCachedString(const EcmaVM *vm, uint32_t propertyIndex); }; } #endif