• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_H
17 #define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_H
18 
19 #include <functional>
20 #include <list>
21 #include <string>
22 #include <unordered_map>
23 #include <unordered_set>
24 #include <vector>
25 #ifdef LINUX_PLATFORM
26 #include<atomic>
27 #endif
28 
29 #include "callback_scope_manager/native_callback_scope_manager.h"
30 #include "module_manager/native_module_manager.h"
31 #include "native_engine/native_async_work.h"
32 #include "native_engine/native_deferred.h"
33 #include "native_engine/native_reference.h"
34 #include "native_engine/native_safe_async_work.h"
35 #include "native_engine/native_value.h"
36 #include "native_property.h"
37 #include "reference_manager/native_reference_manager.h"
38 #include "scope_manager/native_scope_manager.h"
39 #include "utils/macros.h"
40 
41 typedef int32_t (*GetContainerScopeIdCallback)(void);
42 typedef void (*ContainerScopeCallback)(int32_t);
43 
44 typedef struct uv_loop_s uv_loop_t;
45 
46 struct NativeErrorExtendedInfo {
47     const char* message = nullptr;
48     void* reserved = nullptr;
49     uint32_t engineErrorCode = 0;
50     int errorCode = 0;
51 };
52 
53 struct ExceptionInfo {
54     const char* message_ = nullptr;
55     int32_t lineno_ = 0;
56     int32_t colno_ = 0;
57 
~ExceptionInfoExceptionInfo58     ~ExceptionInfo()
59     {
60         if (message_ != nullptr) {
61             delete[] message_;
62         }
63     }
64 };
65 
66 enum LoopMode {
67     LOOP_DEFAULT, LOOP_ONCE, LOOP_NOWAIT
68 };
69 
70 enum class DumpFormat {
71     JSON, BINARY, OTHER
72 };
73 
74 class CleanupHookCallback {
75 public:
76     using Callback = void (*)(void*);
77 
CleanupHookCallback(Callback fn,void * arg,uint64_t insertion_order_counter)78     CleanupHookCallback(Callback fn, void* arg, uint64_t insertion_order_counter)
79         : fn_(fn), arg_(arg), insertion_order_counter_(insertion_order_counter)
80     {}
81 
82     struct Hash {
operatorHash83         inline size_t operator()(const CleanupHookCallback& cb) const
84         {
85             return std::hash<void*>()(cb.arg_);
86         }
87     };
88     struct Equal {
operatorEqual89         inline bool operator()(const CleanupHookCallback& a, const CleanupHookCallback& b) const
90         {
91             return a.fn_ == b.fn_ && a.arg_ == b.arg_;
92         };
93     };
94 
95 private:
96     friend class NativeEngine;
97     Callback fn_;
98     void* arg_;
99     uint64_t insertion_order_counter_;
100 };
101 
102 using PostTask = std::function<void(bool needSync)>;
103 using CleanEnv = std::function<void()>;
104 using InitWorkerFunc = std::function<void(NativeEngine* engine)>;
105 using GetAssetFunc = std::function<void(const std::string& uri, std::vector<uint8_t>& content, std::string& ami)>;
106 using OffWorkerFunc = std::function<void(NativeEngine* engine)>;
107 using DebuggerPostTask = std::function<void(std::function<void()>&&)>;
108 using UncaughtExceptionCallback = std::function<void(NativeValue* value)>;
109 using PermissionCheckCallback = std::function<bool()>;
110 using NapiConcurrentCallback = void (*)(NativeEngine* engine, NativeValue* result, bool success, void* data);
111 using SourceMapCallback = std::function<std::string(const std::string& rawStack)>;
112 
113 class NAPI_EXPORT NativeEngine {
114 public:
115     explicit NativeEngine(void* jsEngine);
116     virtual ~NativeEngine();
117 
118     virtual NativeScopeManager* GetScopeManager();
119     virtual NativeModuleManager* GetModuleManager();
120     virtual NativeReferenceManager* GetReferenceManager();
121     virtual NativeCallbackScopeManager* GetCallbackScopeManager();
122     virtual uv_loop_t* GetUVLoop() const;
123     virtual pthread_t GetTid() const;
124 
125     virtual bool ReinitUVLoop();
126 
127     virtual void Loop(LoopMode mode, bool needSync = false);
128     virtual void SetPostTask(PostTask postTask);
129     virtual void TriggerPostTask();
130 #if !defined(PREVIEW)
131     virtual void CheckUVLoop();
132     virtual void CancelCheckUVLoop();
133 #endif
134     virtual void* GetJsEngine();
135 
136     virtual NativeValue* GetGlobal() = 0;
137 
138     virtual NativeValue* CreateNull() = 0;
139     virtual NativeValue* CreateUndefined() = 0;
140     virtual NativeValue* CreateBoolean(bool value) = 0;
141     virtual NativeValue* CreateNumber(int32_t value) = 0;
142     virtual NativeValue* CreateNumber(uint32_t value) = 0;
143     virtual NativeValue* CreateNumber(int64_t value) = 0;
144     virtual NativeValue* CreateNumber(double value) = 0;
145     virtual NativeValue* CreateBigInt(int64_t value) = 0;
146     virtual NativeValue* CreateBigInt(uint64_t value) = 0;
147     virtual NativeValue* CreateString(const char* value, size_t length) = 0;
148     virtual NativeValue* CreateString16(const char16_t* value, size_t length) = 0;
149 
150     virtual NativeValue* CreateSymbol(NativeValue* value) = 0;
151     virtual NativeValue* CreateExternal(void* value, NativeFinalize callback, void* hint,
152         size_t nativeBindingSize = 0) = 0;
153 
154     virtual NativeValue* CreateObject() = 0;
155     virtual NativeValue* CreateFunction(const char* name, size_t length, NativeCallback cb, void* value) = 0;
156     virtual NativeValue* CreateArray(size_t length) = 0;
157     virtual NativeValue* CreateBuffer(void** value, size_t length) = 0;
158     virtual NativeValue* CreateBufferCopy(void** value, size_t length, const void* data) = 0;
159     virtual NativeValue* CreateBufferExternal(void* value, size_t length, NativeFinalize cb, void* hint) = 0;
160     virtual NativeValue* CreateArrayBuffer(void** value, size_t length) = 0;
161     virtual NativeValue* CreateArrayBufferExternal(void* value, size_t length, NativeFinalize cb, void* hint) = 0;
162 
163     virtual NativeValue* CreateTypedArray(NativeTypedArrayType type,
164                                           NativeValue* value,
165                                           size_t length,
166                                           size_t offset) = 0;
167     virtual NativeValue* CreateDataView(NativeValue* value, size_t length, size_t offset) = 0;
168     virtual NativeValue* CreatePromise(NativeDeferred** deferred) = 0;
169     virtual void SetPromiseRejectCallback(NativeReference* rejectCallbackRef, NativeReference* checkCallbackRef) = 0;
170     virtual NativeValue* CreateError(NativeValue* code, NativeValue* message) = 0;
171 
172     virtual bool InitTaskPoolThread(NativeEngine* engine, NapiConcurrentCallback callback) = 0;
173     virtual bool InitTaskPoolFunc(NativeEngine* engine, NativeValue* func, void* taskInfo) = 0;
174     virtual void* GetCurrentTaskInfo() const = 0;
175 
176     virtual NativeValue* CallFunction(NativeValue* thisVar,
177                                       NativeValue* function,
178                                       NativeValue* const *argv,
179                                       size_t argc) = 0;
180     virtual NativeValue* RunScript(NativeValue* script) = 0;
181     virtual NativeValue* RunScriptPath(const char* path) = 0;
182     virtual NativeValue* RunScriptBuffer(const char* path, std::vector<uint8_t>& buffer, bool isBundle) = 0;
183     virtual bool RunScriptBuffer(const std::string &path, uint8_t* buffer, size_t size, bool isBundle) = 0;
184     virtual NativeValue* RunBufferScript(std::vector<uint8_t>& buffer) = 0;
185     virtual NativeValue* RunActor(std::vector<uint8_t>& buffer, const char* descriptor) = 0;
186     virtual NativeValue* DefineClass(const char* name,
187                                      NativeCallback callback,
188                                      void* data,
189                                      const NativePropertyDescriptor* properties,
190                                      size_t length) = 0;
191 
192     virtual NativeValue* CreateInstance(NativeValue* constructor, NativeValue* const *argv, size_t argc) = 0;
193 
194     virtual NativeReference* CreateReference(NativeValue* value, uint32_t initialRefcount,
195         NativeFinalize callback = nullptr, void* data = nullptr, void* hint = nullptr) = 0;
196 
197     virtual NativeAsyncWork* CreateAsyncWork(NativeValue* asyncResource,
198                                              NativeValue* asyncResourceName,
199                                              NativeAsyncExecuteCallback execute,
200                                              NativeAsyncCompleteCallback complete,
201                                              void* data);
202 
203     virtual NativeAsyncWork* CreateAsyncWork(const std::string &asyncResourceName,
204                                              NativeAsyncExecuteCallback execute,
205                                              NativeAsyncCompleteCallback complete,
206                                              void* data);
207     virtual NativeSafeAsyncWork* CreateSafeAsyncWork(NativeValue* func, NativeValue* asyncResource,
208         NativeValue* asyncResourceName, size_t maxQueueSize, size_t threadCount, void* finalizeData,
209         NativeFinalize finalizeCallback, void* context, NativeThreadSafeFunctionCallJs callJsCallback);
210 
211     virtual bool Throw(NativeValue* error) = 0;
212     virtual bool Throw(NativeErrorType type, const char* code, const char* message) = 0;
213 
214     virtual void* CreateRuntime() = 0;
215     virtual NativeValue* Serialize(NativeEngine* context, NativeValue* value, NativeValue* transfer) = 0;
216     virtual NativeValue* Deserialize(NativeEngine* context, NativeValue* recorder) = 0;
217     virtual void DeleteSerializationData(NativeValue* value) const = 0;
218     virtual NativeValue* LoadModule(NativeValue* str, const std::string& fileName) = 0;
219 
220     virtual void StartCpuProfiler(const std::string& fileName = "") = 0;
221     virtual void StopCpuProfiler() = 0;
222 
223     virtual void ResumeVM() = 0;
224     virtual bool SuspendVM() = 0;
225     virtual bool IsSuspended() = 0;
226     virtual bool CheckSafepoint() = 0;
227     virtual bool SuspendVMById(uint32_t tid) = 0;
228     virtual void ResumeVMById(uint32_t tid) = 0;
229 
230     virtual void DumpHeapSnapshot(const std::string &path, bool isVmMode = true,
231         DumpFormat dumpFormat = DumpFormat::JSON) = 0;
232     virtual void DumpHeapSnapshot(bool isVmMode = true, DumpFormat dumpFormat = DumpFormat::JSON,
233         bool isPrivate = false) = 0;
234     virtual bool BuildNativeAndJsStackTrace(std::string &stackTraceStr) = 0;
235     virtual bool BuildJsStackTrace(std::string &stackTraceStr) = 0;
236     virtual bool BuildJsStackInfoList(uint32_t tid, std::vector<JsFrameInfo>& jsFrames) = 0;
237     virtual bool DeleteWorker(NativeEngine* workerEngine) = 0;
238     virtual bool StartHeapTracking(double timeInterval, bool isVmMode = true) = 0;
239     virtual bool StopHeapTracking(const std::string &filePath) = 0;
240 
241     virtual void AllowCrossThreadExecution() const = 0;
242 
243     NativeErrorExtendedInfo* GetLastError();
244     void SetLastError(int errorCode, uint32_t engineErrorCode = 0, void* engineReserved = nullptr);
245     void ClearLastError();
246     virtual bool IsExceptionPending() const = 0;
247     virtual NativeValue* GetAndClearLastException() = 0;
248     void EncodeToUtf8(NativeValue* nativeValue, char* buffer, int32_t* written, size_t bufferSize, int32_t* nchars);
249     void EncodeToChinese(NativeValue* nativeValue, std::string& buffer, const std::string& encoding);
250     NativeEngine(NativeEngine&) = delete;
251     virtual NativeEngine& operator=(NativeEngine&) = delete;
252 
253     virtual NativeValue* ValueToNativeValue(JSValueWrapper& value) = 0;
254     virtual bool TriggerFatalException(NativeValue* error) = 0;
255     virtual bool AdjustExternalMemory(int64_t ChangeInBytes, int64_t* AdjustedValue) = 0;
256 
MarkWorkerThread()257     void MarkWorkerThread()
258     {
259         jsThreadType_ = JSThreadType::WORKER_THREAD;
260     }
MarkTaskPoolThread()261     void MarkTaskPoolThread()
262     {
263         jsThreadType_ = JSThreadType::TASKPOOL_THREAD;
264     }
IsWorkerThread()265     bool IsWorkerThread() const
266     {
267         return jsThreadType_ == JSThreadType::WORKER_THREAD;
268     }
IsTaskPoolThread()269     bool IsTaskPoolThread() const
270     {
271         return jsThreadType_ == JSThreadType::TASKPOOL_THREAD;
272     }
IsMainThread()273     bool IsMainThread() const
274     {
275         return jsThreadType_ == JSThreadType::MAIN_THREAD;
276     }
277 
SetCleanEnv(CleanEnv cleanEnv)278     void SetCleanEnv(CleanEnv cleanEnv)
279     {
280         cleanEnv_ = cleanEnv;
281     }
282 
283     // register init worker func
284     virtual void SetInitWorkerFunc(InitWorkerFunc func);
285     InitWorkerFunc GetInitWorkerFunc() const;
286     virtual void SetGetAssetFunc(GetAssetFunc func);
287     GetAssetFunc GetGetAssetFunc() const;
288     virtual void SetOffWorkerFunc(OffWorkerFunc func);
289     OffWorkerFunc GetOffWorkerFunc() const;
290 
291     // call init worker func
292     virtual bool CallInitWorkerFunc(NativeEngine* engine);
293     virtual bool CallGetAssetFunc(const std::string& uri, std::vector<uint8_t>& content, std::string& ami);
294     virtual bool CallOffWorkerFunc(NativeEngine* engine);
295 
296     // adapt worker to ace container
297     virtual void SetGetContainerScopeIdFunc(GetContainerScopeIdCallback func);
298     virtual void SetInitContainerScopeFunc(ContainerScopeCallback func);
299     virtual void SetFinishContainerScopeFunc(ContainerScopeCallback func);
300     virtual int32_t GetContainerScopeIdFunc();
301     virtual bool InitContainerScopeFunc(int32_t id);
302     virtual bool FinishContainerScopeFunc(int32_t id);
303 
304 #if !defined(PREVIEW)
305     virtual void SetDebuggerPostTaskFunc(DebuggerPostTask func);
306     virtual void CallDebuggerPostTaskFunc(std::function<void()>&& task);
307 #endif
308 
309     virtual void SetHostEngine(NativeEngine* engine);
310     virtual NativeEngine* GetHostEngine() const;
311 
312     virtual NativeValue* CreateDate(double value) = 0;
313     virtual NativeValue* CreateBigWords(int sign_bit, size_t word_count, const uint64_t* words) = 0;
314     using CleanupCallback = CleanupHookCallback::Callback;
315     virtual void AddCleanupHook(CleanupCallback fun, void* arg);
316     virtual void RemoveCleanupHook(CleanupCallback fun, void* arg);
317 
318     void CleanupHandles();
319     void IncreaseWaitingRequestCounter();
320     void DecreaseWaitingRequestCounter();
321 
322     virtual void RunCleanup();
323 
IsStopping()324     bool IsStopping() const
325     {
326         return isStopping_.load();
327     }
328 
SetStopping(bool value)329     void SetStopping(bool value)
330     {
331         isStopping_.store(value);
332     }
333 
334     virtual void PrintStatisticResult() = 0;
335     virtual void StartRuntimeStat() = 0;
336     virtual void StopRuntimeStat() = 0;
337     virtual size_t GetArrayBufferSize() = 0;
338     virtual size_t GetHeapTotalSize() = 0;
339     virtual size_t GetHeapUsedSize() = 0;
340     virtual void NotifyApplicationState(bool inBackground) = 0;
341     virtual void NotifyIdleStatusControl(std::function<void(bool)> callback) = 0;
342     virtual void NotifyIdleTime(int idleMicroSec) = 0;
343     virtual void NotifyMemoryPressure(bool inHighMemoryPressure = false) = 0;
344 
345     void RegisterWorkerFunction(const NativeEngine* engine);
346 
347     virtual void RegisterUncaughtExceptionHandler(UncaughtExceptionCallback callback) = 0;
348     virtual void HandleUncaughtException() = 0;
HasPendingException()349     virtual bool HasPendingException()
350     {
351         return false;
352     }
353     virtual void RegisterPermissionCheck(PermissionCheckCallback callback) = 0;
354     virtual bool ExecutePermissionCheck() = 0;
355     virtual void RegisterTranslateBySourceMap(SourceMapCallback callback) = 0;
356     virtual std::string ExecuteTranslateBySourceMap(const std::string& rawStack) = 0;
357     // run script by path
358     NativeValue* RunScript(const char* path);
359 
360     const char* GetModuleFileName();
361 
362     void SetModuleFileName(std::string &moduleName);
363 
364     void SetInstanceData(void* data, NativeFinalize finalize_cb, void* hint);
365     void GetInstanceData(void** data);
366 
367     /**
368      * @brief Set the Extension Infos
369      *
370      * @param extensionInfos extension infos to set
371      */
372     void SetExtensionInfos(std::unordered_map<std::string, int32_t>&& extensionInfos);
373 
374     /**
375      * @brief Get the Extension Infos
376      *
377      * @return extension infos
378      */
379     const std::unordered_map<std::string, int32_t>& GetExtensionInfos();
380 
381     /**
382      * @brief Set the Module Blocklist
383      *
384      * @param blocklist the blocklist set to native engine
385      */
386     void SetModuleBlocklist(std::unordered_map<int32_t, std::unordered_set<std::string>>&& blocklist);
387 
388     /**
389      * @brief Set the Module Load Checker
390      *
391      * @param moduleCheckerDelegate the module checker delegate will intercept the module loading
392      */
393     void SetModuleLoadChecker(const std::shared_ptr<ModuleCheckerDelegate>& moduleCheckerDelegate);
394 
395 private:
396     void StartCleanupTimer();
397 protected:
398     void *jsEngine_;
399     void* jsEngineInterface_;
400 
401     void Init();
402     void Deinit();
403 
404     NativeModuleManager* moduleManager_ = nullptr;
405     NativeScopeManager* scopeManager_ = nullptr;
406     NativeReferenceManager* referenceManager_ = nullptr;
407     NativeCallbackScopeManager* callbackScopeManager_ = nullptr;
408 
409     uv_loop_t* loop_ = nullptr;
410 
411     NativeErrorExtendedInfo lastError_;
412 
413     // register for worker
414     InitWorkerFunc initWorkerFunc_ {nullptr};
415     GetAssetFunc getAssetFunc_ {nullptr};
416     OffWorkerFunc offWorkerFunc_ {nullptr};
417 #if !defined(PREVIEW)
418     DebuggerPostTask debuggerPostTaskFunc_ {nullptr};
419 #endif
420     NativeEngine* hostEngine_ {nullptr};
421 
422 private:
423     std::string moduleName_;
424     std::mutex instanceDataLock_;
425     NativeObjectInfo instanceDataInfo_;
426     void FinalizerInstanceData(void);
427     pthread_t tid_ = 0;
428     std::unordered_map<std::string, int32_t> extensionInfos_;
429     uv_sem_t uvSem_;
430 
431     enum JSThreadType { MAIN_THREAD, WORKER_THREAD, TASKPOOL_THREAD };
432     JSThreadType jsThreadType_ = JSThreadType::MAIN_THREAD;
433 
434 #if !defined(PREVIEW)
435     static void UVThreadRunner(void* nativeEngine);
436     void PostLoopTask();
437 
438     bool checkUVLoop_ = false;
439     uv_thread_t uvThread_;
440 #endif
441 
442     PostTask postTask_ = nullptr;
443     CleanEnv cleanEnv_ = nullptr;
444     uv_async_t uvAsync_;
445     std::unordered_set<CleanupHookCallback, CleanupHookCallback::Hash, CleanupHookCallback::Equal> cleanup_hooks_;
446     uint64_t cleanup_hook_counter_ = 0;
447     std::atomic_int request_waiting_ { 0 };
448     std::atomic_bool isStopping_ { false };
449     bool cleanupTimeout_ = false;
450     uv_timer_t timer_;
451 };
452 
453 #endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_H */
454