• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 <macros.h>
19 
20 #include <sstream>
21 #include <string>
22 
23 namespace panda::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                 if (std::holds_alternative<int64_t>(*elem)) {
74                     ss_ << std::to_string(std::get<int64_t>(*elem));
75                 } else {
76                     ss_ << std::to_string(std::get<double>(*elem));
77                 }
78                 // NOLINTNEXTLINE
79             } else {
80                 ss_ << std::to_string(*elem);
81             }
82 
83             (std::next(elem) == array.end()) ? ss_ << "" : ss_ << ",";
84             ss_ << "\n";
85         }
86     }
87 
88     indent_--;
89     Indent();
90 
91     ss_ << "]" << PutComma(comma);
92 }
93 
WriteIns(const pandasm::Ins & ins)94 void DebugInfoDumper::WriteIns(const pandasm::Ins &ins)
95 {
96     ss_ << "{";
97     {
98         pandasm::Ins insCopy;
99         insCopy.opcode = ins.opcode;
100         insCopy.set_label = ins.set_label;
101         insCopy.label = ins.label;
102         WriteProperty("opcode", insCopy.ToString());
103     }
104     indent_++;
105     WrapArray("regs", ins.regs);
106     WrapArray("ids", ins.ids);
107     WrapArray("imms", ins.imms);
108     ss_ << std::endl;
109     Indent();
110     ss_ << "\"label\": "
111         << "\"" << ins.label << "\",";
112     WritePosInfo(ins.ins_debug);
113     indent_--;
114     Indent();
115     ss_ << "}";
116 }
117 
WriteMetaData(const std::vector<pandasm::AnnotationData> & metaData)118 void DebugInfoDumper::WriteMetaData(const std::vector<pandasm::AnnotationData> &metaData)
119 {
120     for (const auto &it : metaData) {
121         for (const auto &elem : it.GetElements()) {
122             pandasm::ScalarValue *value = elem.GetValue()->GetAsScalar();
123             if (value->GetType() == pandasm::Value::Type::STRING) {
124                 WriteProperty(elem.GetName().c_str(), value->GetValue<std::string>(), false);
125             } else if (value->GetType() == pandasm::Value::Type::U32) {
126                 WriteProperty(elem.GetName().c_str(), value->GetValue<size_t>());
127             }
128         }
129     }
130 }
131 
WritePosInfo(const pandasm::debuginfo::Ins & posInfo)132 void DebugInfoDumper::WritePosInfo(const pandasm::debuginfo::Ins &posInfo)
133 {
134     ss_ << std::endl;
135     Indent();
136     ss_ << "\"debug_pos_info\": {";
137     WriteProperty("boundLeft", posInfo.bound_left);
138     WriteProperty("boundRight", posInfo.bound_right);
139     WriteProperty("sourceLineNum", static_cast<int32_t>(posInfo.line_number));
140     WriteProperty("wholeLine", posInfo.whole_line, false);
141     Indent();
142     ss_ << "}" << std::endl;
143 }
144 
WriteVariableInfo(const pandasm::debuginfo::LocalVariable & localVariableDebug)145 void DebugInfoDumper::WriteVariableInfo(const pandasm::debuginfo::LocalVariable &localVariableDebug)
146 {
147     ss_ << "{";
148     WriteProperty("name", localVariableDebug.name);
149     WriteProperty("signature", localVariableDebug.signature);
150     WriteProperty("signatureType", localVariableDebug.signature_type);
151     WriteProperty("reg", localVariableDebug.reg);
152     WriteProperty("start", static_cast<size_t>(localVariableDebug.start));
153     WriteProperty("length", static_cast<size_t>(localVariableDebug.length), false);
154     Indent();
155     ss_ << "}";
156 }
157 
Dump()158 void DebugInfoDumper::Dump()
159 {
160     ss_ << "{\n";
161     indent_++;
162     Indent();
163     ss_ << "\"functions\": [" << std::endl;
164 
165     auto iter = prog_->function_table.begin();
166 
167     for (; iter != prog_->function_table.end(); ++iter) {
168         indent_++;
169         Indent();
170         ss_ << "{";
171         WriteProperty("name", iter->first);
172         ss_ << std::endl;
173 
174         indent_++;
175         Indent();
176         ss_ << "\"signature\": {";
177         WriteProperty("retType", iter->second.return_type.GetName());
178         indent_++;
179         WrapArray("params", iter->second.params, false);
180         indent_ -= 2U;
181         ss_ << std::endl;
182         Indent();
183         ss_ << "},";
184 
185         WrapArray("ins", iter->second.ins);
186         WrapArray("variables", iter->second.local_variable_debug);
187         WriteProperty("sourceFile", iter->second.source_file);
188         WriteProperty("sourceCode", iter->second.source_code);
189         // icSize - parameterLength - funcName
190         WriteMetaData(iter->second.metadata->GetAnnotations());
191 
192         indent_--;
193         Indent();
194         ss_ << "}";
195 
196         if (std::next(iter) != prog_->function_table.end()) {
197             ss_ << ",";
198         }
199 
200         ss_ << std::endl;
201     }
202 
203     indent_--;
204     Indent();
205     ss_ << "]" << std::endl;
206     ss_ << "}";
207     ss_ << std::endl;
208     std::cout << ss_.str();
209 }
210 
WriteProperty(const char * key,const Value & value,bool comma)211 void DebugInfoDumper::WriteProperty(const char *key, const Value &value, bool comma)
212 {
213     ss_ << std::endl;
214     indent_++;
215     Indent();
216     ss_ << "\"" << key << "\": ";
217     if (std::holds_alternative<std::string>(value)) {
218         ss_ << "\"" << std::get<std::string>(value) << "\"";
219     } else if (std::holds_alternative<size_t>(value)) {
220         ss_ << std::to_string(std::get<size_t>(value));
221     } else if (std::holds_alternative<int32_t>(value)) {
222         ss_ << std::to_string(std::get<int32_t>(value));
223     }
224 
225     comma ? ss_ << "," : ss_ << std::endl;
226     indent_--;
227 }
228 
Indent()229 void DebugInfoDumper::Indent()
230 {
231     for (int32_t i = 0; i <= indent_; i++) {
232         ss_ << "  ";
233     }
234 }
235 
236 }  // namespace panda::es2panda::debuginfo
237