1 /* 2 * Copyright (c) 2021-2022 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 FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_INTERFACE_H 17 #define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_INTERFACE_H 18 19 #include <functional> 20 #include <unordered_set> 21 #include <vector> 22 #ifdef LINUX_PLATFORM 23 #include<atomic> 24 #endif 25 26 #include "callback_scope_manager/native_callback_scope_manager.h" 27 #include "module_manager/native_module_manager.h" 28 #include "native_engine/native_async_work.h" 29 #include "native_engine/native_deferred.h" 30 #include "native_engine/native_reference.h" 31 #include "native_engine/native_safe_async_work.h" 32 #include "native_engine/native_value.h" 33 #include "native_property.h" 34 #include "reference_manager/native_reference_manager.h" 35 #include "scope_manager/native_scope_manager.h" 36 #include "utils/macros.h" 37 38 typedef struct uv_loop_s uv_loop_t; 39 40 struct NativeErrorExtendedInfo { 41 const char* message = nullptr; 42 void* reserved = nullptr; 43 uint32_t engineErrorCode = 0; 44 int errorCode = 0; 45 }; 46 47 struct ExceptionInfo { 48 const char* message_ = nullptr; 49 int32_t lineno_ = 0; 50 int32_t colno_ = 0; 51 ~ExceptionInfoExceptionInfo52 ~ExceptionInfo() 53 { 54 if (message_ != nullptr) { 55 delete[] message_; 56 } 57 } 58 }; 59 60 enum LoopMode { 61 LOOP_DEFAULT, LOOP_ONCE, LOOP_NOWAIT 62 }; 63 64 enum class DumpFormat { 65 JSON, BINARY, OTHER 66 }; 67 68 class CleanupHookCallback { 69 public: 70 using Callback = void (*)(void*); 71 CleanupHookCallback(Callback fn,void * arg,uint64_t insertion_order_counter)72 CleanupHookCallback(Callback fn, void* arg, uint64_t insertion_order_counter) 73 : fn_(fn), arg_(arg), insertion_order_counter_(insertion_order_counter) 74 {} 75 76 struct Hash { operatorHash77 inline size_t operator()(const CleanupHookCallback& cb) const 78 { 79 return std::hash<void*>()(cb.arg_); 80 } 81 }; 82 struct Equal { operatorEqual83 inline bool operator()(const CleanupHookCallback& a, const CleanupHookCallback& b) const 84 { 85 return a.fn_ == b.fn_ && a.arg_ == b.arg_; 86 }; 87 }; 88 89 private: 90 friend class NativeEngineInterface; 91 Callback fn_; 92 void* arg_; 93 uint64_t insertion_order_counter_; 94 }; 95 96 using PostTask = std::function<void(bool needSync)>; 97 using CleanEnv = std::function<void()>; 98 using UncaughtExceptionCallback = std::function<void(NativeValue* value)>; 99 using NapiConcurrentCallback = void (*)(NativeEngine* engine, NativeValue* value, NativeValue* data); 100 101 class NAPI_EXPORT NativeEngineInterface { 102 public: 103 NativeEngineInterface(NativeEngine* engine, void* jsEngineInterface); 104 virtual ~NativeEngineInterface(); 105 106 virtual NativeScopeManager* GetScopeManager(); 107 virtual NativeModuleManager* GetModuleManager(); 108 virtual NativeReferenceManager* GetReferenceManager(); 109 virtual NativeCallbackScopeManager* GetCallbackScopeManager(); 110 virtual uv_loop_t* GetUVLoop() const; 111 virtual pthread_t GetTid() const; 112 113 virtual bool ReinitUVLoop(); 114 115 virtual void Loop(LoopMode mode, bool needSync = false); 116 virtual void SetPostTask(PostTask postTask); 117 virtual void TriggerPostTask(); 118 #if !defined(PREVIEW) 119 virtual void CheckUVLoop(); 120 virtual void CancelCheckUVLoop(); 121 #endif 122 virtual void* GetJsEngine(); 123 124 virtual NativeValue* GetGlobal(NativeEngine* engine) = 0; 125 126 virtual NativeValue* CreateNull(NativeEngine* engine) = 0; 127 virtual NativeValue* CreateUndefined(NativeEngine* engine) = 0; 128 virtual NativeValue* CreateBoolean(NativeEngine* engine, bool value) = 0; 129 virtual NativeValue* CreateNumber(NativeEngine* engine, int32_t value) = 0; 130 virtual NativeValue* CreateNumber(NativeEngine* engine, uint32_t value) = 0; 131 virtual NativeValue* CreateNumber(NativeEngine* engine, int64_t value) = 0; 132 virtual NativeValue* CreateNumber(NativeEngine* engine, double value) = 0; 133 virtual NativeValue* CreateBigInt(NativeEngine* engine, int64_t value) = 0; 134 virtual NativeValue* CreateBigInt(NativeEngine* engine, uint64_t value) = 0; 135 virtual NativeValue* CreateString(NativeEngine* engine, const char* value, size_t length) = 0; 136 virtual NativeValue* CreateString16(NativeEngine* engine, const char16_t* value, size_t length) = 0; 137 138 virtual NativeValue* CreateSymbol(NativeEngine* engine, NativeValue* value) = 0; 139 virtual NativeValue* CreateExternal(NativeEngine* engine, void* value, NativeFinalize callback, 140 void* hint, size_t nativeBindingSize = 0) = 0; 141 142 virtual NativeValue* CreateObject(NativeEngine* engine) = 0; 143 virtual NativeValue* CreateNativeBindingObject(NativeEngine* engine, void* detach, void* attach) = 0; 144 virtual NativeValue* CreateNBObject(NativeEngine* engine, DetachCallback detach, AttachCallback attach) = 0; 145 virtual NativeValue* CreateFunction( 146 NativeEngine* engine, const char* name, size_t length, NativeCallback cb, void* value) = 0; 147 virtual NativeValue* CreateArray(NativeEngine* engine, size_t length) = 0; 148 virtual NativeValue* CreateBuffer(NativeEngine* engine, void** value, size_t length) = 0; 149 virtual NativeValue* CreateBufferCopy(NativeEngine* engine, void** value, size_t length, const void* data) = 0; 150 virtual NativeValue* CreateBufferExternal( 151 NativeEngine* engine, void* value, size_t length, NativeFinalize cb, void* hint) = 0; 152 virtual NativeValue* CreateArrayBuffer(NativeEngine* engine, void** value, size_t length) = 0; 153 virtual NativeValue* CreateArrayBufferExternal( 154 NativeEngine* engine, void* value, size_t length, NativeFinalize cb, void* hint) = 0; 155 156 virtual NativeValue* CreateTypedArray( 157 NativeEngine* engine, NativeTypedArrayType type, NativeValue* value, size_t length, size_t offset) = 0; 158 virtual NativeValue* CreateDataView(NativeEngine* engine, NativeValue* value, size_t length, size_t offset) = 0; 159 virtual NativeValue* CreatePromise(NativeEngine* engine, NativeDeferred** deferred) = 0; 160 virtual void SetPromiseRejectCallback( 161 NativeEngine* engine, NativeReference* rejectCallbackRef, NativeReference* checkCallbackRef) = 0; 162 virtual NativeValue* CreateError(NativeEngine* engine, NativeValue* code, NativeValue* message) = 0; 163 164 virtual bool InitTaskPoolThread(NativeEngine* engine, NapiConcurrentCallback callback) = 0; 165 virtual bool InitTaskPoolFunc(NativeEngine* engine, NativeValue* func) = 0; 166 167 virtual NativeValue* CallFunction( 168 NativeEngine* engine, NativeValue* thisVar, NativeValue* function, NativeValue* const *argv, size_t argc) = 0; 169 virtual NativeValue* RunScript(NativeEngine* engine, NativeValue* script) = 0; 170 virtual NativeValue* RunScriptPath(NativeEngine* engine, const char* path) = 0; 171 virtual NativeValue* RunScriptBuffer( 172 NativeEngine* engine, const char* path, std::vector<uint8_t>& buffer, bool isBundle) = 0; 173 virtual NativeValue* RunBufferScript(NativeEngine* engine, std::vector<uint8_t>& buffer) = 0; 174 virtual NativeValue* RunActor(NativeEngine* engine, std::vector<uint8_t>& buffer, const char* descriptor) = 0; 175 virtual NativeValue* DefineClass(NativeEngine* engine, 176 const char* name, 177 NativeCallback callback, 178 void* data, 179 const NativePropertyDescriptor* properties, 180 size_t length) = 0; 181 182 virtual NativeValue* CreateInstance( 183 NativeEngine* engine, NativeValue* constructor, NativeValue* const *argv, size_t argc) = 0; 184 185 virtual NativeReference* CreateReference(NativeEngine* engine, NativeValue* value, uint32_t initialRefcount, 186 NativeFinalize callback = nullptr, void* data = nullptr, void* hint = nullptr) = 0; 187 188 virtual NativeAsyncWork* CreateAsyncWork(NativeEngine* engine, NativeValue* asyncResource, 189 NativeValue* asyncResourceName, NativeAsyncExecuteCallback execute, NativeAsyncCompleteCallback complete, 190 void* data); 191 192 virtual NativeAsyncWork* CreateAsyncWork(NativeEngine* engine, const std::string &asyncResourceName, 193 NativeAsyncExecuteCallback execute, NativeAsyncCompleteCallback complete, void* data); 194 virtual NativeSafeAsyncWork* CreateSafeAsyncWork(NativeEngine* engine, NativeValue* func, 195 NativeValue* asyncResource, NativeValue* asyncResourceName, size_t maxQueueSize, size_t threadCount, 196 void* finalizeData, NativeFinalize finalizeCallback, void* context, 197 NativeThreadSafeFunctionCallJs callJsCallback); 198 199 virtual bool Throw(NativeValue* error) = 0; 200 virtual bool Throw(NativeEngine* engine, NativeErrorType type, const char* code, const char* message) = 0; 201 202 virtual void* CreateRuntime(NativeEngine* engine) = 0; 203 virtual NativeValue* Serialize(NativeEngine* context, NativeValue* value, NativeValue* transfer) = 0; 204 virtual NativeValue* Deserialize(NativeEngine* engine, NativeEngine* context, NativeValue* recorder) = 0; 205 virtual void DeleteSerializationData(NativeValue* value) const = 0; 206 virtual NativeValue* LoadModule(NativeEngine* engine, NativeValue* str, const std::string& fileName) = 0; 207 208 virtual void StartCpuProfiler(const std::string& fileName = "") = 0; 209 virtual void StopCpuProfiler() = 0; 210 211 virtual void ResumeVM() = 0; 212 virtual bool SuspendVM() = 0; 213 virtual bool IsSuspended() = 0; 214 virtual bool CheckSafepoint() = 0; 215 216 virtual void DumpHeapSnapshot(const std::string& path, bool isVmMode = true, 217 DumpFormat dumpFormat = DumpFormat::JSON) = 0; 218 virtual void DumpHeapSnapshotExt(bool isVmMode = true, DumpFormat dumpFormat = DumpFormat::JSON, 219 bool isPrivate = false) = 0; 220 virtual bool BuildNativeAndJsStackTrace(std::string& stackTraceStr) = 0; 221 virtual bool BuildJsStackTrace(std::string& stackTraceStr) = 0; 222 virtual bool BuildJsStackInfoList(uint32_t tid, std::vector<JsFrameInfo>& jsFrames) = 0; 223 virtual bool DeleteWorker(NativeEngine* hostEngine, NativeEngine* workerEngine) = 0; 224 virtual bool StartHeapTracking(double timeInterval, bool isVmMode = true) = 0; 225 virtual bool StopHeapTracking(const std::string& filePath) = 0; 226 227 NativeErrorExtendedInfo* GetLastError(); 228 void SetLastError(int errorCode, uint32_t engineErrorCode = 0, void* engineReserved = nullptr); 229 void ClearLastError(); 230 virtual bool IsExceptionPending() const = 0; 231 virtual NativeValue* GetAndClearLastException(NativeEngine* engine) = 0; 232 void EncodeToUtf8(NativeValue* nativeValue, char* buffer, int32_t* written, size_t bufferSize, int32_t* nchars); 233 void EncodeToChinese(NativeValue* nativeValue, std::string& buffer, const std::string& encoding); 234 NativeEngineInterface(NativeEngineInterface&) = delete; 235 virtual NativeEngineInterface& operator=(NativeEngineInterface&) = delete; 236 237 virtual NativeValue* ValueToNativeValue(NativeEngine* engine, JSValueWrapper& value) = 0; 238 virtual bool TriggerFatalException(NativeValue* error) = 0; 239 virtual bool AdjustExternalMemory(int64_t ChangeInBytes, int64_t* AdjustedValue) = 0; 240 MarkSubThread()241 void MarkSubThread() 242 { 243 isMainThread_ = false; 244 } 245 IsMainThread()246 bool IsMainThread() const 247 { 248 return isMainThread_; 249 } 250 SetCleanEnv(CleanEnv cleanEnv)251 void SetCleanEnv(CleanEnv cleanEnv) 252 { 253 cleanEnv_ = cleanEnv; 254 } 255 256 virtual NativeValue* CreateDate(NativeEngine* engine, double value) = 0; 257 virtual NativeValue* CreateBigWords( 258 NativeEngine* engine, int sign_bit, size_t word_count, const uint64_t* words) = 0; 259 using CleanupCallback = CleanupHookCallback::Callback; 260 virtual void AddCleanupHook(CleanupCallback fun, void* arg); 261 virtual void RemoveCleanupHook(CleanupCallback fun, void* arg); 262 263 void CleanupHandles(); 264 void IncreaseWaitingRequestCounter(); 265 void DecreaseWaitingRequestCounter(); 266 virtual void RunCleanup(); 267 IsStopping()268 bool IsStopping() const 269 { 270 return isStopping_.load(); 271 } 272 SetStopping(bool value)273 void SetStopping(bool value) 274 { 275 isStopping_.store(value); 276 } 277 278 virtual void PrintStatisticResult() = 0; 279 virtual void StartRuntimeStat() = 0; 280 virtual void StopRuntimeStat() = 0; 281 virtual size_t GetArrayBufferSize() = 0; 282 virtual size_t GetHeapTotalSize() = 0; 283 virtual size_t GetHeapUsedSize() = 0; NotifyApplicationState(bool inBackground)284 virtual void NotifyApplicationState([[maybe_unused]] bool inBackground) {} NotifyIdleTime(int idleMicroSec)285 virtual void NotifyIdleTime([[maybe_unused]] int idleMicroSec) {} 286 virtual void NotifyMemoryPressure([[maybe_unused]] bool inHighMemoryPressure = false) {} 287 288 virtual void RegisterUncaughtExceptionHandler(UncaughtExceptionCallback callback) = 0; 289 virtual void HandleUncaughtException(NativeEngine* engine) = 0; 290 virtual bool HasPendingException() = 0; 291 // run script by path 292 NativeValue* RunScript(const char* path); 293 NativeEngine* GetRootNativeEngine(void); 294 protected: 295 void Init(); 296 void Deinit(); 297 298 NativeModuleManager* moduleManager_ = nullptr; 299 NativeScopeManager* scopeManager_ = nullptr; 300 NativeReferenceManager* referenceManager_ = nullptr; 301 NativeCallbackScopeManager* callbackScopeManager_ = nullptr; 302 303 NativeErrorExtendedInfo lastError_; 304 305 uv_loop_t* loop_ = nullptr; 306 307 void* jsEngineInterface_; 308 NativeEngine* rootNativeEngine__; 309 private: 310 bool isMainThread_ { true }; 311 312 #if !defined(PREVIEW) 313 static void UVThreadRunner(void* nativeEngine); 314 void PostLoopTask(); 315 316 bool checkUVLoop_ = false; 317 uv_thread_t uvThread_; 318 #endif 319 320 PostTask postTask_ = nullptr; 321 CleanEnv cleanEnv_ = nullptr; 322 uv_sem_t uvSem_; 323 uv_async_t uvAsync_; 324 std::unordered_set<CleanupHookCallback, CleanupHookCallback::Hash, CleanupHookCallback::Equal> cleanup_hooks_; 325 uint64_t cleanup_hook_counter_ = 0; 326 int request_waiting_ = 0; 327 std::atomic_bool isStopping_ { false }; 328 pthread_t tid_ = 0; 329 }; 330 331 #endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_H */ 332