• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *>(&notificationManager_);
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