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_FRAMEWORKS_BRIDGE_ENGINE_JSI_ARK_JS_RUNTIME_H 17 #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_ENGINE_JSI_ARK_JS_RUNTIME_H 18 19 #if defined(PREVIEW) 20 #include <map> 21 #include "frameworks/bridge/declarative_frontend/engine/jsi/utils/jsi_module_searcher.h" 22 #endif 23 #include <memory> 24 25 #include "ecmascript/napi/include/jsnapi.h" 26 #include "native_engine/native_engine.h" 27 28 #include "base/log/log.h" 29 #include "frameworks/bridge/js_frontend/engine/jsi/js_runtime.h" 30 31 namespace panda::ecmascript { 32 class EcmaVM; 33 } // namespace panda::ecmascript 34 35 // NOLINTNEXTLINE(readability-identifier-naming) 36 namespace OHOS::Ace::Framework { 37 using panda::ArrayRef; 38 using panda::BooleanRef; 39 using panda::EscapeLocalScope; 40 using panda::FunctionRef; 41 using panda::Global; 42 using panda::IntegerRef; 43 using panda::JSExecutionScope; 44 using panda::JSNApi; 45 using panda::JSON; 46 using panda::JSValueRef; 47 using panda::Local; 48 using panda::LocalScope; 49 using panda::NativePointerRef; 50 using panda::NumberRef; 51 using panda::ObjectRef; 52 using panda::RuntimeOption; 53 using panda::StringRef; 54 using panda::ecmascript::EcmaVM; 55 class PandaFunctionData; 56 57 using DebuggerPostTask = std::function<void(std::function<void()>&&)>; 58 59 // NOLINTNEXTLINE(fuchsia-multiple-inheritance) 60 class ArkJSRuntime final : public JsRuntime, public std::enable_shared_from_this<ArkJSRuntime> { 61 public: 62 using ErrorEventHandler = std::function<void(const std::string&, const std::string&)>; 63 #if !defined(PREVIEW) 64 void StartDebuggerForSocketPair(std::string& option, uint32_t socketFd); 65 #endif 66 void SetUniqueId(const std::string& uniqueId) override; 67 const std::string& GetUniqueId() const override; 68 bool Initialize(const std::string& libraryPath, bool isDebugMode, int32_t instanceId) override; 69 bool InitializeFromExistVM(EcmaVM* vm); 70 void Reset() override; 71 void SetLogPrint(LOG_PRINT out) override; 72 bool StartDebugger() override; 73 shared_ptr<JsValue> EvaluateJsCode(const std::string& src) override; 74 bool EvaluateJsCode( 75 const uint8_t* buffer, int32_t size, const std::string& filePath = "", bool needUpdate = false) override; 76 bool ExecuteJsBin(const std::string& fileName, 77 const std::function<void(const std::string&, int32_t)>& errorCallback = nullptr) override; 78 bool ExecuteJsBinForAOT(const std::string& fileName, 79 const std::function<void(const std::string&, int32_t)>& errorCallback = nullptr) override; 80 shared_ptr<JsValue> GetGlobal() override; 81 void RunGC() override; 82 void RunFullGC() override; 83 84 shared_ptr<JsValue> NewNumber(double d) override; 85 shared_ptr<JsValue> NewInt32(int32_t value) override; 86 shared_ptr<JsValue> NewBoolean(bool value) override; 87 shared_ptr<JsValue> NewNull() override; 88 shared_ptr<JsValue> NewUndefined() override; 89 shared_ptr<JsValue> NewString(const std::string& str) override; 90 shared_ptr<JsValue> ParseJson(const std::string& str) override; 91 shared_ptr<JsValue> NewObject() override; 92 shared_ptr<JsValue> NewArray() override; 93 shared_ptr<JsValue> NewFunction(RegisterFunctionType func) override; 94 shared_ptr<JsValue> NewNativePointer(void* ptr) override; 95 void ThrowError(const std::string& msg, int32_t code) override; 96 void RegisterUncaughtExceptionHandler(UncaughtExceptionCallback callback) override; 97 void HandleUncaughtException(panda::TryCatch& tryCatch, 98 const std::function<void(const std::string&, int32_t)>& errorCallback = nullptr) override; 99 void HandleUncaughtExceptionWithoutNativeEngine(panda::TryCatch& trycatch, 100 const std::function<void(const std::string&, int32_t)>& errorCallback = nullptr) override; 101 bool HasPendingException() override; 102 void ExecutePendingJob() override; 103 void DumpHeapSnapshot(bool isPrivate) override; 104 void NotifyUIIdle() override; 105 void DestroyHeapProfiler() override; 106 bool IsExecuteModuleInAbcFile( 107 const std::string &bundleName, const std::string &moduleName, const std::string &ohmurl); 108 bool ExecuteModuleBuffer(const uint8_t *data, int32_t size, const std::string &filename, bool needUpdate = false); 109 110 int32_t LoadDestinationFile(const std::string& bundleName, const std::string& moduleName, 111 const std::string& pageSourceFile, bool isSingleton); 112 GetEcmaVm()113 const EcmaVM* GetEcmaVm() const override 114 { 115 return GetThreadVm() ? GetThreadVm() : vm_; 116 } 117 GetThreadVm()118 const EcmaVM* GetThreadVm() const 119 { 120 return threadVm_; 121 } 122 SetThreadVm(EcmaVM * vm)123 void SetThreadVm(EcmaVM* vm) 124 { 125 threadVm_ = vm; 126 } 127 SetAssetPath(const std::string & assetPath)128 void SetAssetPath(const std::string& assetPath) 129 { 130 panda::JSNApi::SetAssetPath(vm_, assetPath); 131 } 132 SetBundleName(const std::string & bundleName)133 void SetBundleName(const std::string& bundleName) 134 { 135 panda::JSNApi::SetBundleName(vm_, bundleName); 136 } 137 SetBundle(bool isBundle)138 void SetBundle(bool isBundle) 139 { 140 panda::JSNApi::SetBundle(vm_, isBundle); 141 } 142 SetModuleName(const std::string & moduleName)143 void SetModuleName(const std::string& moduleName) 144 { 145 panda::JSNApi::SetModuleName(vm_, moduleName); 146 } 147 SetDebuggerPostTask(DebuggerPostTask && task)148 void SetDebuggerPostTask(DebuggerPostTask&& task) 149 { 150 debuggerPostTask_ = std::move(task); 151 } 152 SetErrorEventHandler(ErrorEventHandler && errorCallback)153 void SetErrorEventHandler(ErrorEventHandler&& errorCallback) override 154 { 155 errorCallback_ = std::move(errorCallback); 156 } 157 GetErrorEventHandler()158 const ErrorEventHandler& GetErrorEventHandler() 159 { 160 return errorCallback_; 161 } 162 SetDebugMode(bool isDebugMode)163 void SetDebugMode(bool isDebugMode) 164 { 165 isDebugMode_ = isDebugMode; 166 } 167 SetInstanceId(int32_t instanceId)168 void SetInstanceId(int32_t instanceId) 169 { 170 instanceId_ = instanceId; 171 } 172 SetLanguage(const std::string & language)173 void SetLanguage(const std::string& language) 174 { 175 language_ = language; 176 } 177 SetNativeEngine(NativeEngine * nativeEngine)178 void SetNativeEngine(NativeEngine* nativeEngine) 179 { 180 nativeEngine_ = nativeEngine; 181 } 182 GetNativeEngine()183 NativeEngine* GetNativeEngine() const 184 { 185 return nativeEngine_; 186 } 187 188 #if defined(PREVIEW) SetPkgNameList(const std::map<std::string,std::string> & map)189 void SetPkgNameList(const std::map<std::string, std::string>& map) 190 { 191 pkgNameMap_ = map; 192 } 193 SetPkgAliasList(const std::map<std::string,std::string> & map)194 void SetPkgAliasList(const std::map<std::string, std::string>& map) 195 { 196 pkgAliasMap_ = map; 197 } 198 SetpkgContextInfoList(const std::map<std::string,std::vector<std::vector<std::string>>> & map)199 void SetpkgContextInfoList(const std::map<std::string, std::vector<std::vector<std::string>>>& map) 200 { 201 pkgContextInfoMap_ = map; 202 } 203 SetPreviewFlag(bool flag)204 void SetPreviewFlag(bool flag) 205 { 206 isComponentPreview_ = flag; 207 } 208 GetPreviewFlag()209 bool GetPreviewFlag() const 210 { 211 return isComponentPreview_; 212 } 213 GetRequiredComponent()214 std::string GetRequiredComponent() const 215 { 216 return requiredComponent_; 217 } 218 SetRequiredComponent(const std::string & componentName)219 void SetRequiredComponent(const std::string &componentName) 220 { 221 requiredComponent_ = componentName; 222 } 223 AddPreviewComponent(const std::string & componentName,const panda::Global<panda::ObjectRef> & componentObj)224 void AddPreviewComponent(const std::string &componentName, const panda::Global<panda::ObjectRef> &componentObj) 225 { 226 previewComponents_.emplace(componentName, componentObj); 227 } 228 GetPreviewComponent(EcmaVM * vm,const std::string & componentName)229 panda::Global<panda::ObjectRef> GetPreviewComponent(EcmaVM* vm, const std::string &componentName) 230 { 231 auto iter = previewComponents_.find(componentName); 232 if (iter != previewComponents_.end()) { 233 auto retVal = iter->second; 234 previewComponents_.erase(iter); 235 return retVal; 236 } 237 panda::Global<panda::ObjectRef> undefined(vm, panda::JSValueRef::Undefined(vm)); 238 return undefined; 239 } 240 AddRootView(const panda::Global<panda::ObjectRef> & RootView)241 void AddRootView(const panda::Global<panda::ObjectRef> &RootView) 242 { 243 RootView_ = RootView; 244 } 245 GetRootView()246 panda::Global<panda::ObjectRef> GetRootView() 247 { 248 return RootView_; 249 } 250 #endif 251 252 private: 253 EcmaVM* vm_ = nullptr; 254 int32_t instanceId_ = 0; 255 std::string uniqueId_; 256 std::string language_; 257 LOG_PRINT print_ { nullptr }; 258 UncaughtExceptionCallback uncaughtErrorHandler_ { nullptr }; 259 std::string libPath_ {}; 260 bool usingExistVM_ = false; 261 bool isDebugMode_ = false; 262 DebuggerPostTask debuggerPostTask_; 263 ErrorEventHandler errorCallback_; 264 NativeEngine* nativeEngine_; 265 #if defined(PREVIEW) 266 bool isComponentPreview_ = false; 267 std::string requiredComponent_ {}; 268 std::multimap<std::string, panda::Global<panda::ObjectRef>> previewComponents_; 269 panda::Global<panda::ObjectRef> RootView_; 270 std::map<std::string, std::string> pkgNameMap_; 271 std::map<std::string, std::string> pkgAliasMap_; 272 std::map<std::string, std::vector<std::vector<std::string>>> pkgContextInfoMap_; 273 #endif 274 static thread_local EcmaVM* threadVm_; 275 }; 276 277 class PandaFunctionData { 278 public: PandaFunctionData(std::weak_ptr<ArkJSRuntime> runtime,RegisterFunctionType func)279 PandaFunctionData(std::weak_ptr<ArkJSRuntime> runtime, RegisterFunctionType func) 280 : runtime_(runtime), func_(std::move(func)) 281 {} 282 283 ~PandaFunctionData() = default; 284 285 PandaFunctionData(const PandaFunctionData&) = delete; 286 void operator=(const PandaFunctionData&) = delete; 287 PandaFunctionData(PandaFunctionData&&) = delete; 288 PandaFunctionData& operator=(PandaFunctionData&&) = delete; 289 290 private: 291 Local<JSValueRef> Callback(panda::JsiRuntimeCallInfo* info) const; 292 std::weak_ptr<ArkJSRuntime> runtime_; 293 RegisterFunctionType func_; 294 friend Local<JSValueRef> FunctionCallback(panda::JsiRuntimeCallInfo* info); 295 }; 296 } // namespace OHOS::Ace::Framework 297 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_ENGINE_JSI_ARK_JS_RUNTIME_H 298