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