1 /* 2 * Copyright (c) 2022-2024 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/lexical_env.h" 29 #include "ecmascript/napi/include/jsnapi.h" 30 #include "ecmascript/global_handle_collection.h" 31 32 #include "libpandabase/os/library_loader.h" 33 34 namespace panda::ecmascript::tooling { 35 class ProtocolHandler; 36 class JsDebuggerManager { 37 public: 38 using LibraryHandle = os::library_loader::LibraryHandle; 39 using ObjectUpdaterFunc = 40 std::function<void(const FrameHandler *, std::string_view, Local<JSValueRef>, const std::string&)>; 41 using SingleStepperFunc = std::function<void()>; 42 using ReturnNativeFunc = std::function<void()>; 43 JsDebuggerManager(const EcmaVM *vm)44 explicit JsDebuggerManager(const EcmaVM *vm) : hotReloadManager_(vm) 45 { 46 jsThread_ = vm->GetJSThread(); 47 } 48 ~JsDebuggerManager() = default; 49 50 NO_COPY_SEMANTIC(JsDebuggerManager); 51 NO_MOVE_SEMANTIC(JsDebuggerManager); 52 GetNotificationManager() const53 NotificationManager *GetNotificationManager() const 54 { 55 return const_cast<NotificationManager *>(¬ificationManager_); 56 } 57 GetHotReloadManager() const58 HotReloadManager *GetHotReloadManager() const 59 { 60 return const_cast<HotReloadManager *>(&hotReloadManager_); 61 } 62 SetDebugMode(bool isDebugMode)63 void SetDebugMode(bool isDebugMode) 64 { 65 if (isDebugMode_ == isDebugMode) { 66 return; 67 } 68 69 isDebugMode_ = isDebugMode; 70 71 if (isDebugMode) { 72 jsThread_->SetDebugModeState(); 73 } else { 74 jsThread_->ResetDebugModeState(); 75 } 76 } 77 IsDebugMode() const78 bool IsDebugMode() const 79 { 80 return isDebugMode_; 81 } 82 SetIsDebugApp(bool isDebugApp)83 void SetIsDebugApp(bool isDebugApp) 84 { 85 isDebugApp_ = isDebugApp; 86 } 87 IsDebugApp() const88 bool IsDebugApp() const 89 { 90 return isDebugApp_; 91 } 92 SetMixedStackEnabled(bool mixedStackEnabled)93 void SetMixedStackEnabled(bool mixedStackEnabled) 94 { 95 isMixedStackEnabled_ = mixedStackEnabled; 96 } 97 IsMixedStackEnabled() const98 bool IsMixedStackEnabled() const 99 { 100 return isMixedStackEnabled_; 101 } 102 SetMixedDebugEnabled(bool enabled)103 void SetMixedDebugEnabled(bool enabled) 104 { 105 isMixedDebugEnabled_ = enabled; 106 } 107 IsMixedDebugEnabled() const108 bool IsMixedDebugEnabled() const 109 { 110 return isMixedDebugEnabled_; 111 } 112 SetDebuggerHandler(ProtocolHandler *debuggerHandler)113 void SetDebuggerHandler(ProtocolHandler *debuggerHandler) 114 { 115 debuggerHandler_ = debuggerHandler; 116 } 117 GetDebuggerHandler() const118 ProtocolHandler *GetDebuggerHandler() const 119 { 120 return debuggerHandler_; 121 } 122 SetDebugLibraryHandle(LibraryHandle handle)123 void SetDebugLibraryHandle(LibraryHandle handle) 124 { 125 debuggerLibraryHandle_ = std::move(handle); 126 } 127 GetDebugLibraryHandle() const128 const LibraryHandle &GetDebugLibraryHandle() const 129 { 130 return debuggerLibraryHandle_; 131 } 132 GetSignalState() const133 bool GetSignalState() const 134 { 135 return isSignalInterrupt_; 136 } 137 SetSignalState(bool isSignalInterrupt)138 void SetSignalState(bool isSignalInterrupt) 139 { 140 isSignalInterrupt_ = isSignalInterrupt; 141 } 142 SetEvalFrameHandler(std::shared_ptr<FrameHandler> frameHandler)143 void SetEvalFrameHandler(std::shared_ptr<FrameHandler> frameHandler) 144 { 145 frameHandler_ = frameHandler; 146 } 147 GetEvalFrameHandler() const148 const std::shared_ptr<FrameHandler> &GetEvalFrameHandler() const 149 { 150 return frameHandler_; 151 } 152 SetLocalScopeUpdater(ObjectUpdaterFunc *updaterFunc)153 void SetLocalScopeUpdater(ObjectUpdaterFunc *updaterFunc) 154 { 155 updaterFunc_ = updaterFunc; 156 } 157 NotifyScopeUpdated(std::string_view varName, Local<JSValueRef> value, const std::string& scope)158 void NotifyScopeUpdated(std::string_view varName, Local<JSValueRef> value, const std::string& scope) 159 { 160 if (updaterFunc_ != nullptr) { 161 (*updaterFunc_)(frameHandler_.get(), varName, value, scope); 162 } 163 } 164 SetJSReturnNativeFunc(ReturnNativeFunc *returnNative)165 void SetJSReturnNativeFunc(ReturnNativeFunc *returnNative) 166 { 167 returnNative_ = returnNative; 168 } 169 NotifyReturnNative()170 void NotifyReturnNative() 171 { 172 if (returnNative_ != nullptr) { 173 (*returnNative_)(); 174 } 175 } 176 SetStepperFunc(SingleStepperFunc *stepperFunc)177 void SetStepperFunc(SingleStepperFunc *stepperFunc) 178 { 179 stepperFunc_ = stepperFunc; 180 } 181 ClearSingleStepper()182 void ClearSingleStepper() 183 { 184 if (stepperFunc_ != nullptr) { 185 (*stepperFunc_)(); 186 } 187 } 188 MethodEntry(JSHandle<Method> method, JSHandle<JSTaggedValue> envHandle)189 void MethodEntry(JSHandle<Method> method, JSHandle<JSTaggedValue> envHandle) 190 { 191 dropframeManager_.MethodEntry(jsThread_, method, envHandle); 192 } 193 MethodExit(JSHandle<Method> method)194 void MethodExit(JSHandle<Method> method) 195 { 196 dropframeManager_.MethodExit(jsThread_, method); 197 } 198 DropLastFrame()199 void DropLastFrame() 200 { 201 dropframeManager_.DropLastFrame(jsThread_); 202 } 203 GetPromiseQueueSizeRecordOfTopFrame()204 uint32_t GetPromiseQueueSizeRecordOfTopFrame() 205 { 206 return dropframeManager_.GetPromiseQueueSizeRecordOfTopFrame(); 207 } 208 CheckIsSendableMethod()209 bool CheckIsSendableMethod() 210 { 211 return dropframeManager_.CheckIsSendableMethod(); 212 } 213 EnableObjectHashDisplay()214 void EnableObjectHashDisplay() 215 { 216 isObjHashDisplayEnabled_ = true; 217 } 218 DisableObjectHashDisplay()219 void DisableObjectHashDisplay() 220 { 221 isObjHashDisplayEnabled_ = false; 222 } 223 IsObjHashDisplayEnabled()224 bool IsObjHashDisplayEnabled() 225 { 226 return isObjHashDisplayEnabled_; 227 } 228 EnableSerializationTimeoutCheck()229 void EnableSerializationTimeoutCheck() 230 { 231 isSerializationTimeoutCheckEnabled_ = true; 232 } 233 DisableSerializationTimeoutCheck()234 void DisableSerializationTimeoutCheck() 235 { 236 isSerializationTimeoutCheckEnabled_ = false; 237 } 238 IsSerializationTimeoutCheckEnabled()239 bool IsSerializationTimeoutCheckEnabled() 240 { 241 return isSerializationTimeoutCheckEnabled_; 242 } 243 SetSerializationCheckThreshold(int threshold)244 void SetSerializationCheckThreshold(int threshold) 245 { 246 serializationCheckThreshold_ = threshold; 247 } 248 GetSerializationCheckThreshold() const249 int32_t GetSerializationCheckThreshold() const 250 { 251 return serializationCheckThreshold_; 252 } 253 254 static void AddJsDebuggerManager(int tid, JsDebuggerManager *jsDebuggerManager); 255 static JsDebuggerManager* GetJsDebuggerManager(int tid); 256 static void DeleteJsDebuggerManager(int tid); 257 258 private: 259 bool isDebugMode_ {false}; 260 bool isDebugApp_ {false}; 261 bool isMixedDebugEnabled_ { false }; 262 bool isMixedStackEnabled_ { false }; 263 bool isSignalInterrupt_ {false}; 264 bool isObjHashDisplayEnabled_ { true }; 265 ProtocolHandler *debuggerHandler_ {nullptr}; 266 LibraryHandle debuggerLibraryHandle_ {nullptr}; 267 ObjectUpdaterFunc *updaterFunc_ {nullptr}; 268 SingleStepperFunc *stepperFunc_ {nullptr}; 269 ReturnNativeFunc *returnNative_ {nullptr}; 270 JSThread *jsThread_ {nullptr}; 271 std::shared_ptr<FrameHandler> frameHandler_; 272 DropframeManager dropframeManager_ { }; 273 274 NotificationManager notificationManager_; 275 HotReloadManager hotReloadManager_; 276 // Serialization / DeSerialization Timeout flag 277 bool isSerializationTimeoutCheckEnabled_ { false }; 278 // in milliseconds 279 static constexpr int32_t DEFAULT_THRESHOLD = 8; 280 int32_t serializationCheckThreshold_ { DEFAULT_THRESHOLD }; 281 282 static std::unordered_map<int, JsDebuggerManager *> jsDebuggerManagerMap_; 283 static std::shared_mutex mutex_; 284 }; 285 } // panda::ecmascript::tooling 286 287 #endif // ECMASCRIPT_DEBUGGER_JS_DEBUGGER_MANAGER_H 288