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