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