14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_DEBUGGER_NOTIFICATION_MANAGER_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_DEBUGGER_NOTIFICATION_MANAGER_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include <string_view> 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_ci#include "ecmascript/js_handle.h" 224514f5e3Sopenharmony_ci#include "ecmascript/js_thread.h" 234514f5e3Sopenharmony_ci#include "ecmascript/method.h" 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_cinamespace panda::ecmascript::tooling { 264514f5e3Sopenharmony_ciclass RuntimeListener { 274514f5e3Sopenharmony_cipublic: 284514f5e3Sopenharmony_ci RuntimeListener() = default; 294514f5e3Sopenharmony_ci virtual ~RuntimeListener() = default; 304514f5e3Sopenharmony_ci DEFAULT_COPY_SEMANTIC(RuntimeListener); 314514f5e3Sopenharmony_ci DEFAULT_MOVE_SEMANTIC(RuntimeListener); 324514f5e3Sopenharmony_ci 334514f5e3Sopenharmony_ci virtual void LoadModule(std::string_view name, std::string_view) = 0; 344514f5e3Sopenharmony_ci 354514f5e3Sopenharmony_ci virtual void BytecodePcChanged(JSThread *thread, JSHandle<Method> method, 364514f5e3Sopenharmony_ci uint32_t bcOffset) = 0; 374514f5e3Sopenharmony_ci 384514f5e3Sopenharmony_ci virtual bool HandleDebuggerStmt(JSHandle<Method> method, uint32_t bcOffset) = 0; 394514f5e3Sopenharmony_ci virtual void VmStart() = 0; 404514f5e3Sopenharmony_ci virtual void VmDeath() = 0; 414514f5e3Sopenharmony_ci virtual void NativeCalling(const void *nativeAddress) = 0; 424514f5e3Sopenharmony_ci virtual void NativeReturn(const void *nativeAddress) = 0; 434514f5e3Sopenharmony_ci virtual void MethodEntry(JSHandle<Method> method, JSHandle<JSTaggedValue> envHandle) = 0; 444514f5e3Sopenharmony_ci virtual void MethodExit(JSHandle<Method> method) = 0; 454514f5e3Sopenharmony_ci}; 464514f5e3Sopenharmony_ci 474514f5e3Sopenharmony_ciclass NotificationManager { 484514f5e3Sopenharmony_cipublic: 494514f5e3Sopenharmony_ci NotificationManager() = default; 504514f5e3Sopenharmony_ci ~NotificationManager() = default; 514514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(NotificationManager); 524514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(NotificationManager); 534514f5e3Sopenharmony_ci 544514f5e3Sopenharmony_ci void AddListener(RuntimeListener *listener) 554514f5e3Sopenharmony_ci { 564514f5e3Sopenharmony_ci if (listener != nullptr) { 574514f5e3Sopenharmony_ci listeners_.emplace_back(listener); 584514f5e3Sopenharmony_ci } 594514f5e3Sopenharmony_ci } 604514f5e3Sopenharmony_ci void RemoveListener(RuntimeListener *listener) 614514f5e3Sopenharmony_ci { 624514f5e3Sopenharmony_ci for (auto it = listeners_.begin(); it != listeners_.end(); ++it) { 634514f5e3Sopenharmony_ci if (*it == listener) { 644514f5e3Sopenharmony_ci listeners_.erase(it); 654514f5e3Sopenharmony_ci return; 664514f5e3Sopenharmony_ci } 674514f5e3Sopenharmony_ci } 684514f5e3Sopenharmony_ci } 694514f5e3Sopenharmony_ci 704514f5e3Sopenharmony_ci void LoadModuleEvent(std::string_view name, std::string_view entryPoint) const 714514f5e3Sopenharmony_ci { 724514f5e3Sopenharmony_ci for (auto it: listeners_) { 734514f5e3Sopenharmony_ci it->LoadModule(name, entryPoint); 744514f5e3Sopenharmony_ci } 754514f5e3Sopenharmony_ci } 764514f5e3Sopenharmony_ci 774514f5e3Sopenharmony_ci void BytecodePcChangedEvent(JSThread *thread, Method *method, uint32_t bcOffset) const 784514f5e3Sopenharmony_ci { 794514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 804514f5e3Sopenharmony_ci JSHandle<Method> methodHandle(thread, method); 814514f5e3Sopenharmony_ci for (auto it: listeners_) { 824514f5e3Sopenharmony_ci it->BytecodePcChanged(thread, methodHandle, bcOffset); 834514f5e3Sopenharmony_ci } 844514f5e3Sopenharmony_ci } 854514f5e3Sopenharmony_ci 864514f5e3Sopenharmony_ci void DebuggerStmtEvent(JSThread *thread, Method *method, uint32_t bcOffset) const 874514f5e3Sopenharmony_ci { 884514f5e3Sopenharmony_ci JSHandle<Method> methodHandle(thread, method); 894514f5e3Sopenharmony_ci for (auto it: listeners_) { 904514f5e3Sopenharmony_ci it->HandleDebuggerStmt(methodHandle, bcOffset); 914514f5e3Sopenharmony_ci } 924514f5e3Sopenharmony_ci } 934514f5e3Sopenharmony_ci 944514f5e3Sopenharmony_ci void NativeCallingEvent(const void *nativeAddress) const 954514f5e3Sopenharmony_ci { 964514f5e3Sopenharmony_ci for (auto it: listeners_) { 974514f5e3Sopenharmony_ci it->NativeCalling(nativeAddress); 984514f5e3Sopenharmony_ci } 994514f5e3Sopenharmony_ci } 1004514f5e3Sopenharmony_ci 1014514f5e3Sopenharmony_ci void NativeReturnEvent(const void *nativeAddress) const 1024514f5e3Sopenharmony_ci { 1034514f5e3Sopenharmony_ci for (auto it: listeners_) { 1044514f5e3Sopenharmony_ci it->NativeReturn(nativeAddress); 1054514f5e3Sopenharmony_ci } 1064514f5e3Sopenharmony_ci } 1074514f5e3Sopenharmony_ci 1084514f5e3Sopenharmony_ci void VmStartEvent() const 1094514f5e3Sopenharmony_ci { 1104514f5e3Sopenharmony_ci for (auto it: listeners_) { 1114514f5e3Sopenharmony_ci it->VmStart(); 1124514f5e3Sopenharmony_ci } 1134514f5e3Sopenharmony_ci } 1144514f5e3Sopenharmony_ci void VmDeathEvent() const 1154514f5e3Sopenharmony_ci { 1164514f5e3Sopenharmony_ci for (auto it: listeners_) { 1174514f5e3Sopenharmony_ci it->VmDeath(); 1184514f5e3Sopenharmony_ci } 1194514f5e3Sopenharmony_ci } 1204514f5e3Sopenharmony_ci 1214514f5e3Sopenharmony_ci void MethodEntryEvent(JSThread *thread, Method *method, JSTaggedValue env) const 1224514f5e3Sopenharmony_ci { 1234514f5e3Sopenharmony_ci JSHandle<Method> methodHandle(thread, method); 1244514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> envHandle(thread, env); 1254514f5e3Sopenharmony_ci for (auto it: listeners_) { 1264514f5e3Sopenharmony_ci it->MethodEntry(methodHandle, envHandle); 1274514f5e3Sopenharmony_ci } 1284514f5e3Sopenharmony_ci } 1294514f5e3Sopenharmony_ci void MethodExitEvent(JSThread *thread, Method *method) const 1304514f5e3Sopenharmony_ci { 1314514f5e3Sopenharmony_ci JSHandle<Method> methodHandle(thread, method); 1324514f5e3Sopenharmony_ci for (auto it: listeners_) { 1334514f5e3Sopenharmony_ci it->MethodExit(methodHandle); 1344514f5e3Sopenharmony_ci } 1354514f5e3Sopenharmony_ci } 1364514f5e3Sopenharmony_ciprivate: 1374514f5e3Sopenharmony_ci std::vector<RuntimeListener*> listeners_; 1384514f5e3Sopenharmony_ci}; 1394514f5e3Sopenharmony_ci} // panda::ecmascript::tooling 1404514f5e3Sopenharmony_ci 1414514f5e3Sopenharmony_ci#endif // ECMASCRIPT_DEBUGGER_NOTIFICATION_MANAGER_H