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()53 NotificationManager *GetNotificationManager() const 54 { 55 return const_cast<NotificationManager *>(¬ificationManager_); 56 } 57 GetHotReloadManager()58 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()78 bool IsDebugMode() const 79 { 80 return isDebugMode_; 81 } 82 SetIsDebugApp(bool isDebugApp)83 void SetIsDebugApp(bool isDebugApp) 84 { 85 isDebugApp_ = isDebugApp; 86 } 87 IsDebugApp()88 bool IsDebugApp() const 89 { 90 return isDebugApp_; 91 } 92 SetFaApp(bool isFaApp)93 void SetFaApp(bool isFaApp) 94 { 95 isFaApp_ = isFaApp; 96 } 97 GetFaApp()98 bool GetFaApp() const 99 { 100 return isFaApp_; 101 } 102 SetMixedStackEnabled(bool mixedStackEnabled)103 void SetMixedStackEnabled(bool mixedStackEnabled) 104 { 105 isMixedStackEnabled_ = mixedStackEnabled; 106 } 107 IsMixedStackEnabled()108 bool IsMixedStackEnabled() const 109 { 110 return isMixedStackEnabled_; 111 } 112 SetMixedDebugEnabled(bool enabled)113 void SetMixedDebugEnabled(bool enabled) 114 { 115 isMixedDebugEnabled_ = enabled; 116 } 117 IsMixedDebugEnabled()118 bool IsMixedDebugEnabled() const 119 { 120 return isMixedDebugEnabled_; 121 } 122 SetDebuggerHandler(ProtocolHandler * debuggerHandler)123 void SetDebuggerHandler(ProtocolHandler *debuggerHandler) 124 { 125 debuggerHandler_ = debuggerHandler; 126 } 127 GetDebuggerHandler()128 ProtocolHandler *GetDebuggerHandler() const 129 { 130 return debuggerHandler_; 131 } 132 SetDebugLibraryHandle(LibraryHandle handle)133 void SetDebugLibraryHandle(LibraryHandle handle) 134 { 135 debuggerLibraryHandle_ = std::move(handle); 136 } 137 GetDebugLibraryHandle()138 const LibraryHandle &GetDebugLibraryHandle() const 139 { 140 return debuggerLibraryHandle_; 141 } 142 GetSignalState()143 bool GetSignalState() const 144 { 145 return isSignalInterrupt_; 146 } 147 SetSignalState(bool isSignalInterrupt)148 void SetSignalState(bool isSignalInterrupt) 149 { 150 isSignalInterrupt_ = isSignalInterrupt; 151 } 152 SetEvalFrameHandler(std::shared_ptr<FrameHandler> frameHandler)153 void SetEvalFrameHandler(std::shared_ptr<FrameHandler> frameHandler) 154 { 155 frameHandler_ = frameHandler; 156 } 157 GetEvalFrameHandler()158 const std::shared_ptr<FrameHandler> &GetEvalFrameHandler() const 159 { 160 return frameHandler_; 161 } 162 SetLocalScopeUpdater(ObjectUpdaterFunc * updaterFunc)163 void SetLocalScopeUpdater(ObjectUpdaterFunc *updaterFunc) 164 { 165 updaterFunc_ = updaterFunc; 166 } 167 NotifyScopeUpdated(std::string_view varName,Local<JSValueRef> value,const std::string & scope)168 void NotifyScopeUpdated(std::string_view varName, Local<JSValueRef> value, const std::string& scope) 169 { 170 if (updaterFunc_ != nullptr) { 171 (*updaterFunc_)(frameHandler_.get(), varName, value, scope); 172 } 173 } 174 SetJSReturnNativeFunc(ReturnNativeFunc * returnNative)175 void SetJSReturnNativeFunc(ReturnNativeFunc *returnNative) 176 { 177 returnNative_ = returnNative; 178 } 179 NotifyReturnNative()180 void NotifyReturnNative() 181 { 182 if (returnNative_ != nullptr) { 183 (*returnNative_)(); 184 } 185 } 186 SetStepperFunc(SingleStepperFunc * stepperFunc)187 void SetStepperFunc(SingleStepperFunc *stepperFunc) 188 { 189 stepperFunc_ = stepperFunc; 190 } 191 ClearSingleStepper()192 void ClearSingleStepper() 193 { 194 if (stepperFunc_ != nullptr) { 195 (*stepperFunc_)(); 196 } 197 } 198 MethodEntry(JSHandle<Method> method,JSHandle<JSTaggedValue> envHandle)199 void MethodEntry(JSHandle<Method> method, JSHandle<JSTaggedValue> envHandle) 200 { 201 dropframeManager_.MethodEntry(jsThread_, method, envHandle); 202 } 203 MethodExit(JSHandle<Method> method)204 void MethodExit(JSHandle<Method> method) 205 { 206 dropframeManager_.MethodExit(jsThread_, method); 207 } 208 DropLastFrame()209 void DropLastFrame() 210 { 211 dropframeManager_.DropLastFrame(jsThread_); 212 } 213 GetPromiseQueueSizeRecordOfTopFrame()214 uint32_t GetPromiseQueueSizeRecordOfTopFrame() 215 { 216 return dropframeManager_.GetPromiseQueueSizeRecordOfTopFrame(); 217 } 218 CheckIsSendableMethod()219 bool CheckIsSendableMethod() 220 { 221 return dropframeManager_.CheckIsSendableMethod(); 222 } 223 EnableObjectHashDisplay()224 void EnableObjectHashDisplay() 225 { 226 isObjHashDisplayEnabled_ = true; 227 } 228 DisableObjectHashDisplay()229 void DisableObjectHashDisplay() 230 { 231 isObjHashDisplayEnabled_ = false; 232 } 233 IsObjHashDisplayEnabled()234 bool IsObjHashDisplayEnabled() 235 { 236 return isObjHashDisplayEnabled_; 237 } 238 EnableSerializationTimeoutCheck()239 void EnableSerializationTimeoutCheck() 240 { 241 isSerializationTimeoutCheckEnabled_ = true; 242 } 243 DisableSerializationTimeoutCheck()244 void DisableSerializationTimeoutCheck() 245 { 246 isSerializationTimeoutCheckEnabled_ = false; 247 } 248 IsSerializationTimeoutCheckEnabled()249 bool IsSerializationTimeoutCheckEnabled() 250 { 251 return isSerializationTimeoutCheckEnabled_; 252 } 253 SetSerializationCheckThreshold(int threshold)254 void SetSerializationCheckThreshold(int threshold) 255 { 256 serializationCheckThreshold_ = threshold; 257 } 258 GetSerializationCheckThreshold()259 int32_t GetSerializationCheckThreshold() const 260 { 261 return serializationCheckThreshold_; 262 } 263 264 static void AddJsDebuggerManager(int tid, JsDebuggerManager *jsDebuggerManager); 265 static JsDebuggerManager* GetJsDebuggerManager(int tid); 266 static void DeleteJsDebuggerManager(int tid); 267 268 private: 269 bool isDebugMode_ {false}; 270 bool isDebugApp_ {false}; 271 bool isFaApp_ {false}; 272 bool isMixedDebugEnabled_ { false }; 273 bool isMixedStackEnabled_ { false }; 274 bool isSignalInterrupt_ {false}; 275 bool isObjHashDisplayEnabled_ { true }; 276 ProtocolHandler *debuggerHandler_ {nullptr}; 277 LibraryHandle debuggerLibraryHandle_ {nullptr}; 278 ObjectUpdaterFunc *updaterFunc_ {nullptr}; 279 SingleStepperFunc *stepperFunc_ {nullptr}; 280 ReturnNativeFunc *returnNative_ {nullptr}; 281 JSThread *jsThread_ {nullptr}; 282 std::shared_ptr<FrameHandler> frameHandler_ {nullptr}; 283 DropframeManager dropframeManager_; 284 285 NotificationManager notificationManager_; 286 HotReloadManager hotReloadManager_; 287 // Serialization / DeSerialization Timeout flag 288 bool isSerializationTimeoutCheckEnabled_ { false }; 289 // in milliseconds 290 static constexpr int32_t DEFAULT_THRESHOLD = 8; 291 int32_t serializationCheckThreshold_ { DEFAULT_THRESHOLD }; 292 293 static std::unordered_map<int, JsDebuggerManager *> jsDebuggerManagerMap_; 294 static std::shared_mutex mutex_; 295 }; 296 } // panda::ecmascript::tooling 297 298 #endif // ECMASCRIPT_DEBUGGER_JS_DEBUGGER_MANAGER_H 299