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