• 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_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