• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024-2025 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 "include/tooling/debug_interface.h"
17 #include "include/tooling/vreg_value.h"
18 #include "intrinsics.h"
19 #include "libpandabase/utils/logger.h"
20 #include "plugins/ets/runtime/ets_exceptions.h"
21 #include "plugins/ets/runtime/tooling/helpers.h"
22 #include "plugins/ets/runtime/types/ets_primitives.h"
23 
24 namespace ark::ets::intrinsics {
25 
SetNotFoundException(EtsLong regNumber,EtsCoroutine * coroutine,std::string_view typeName)26 static void SetNotFoundException(EtsLong regNumber, EtsCoroutine *coroutine, std::string_view typeName)
27 {
28     auto errorMsg =
29         "No local variable found at vreg #" + std::to_string(regNumber) + " and type " + std::string(typeName);
30     ark::ets::ThrowEtsException(coroutine, panda_file_items::class_descriptors::LINKER_UNRESOLVED_FIELD_ERROR.data(),
31                                 errorMsg);
32 }
33 
SetRuntimeException(EtsLong regNumber,EtsCoroutine * coroutine,std::string_view typeName)34 static void SetRuntimeException(EtsLong regNumber, EtsCoroutine *coroutine, std::string_view typeName)
35 {
36     auto errorMsg =
37         "Failed to access variable at vreg #" + std::to_string(regNumber) + " and type " + std::string(typeName);
38     ark::ets::ThrowEtsException(coroutine, panda_file_items::class_descriptors::ERROR, errorMsg);
39 }
40 
41 template <typename T>
DebuggerAPIGetLocal(EtsCoroutine * coroutine,EtsLong regNumber)42 static T DebuggerAPIGetLocal(EtsCoroutine *coroutine, EtsLong regNumber)
43 {
44     static constexpr uint32_t PREVIOUS_FRAME_DEPTH = 1;
45 
46     ASSERT(coroutine);
47 
48     if (regNumber < 0) {
49         SetNotFoundException(regNumber, coroutine, ark::ets::tooling::EtsTypeName<T>::NAME);
50     }
51 
52     ark::tooling::VRegValue vregValue;
53     auto &debugger = Runtime::GetCurrent()->StartDebugSession()->GetDebugger();
54     auto err = debugger.GetVariable(ark::ets::tooling::CoroutineToPtThread(coroutine), PREVIOUS_FRAME_DEPTH, regNumber,
55                                     &vregValue);
56     if (err) {
57         LOG(ERROR, DEBUGGER) << "Failed to get local variable: " << err.value().GetMessage();
58         SetRuntimeException(regNumber, coroutine, ark::ets::tooling::EtsTypeName<T>::NAME);
59         return static_cast<T>(0);
60     }
61     return ark::ets::tooling::VRegValueToEtsValue<T>(vregValue);
62 }
63 
DebuggerAPIGetLocalBoolean(EtsLong regNumber)64 EtsBoolean DebuggerAPIGetLocalBoolean(EtsLong regNumber)
65 {
66     auto *coroutine = EtsCoroutine::GetCurrent();
67     return DebuggerAPIGetLocal<EtsBoolean>(coroutine, regNumber);
68 }
69 
DebuggerAPIGetLocalByte(EtsLong regNumber)70 EtsByte DebuggerAPIGetLocalByte(EtsLong regNumber)
71 {
72     auto *coroutine = EtsCoroutine::GetCurrent();
73     return DebuggerAPIGetLocal<EtsByte>(coroutine, regNumber);
74 }
75 
DebuggerAPIGetLocalShort(EtsLong regNumber)76 EtsShort DebuggerAPIGetLocalShort(EtsLong regNumber)
77 {
78     auto *coroutine = EtsCoroutine::GetCurrent();
79     return DebuggerAPIGetLocal<EtsShort>(coroutine, regNumber);
80 }
81 
DebuggerAPIGetLocalChar(EtsLong regNumber)82 EtsChar DebuggerAPIGetLocalChar(EtsLong regNumber)
83 {
84     auto *coroutine = EtsCoroutine::GetCurrent();
85     return DebuggerAPIGetLocal<EtsChar>(coroutine, regNumber);
86 }
87 
DebuggerAPIGetLocalInt(EtsLong regNumber)88 EtsInt DebuggerAPIGetLocalInt(EtsLong regNumber)
89 {
90     auto *coroutine = EtsCoroutine::GetCurrent();
91     return DebuggerAPIGetLocal<EtsInt>(coroutine, regNumber);
92 }
93 
DebuggerAPIGetLocalFloat(EtsLong regNumber)94 EtsFloat DebuggerAPIGetLocalFloat(EtsLong regNumber)
95 {
96     auto *coroutine = EtsCoroutine::GetCurrent();
97     return DebuggerAPIGetLocal<EtsFloat>(coroutine, regNumber);
98 }
99 
DebuggerAPIGetLocalDouble(EtsLong regNumber)100 EtsDouble DebuggerAPIGetLocalDouble(EtsLong regNumber)
101 {
102     auto *coroutine = EtsCoroutine::GetCurrent();
103     return DebuggerAPIGetLocal<EtsDouble>(coroutine, regNumber);
104 }
105 
DebuggerAPIGetLocalLong(EtsLong regNumber)106 EtsLong DebuggerAPIGetLocalLong(EtsLong regNumber)
107 {
108     auto *coroutine = EtsCoroutine::GetCurrent();
109     return DebuggerAPIGetLocal<EtsLong>(coroutine, regNumber);
110 }
111 
DebuggerAPIGetLocalObject(EtsLong regNumber)112 EtsObject *DebuggerAPIGetLocalObject(EtsLong regNumber)
113 {
114     auto *coroutine = EtsCoroutine::GetCurrent();
115     [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
116 
117     auto *obj = DebuggerAPIGetLocal<ObjectHeader *>(coroutine, regNumber);
118     obj = (obj == nullptr) ? coroutine->GetNullValue() : obj;
119     VMHandle<ObjectHeader> objHandle(coroutine, obj);
120     return EtsObject::FromCoreType(objHandle.GetPtr());
121 }
122 
123 template <typename T>
DebuggerAPISetLocal(EtsCoroutine * coroutine,EtsLong regNumber,T value)124 static void DebuggerAPISetLocal(EtsCoroutine *coroutine, EtsLong regNumber, T value)
125 {
126     static constexpr uint32_t PREVIOUS_FRAME_DEPTH = 1;
127 
128     ASSERT(coroutine);
129 
130     if (regNumber < 0) {
131         SetNotFoundException(regNumber, coroutine, ark::ets::tooling::EtsTypeName<T>::NAME);
132         return;
133     }
134 
135     auto vregValue = ark::ets::tooling::EtsValueToVRegValue<T>(value);
136     auto &debugger = Runtime::GetCurrent()->StartDebugSession()->GetDebugger();
137     auto err = debugger.SetVariable(ark::ets::tooling::CoroutineToPtThread(coroutine), PREVIOUS_FRAME_DEPTH, regNumber,
138                                     vregValue);
139     if (err) {
140         LOG(ERROR, DEBUGGER) << "Failed to set local variable: " << err.value().GetMessage();
141         SetRuntimeException(regNumber, coroutine, ark::ets::tooling::EtsTypeName<T>::NAME);
142     }
143 }
144 
DebuggerAPISetLocalBoolean(EtsLong regNumber,EtsBoolean value)145 void DebuggerAPISetLocalBoolean(EtsLong regNumber, EtsBoolean value)
146 {
147     auto coroutine = EtsCoroutine::GetCurrent();
148     DebuggerAPISetLocal<EtsBoolean>(coroutine, regNumber, value);
149 }
150 
DebuggerAPISetLocalByte(EtsLong regNumber,EtsByte value)151 void DebuggerAPISetLocalByte(EtsLong regNumber, EtsByte value)
152 {
153     auto coroutine = EtsCoroutine::GetCurrent();
154     DebuggerAPISetLocal<EtsByte>(coroutine, regNumber, value);
155 }
156 
DebuggerAPISetLocalShort(EtsLong regNumber,EtsShort value)157 void DebuggerAPISetLocalShort(EtsLong regNumber, EtsShort value)
158 {
159     auto coroutine = EtsCoroutine::GetCurrent();
160     DebuggerAPISetLocal<EtsShort>(coroutine, regNumber, value);
161 }
162 
DebuggerAPISetLocalChar(EtsLong regNumber,EtsChar value)163 void DebuggerAPISetLocalChar(EtsLong regNumber, EtsChar value)
164 {
165     auto coroutine = EtsCoroutine::GetCurrent();
166     DebuggerAPISetLocal<EtsChar>(coroutine, regNumber, value);
167 }
168 
DebuggerAPISetLocalInt(EtsLong regNumber,EtsInt value)169 void DebuggerAPISetLocalInt(EtsLong regNumber, EtsInt value)
170 {
171     auto coroutine = EtsCoroutine::GetCurrent();
172     DebuggerAPISetLocal<EtsInt>(coroutine, regNumber, value);
173 }
174 
DebuggerAPISetLocalFloat(EtsLong regNumber,EtsFloat value)175 void DebuggerAPISetLocalFloat(EtsLong regNumber, EtsFloat value)
176 {
177     auto coroutine = EtsCoroutine::GetCurrent();
178     DebuggerAPISetLocal<EtsFloat>(coroutine, regNumber, value);
179 }
180 
DebuggerAPISetLocalDouble(EtsLong regNumber,EtsDouble value)181 void DebuggerAPISetLocalDouble(EtsLong regNumber, EtsDouble value)
182 {
183     auto coroutine = EtsCoroutine::GetCurrent();
184     DebuggerAPISetLocal<EtsDouble>(coroutine, regNumber, value);
185 }
186 
DebuggerAPISetLocalLong(EtsLong regNumber,EtsLong value)187 void DebuggerAPISetLocalLong(EtsLong regNumber, EtsLong value)
188 {
189     auto coroutine = EtsCoroutine::GetCurrent();
190     DebuggerAPISetLocal<EtsLong>(coroutine, regNumber, value);
191 }
192 
DebuggerAPISetLocalObject(EtsLong regNumber,EtsObject * value)193 void DebuggerAPISetLocalObject(EtsLong regNumber, EtsObject *value)
194 {
195     auto coroutine = EtsCoroutine::GetCurrent();
196     [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
197     VMHandle<EtsObject> objHandle(coroutine, value->GetCoreType());
198 
199     DebuggerAPISetLocal<ObjectHeader *>(coroutine, regNumber, objHandle.GetPtr()->GetCoreType());
200 }
201 
202 }  // namespace ark::ets::intrinsics
203