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