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