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