• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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_NOTIFICATION_MANAGER_H
17 #define ECMASCRIPT_DEBUGGER_NOTIFICATION_MANAGER_H
18 
19 #include <string_view>
20 
21 #include "ecmascript/js_handle.h"
22 #include "ecmascript/js_thread.h"
23 #include "ecmascript/method.h"
24 
25 namespace panda::ecmascript::tooling {
26 class RuntimeListener {
27 public:
28     RuntimeListener() = default;
29     virtual ~RuntimeListener() = default;
30     DEFAULT_COPY_SEMANTIC(RuntimeListener);
31     DEFAULT_MOVE_SEMANTIC(RuntimeListener);
32 
33     virtual void LoadModule(std::string_view name, std::string_view) = 0;
34 
35     virtual void BytecodePcChanged(JSThread *thread, JSHandle<Method> method,
36                                    uint32_t bcOffset) = 0;
37 
38     virtual bool HandleDebuggerStmt(JSHandle<Method> method, uint32_t bcOffset) = 0;
39     virtual void VmStart() = 0;
40     virtual void VmDeath() = 0;
41     virtual void NativeCalling(const void *nativeAddress) = 0;
42     virtual void NativeReturn(const void *nativeAddress) = 0;
43     virtual void MethodEntry(JSHandle<Method> method, JSHandle<JSTaggedValue> envHandle) = 0;
44     virtual void MethodExit(JSHandle<Method> method) = 0;
45 };
46 
47 class NotificationManager {
48 public:
49     NotificationManager() = default;
50     ~NotificationManager() = default;
51     NO_COPY_SEMANTIC(NotificationManager);
52     NO_MOVE_SEMANTIC(NotificationManager);
53 
AddListener(RuntimeListener * listener)54     void AddListener(RuntimeListener *listener)
55     {
56         if (listener != nullptr) {
57             listeners_.emplace_back(listener);
58         }
59     }
RemoveListener(RuntimeListener * listener)60     void RemoveListener(RuntimeListener *listener)
61     {
62         for (auto it = listeners_.begin(); it != listeners_.end(); ++it) {
63             if (*it == listener) {
64                 listeners_.erase(it);
65                 return;
66             }
67         }
68     }
69 
LoadModuleEvent(std::string_view name,std::string_view entryPoint)70     void LoadModuleEvent(std::string_view name, std::string_view entryPoint) const
71     {
72         for (auto it: listeners_) {
73             it->LoadModule(name, entryPoint);
74         }
75     }
76 
BytecodePcChangedEvent(JSThread * thread,Method * method,uint32_t bcOffset)77     void BytecodePcChangedEvent(JSThread *thread, Method *method, uint32_t bcOffset) const
78     {
79         [[maybe_unused]] EcmaHandleScope handleScope(thread);
80         JSHandle<Method> methodHandle(thread, method);
81         for (auto it: listeners_) {
82             it->BytecodePcChanged(thread, methodHandle, bcOffset);
83         }
84     }
85 
DebuggerStmtEvent(JSThread * thread,Method * method,uint32_t bcOffset)86     void DebuggerStmtEvent(JSThread *thread, Method *method, uint32_t bcOffset) const
87     {
88         JSHandle<Method> methodHandle(thread, method);
89         for (auto it: listeners_) {
90             it->HandleDebuggerStmt(methodHandle, bcOffset);
91         }
92     }
93 
NativeCallingEvent(const void * nativeAddress)94     void NativeCallingEvent(const void *nativeAddress) const
95     {
96         for (auto it: listeners_) {
97             it->NativeCalling(nativeAddress);
98         }
99     }
100 
NativeReturnEvent(const void * nativeAddress)101     void NativeReturnEvent(const void *nativeAddress) const
102     {
103         for (auto it: listeners_) {
104             it->NativeReturn(nativeAddress);
105         }
106     }
107 
VmStartEvent()108     void VmStartEvent() const
109     {
110         for (auto it: listeners_) {
111             it->VmStart();
112         }
113     }
VmDeathEvent()114     void VmDeathEvent() const
115     {
116         for (auto it: listeners_) {
117             it->VmDeath();
118         }
119     }
120 
MethodEntryEvent(JSThread * thread,Method * method,JSTaggedValue env)121     void MethodEntryEvent(JSThread *thread, Method *method, JSTaggedValue env) const
122     {
123         JSHandle<Method> methodHandle(thread, method);
124         JSHandle<JSTaggedValue> envHandle(thread, env);
125         for (auto it: listeners_) {
126             it->MethodEntry(methodHandle, envHandle);
127         }
128     }
MethodExitEvent(JSThread * thread,Method * method)129     void MethodExitEvent(JSThread *thread, Method *method) const
130     {
131         JSHandle<Method> methodHandle(thread, method);
132         for (auto it: listeners_) {
133             it->MethodExit(methodHandle);
134         }
135     }
136 private:
137     std::vector<RuntimeListener*> listeners_;
138 };
139 }  // panda::ecmascript::tooling
140 
141 #endif  // ECMASCRIPT_DEBUGGER_NOTIFICATION_MANAGER_H