• 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_IMPL_ARK_ARK_NATIVE_ENGINE_H
17 #define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_ARK_NATIVE_ENGINE_H
18 
19 #include <memory>
20 #if !defined(PREVIEW) && !defined(IOS_PLATFORM) && !defined(IOS_PLATFORM)
21 #include <sys/wait.h>
22 #include <sys/types.h>
23 #endif
24 #include <unistd.h>
25 #include <map>
26 #include <mutex>
27 #include <thread>
28 #include <iostream>
29 #include <regex>
30 
31 #include "ecmascript/napi/include/dfx_jsnapi.h"
32 #include "ecmascript/napi/include/jsnapi.h"
33 #include "native_engine/native_engine.h"
34 
35 namespace panda::ecmascript {
36 struct JsHeapDumpWork;
37 struct JsFrameInfo {
38     std::string functionName;
39     std::string fileName;
40     std::string pos;
41     uintptr_t* nativePointer = nullptr;
42 };
43 struct ApiCheckContext {
44     NativeModuleManager* moduleManager;
45     EcmaVM* ecmaVm;
46     panda::Local<panda::StringRef>& moduleName;
47     panda::Local<panda::ObjectRef>& exportObj;
48     panda::EscapeLocalScope& scope;
49 };
50 }
51 using ArkJsFrameInfo = panda::ecmascript::JsFrameInfo;
52 
53 using panda::DFXJSNApi;
54 using panda::Local;
55 using panda::LocalScope;
56 using panda::JSNApi;
57 using panda::JSValueRef;
58 using panda::JsiRuntimeCallInfo;
59 using panda::PropertyAttribute;
60 
61 panda::JSValueRef ArkNativeFunctionCallBack(JsiRuntimeCallInfo *runtimeInfo);
62 bool NapiDefineProperty(napi_env env, panda::Local<panda::ObjectRef> &obj, NapiPropertyDescriptor propertyDescriptor);
63 NAPI_EXPORT panda::Local<panda::JSValueRef> NapiValueToLocalValue(napi_value v);
64 NAPI_EXPORT napi_value LocalValueToLocalNapiValue(panda::Local<panda::JSValueRef> local);
65 void FunctionSetContainerId(const EcmaVM *vm, panda::Local<panda::JSValueRef> &local);
66 panda::Local<panda::JSValueRef> NapiDefineClass(napi_env env, const char* name, NapiNativeCallback callback,
67     void* data, const NapiPropertyDescriptor* properties, size_t length);
68 panda::Local<panda::ObjectRef> NapiCreateObjectWithProperties(napi_env env, size_t propertyCount,
69                                                               const napi_property_descriptor *properties,
70                                                               Local<panda::JSValueRef> *keys,
71                                                               PropertyAttribute *attrs);
72 
73 enum class ForceExpandState : int32_t {
74     FINISH_COLD_START = 0,
75     START_HIGH_SENSITIVE,
76     FINISH_HIGH_SENSITIVE,
77 };
78 
79 class SerializationData {
80 public:
SerializationData()81     SerializationData() : data_(nullptr), size_(0) {}
82     ~SerializationData() = default;
83 
GetData()84     uint8_t* GetData() const
85     {
86         return data_.get();
87     }
GetSize()88     size_t GetSize() const
89     {
90         return size_;
91     }
92 
93 private:
94     struct DataDeleter {
operatorDataDeleter95         void operator()(uint8_t* p) const
96         {
97             free(p);
98         }
99     };
100 
101     std::unique_ptr<uint8_t, DataDeleter> data_;
102     size_t size_;
103 };
104 
105 class NAPI_EXPORT ArkNativeEngine : public NativeEngine {
106 friend struct MoudleNameLocker;
107 public:
108     // ArkNativeEngine constructor
109     ArkNativeEngine(EcmaVM* vm, void* jsEngine, bool isLimitedWorker = false);
110     // ArkNativeEngine destructor
111     ~ArkNativeEngine() override;
112 
GetEcmaVm()113     NAPI_EXPORT const EcmaVM* GetEcmaVm() const override
114     {
115         return vm_;
116     }
117 
118     void Loop(LoopMode mode, bool needSync = false) override;
119     void SetPromiseRejectCallback(NativeReference* rejectCallbackRef, NativeReference* checkCallbackRef) override;
120     // For concurrent
121     bool InitTaskPoolThread(NativeEngine* engine, NapiConcurrentCallback callback) override;
122     bool InitTaskPoolThread(napi_env env, NapiConcurrentCallback callback) override;
123     bool InitTaskPoolFunc(napi_env env, napi_value func, void* taskInfo) override;
124     bool HasPendingJob() const override;
125     bool IsProfiling() const override;
126     bool IsExecutingPendingJob() const override;
127     void* GetCurrentTaskInfo() const override;
128     void TerminateExecution() const override;
129     // Call function
130     napi_value CallFunction(napi_value thisVar,
131                             napi_value function,
132                             napi_value const* argv,
133                             size_t argc) override;
134     bool RunScriptPath(const char* path) override;
135 
136     virtual void StartMonitorJSHeapUsage() override;
137     virtual void StopMonitorJSHeapUsage() override;
138     napi_value RunScriptBuffer(const char* path, std::vector<uint8_t>& buffer, bool isBundle) override;
139     bool RunScriptBuffer(const std::string& path, uint8_t* buffer, size_t size, bool isBundle) override;
140 
141     // Run buffer script
142     napi_value RunBufferScript(std::vector<uint8_t>& buffer) override;
143     napi_value RunActor(std::vector<uint8_t>& buffer, const char* descriptor, char* entryPoint = nullptr) override;
144     // Set lib path
145     NAPI_EXPORT void SetPackagePath(const std::string appLinPathKey, const std::vector<std::string>& packagePath);
146     napi_value CreateInstance(napi_value constructor, napi_value const* argv, size_t argc) override;
147 
148     // Create native reference
149     NativeReference* CreateReference(napi_value value, uint32_t initialRefcount, bool flag = false,
150         NapiNativeFinalize callback = nullptr, void* data = nullptr, void* hint = nullptr) override;
151     napi_value CreatePromise(NativeDeferred** deferred) override;
152     void* CreateRuntime(bool isLimitedWorker = false) override;
153     panda::Local<panda::ObjectRef> LoadArkModule(const void *buffer, int32_t len, const std::string& fileName);
154     napi_value ValueToNapiValue(JSValueWrapper& value) override;
155     NAPI_EXPORT static napi_value ArkValueToNapiValue(napi_env env, Local<JSValueRef> value);
156 
157     std::string GetSourceCodeInfo(napi_value value, ErrorPos pos) override;
158 
159     NAPI_EXPORT bool ExecuteJsBin(const std::string& fileName);
160     NAPI_EXPORT panda::Local<panda::ObjectRef> LoadModuleByName(const std::string& moduleName, bool isAppModule,
161         const std::string& param, const std::string& instanceName, void* instance, const std::string& path = "");
162 
163     bool TriggerFatalException(napi_value error) override;
164     bool AdjustExternalMemory(int64_t ChangeInBytes, int64_t* AdjustedValue) override;
165 
166     // Detect performance to obtain cpuprofiler file
167     void StartCpuProfiler(const std::string& fileName = "") override;
168     void StopCpuProfiler() override;
169 
170     void ResumeVM() override;
171     bool SuspendVM() override;
172     bool IsSuspended() override;
173     bool CheckSafepoint() override;
174     bool SuspendVMById(uint32_t tid) override;
175     void ResumeVMById(uint32_t tid) override;
176 
177     // isVmMode means the internal class in vm is visible.
178     // isPrivate means the number and string is not visible.
179     void DumpHeapSnapshot(const std::string& path, bool isVmMode = true,
180         DumpFormat dumpFormat = DumpFormat::JSON) override;
181     void DumpCpuProfile(bool isVmMode = true, DumpFormat dumpFormat = DumpFormat::JSON,
182         bool isPrivate = false, bool isFullGC = true) override;
183     // Dump the file into faultlog for heap leak.
184     void DumpHeapSnapshot(bool isVmMode = true, DumpFormat dumpFormat = DumpFormat::JSON,
185         bool isPrivate = false, bool isFullGC = true) override;
186     bool BuildNativeAndJsStackTrace(std::string& stackTraceStr) override;
187     bool BuildJsStackTrace(std::string& stackTraceStr) override;
188     bool BuildJsStackInfoList(uint32_t tid, std::vector<JsFrameInfo>& jsFrames) override;
189 
190     bool DeleteWorker(NativeEngine* workerEngine) override;
191     bool StartHeapTracking(double timeInterval, bool isVmMode = true) override;
192     bool StopHeapTracking(const std::string& filePath) override;
193 
194     void PrintStatisticResult() override;
195     void StartRuntimeStat() override;
196     void StopRuntimeStat() override;
197     size_t GetArrayBufferSize() override;
198     size_t GetHeapTotalSize() override;
199     size_t GetHeapUsedSize() override;
200     size_t GetHeapObjectSize() override;
201     size_t GetHeapLimitSize() override;
202     void NotifyApplicationState(bool inBackground) override;
203     void NotifyIdleStatusControl(std::function<void(bool)> callback) override;
204     void NotifyIdleTime(int idleMicroSec) override;
205     void NotifyMemoryPressure(bool inHighMemoryPressure = false) override;
206     void NotifyForceExpandState(int32_t value) override;
207 
208     void AllowCrossThreadExecution() const override;
209     static void PromiseRejectCallback(void* values);
210 
211     void SetMockModuleList(const std::map<std::string, std::string> &list) override;
212 
213     // debugger
214     bool IsMixedDebugEnabled();
215     void JsHeapStart();
216     uint64_t GetCurrentTickMillseconds();
217     void JudgmentDump(size_t limitSize);
218     void NotifyNativeCalling(const void *nativeAddress);
219 
220     void RegisterNapiUncaughtExceptionHandler(NapiUncaughtExceptionCallback callback) override;
221     void HandleUncaughtException() override;
222     bool HasPendingException() override;
223     void RegisterPermissionCheck(PermissionCheckCallback callback) override;
224     bool ExecutePermissionCheck() override;
225     void RegisterTranslateBySourceMap(SourceMapCallback callback) override;
226     std::string ExecuteTranslateBySourceMap(const std::string& rawStack) override;
227         void RegisterSourceMapTranslateCallback(SourceMapTranslateCallback callback) override;
228     panda::Local<panda::ObjectRef> GetModuleFromName(
229         const std::string& moduleName, bool isAppModule, const std::string& id, const std::string& param,
230         const std::string& instanceName, void** instance);
231     napi_value NapiLoadModule(const char* str) override;
232     std::string GetOhmurl(const char* str);
GetPromiseRejectCallBackRef()233     NativeReference* GetPromiseRejectCallBackRef()
234     {
235         return promiseRejectCallbackRef_;
236     }
237 
SetPromiseRejectCallBackRef(NativeReference * rejectCallbackRef)238     void SetPromiseRejectCallBackRef(NativeReference* rejectCallbackRef) override
239     {
240         promiseRejectCallbackRef_ = rejectCallbackRef;
241     }
242 
GetConcurrentCallbackFunc()243     NapiConcurrentCallback GetConcurrentCallbackFunc()
244     {
245         return concurrentCallbackFunc_;
246     }
247 
GetCheckCallbackRef()248     NativeReference* GetCheckCallbackRef()
249     {
250         return checkCallbackRef_;
251     }
252 
SetCheckCallbackRef(NativeReference * checkCallbackRef)253     void SetCheckCallbackRef(NativeReference* checkCallbackRef) override
254     {
255         checkCallbackRef_ = checkCallbackRef;
256     }
257 
GetNapiUncaughtExceptionCallback()258     NapiUncaughtExceptionCallback GetNapiUncaughtExceptionCallback() override
259     {
260         return napiUncaughtExceptionCallback_;
261     }
262 
GetPromiseRejectCallback()263     void* GetPromiseRejectCallback() override
264     {
265         return reinterpret_cast<void*>(PromiseRejectCallback);
266     }
267 
268     void SetModuleName(panda::Local<panda::ObjectRef> &nativeObj, std::string moduleName);
269     void GetCurrentModuleInfo(std::string& moduleName, std::string& fileName, bool needRecordName) override;
270     bool GetIsBundle() override;
271 
272     static bool napiProfilerEnabled;
273     static std::string tempModuleName_;
274 
275     static void* GetNativePtrCallBack(void* data);
276     static void CopyPropertyApiFilter(const std::unique_ptr<ApiAllowListChecker>& apiAllowListChecker,
277         const EcmaVM* ecmaVm, const panda::Local<panda::ObjectRef> exportObj,
278         panda::Local<panda::ObjectRef>& exportCopy, const std::string& apiPath);
279 
280 private:
281     static NativeEngine* CreateRuntimeFunc(NativeEngine* engine, void* jsEngine, bool isLimitedWorker = false);
282     static bool CheckArkApiAllowList(
283         NativeModule* module, panda::ecmascript::ApiCheckContext context, panda::Local<panda::ObjectRef>& exportCopy);
284     EcmaVM* vm_ = nullptr;
285     bool needStop_ = false;
286     panda::LocalScope topScope_;
287     NapiConcurrentCallback concurrentCallbackFunc_ { nullptr };
288     NativeReference* promiseRejectCallbackRef_ { nullptr };
289     NativeReference* checkCallbackRef_ { nullptr };
290     std::map<NativeModule*, panda::Global<panda::JSValueRef>> loadedModules_;
291     static PermissionCheckCallback permissionCheckCallback_;
292     NapiUncaughtExceptionCallback napiUncaughtExceptionCallback_ { nullptr };
293     SourceMapCallback SourceMapCallback_ { nullptr };
294     static bool napiProfilerParamReaded;
295     std::once_flag flag_;
296     std::unique_ptr<std::thread> threadJsHeap_;
297     std::mutex lock_;
298     std::condition_variable condition_;
299     bool isLimitedWorker_ = false;
300     struct JsHeapDumpWork *dumpWork_;
301 };
302 #endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_IMPL_ARK_ARK_NATIVE_ENGINE_H */
303