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