1 /*
2 * Copyright (c) 2021 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 #include "backend/js_pt_hooks.h"
17
18 #include "agent/debugger_impl.h"
19
20 namespace panda::ecmascript::tooling {
DebuggerStmt(const JSPtLocation & location)21 void JSPtHooks::DebuggerStmt([[maybe_unused]] const JSPtLocation &location)
22 {
23 LOG_DEBUGGER(VERBOSE) << "JSPHooks: Debugger Statement";
24 [[maybe_unused]] LocalScope scope(debugger_->vm_);
25 debugger_->NotifyPaused({}, DEBUGGERSTMT);
26 }
27
Breakpoint(const JSPtLocation & location)28 void JSPtHooks::Breakpoint(const JSPtLocation &location)
29 {
30 LOG_DEBUGGER(VERBOSE) << "JSPtHooks: Breakpoint => " << location.GetMethodId() << ": "
31 << location.GetBytecodeOffset();
32
33 [[maybe_unused]] LocalScope scope(debugger_->vm_);
34 debugger_->NotifyPaused(location, OTHER);
35 }
36
Exception(const JSPtLocation & location)37 void JSPtHooks::Exception([[maybe_unused]] const JSPtLocation &location)
38 {
39 LOG_DEBUGGER(VERBOSE) << "JSPtHooks: Exception";
40 [[maybe_unused]] LocalScope scope(debugger_->vm_);
41
42 debugger_->NotifyPaused({}, EXCEPTION);
43 }
44
SingleStep(const JSPtLocation & location)45 bool JSPtHooks::SingleStep(const JSPtLocation &location)
46 {
47 LOG_DEBUGGER(VERBOSE) << "JSPtHooks: SingleStep => " << location.GetBytecodeOffset();
48
49 [[maybe_unused]] LocalScope scope(debugger_->vm_);
50 if (UNLIKELY(firstTime_)) {
51 firstTime_ = false;
52
53 debugger_->NotifyPaused({}, BREAK_ON_START);
54 return false;
55 }
56
57 // pause or step complete
58 if (debugger_->NotifySingleStep(location)) {
59 debugger_->NotifyPaused({}, OTHER);
60 return true;
61 }
62
63 // temporary "safepoint" to handle possible protocol command
64 debugger_->NotifyHandleProtocolCommand();
65
66 return false;
67 }
68
NativeOut()69 bool JSPtHooks::NativeOut()
70 {
71 [[maybe_unused]] LocalScope scope(debugger_->vm_);
72 if (debugger_->NotifyNativeOut()) {
73 debugger_->NotifyPaused({}, NATIVE_OUT);
74 return true;
75 }
76
77 return false;
78 }
79
LoadModule(std::string_view pandaFileName,std::string_view entryPoint)80 void JSPtHooks::LoadModule(std::string_view pandaFileName, std::string_view entryPoint)
81 {
82 LOG_DEBUGGER(VERBOSE) << "JSPtHooks: LoadModule: " << pandaFileName;
83
84 [[maybe_unused]] LocalScope scope(debugger_->vm_);
85
86 if (debugger_->NotifyScriptParsed(pandaFileName.data(), entryPoint)) {
87 if (!debugger_->IsLaunchAccelerateMode()) {
88 firstTime_ = true;
89 }
90 }
91 }
92
NativeCalling(const void * nativeAddress)93 void JSPtHooks::NativeCalling(const void *nativeAddress)
94 {
95 LOG_DEBUGGER(VERBOSE) << "JSPtHooks: NativeCalling, addr = " << nativeAddress;
96
97 [[maybe_unused]] LocalScope scope(debugger_->vm_);
98
99 debugger_->NotifyNativeCalling(nativeAddress);
100 }
101
NativeReturn(const void * nativeAddress)102 void JSPtHooks::NativeReturn(const void *nativeAddress)
103 {
104 [[maybe_unused]] LocalScope scope(debugger_->vm_);
105
106 debugger_->NotifyNativeReturn(nativeAddress);
107 }
108
SendableMethodEntry(JSHandle<Method> method)109 void JSPtHooks::SendableMethodEntry(JSHandle<Method> method)
110 {
111 LOG_DEBUGGER(VERBOSE) << "JSPtHooks: MethodEntry";
112
113 [[maybe_unused]] LocalScope scope(debugger_->vm_);
114
115 if (debugger_->NotifyScriptParsedBySendable(method)) {
116 if (!debugger_->IsLaunchAccelerateMode()) {
117 firstTime_ = true;
118 }
119 }
120 }
121
DisableFirstTimeFlag()122 void JSPtHooks::DisableFirstTimeFlag()
123 {
124 firstTime_ = false;
125 }
126 } // namespace panda::ecmascript::tooling
127