1 /*
2  * Copyright (c) 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 "function.h"
17 #include "libpandafile/method_data_accessor.h"
18 #include "abc_file.h"
19 #include "callee_info.h"
20 
21 namespace panda::defect_scan_aux {
GetRecordName() const22 const std::string &Function::GetRecordName() const
23 {
24     return record_name_;
25 }
26 
GetFunctionName() const27 const std::string &Function::GetFunctionName() const
28 {
29     return func_name_;
30 }
31 
GetAbcFileInstance() const32 const AbcFile *Function::GetAbcFileInstance() const
33 {
34     return abc_file_;
35 }
36 
GetGraph() const37 const Graph &Function::GetGraph() const
38 {
39     return graph_;
40 }
41 
GetClass() const42 const Class *Function::GetClass() const
43 {
44     return class_;
45 }
46 
GetParentFunction() const47 Function *Function::GetParentFunction() const
48 {
49     return parent_func_;
50 }
51 
GetArgCount() const52 uint32_t Function::GetArgCount() const
53 {
54     return arg_count_;
55 }
56 
GetDefinedClassCount() const57 size_t Function::GetDefinedClassCount() const
58 {
59     return def_class_list_.size();
60 }
61 
GetDefinedFunctionCount() const62 size_t Function::GetDefinedFunctionCount() const
63 {
64     return def_func_list_.size();
65 }
66 
GetCalleeInfoCount() const67 size_t Function::GetCalleeInfoCount() const
68 {
69     return callee_info_list_.size();
70 }
71 
GetDefinedClassByIndex(size_t index) const72 const Class *Function::GetDefinedClassByIndex(size_t index) const
73 {
74     ASSERT(index < def_class_list_.size());
75     return def_class_list_[index];
76 }
77 
78 const Function *Function::GetDefinedFunctionByIndex(size_t index) const
79 {
80     ASSERT(index < def_func_list_.size());
81     return def_func_list_[index];
82 }
83 
84 const CalleeInfo *Function::GetCalleeInfoByIndex(size_t index) const
85 {
86     ASSERT(index < callee_info_list_.size());
87     return callee_info_list_[index];
88 }
89 
90 std::vector<Inst> Function::GetReturnInstList() const
91 {
92     std::vector<Inst> ret_inst_list;
93     graph_.VisitAllInstructions([&](const Inst &inst) {
94         InstType type = inst.GetType();
95         if (type == InstType::RETURN) {
96             ret_inst_list.push_back(inst);
97         }
98     });
99     return ret_inst_list;
100 }
101 
102 const CalleeInfo *Function::GetCalleeInfoByCallInst(const Inst &call_inst) const
103 {
104     for (auto callee_info : callee_info_list_) {
105         auto &cur_call_inst = callee_info->GetCallInst();
106         if (cur_call_inst == call_inst) {
107             return callee_info;
108         }
109     }
110     return nullptr;
111 }
112 
113 uint32_t Function::GetAndUpdateToVisitInputForInst(const Inst &inst)
114 {
115     auto inst_input_size = inst.GetInputInsts().size();
116     ASSERT(inst_input_size != 0);
117     uint32_t inst_id = inst.GetInstId();
118     auto iter = to_visit_inputs_.find(inst_id);
119     uint32_t to_visit_input = iter == to_visit_inputs_.end() ? 0 : iter->second;
120     uint32_t next_to_visit_input = to_visit_input + 1;
121     if (next_to_visit_input >= inst_input_size)
122         next_to_visit_input = 0;
123     to_visit_inputs_[inst_id] = next_to_visit_input;
124     return to_visit_input;
125 }
126 
GetMethodId() const127 panda_file::File::EntityId Function::GetMethodId() const
128 {
129     return m_id_;
130 }
131 
SetParentFunction(Function *parent_func)132 void Function::SetParentFunction(Function *parent_func)
133 {
134     ASSERT(parent_func != nullptr);
135     parent_func_ = parent_func;
136 }
137 
SetClass(const Class *clazz)138 void Function::SetClass(const Class *clazz)
139 {
140     ASSERT(clazz != nullptr);
141     class_ = clazz;
142 }
143 
AddDefinedClass(const Class *def_class)144 void Function::AddDefinedClass(const Class *def_class)
145 {
146     ASSERT(def_class != nullptr);
147     def_class_list_.push_back(def_class);
148 }
149 
AddDefinedFunction(const Function *def_func)150 void Function::AddDefinedFunction(const Function *def_func)
151 {
152     ASSERT(def_func != nullptr);
153     def_func_list_.push_back(def_func);
154 }
155 
AddCalleeInfo(const CalleeInfo *callee_info)156 void Function::AddCalleeInfo(const CalleeInfo *callee_info)
157 {
158     ASSERT(callee_info != nullptr);
159     callee_info_list_.push_back(callee_info);
160 }
161 }  // namespace panda::defect_scan_aux