• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "abc_method_processor.h"
17 #include "abc_code_processor.h"
18 #include "method_data_accessor-inl.h"
19 #include "file_items.h"
20 
21 namespace panda::abc2program {
22 
AbcMethodProcessor(panda_file::File::EntityId entity_id,Abc2ProgramEntityContainer & entity_container)23 AbcMethodProcessor::AbcMethodProcessor(panda_file::File::EntityId entity_id,
24                                        Abc2ProgramEntityContainer &entity_container)
25     : AbcFileEntityProcessor(entity_id, entity_container),
26       type_converter_(entity_container),
27       function_(pandasm::Function(entity_container_.GetFullMethodNameById(entity_id_), LANG_ECMA)),
28       debug_info_extractor_(entity_container.GetDebugInfoExtractor())
29 {
30     method_data_accessor_ = std::make_unique<panda_file::MethodDataAccessor>(*file_, entity_id_);
31 }
32 
FillProgramData()33 void AbcMethodProcessor::FillProgramData()
34 {
35     FillFunctionData();
36     program_->function_table.emplace(function_.name, std::move(function_));
37 }
38 
FillFunctionData()39 void AbcMethodProcessor::FillFunctionData()
40 {
41     FillProto();
42     FillFunctionKind();
43     FillFunctionMetaData();
44     FillCodeData();
45     FillDebugInfo();
46     FillFuncAnnotation();
47     FillAnnotationData();
48 }
49 
FillProto()50 void AbcMethodProcessor::FillProto()
51 {
52     uint32_t params_num = GetNumArgs();
53     pandasm::Type any_type = pandasm::Type(ANY_TYPE_NAME, 0);
54     function_.return_type = any_type;
55     for (uint8_t i = 0; i < params_num; i++) {
56         function_.params.emplace_back(pandasm::Function::Parameter(any_type, LANG_ECMA));
57     }
58 }
59 
GetNumArgs() const60 uint32_t AbcMethodProcessor::GetNumArgs() const
61 {
62     std::optional<panda_file::File::EntityId> code_id = method_data_accessor_->GetCodeId();
63     if (!code_id.has_value()) {
64         return 0;
65     }
66     panda_file::File::EntityId code_id_value = code_id.value();
67     panda_file::CodeDataAccessor code_data_accessor(*file_, code_id_value);
68     return code_data_accessor.GetNumArgs();
69 }
70 
FillFunctionKind()71 void AbcMethodProcessor::FillFunctionKind()
72 {
73     uint32_t method_acc_flags = method_data_accessor_->GetAccessFlags();
74     uint32_t func_kind_u32 = ((method_acc_flags & panda_file::FUNCTION_KIND_MASK) >> panda_file::FLAG_WIDTH);
75     panda_file::FunctionKind func_kind = static_cast<panda_file::FunctionKind>(func_kind_u32);
76     function_.SetFunctionKind(func_kind);
77 }
78 
FillFunctionMetaData()79 void AbcMethodProcessor::FillFunctionMetaData()
80 {
81     FillFunctionAttributes();
82     FillAccessFlags();
83 }
84 
FillFunctionAttributes()85 void AbcMethodProcessor::FillFunctionAttributes()
86 {
87     if (method_data_accessor_->IsStatic()) {
88         function_.metadata->SetAttribute(ABC_ATTR_STATIC);
89     }
90     if (file_->IsExternal(method_data_accessor_->GetMethodId())) {
91         function_.metadata->SetAttribute(ABC_ATTR_EXTERNAL);
92     }
93 }
94 
FillAccessFlags()95 void AbcMethodProcessor::FillAccessFlags()
96 {
97     uint32_t access_flags = method_data_accessor_->GetAccessFlags();
98     access_flags = (access_flags & panda_file::FLAG_MASK);
99     function_.metadata->SetAccessFlags(access_flags);
100 }
101 
FillCodeData()102 void AbcMethodProcessor::FillCodeData()
103 {
104     std::optional<panda_file::File::EntityId> code_id = method_data_accessor_->GetCodeId();
105     if (code_id.has_value()) {
106         AbcCodeProcessor code_processor(code_id.value(), entity_container_, entity_id_, function_);
107         code_processor.FillProgramData();
108     }
109 }
110 
FillDebugInfo()111 void AbcMethodProcessor::FillDebugInfo()
112 {
113     FillSourceFile();
114     FillSourceCode();
115 }
116 
FillSourceFile()117 void AbcMethodProcessor::FillSourceFile()
118 {
119     function_.source_file = debug_info_extractor_.GetSourceFile(entity_id_);
120 }
121 
FillSourceCode()122 void AbcMethodProcessor::FillSourceCode()
123 {
124     function_.source_code = debug_info_extractor_.GetSourceCode(entity_id_);
125 }
126 
FillFuncAnnotation()127 void AbcMethodProcessor::FillFuncAnnotation()
128 {
129     method_data_accessor_->EnumerateAnnotations([&](panda_file::File::EntityId annotation_id) {
130         AbcAnnotationProcessor annotation_processor(annotation_id, entity_container_, function_);
131         annotation_processor.FillProgramData();
132     });
133 }
134 
FillAnnotationData()135 void AbcMethodProcessor::FillAnnotationData()
136 {
137     for (auto annotation : function_.metadata->GetAnnotations()) {
138         const auto& name = annotation.GetName();
139         const auto& elements = annotation.GetElements();
140 
141         if (name == SLOT_NUMBER_RECORD_NAME && !elements.empty()) {
142             uint32_t slots_num = elements[0].GetValue()->GetAsScalar()->GetValue<uint32_t>();
143             function_.SetSlotsNum(static_cast<size_t>(slots_num));
144         } else if (name == CONCURRENT_MODULE_REQUEST_RECORD_NAME) {
145             for (auto &elem : elements) {
146                 function_.concurrent_module_requests.emplace_back(
147                     elem.GetValue()->GetAsScalar()->GetValue<uint32_t>());
148             }
149         }
150     }
151 }
152 } // namespace panda::abc2program
153