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