• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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