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/impl/ark/ark_native_engine.h" 27 #include "native_engine/native_engine.h" 28 29 #include "base/log/log.h" 30 #include "frameworks/bridge/js_frontend/engine/jsi/js_runtime.h" 31 32 namespace panda::ecmascript { 33 class EcmaVM; 34 } // namespace panda::ecmascript 35 36 // NOLINTNEXTLINE(readability-identifier-naming) 37 namespace OHOS::Ace::Framework { 38 using panda::ArrayRef; 39 using panda::BooleanRef; 40 using panda::EscapeLocalScope; 41 using panda::FunctionRef; 42 using panda::Global; 43 using panda::IntegerRef; 44 using panda::JSExecutionScope; 45 using panda::JSNApi; 46 using panda::JSON; 47 using panda::JSValueRef; 48 using panda::Local; 49 using panda::LocalScope; 50 using panda::NativePointerRef; 51 using panda::NumberRef; 52 using panda::ObjectRef; 53 using panda::RuntimeOption; 54 using panda::StringRef; 55 using panda::ecmascript::EcmaVM; 56 class PandaFunctionData; 57 58 using DebuggerPostTask = std::function<void(std::function<void()>&&)>; 59 60 // NOLINTNEXTLINE(fuchsia-multiple-inheritance) 61 class ArkJSRuntime final : public JsRuntime, public std::enable_shared_from_this<ArkJSRuntime> { 62 public: 63 using ErrorEventHandler = std::function<void(const std::string&, const std::string&)>; 64 #if !defined(PREVIEW) 65 void StartDebuggerForSocketPair(std::string& option, uint32_t socketFd); 66 #endif 67 bool Initialize(const std::string& libraryPath, bool isDebugMode, int32_t instanceId) override; 68 bool InitializeFromExistVM(EcmaVM* vm); 69 void Reset() override; 70 void SetLogPrint(LOG_PRINT out) override; 71 bool StartDebugger() override; 72 shared_ptr<JsValue> EvaluateJsCode(const std::string& src) override; 73 bool EvaluateJsCode( 74 const uint8_t* buffer, int32_t size, const std::string& filePath = "", bool needUpdate = false) override; 75 bool ExecuteJsBin(const std::string& fileName, 76 const std::function<void(const std::string&, int32_t)>& errorCallback = nullptr) override; 77 bool ExecuteJsBinForAOT(const std::string& fileName, 78 const std::function<void(const std::string&, int32_t)>& errorCallback = nullptr) override; 79 shared_ptr<JsValue> GetGlobal() override; 80 shared_ptr<JsValue> GetGlobal(ArkNativeEngine* nativeArkEngine); 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 IsStaticOrInvalidFile(const uint8_t *data, int32_t size); 109 bool ExecuteModuleBuffer(const uint8_t *data, int32_t size, const std::string &filename, bool needUpdate = false); 110 111 int32_t LoadDestinationFile(const std::string& bundleName, const std::string& moduleName, 112 const std::string& pageSourceFile, bool isSingleton); 113 GetEcmaVm()114 const EcmaVM* GetEcmaVm() const override 115 { 116 return GetThreadVm() ? GetThreadVm() : vm_; 117 } 118 GetThreadVm()119 const EcmaVM* GetThreadVm() const 120 { 121 return threadVm_; 122 } 123 SetThreadVm(EcmaVM * vm)124 void SetThreadVm(EcmaVM* vm) 125 { 126 threadVm_ = vm; 127 } 128 SetAssetPath(const std::string & assetPath)129 void SetAssetPath(const std::string& assetPath) 130 { 131 panda::JSNApi::SetAssetPath(vm_, assetPath); 132 } 133 SetBundleName(const std::string & bundleName)134 void SetBundleName(const std::string& bundleName) 135 { 136 panda::JSNApi::SetBundleName(vm_, bundleName); 137 } 138 SetBundle(bool isBundle)139 void SetBundle(bool isBundle) 140 { 141 panda::JSNApi::SetBundle(vm_, isBundle); 142 } 143 SetModuleName(const std::string & moduleName)144 void SetModuleName(const std::string& moduleName) 145 { 146 panda::JSNApi::SetModuleName(vm_, moduleName); 147 } 148 SetDebuggerPostTask(DebuggerPostTask && task)149 void SetDebuggerPostTask(DebuggerPostTask&& task) 150 { 151 debuggerPostTask_ = std::move(task); 152 } 153 SetErrorEventHandler(ErrorEventHandler && errorCallback)154 void SetErrorEventHandler(ErrorEventHandler&& errorCallback) override 155 { 156 errorCallback_ = std::move(errorCallback); 157 } 158 GetErrorEventHandler()159 const ErrorEventHandler& GetErrorEventHandler() 160 { 161 return errorCallback_; 162 } 163 SetDebugMode(bool isDebugMode)164 void SetDebugMode(bool isDebugMode) 165 { 166 isDebugMode_ = isDebugMode; 167 } 168 SetInstanceId(int32_t instanceId)169 void SetInstanceId(int32_t instanceId) 170 { 171 instanceId_ = instanceId; 172 } 173 SetLanguage(const std::string & language)174 void SetLanguage(const std::string& language) 175 { 176 language_ = language; 177 } 178 SetNativeEngine(NativeEngine * nativeEngine)179 void SetNativeEngine(NativeEngine* nativeEngine) 180 { 181 nativeEngine_ = nativeEngine; 182 } 183 GetNativeEngine()184 NativeEngine* GetNativeEngine() const 185 { 186 return nativeEngine_; 187 } 188 189 #if defined(PREVIEW) SetPkgNameList(const std::map<std::string,std::string> & map)190 void SetPkgNameList(const std::map<std::string, std::string>& map) 191 { 192 pkgNameMap_ = map; 193 } 194 SetPkgAliasList(const std::map<std::string,std::string> & map)195 void SetPkgAliasList(const std::map<std::string, std::string>& map) 196 { 197 pkgAliasMap_ = map; 198 } 199 SetpkgContextInfoList(const std::map<std::string,std::vector<std::vector<std::string>>> & map)200 void SetpkgContextInfoList(const std::map<std::string, std::vector<std::vector<std::string>>>& map) 201 { 202 pkgContextInfoMap_ = map; 203 } 204 SetPreviewFlag(bool flag)205 void SetPreviewFlag(bool flag) 206 { 207 isComponentPreview_ = flag; 208 } 209 GetPreviewFlag()210 bool GetPreviewFlag() const 211 { 212 return isComponentPreview_; 213 } 214 GetRequiredComponent()215 std::string GetRequiredComponent() const 216 { 217 return requiredComponent_; 218 } 219 SetRequiredComponent(const std::string & componentName)220 void SetRequiredComponent(const std::string &componentName) 221 { 222 requiredComponent_ = componentName; 223 } 224 AddPreviewComponent(const std::string & componentName,const panda::Global<panda::ObjectRef> & componentObj)225 void AddPreviewComponent(const std::string &componentName, const panda::Global<panda::ObjectRef> &componentObj) 226 { 227 previewComponents_.emplace(componentName, componentObj); 228 } 229 GetPreviewComponent(EcmaVM * vm,const std::string & componentName)230 panda::Global<panda::ObjectRef> GetPreviewComponent(EcmaVM* vm, const std::string &componentName) 231 { 232 auto iter = previewComponents_.find(componentName); 233 if (iter != previewComponents_.end()) { 234 auto retVal = iter->second; 235 previewComponents_.erase(iter); 236 return retVal; 237 } 238 panda::Global<panda::ObjectRef> undefined(vm, panda::JSValueRef::Undefined(vm)); 239 return undefined; 240 } 241 AddRootView(const panda::Global<panda::ObjectRef> & RootView)242 void AddRootView(const panda::Global<panda::ObjectRef> &RootView) 243 { 244 RootView_ = RootView; 245 } 246 GetRootView()247 panda::Global<panda::ObjectRef> GetRootView() 248 { 249 return RootView_; 250 } 251 #endif 252 253 private: 254 EcmaVM* vm_ = nullptr; 255 int32_t instanceId_ = 0; 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