• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "debuginfoDumper.h"
17 
18 #include "util/es2pandaMacros.h"
19 
20 #include <sstream>
21 #include <string>
22 
23 namespace ark::es2panda::debuginfo {
24 
DebugInfoDumper(const pandasm::Program * prog)25 DebugInfoDumper::DebugInfoDumper(const pandasm::Program *prog) : prog_(prog) {}
26 
PutComma(bool comma)27 static const char *PutComma(bool comma)
28 {
29     return comma ? "," : "";
30 }
31 
32 template <typename T>
WrapArray(const char * name,const std::vector<T> & array,bool comma)33 void DebugInfoDumper::WrapArray(const char *name, const std::vector<T> &array, bool comma)
34 {
35     ss_ << std::endl;
36     Indent();
37     ss_ << "\"" << name << "\": "
38         << "[";
39 
40     if (array.empty()) {
41         ss_ << "]" << PutComma(comma);
42         return;
43     }
44 
45     ss_ << "\n";
46     indent_++;
47     // dump VariableDebugInfo in reverse order to match ts2panda
48     // NOLINTNEXTLINE
49     if constexpr (std::is_same_v<T, pandasm::debuginfo::LocalVariable>) {
50         typename std::vector<T>::const_reverse_iterator elem;
51         for (elem = array.rbegin(); elem != array.rend(); ++elem) {
52             Indent();
53             WriteVariableInfo(*elem);
54             (std::next(elem) == array.rend()) ? ss_ << "" : ss_ << ",";
55             ss_ << "\n";
56         }
57         // NOLINTNEXTLINE
58     } else {
59         typename std::vector<T>::const_iterator elem;
60         for (elem = array.begin(); elem != array.end(); ++elem) {
61             Indent();
62             // NOLINTNEXTLINE
63             if constexpr (std::is_same_v<T, pandasm::Ins>) {
64                 WriteIns(*elem);
65                 // NOLINTNEXTLINE
66             } else if constexpr (std::is_same_v<T, pandasm::Function::Parameter>) {
67                 ss_ << "\"" << (*elem).type.GetName() << "\"";
68                 // NOLINTNEXTLINE
69             } else if constexpr (std::is_same_v<T, std::string>) {
70                 ss_ << "\"" << *elem << "\"";
71                 // NOLINTNEXTLINE
72             } else if constexpr (std::is_same_v<T, std::variant<int64_t, double>>) {
73                 ss_ << (std::holds_alternative<int64_t>(*elem) ? std::to_string(std::get<int64_t>(*elem))
74                                                                : std::to_string(std::get<double>(*elem)));
75                 // NOLINTNEXTLINE
76             } else {
77                 ss_ << std::to_string(*elem);
78             }
79 
80             (std::next(elem) == array.end()) ? ss_ << "" : ss_ << ",";
81             ss_ << "\n";
82         }
83     }
84 
85     indent_--;
86     Indent();
87 
88     ss_ << "]" << PutComma(comma);
89 }
90 
WriteIns(const pandasm::Ins & ins)91 void DebugInfoDumper::WriteIns(const pandasm::Ins &ins)
92 {
93     ss_ << "{";
94     {
95         pandasm::Ins insCopy;
96         insCopy.opcode = ins.opcode;
97         insCopy.setLabel = ins.setLabel;
98         insCopy.label = ins.label;
99         WriteProperty("opcode", insCopy.ToString());
100     }
101     indent_++;
102     WrapArray("regs", ins.regs);
103     WrapArray("ids", ins.ids);
104     WrapArray("imms", ins.imms);
105     ss_ << std::endl;
106     Indent();
107     ss_ << "\"label\": "
108         << "\"" << ins.label << "\",";
109     WritePosInfo(ins.insDebug);
110     indent_--;
111     Indent();
112     ss_ << "}";
113 }
114 
WriteMetaData(const std::vector<pandasm::AnnotationData> & metaData)115 void DebugInfoDumper::WriteMetaData(const std::vector<pandasm::AnnotationData> &metaData)
116 {
117     for (const auto &it : metaData) {
118         for (const auto &elem : it.GetElements()) {
119             pandasm::ScalarValue *value = elem.GetValue()->GetAsScalar();
120             if (value->GetType() == pandasm::Value::Type::STRING) {
121                 WriteProperty(elem.GetName().c_str(), value->GetValue<std::string>(), false);
122             } else if (value->GetType() == pandasm::Value::Type::U32) {
123                 WriteProperty(elem.GetName().c_str(), value->GetValue<size_t>());
124             }
125         }
126     }
127 }
128 
WritePosInfo(const pandasm::debuginfo::Ins & posInfo)129 void DebugInfoDumper::WritePosInfo(const pandasm::debuginfo::Ins &posInfo)
130 {
131     ss_ << std::endl;
132     Indent();
133     ss_ << "\"debug_pos_info\": {";
134     WriteProperty("boundLeft", posInfo.boundLeft);
135     WriteProperty("boundRight", posInfo.boundRight);
136     WriteProperty("sourceLineNum", static_cast<int32_t>(posInfo.lineNumber));
137     WriteProperty("wholeLine", posInfo.wholeLine, false);
138     Indent();
139     ss_ << "}" << std::endl;
140 }
141 
WriteVariableInfo(const pandasm::debuginfo::LocalVariable & localVariableDebug)142 void DebugInfoDumper::WriteVariableInfo(const pandasm::debuginfo::LocalVariable &localVariableDebug)
143 {
144     ss_ << "{";
145     WriteProperty("name", localVariableDebug.name);
146     WriteProperty("signature", localVariableDebug.signature);
147     WriteProperty("signatureType", localVariableDebug.signatureType);
148     WriteProperty("reg", localVariableDebug.reg);
149     WriteProperty("start", static_cast<size_t>(localVariableDebug.start));
150     WriteProperty("length", static_cast<size_t>(localVariableDebug.length), false);
151     Indent();
152     ss_ << "}";
153 }
154 
DumpFuncBody(std::string name,const pandasm::Function & func)155 void DebugInfoDumper::DumpFuncBody(std::string name, const pandasm::Function &func)
156 {
157     indent_++;
158     Indent();
159     ss_ << "{";
160     WriteProperty("name", name);
161     ss_ << std::endl;
162 
163     indent_++;
164     Indent();
165     ss_ << "\"signature\": {";
166     WriteProperty("retType", func.returnType.GetName());
167     indent_++;
168     WrapArray("params", func.params, false);
169     indent_ -= 2U;
170     ss_ << std::endl;
171     Indent();
172     ss_ << "},";
173 
174     WrapArray("ins", func.ins);
175     WrapArray("variables", func.localVariableDebug);
176     WriteProperty("sourceFile", func.sourceFile);
177     WriteProperty("sourceCode", func.sourceCode);
178     // icSize - parameterLength - funcName
179     WriteMetaData(func.metadata->GetAnnotations());
180 
181     indent_--;
182     Indent();
183     ss_ << "}";
184 }
185 
DumpFunctions(const std::map<std::string,pandasm::Function> & table)186 void DebugInfoDumper::DumpFunctions(const std::map<std::string, pandasm::Function> &table)
187 {
188     auto iter = table.begin();
189 
190     for (; iter != table.end(); ++iter) {
191         DumpFuncBody(iter->first, iter->second);
192 
193         if (std::next(iter) != table.end()) {
194             ss_ << ",";
195         }
196 
197         ss_ << std::endl;
198     }
199 }
200 
Dump()201 void DebugInfoDumper::Dump()
202 {
203     ss_ << "{\n";
204     indent_++;
205     Indent();
206     ss_ << "\"functions\": [" << std::endl;
207 
208     DumpFunctions(prog_->functionStaticTable);
209     DumpFunctions(prog_->functionInstanceTable);
210 
211     indent_--;
212     Indent();
213     ss_ << "]" << std::endl;
214     ss_ << "}";
215     ss_ << std::endl;
216     std::cout << ss_.str();
217 }
218 
WriteProperty(const char * key,const Value & value,bool comma)219 void DebugInfoDumper::WriteProperty(const char *key, const Value &value, bool comma)
220 {
221     ss_ << std::endl;
222     indent_++;
223     Indent();
224     ss_ << "\"" << key << "\": ";
225     if (std::holds_alternative<std::string>(value)) {
226         ss_ << "\"" << std::get<std::string>(value) << "\"";
227     } else if (std::holds_alternative<size_t>(value)) {
228         ss_ << std::to_string(std::get<size_t>(value));
229     } else if (std::holds_alternative<int32_t>(value)) {
230         ss_ << std::to_string(std::get<int32_t>(value));
231     }
232 
233     comma ? ss_ << "," : ss_ << std::endl;
234     indent_--;
235 }
236 
Indent()237 void DebugInfoDumper::Indent()
238 {
239     for (int32_t i = 0; i <= indent_; i++) {
240         ss_ << "  ";
241     }
242 }
243 
244 }  // namespace ark::es2panda::debuginfo
245