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 "abc2program_entity_container.h"
17 #include "abc_file_utils.h"
18 #include "file-inl.h"
19 #include "method_data_accessor-inl.h"
20 #include "mangling.h"
21 #include "os/file.h"
22 
23 namespace panda::abc2program {
24 
GetAbcFile() const25 const panda_file::File &Abc2ProgramEntityContainer::GetAbcFile() const
26 {
27     return file_;
28 }
29 
GetProgram() const30 pandasm::Program &Abc2ProgramEntityContainer::GetProgram() const
31 {
32     return program_;
33 }
34 
GetDebugInfoExtractor() const35 const panda_file::DebugInfoExtractor &Abc2ProgramEntityContainer::GetDebugInfoExtractor() const
36 {
37     return debug_info_extractor_;
38 }
39 
GetStringById(const panda_file::File::EntityId &entity_id) const40 std::string Abc2ProgramEntityContainer::GetStringById(const panda_file::File::EntityId &entity_id) const
41 {
42     panda_file::File::StringData sd = file_.GetStringData(entity_id);
43     return (reinterpret_cast<const char *>(sd.data));
44 }
45 
GetFullRecordNameById(const panda_file::File::EntityId &class_id)46 std::string Abc2ProgramEntityContainer::GetFullRecordNameById(const panda_file::File::EntityId &class_id)
47 {
48     uint32_t class_id_offset = class_id.GetOffset();
49     auto it = record_full_name_map_.find(class_id_offset);
50     if (it != record_full_name_map_.end()) {
51         return it->second;
52     }
53     std::string name = GetStringById(class_id);
54     pandasm::Type type = pandasm::Type::FromDescriptor(name);
55     std::string record_full_name = type.GetName();
56     record_full_name_map_.emplace(class_id_offset, record_full_name);
57     return record_full_name;
58 }
59 
GetFullMethodNameById(const panda_file::File::EntityId &method_id)60 std::string Abc2ProgramEntityContainer::GetFullMethodNameById(const panda_file::File::EntityId &method_id)
61 {
62     auto method_id_offset = method_id.GetOffset();
63     auto it = method_full_name_map_.find(method_id_offset);
64     if (it != method_full_name_map_.end()) {
65         return it->second;
66     }
67     std::string full_method_name = ConcatFullMethodNameById(method_id);
68     method_full_name_map_.emplace(method_id_offset, full_method_name);
69     return full_method_name;
70 }
71 
ConcatFullMethodNameById(const panda_file::File::EntityId &method_id)72 std::string Abc2ProgramEntityContainer::ConcatFullMethodNameById(const panda_file::File::EntityId &method_id)
73 {
74     panda::panda_file::MethodDataAccessor method_data_accessor(file_, method_id);
75     std::string method_name_raw = GetStringById(method_data_accessor.GetNameId());
76     std::string record_name = GetFullRecordNameById(method_data_accessor.GetClassId());
77     std::stringstream ss;
78     if (AbcFileUtils::IsSystemTypeName(record_name)) {
79         ss << DOT;
80     } else {
81         ss << record_name << DOT;
82     }
83     ss << method_name_raw;
84     return ss.str();
85 }
86 
GetMouleLiteralArrayIdSet() const87 const std::unordered_set<uint32_t> &Abc2ProgramEntityContainer::GetMouleLiteralArrayIdSet() const
88 {
89     return module_literal_array_id_set_;
90 }
91 
GetModuleRequestPhaseIdSet() const92 const std::unordered_set<uint32_t> &Abc2ProgramEntityContainer::GetModuleRequestPhaseIdSet() const
93 {
94     return module_request_phase_id_set_;
95 }
96 
GetUnnestedLiteralArrayIdSet() const97 const std::unordered_set<uint32_t> &Abc2ProgramEntityContainer::GetUnnestedLiteralArrayIdSet() const
98 {
99     return unnested_literal_array_id_set_;
100 }
101 
GetUnprocessedNestedLiteralArrayIdSet()102 std::unordered_set<uint32_t> &Abc2ProgramEntityContainer::GetUnprocessedNestedLiteralArrayIdSet()
103 {
104     return unprocessed_nested_literal_array_id_set_;
105 }
106 
AddModuleLiteralArrayId(uint32_t module_literal_array_id)107 void Abc2ProgramEntityContainer::AddModuleLiteralArrayId(uint32_t module_literal_array_id)
108 {
109     module_literal_array_id_set_.insert(module_literal_array_id);
110 }
111 
112 
AddModuleRequestPhaseId(uint32_t module_request_phase_id)113 void Abc2ProgramEntityContainer::AddModuleRequestPhaseId(uint32_t module_request_phase_id)
114 {
115     module_request_phase_id_set_.insert(module_request_phase_id);
116 }
117 
AddUnnestedLiteralArrayId(uint32_t literal_array_id)118 void Abc2ProgramEntityContainer::AddUnnestedLiteralArrayId(uint32_t literal_array_id)
119 {
120     unnested_literal_array_id_set_.insert(literal_array_id);
121 }
122 
AddProcessedNestedLiteralArrayId(uint32_t nested_literal_array_id)123 void Abc2ProgramEntityContainer::AddProcessedNestedLiteralArrayId(uint32_t nested_literal_array_id)
124 {
125     processed_nested_literal_array_id_set_.insert(nested_literal_array_id);
126 }
127 
TryAddUnprocessedNestedLiteralArrayId(uint32_t nested_literal_array_id)128 void Abc2ProgramEntityContainer::TryAddUnprocessedNestedLiteralArrayId(uint32_t nested_literal_array_id)
129 {
130     if (unnested_literal_array_id_set_.count(nested_literal_array_id)) {
131         return;
132     }
133     if (processed_nested_literal_array_id_set_.count(nested_literal_array_id)) {
134         return;
135     }
136     unprocessed_nested_literal_array_id_set_.insert(nested_literal_array_id);
137 }
138 
GetLiteralArrayIdName(uint32_t literal_array_id)139 std::string Abc2ProgramEntityContainer::GetLiteralArrayIdName(uint32_t literal_array_id)
140 {
141     std::stringstream name;
142     auto cur_record_name = GetFullRecordNameById(panda_file::File::EntityId(current_class_id_));
143     name << cur_record_name << UNDERLINE << literal_array_id;
144     return name.str();
145 }
146 
AddProgramString(const std::string &str) const147 void Abc2ProgramEntityContainer::AddProgramString(const std::string &str) const
148 {
149     program_.strings.insert(str);
150 }
151 
152 }  // namespace panda::abc2program