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