1 /* 2 * Copyright (c) 2021-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_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 24 namespace panda::ecmascript::tooling { 25 class RuntimeListener { 26 public: 27 RuntimeListener() = default; 28 virtual ~RuntimeListener() = default; 29 DEFAULT_COPY_SEMANTIC(RuntimeListener); 30 DEFAULT_MOVE_SEMANTIC(RuntimeListener); 31 32 virtual void LoadModule(std::string_view name, std::string_view) = 0; 33 34 virtual void BytecodePcChanged(JSThread *thread, JSHandle<Method> method, 35 uint32_t bcOffset) = 0; 36 37 virtual bool HandleDebuggerStmt(JSHandle<Method> method, uint32_t bcOffset) = 0; 38 virtual void VmStart() = 0; 39 virtual void VmDeath() = 0; 40 virtual void NativeCalling(const void *nativeAddress) = 0; 41 virtual void MethodEntry(JSHandle<Method> method) = 0; 42 virtual void MethodExit(JSHandle<Method> method) = 0; 43 }; 44 45 class NotificationManager { 46 public: 47 NotificationManager() = default; 48 ~NotificationManager() = default; 49 NO_COPY_SEMANTIC(NotificationManager); 50 NO_MOVE_SEMANTIC(NotificationManager); 51 AddListener(RuntimeListener * listener)52 void AddListener(RuntimeListener *listener) 53 { 54 listener_ = listener; 55 } RemoveListener()56 void RemoveListener() 57 { 58 listener_ = nullptr; 59 } 60 LoadModuleEvent(std::string_view name,std::string_view entryPoint)61 void LoadModuleEvent(std::string_view name, std::string_view entryPoint) const 62 { 63 if (UNLIKELY(listener_ != nullptr)) { 64 listener_->LoadModule(name, entryPoint); 65 } 66 } 67 BytecodePcChangedEvent(JSThread * thread,Method * method,uint32_t bcOffset)68 void BytecodePcChangedEvent(JSThread *thread, Method *method, uint32_t bcOffset) const 69 { 70 if (UNLIKELY(listener_ != nullptr)) { 71 [[maybe_unused]] EcmaHandleScope handleScope(thread); 72 JSHandle<Method> methodHandle(thread, method); 73 listener_->BytecodePcChanged(thread, methodHandle, bcOffset); 74 } 75 } 76 DebuggerStmtEvent(JSThread * thread,Method * method,uint32_t bcOffset)77 void DebuggerStmtEvent(JSThread *thread, Method *method, uint32_t bcOffset) const 78 { 79 if (UNLIKELY(listener_ != nullptr)) { 80 JSHandle<Method> methodHandle(thread, method); 81 listener_->HandleDebuggerStmt(methodHandle, bcOffset); 82 } 83 } 84 NativeCallingEvent(const void * nativeAddress)85 void NativeCallingEvent(const void *nativeAddress) const 86 { 87 if (UNLIKELY(listener_ != nullptr)) { 88 listener_->NativeCalling(nativeAddress); 89 } 90 } 91 VmStartEvent()92 void VmStartEvent() const 93 { 94 if (UNLIKELY(listener_ != nullptr)) { 95 listener_->VmStart(); 96 } 97 } VmDeathEvent()98 void VmDeathEvent() const 99 { 100 if (UNLIKELY(listener_ != nullptr)) { 101 listener_->VmDeath(); 102 } 103 } 104 MethodEntryEvent(JSThread * thread,Method * method)105 void MethodEntryEvent(JSThread *thread, Method *method) const 106 { 107 if (UNLIKELY(listener_ != nullptr)) { 108 JSHandle<Method> methodHandle(thread, method); 109 listener_->MethodEntry(methodHandle); 110 } 111 } MethodExitEvent(JSThread * thread,Method * method)112 void MethodExitEvent(JSThread *thread, Method *method) const 113 { 114 if (UNLIKELY(listener_ != nullptr)) { 115 JSHandle<Method> methodHandle(thread, method); 116 listener_->MethodExit(methodHandle); 117 } 118 } 119 private: 120 RuntimeListener *listener_ {nullptr}; 121 }; 122 } // panda::ecmascript::tooling 123 124 #endif // ECMASCRIPT_DEBUGGER_NOTIFICATION_MANAGER_H