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 27 #include "frameworks/bridge/js_frontend/engine/jsi/js_runtime.h" 28 29 namespace panda::ecmascript { 30 class EcmaVM; 31 } // namespace panda::ecmascript 32 33 // NOLINTNEXTLINE(readability-identifier-naming) 34 namespace OHOS::Ace::Framework { 35 using panda::ArrayRef; 36 using panda::BooleanRef; 37 using panda::EscapeLocalScope; 38 using panda::FunctionRef; 39 using panda::Global; 40 using panda::IntegerRef; 41 using panda::JSExecutionScope; 42 using panda::JSNApi; 43 using panda::JSON; 44 using panda::JSValueRef; 45 using panda::Local; 46 using panda::LocalScope; 47 using panda::NativePointerRef; 48 using panda::NumberRef; 49 using panda::ObjectRef; 50 using panda::RuntimeOption; 51 using panda::StringRef; 52 using panda::ecmascript::EcmaVM; 53 class PandaFunctionData; 54 55 using DebuggerPostTask = std::function<void(std::function<void()>&&)>; 56 57 // NOLINTNEXTLINE(fuchsia-multiple-inheritance) 58 class ArkJSRuntime final : public JsRuntime, public std::enable_shared_from_this<ArkJSRuntime> { 59 public: 60 using ErrorEventHandler = std::function<void(const std::string&, const std::string&)>; 61 #if !defined(WINDOWS_PLATFORM) 62 bool StartDebugger(const char* libraryPath, EcmaVM* vm) const; 63 #endif 64 bool Initialize(const std::string& libraryPath, bool isDebugMode, int32_t instanceId) override; 65 bool InitializeFromExistVM(EcmaVM* vm); 66 void Reset() override; 67 void SetLogPrint(LOG_PRINT out) override; 68 bool StartDebugger() override; 69 shared_ptr<JsValue> EvaluateJsCode(const std::string& src) override; 70 bool EvaluateJsCode( 71 const uint8_t* buffer, int32_t size, const std::string& filePath = "", bool needUpdate = false) override; 72 bool ExecuteJsBin(const std::string& fileName, 73 const std::function<void(const std::string&, int32_t)>& errorCallback = nullptr) override; 74 shared_ptr<JsValue> GetGlobal() override; 75 void RunGC() override; 76 void RunFullGC() override; 77 78 shared_ptr<JsValue> NewNumber(double d) override; 79 shared_ptr<JsValue> NewInt32(int32_t value) override; 80 shared_ptr<JsValue> NewBoolean(bool value) override; 81 shared_ptr<JsValue> NewNull() override; 82 shared_ptr<JsValue> NewUndefined() override; 83 shared_ptr<JsValue> NewString(const std::string& str) override; 84 shared_ptr<JsValue> ParseJson(const std::string& str) override; 85 shared_ptr<JsValue> NewObject() override; 86 shared_ptr<JsValue> NewArray() override; 87 shared_ptr<JsValue> NewFunction(RegisterFunctionType func) override; 88 shared_ptr<JsValue> NewNativePointer(void* ptr) override; 89 void ThrowError(const std::string& msg, int32_t code) override; 90 void RegisterUncaughtExceptionHandler(UncaughtExceptionCallback callback) override; 91 void HandleUncaughtException( 92 const std::function<void(const std::string&, int32_t)>& errorCallback = nullptr) override; 93 bool HasPendingException() override; 94 void ExecutePendingJob() override; 95 void DumpHeapSnapshot(bool isPrivate) override; 96 bool ExecuteModuleBuffer(const uint8_t *data, int32_t size, const std::string &filename, bool needUpdate = false); 97 GetEcmaVm()98 const EcmaVM* GetEcmaVm() const 99 { 100 return vm_; 101 } 102 SetAssetPath(const std::string & assetPath)103 void SetAssetPath(const std::string& assetPath) 104 { 105 panda::JSNApi::SetAssetPath(vm_, assetPath); 106 } 107 SetBundleName(const std::string & bundleName)108 void SetBundleName(const std::string& bundleName) 109 { 110 panda::JSNApi::SetBundleName(vm_, bundleName); 111 } 112 SetBundle(bool isBundle)113 void SetBundle(bool isBundle) 114 { 115 panda::JSNApi::SetBundle(vm_, isBundle); 116 } 117 SetModuleName(const std::string & moduleName)118 void SetModuleName(const std::string& moduleName) 119 { 120 panda::JSNApi::SetModuleName(vm_, moduleName); 121 } 122 SetDebuggerPostTask(DebuggerPostTask && task)123 void SetDebuggerPostTask(DebuggerPostTask&& task) 124 { 125 debuggerPostTask_ = std::move(task); 126 } 127 SetErrorEventHandler(ErrorEventHandler && errorCallback)128 void SetErrorEventHandler(ErrorEventHandler&& errorCallback) override 129 { 130 errorCallback_ = std::move(errorCallback); 131 } 132 GetErrorEventHandler()133 const ErrorEventHandler& GetErrorEventHandler() 134 { 135 return errorCallback_; 136 } 137 138 #if defined(PREVIEW) SetPreviewFlag(bool flag)139 void SetPreviewFlag(bool flag) 140 { 141 isComponentPreview_ = flag; 142 } 143 GetPreviewFlag()144 bool GetPreviewFlag() const 145 { 146 return isComponentPreview_; 147 } 148 GetRequiredComponent()149 std::string GetRequiredComponent() const 150 { 151 return requiredComponent_; 152 } 153 SetRequiredComponent(const std::string & componentName)154 void SetRequiredComponent(const std::string &componentName) 155 { 156 requiredComponent_ = componentName; 157 } 158 AddPreviewComponent(const std::string & componentName,const panda::Global<panda::ObjectRef> & componentObj)159 void AddPreviewComponent(const std::string &componentName, const panda::Global<panda::ObjectRef> &componentObj) 160 { 161 previewComponents_.emplace(componentName, componentObj); 162 } 163 GetPreviewComponent(EcmaVM * vm,const std::string & componentName)164 panda::Global<panda::ObjectRef> GetPreviewComponent(EcmaVM* vm, const std::string &componentName) 165 { 166 auto iter = previewComponents_.find(componentName); 167 if (iter != previewComponents_.end()) { 168 auto retVal = iter->second; 169 previewComponents_.erase(iter); 170 return retVal; 171 } 172 panda::Global<panda::ObjectRef> undefined(vm, panda::JSValueRef::Undefined(vm)); 173 return undefined; 174 } 175 AddRootView(const panda::Global<panda::ObjectRef> & RootView)176 void AddRootView(const panda::Global<panda::ObjectRef> &RootView) 177 { 178 RootView_ = RootView; 179 } 180 GetRootView()181 panda::Global<panda::ObjectRef> GetRootView() 182 { 183 return RootView_; 184 } 185 #endif 186 187 private: 188 EcmaVM* vm_ = nullptr; 189 int32_t instanceId_ = 0; 190 LOG_PRINT print_ { nullptr }; 191 UncaughtExceptionCallback uncaughtErrorHandler_ { nullptr }; 192 std::string libPath_ {}; 193 bool usingExistVM_ = false; 194 bool isDebugMode_ = true; 195 DebuggerPostTask debuggerPostTask_; 196 ErrorEventHandler errorCallback_; 197 #if defined(PREVIEW) 198 bool isComponentPreview_ = false; 199 std::string requiredComponent_ {}; 200 std::multimap<std::string, panda::Global<panda::ObjectRef>> previewComponents_; 201 panda::Global<panda::ObjectRef> RootView_; 202 #endif 203 }; 204 205 class PandaFunctionData { 206 public: PandaFunctionData(std::weak_ptr<ArkJSRuntime> runtime,RegisterFunctionType func)207 PandaFunctionData(std::weak_ptr<ArkJSRuntime> runtime, RegisterFunctionType func) 208 : runtime_(runtime), func_(std::move(func)) 209 {} 210 211 ~PandaFunctionData() = default; 212 213 NO_COPY_SEMANTIC(PandaFunctionData); 214 NO_MOVE_SEMANTIC(PandaFunctionData); 215 216 private: 217 Local<JSValueRef> Callback(panda::JsiRuntimeCallInfo* info) const; 218 std::weak_ptr<ArkJSRuntime> runtime_; 219 RegisterFunctionType func_; 220 friend Local<JSValueRef> FunctionCallback(panda::JsiRuntimeCallInfo* info); 221 }; 222 } // namespace OHOS::Ace::Framework 223 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_ENGINE_JSI_ARK_JS_RUNTIME_H 224