1 /* 2 * Copyright (c) 2022-2023 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 ECMASCRIPT_DEBUGGER_JS_DEBUGGER_MANAGER_H 17 #define ECMASCRIPT_DEBUGGER_JS_DEBUGGER_MANAGER_H 18 19 #include <shared_mutex> 20 #include <unordered_map> 21 22 #include "ecmascript/debugger/hot_reload_manager.h" 23 #include "ecmascript/debugger/notification_manager.h" 24 #include "ecmascript/debugger/dropframe_manager.h" 25 #include "ecmascript/ecma_vm.h" 26 #include "ecmascript/interpreter/frame_handler.h" 27 #include "ecmascript/js_thread.h" 28 #include "ecmascript/napi/include/jsnapi.h" 29 #include "ecmascript/global_handle_collection.h" 30 31 #include "libpandabase/os/library_loader.h" 32 33 namespace panda::ecmascript::tooling { 34 class ProtocolHandler; 35 class JsDebuggerManager { 36 public: 37 using LibraryHandle = os::library_loader::LibraryHandle; 38 using ObjectUpdaterFunc = 39 std::function<void(const FrameHandler *, std::string_view, Local<JSValueRef>)>; 40 using SingleStepperFunc = std::function<void()>; 41 using ReturnNativeFunc = std::function<void()>; 42 JsDebuggerManager(const EcmaVM * vm)43 explicit JsDebuggerManager(const EcmaVM *vm) : hotReloadManager_(vm) 44 { 45 jsThread_ = vm->GetJSThread(); 46 } 47 ~JsDebuggerManager() = default; 48 49 NO_COPY_SEMANTIC(JsDebuggerManager); 50 NO_MOVE_SEMANTIC(JsDebuggerManager); 51 GetNotificationManager()52 NotificationManager *GetNotificationManager() const 53 { 54 return const_cast<NotificationManager *>(¬ificationManager_); 55 } 56 GetHotReloadManager()57 HotReloadManager *GetHotReloadManager() const 58 { 59 return const_cast<HotReloadManager *>(&hotReloadManager_); 60 } 61 SetDebugMode(bool isDebugMode)62 void SetDebugMode(bool isDebugMode) 63 { 64 if (isDebugMode_ == isDebugMode) { 65 return; 66 } 67 68 isDebugMode_ = isDebugMode; 69 70 if (isDebugMode) { 71 jsThread_->SetDebugModeState(); 72 } else { 73 jsThread_->ResetDebugModeState(); 74 } 75 } 76 IsDebugMode()77 bool IsDebugMode() const 78 { 79 return isDebugMode_; 80 } 81 SetIsDebugApp(bool isDebugApp)82 void SetIsDebugApp(bool isDebugApp) 83 { 84 isDebugApp_ = isDebugApp; 85 } 86 IsDebugApp()87 bool IsDebugApp() const 88 { 89 return isDebugApp_; 90 } 91 SetMixedStackEnabled(bool mixedStackEnabled)92 void SetMixedStackEnabled(bool mixedStackEnabled) 93 { 94 isMixedStackEnabled_ = mixedStackEnabled; 95 } 96 IsMixedStackEnabled()97 bool IsMixedStackEnabled() const 98 { 99 return isMixedStackEnabled_; 100 } 101 SetMixedDebugEnabled(bool enabled)102 void SetMixedDebugEnabled(bool enabled) 103 { 104 isMixedDebugEnabled_ = enabled; 105 } 106 IsMixedDebugEnabled()107 bool IsMixedDebugEnabled() const 108 { 109 return isMixedDebugEnabled_; 110 } 111 SetDebuggerHandler(ProtocolHandler * debuggerHandler)112 void SetDebuggerHandler(ProtocolHandler *debuggerHandler) 113 { 114 debuggerHandler_ = debuggerHandler; 115 } 116 GetDebuggerHandler()117 ProtocolHandler *GetDebuggerHandler() const 118 { 119 return debuggerHandler_; 120 } 121 SetDebugLibraryHandle(LibraryHandle handle)122 void SetDebugLibraryHandle(LibraryHandle handle) 123 { 124 debuggerLibraryHandle_ = std::move(handle); 125 } 126 GetDebugLibraryHandle()127 const LibraryHandle &GetDebugLibraryHandle() const 128 { 129 return debuggerLibraryHandle_; 130 } 131 SetEvalFrameHandler(std::shared_ptr<FrameHandler> frameHandler)132 void SetEvalFrameHandler(std::shared_ptr<FrameHandler> frameHandler) 133 { 134 frameHandler_ = frameHandler; 135 } 136 GetEvalFrameHandler()137 const std::shared_ptr<FrameHandler> &GetEvalFrameHandler() const 138 { 139 return frameHandler_; 140 } 141 SetLocalScopeUpdater(ObjectUpdaterFunc * updaterFunc)142 void SetLocalScopeUpdater(ObjectUpdaterFunc *updaterFunc) 143 { 144 updaterFunc_ = updaterFunc; 145 } 146 NotifyLocalScopeUpdated(std::string_view varName,Local<JSValueRef> value)147 void NotifyLocalScopeUpdated(std::string_view varName, Local<JSValueRef> value) 148 { 149 if (updaterFunc_ != nullptr) { 150 (*updaterFunc_)(frameHandler_.get(), varName, value); 151 } 152 } 153 SetJSReturnNativeFunc(ReturnNativeFunc * returnNative)154 void SetJSReturnNativeFunc(ReturnNativeFunc *returnNative) 155 { 156 returnNative_ = returnNative; 157 } 158 NotifyReturnNative()159 void NotifyReturnNative() 160 { 161 if (returnNative_ != nullptr) { 162 (*returnNative_)(); 163 } 164 } 165 SetStepperFunc(SingleStepperFunc * stepperFunc)166 void SetStepperFunc(SingleStepperFunc *stepperFunc) 167 { 168 stepperFunc_ = stepperFunc; 169 } 170 ClearSingleStepper()171 void ClearSingleStepper() 172 { 173 if (stepperFunc_ != nullptr) { 174 (*stepperFunc_)(); 175 } 176 } 177 MethodEntry(JSHandle<Method> method,JSHandle<JSTaggedValue> envHandle)178 void MethodEntry(JSHandle<Method> method, JSHandle<JSTaggedValue> envHandle) 179 { 180 dropframeManager_.MethodEntry(jsThread_, method, envHandle); 181 } 182 MethodExit(JSHandle<Method> method)183 void MethodExit(JSHandle<Method> method) 184 { 185 dropframeManager_.MethodExit(jsThread_, method); 186 } 187 DropLastFrame()188 void DropLastFrame() 189 { 190 dropframeManager_.DropLastFrame(jsThread_); 191 } 192 GetPromiseQueueSizeRecordOfTopFrame()193 uint32_t GetPromiseQueueSizeRecordOfTopFrame() 194 { 195 return dropframeManager_.GetPromiseQueueSizeRecordOfTopFrame(); 196 } 197 EnableObjectHashDisplay()198 void EnableObjectHashDisplay() 199 { 200 isObjHashDisplayEnabled_ = true; 201 } 202 DisableObjectHashDisplay()203 void DisableObjectHashDisplay() 204 { 205 isObjHashDisplayEnabled_ = false; 206 } 207 IsObjHashDisplayEnabled()208 bool IsObjHashDisplayEnabled() 209 { 210 return isObjHashDisplayEnabled_; 211 } 212 213 static void AddJsDebuggerManager(int tid, JsDebuggerManager *jsDebuggerManager); 214 static JsDebuggerManager* GetJsDebuggerManager(int tid); 215 216 private: 217 bool isDebugMode_ {false}; 218 bool isDebugApp_ {false}; 219 bool isMixedDebugEnabled_ { false }; 220 bool isMixedStackEnabled_ { false }; 221 bool isObjHashDisplayEnabled_ { true }; 222 ProtocolHandler *debuggerHandler_ {nullptr}; 223 LibraryHandle debuggerLibraryHandle_ {nullptr}; 224 ObjectUpdaterFunc *updaterFunc_ {nullptr}; 225 SingleStepperFunc *stepperFunc_ {nullptr}; 226 ReturnNativeFunc *returnNative_ {nullptr}; 227 JSThread *jsThread_ {nullptr}; 228 std::shared_ptr<FrameHandler> frameHandler_; 229 DropframeManager dropframeManager_ { }; 230 231 NotificationManager notificationManager_; 232 HotReloadManager hotReloadManager_; 233 234 static std::unordered_map<int, JsDebuggerManager *> jsDebuggerManagerMap_; 235 static std::shared_mutex mutex_; 236 }; 237 } // panda::ecmascript::tooling 238 239 #endif // ECMASCRIPT_DEBUGGER_JS_DEBUGGER_MANAGER_H