13af6ab5fSopenharmony_ci/*
23af6ab5fSopenharmony_ci * Copyright (c) 2021 - 2023 Huawei Device Co., Ltd.
33af6ab5fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43af6ab5fSopenharmony_ci * you may not use this file except in compliance with the License.
53af6ab5fSopenharmony_ci * You may obtain a copy of the License at
63af6ab5fSopenharmony_ci *
73af6ab5fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
83af6ab5fSopenharmony_ci *
93af6ab5fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103af6ab5fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113af6ab5fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123af6ab5fSopenharmony_ci * See the License for the specific language governing permissions and
133af6ab5fSopenharmony_ci * limitations under the License.
143af6ab5fSopenharmony_ci */
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ci#include "debuginfoDumper.h"
173af6ab5fSopenharmony_ci
183af6ab5fSopenharmony_ci#include "macros.h"
193af6ab5fSopenharmony_ci
203af6ab5fSopenharmony_ci#include <sstream>
213af6ab5fSopenharmony_ci#include <string>
223af6ab5fSopenharmony_ci
233af6ab5fSopenharmony_cinamespace ark::es2panda::debuginfo {
243af6ab5fSopenharmony_ci
253af6ab5fSopenharmony_ciDebugInfoDumper::DebugInfoDumper(const pandasm::Program *prog) : prog_(prog) {}
263af6ab5fSopenharmony_ci
273af6ab5fSopenharmony_cistatic const char *PutComma(bool comma)
283af6ab5fSopenharmony_ci{
293af6ab5fSopenharmony_ci    return comma ? "," : "";
303af6ab5fSopenharmony_ci}
313af6ab5fSopenharmony_ci
323af6ab5fSopenharmony_citemplate <typename T>
333af6ab5fSopenharmony_civoid DebugInfoDumper::WrapArray(const char *name, const std::vector<T> &array, bool comma)
343af6ab5fSopenharmony_ci{
353af6ab5fSopenharmony_ci    ss_ << std::endl;
363af6ab5fSopenharmony_ci    Indent();
373af6ab5fSopenharmony_ci    ss_ << "\"" << name << "\": "
383af6ab5fSopenharmony_ci        << "[";
393af6ab5fSopenharmony_ci
403af6ab5fSopenharmony_ci    if (array.empty()) {
413af6ab5fSopenharmony_ci        ss_ << "]" << PutComma(comma);
423af6ab5fSopenharmony_ci        return;
433af6ab5fSopenharmony_ci    }
443af6ab5fSopenharmony_ci
453af6ab5fSopenharmony_ci    ss_ << "\n";
463af6ab5fSopenharmony_ci    indent_++;
473af6ab5fSopenharmony_ci    // dump VariableDebugInfo in reverse order to match ts2panda
483af6ab5fSopenharmony_ci    // NOLINTNEXTLINE
493af6ab5fSopenharmony_ci    if constexpr (std::is_same_v<T, pandasm::debuginfo::LocalVariable>) {
503af6ab5fSopenharmony_ci        typename std::vector<T>::const_reverse_iterator elem;
513af6ab5fSopenharmony_ci        for (elem = array.rbegin(); elem != array.rend(); ++elem) {
523af6ab5fSopenharmony_ci            Indent();
533af6ab5fSopenharmony_ci            WriteVariableInfo(*elem);
543af6ab5fSopenharmony_ci            (std::next(elem) == array.rend()) ? ss_ << "" : ss_ << ",";
553af6ab5fSopenharmony_ci            ss_ << "\n";
563af6ab5fSopenharmony_ci        }
573af6ab5fSopenharmony_ci        // NOLINTNEXTLINE
583af6ab5fSopenharmony_ci    } else {
593af6ab5fSopenharmony_ci        typename std::vector<T>::const_iterator elem;
603af6ab5fSopenharmony_ci        for (elem = array.begin(); elem != array.end(); ++elem) {
613af6ab5fSopenharmony_ci            Indent();
623af6ab5fSopenharmony_ci            // NOLINTNEXTLINE
633af6ab5fSopenharmony_ci            if constexpr (std::is_same_v<T, pandasm::Ins>) {
643af6ab5fSopenharmony_ci                WriteIns(*elem);
653af6ab5fSopenharmony_ci                // NOLINTNEXTLINE
663af6ab5fSopenharmony_ci            } else if constexpr (std::is_same_v<T, pandasm::Function::Parameter>) {
673af6ab5fSopenharmony_ci                ss_ << "\"" << (*elem).type.GetName() << "\"";
683af6ab5fSopenharmony_ci                // NOLINTNEXTLINE
693af6ab5fSopenharmony_ci            } else if constexpr (std::is_same_v<T, std::string>) {
703af6ab5fSopenharmony_ci                ss_ << "\"" << *elem << "\"";
713af6ab5fSopenharmony_ci                // NOLINTNEXTLINE
723af6ab5fSopenharmony_ci            } else if constexpr (std::is_same_v<T, std::variant<int64_t, double>>) {
733af6ab5fSopenharmony_ci                ss_ << (std::holds_alternative<int64_t>(*elem) ? std::to_string(std::get<int64_t>(*elem))
743af6ab5fSopenharmony_ci                                                               : std::to_string(std::get<double>(*elem)));
753af6ab5fSopenharmony_ci                // NOLINTNEXTLINE
763af6ab5fSopenharmony_ci            } else {
773af6ab5fSopenharmony_ci                ss_ << std::to_string(*elem);
783af6ab5fSopenharmony_ci            }
793af6ab5fSopenharmony_ci
803af6ab5fSopenharmony_ci            (std::next(elem) == array.end()) ? ss_ << "" : ss_ << ",";
813af6ab5fSopenharmony_ci            ss_ << "\n";
823af6ab5fSopenharmony_ci        }
833af6ab5fSopenharmony_ci    }
843af6ab5fSopenharmony_ci
853af6ab5fSopenharmony_ci    indent_--;
863af6ab5fSopenharmony_ci    Indent();
873af6ab5fSopenharmony_ci
883af6ab5fSopenharmony_ci    ss_ << "]" << PutComma(comma);
893af6ab5fSopenharmony_ci}
903af6ab5fSopenharmony_ci
913af6ab5fSopenharmony_civoid DebugInfoDumper::WriteIns(const pandasm::Ins &ins)
923af6ab5fSopenharmony_ci{
933af6ab5fSopenharmony_ci    ss_ << "{";
943af6ab5fSopenharmony_ci    {
953af6ab5fSopenharmony_ci        pandasm::Ins insCopy;
963af6ab5fSopenharmony_ci        insCopy.opcode = ins.opcode;
973af6ab5fSopenharmony_ci        insCopy.setLabel = ins.setLabel;
983af6ab5fSopenharmony_ci        insCopy.label = ins.label;
993af6ab5fSopenharmony_ci        WriteProperty("opcode", insCopy.ToString());
1003af6ab5fSopenharmony_ci    }
1013af6ab5fSopenharmony_ci    indent_++;
1023af6ab5fSopenharmony_ci    WrapArray("regs", ins.regs);
1033af6ab5fSopenharmony_ci    WrapArray("ids", ins.ids);
1043af6ab5fSopenharmony_ci    WrapArray("imms", ins.imms);
1053af6ab5fSopenharmony_ci    ss_ << std::endl;
1063af6ab5fSopenharmony_ci    Indent();
1073af6ab5fSopenharmony_ci    ss_ << "\"label\": "
1083af6ab5fSopenharmony_ci        << "\"" << ins.label << "\",";
1093af6ab5fSopenharmony_ci    WritePosInfo(ins.insDebug);
1103af6ab5fSopenharmony_ci    indent_--;
1113af6ab5fSopenharmony_ci    Indent();
1123af6ab5fSopenharmony_ci    ss_ << "}";
1133af6ab5fSopenharmony_ci}
1143af6ab5fSopenharmony_ci
1153af6ab5fSopenharmony_civoid DebugInfoDumper::WriteMetaData(const std::vector<pandasm::AnnotationData> &metaData)
1163af6ab5fSopenharmony_ci{
1173af6ab5fSopenharmony_ci    for (const auto &it : metaData) {
1183af6ab5fSopenharmony_ci        for (const auto &elem : it.GetElements()) {
1193af6ab5fSopenharmony_ci            pandasm::ScalarValue *value = elem.GetValue()->GetAsScalar();
1203af6ab5fSopenharmony_ci            if (value->GetType() == pandasm::Value::Type::STRING) {
1213af6ab5fSopenharmony_ci                WriteProperty(elem.GetName().c_str(), value->GetValue<std::string>(), false);
1223af6ab5fSopenharmony_ci            } else if (value->GetType() == pandasm::Value::Type::U32) {
1233af6ab5fSopenharmony_ci                WriteProperty(elem.GetName().c_str(), value->GetValue<size_t>());
1243af6ab5fSopenharmony_ci            }
1253af6ab5fSopenharmony_ci        }
1263af6ab5fSopenharmony_ci    }
1273af6ab5fSopenharmony_ci}
1283af6ab5fSopenharmony_ci
1293af6ab5fSopenharmony_civoid DebugInfoDumper::WritePosInfo(const pandasm::debuginfo::Ins &posInfo)
1303af6ab5fSopenharmony_ci{
1313af6ab5fSopenharmony_ci    ss_ << std::endl;
1323af6ab5fSopenharmony_ci    Indent();
1333af6ab5fSopenharmony_ci    ss_ << "\"debug_pos_info\": {";
1343af6ab5fSopenharmony_ci    WriteProperty("boundLeft", posInfo.boundLeft);
1353af6ab5fSopenharmony_ci    WriteProperty("boundRight", posInfo.boundRight);
1363af6ab5fSopenharmony_ci    WriteProperty("sourceLineNum", static_cast<int32_t>(posInfo.lineNumber));
1373af6ab5fSopenharmony_ci    WriteProperty("wholeLine", posInfo.wholeLine, false);
1383af6ab5fSopenharmony_ci    Indent();
1393af6ab5fSopenharmony_ci    ss_ << "}" << std::endl;
1403af6ab5fSopenharmony_ci}
1413af6ab5fSopenharmony_ci
1423af6ab5fSopenharmony_civoid DebugInfoDumper::WriteVariableInfo(const pandasm::debuginfo::LocalVariable &localVariableDebug)
1433af6ab5fSopenharmony_ci{
1443af6ab5fSopenharmony_ci    ss_ << "{";
1453af6ab5fSopenharmony_ci    WriteProperty("name", localVariableDebug.name);
1463af6ab5fSopenharmony_ci    WriteProperty("signature", localVariableDebug.signature);
1473af6ab5fSopenharmony_ci    WriteProperty("signatureType", localVariableDebug.signatureType);
1483af6ab5fSopenharmony_ci    WriteProperty("reg", localVariableDebug.reg);
1493af6ab5fSopenharmony_ci    WriteProperty("start", static_cast<size_t>(localVariableDebug.start));
1503af6ab5fSopenharmony_ci    WriteProperty("length", static_cast<size_t>(localVariableDebug.length), false);
1513af6ab5fSopenharmony_ci    Indent();
1523af6ab5fSopenharmony_ci    ss_ << "}";
1533af6ab5fSopenharmony_ci}
1543af6ab5fSopenharmony_ci
1553af6ab5fSopenharmony_civoid DebugInfoDumper::Dump()
1563af6ab5fSopenharmony_ci{
1573af6ab5fSopenharmony_ci    ss_ << "{\n";
1583af6ab5fSopenharmony_ci    indent_++;
1593af6ab5fSopenharmony_ci    Indent();
1603af6ab5fSopenharmony_ci    ss_ << "\"functions\": [" << std::endl;
1613af6ab5fSopenharmony_ci
1623af6ab5fSopenharmony_ci    auto iter = prog_->functionTable.begin();
1633af6ab5fSopenharmony_ci
1643af6ab5fSopenharmony_ci    for (; iter != prog_->functionTable.end(); ++iter) {
1653af6ab5fSopenharmony_ci        indent_++;
1663af6ab5fSopenharmony_ci        Indent();
1673af6ab5fSopenharmony_ci        ss_ << "{";
1683af6ab5fSopenharmony_ci        WriteProperty("name", iter->first);
1693af6ab5fSopenharmony_ci        ss_ << std::endl;
1703af6ab5fSopenharmony_ci
1713af6ab5fSopenharmony_ci        indent_++;
1723af6ab5fSopenharmony_ci        Indent();
1733af6ab5fSopenharmony_ci        ss_ << "\"signature\": {";
1743af6ab5fSopenharmony_ci        WriteProperty("retType", iter->second.returnType.GetName());
1753af6ab5fSopenharmony_ci        indent_++;
1763af6ab5fSopenharmony_ci        WrapArray("params", iter->second.params, false);
1773af6ab5fSopenharmony_ci        indent_ -= 2U;
1783af6ab5fSopenharmony_ci        ss_ << std::endl;
1793af6ab5fSopenharmony_ci        Indent();
1803af6ab5fSopenharmony_ci        ss_ << "},";
1813af6ab5fSopenharmony_ci
1823af6ab5fSopenharmony_ci        WrapArray("ins", iter->second.ins);
1833af6ab5fSopenharmony_ci        WrapArray("variables", iter->second.localVariableDebug);
1843af6ab5fSopenharmony_ci        WriteProperty("sourceFile", iter->second.sourceFile);
1853af6ab5fSopenharmony_ci        WriteProperty("sourceCode", iter->second.sourceCode);
1863af6ab5fSopenharmony_ci        // icSize - parameterLength - funcName
1873af6ab5fSopenharmony_ci        WriteMetaData(iter->second.metadata->GetAnnotations());
1883af6ab5fSopenharmony_ci
1893af6ab5fSopenharmony_ci        indent_--;
1903af6ab5fSopenharmony_ci        Indent();
1913af6ab5fSopenharmony_ci        ss_ << "}";
1923af6ab5fSopenharmony_ci
1933af6ab5fSopenharmony_ci        if (std::next(iter) != prog_->functionTable.end()) {
1943af6ab5fSopenharmony_ci            ss_ << ",";
1953af6ab5fSopenharmony_ci        }
1963af6ab5fSopenharmony_ci
1973af6ab5fSopenharmony_ci        ss_ << std::endl;
1983af6ab5fSopenharmony_ci    }
1993af6ab5fSopenharmony_ci
2003af6ab5fSopenharmony_ci    indent_--;
2013af6ab5fSopenharmony_ci    Indent();
2023af6ab5fSopenharmony_ci    ss_ << "]" << std::endl;
2033af6ab5fSopenharmony_ci    ss_ << "}";
2043af6ab5fSopenharmony_ci    ss_ << std::endl;
2053af6ab5fSopenharmony_ci    std::cout << ss_.str();
2063af6ab5fSopenharmony_ci}
2073af6ab5fSopenharmony_ci
2083af6ab5fSopenharmony_civoid DebugInfoDumper::WriteProperty(const char *key, const Value &value, bool comma)
2093af6ab5fSopenharmony_ci{
2103af6ab5fSopenharmony_ci    ss_ << std::endl;
2113af6ab5fSopenharmony_ci    indent_++;
2123af6ab5fSopenharmony_ci    Indent();
2133af6ab5fSopenharmony_ci    ss_ << "\"" << key << "\": ";
2143af6ab5fSopenharmony_ci    if (std::holds_alternative<std::string>(value)) {
2153af6ab5fSopenharmony_ci        ss_ << "\"" << std::get<std::string>(value) << "\"";
2163af6ab5fSopenharmony_ci    } else if (std::holds_alternative<size_t>(value)) {
2173af6ab5fSopenharmony_ci        ss_ << std::to_string(std::get<size_t>(value));
2183af6ab5fSopenharmony_ci    } else if (std::holds_alternative<int32_t>(value)) {
2193af6ab5fSopenharmony_ci        ss_ << std::to_string(std::get<int32_t>(value));
2203af6ab5fSopenharmony_ci    }
2213af6ab5fSopenharmony_ci
2223af6ab5fSopenharmony_ci    comma ? ss_ << "," : ss_ << std::endl;
2233af6ab5fSopenharmony_ci    indent_--;
2243af6ab5fSopenharmony_ci}
2253af6ab5fSopenharmony_ci
2263af6ab5fSopenharmony_civoid DebugInfoDumper::Indent()
2273af6ab5fSopenharmony_ci{
2283af6ab5fSopenharmony_ci    for (int32_t i = 0; i <= indent_; i++) {
2293af6ab5fSopenharmony_ci        ss_ << "  ";
2303af6ab5fSopenharmony_ci    }
2313af6ab5fSopenharmony_ci}
2323af6ab5fSopenharmony_ci
2333af6ab5fSopenharmony_ci}  // namespace ark::es2panda::debuginfo
234