• 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_annotation_processor.h"
17 #include "abc_literal_array_processor.h"
18 #include "file-inl.h"
19 
20 namespace panda::abc2program {
21 
AbcAnnotationProcessor(panda_file::File::EntityId entity_id,Abc2ProgramEntityContainer & entity_container,pandasm::Function & function)22 AbcAnnotationProcessor::AbcAnnotationProcessor(panda_file::File::EntityId entity_id,
23                                                Abc2ProgramEntityContainer &entity_container,
24                                                pandasm::Function &function)
25     : AbcFileEntityProcessor(entity_id, entity_container), function_(function)
26 {
27     annotation_data_accessor_ = std::make_unique<panda_file::AnnotationDataAccessor>(*file_, entity_id_);
28     annotation_name_ = pandasm::Type::FromDescriptor(GetStringById(annotation_data_accessor_->GetClassId())).GetName();
29 }
30 
FillProgramData()31 void AbcAnnotationProcessor::FillProgramData()
32 {
33     if (annotation_name_.empty()) {
34         return;
35     }
36     FillAnnotation();
37 }
38 
FillAnnotation()39 void AbcAnnotationProcessor::FillAnnotation()
40 {
41     std::vector<pandasm::AnnotationElement> elements;
42     FillAnnotationElements(elements);
43     pandasm::AnnotationData annotation_data(annotation_name_, elements);
44     std::vector<pandasm::AnnotationData> annotations;
45     annotations.emplace_back(std::move(annotation_data));
46     function_.metadata->AddAnnotations(annotations);
47 }
48 
FillLiteralArrayAnnotation(std::vector<pandasm::AnnotationElement> & elements,const std::string & annotation_elem_name,uint32_t value)49 void AbcAnnotationProcessor::FillLiteralArrayAnnotation(std::vector<pandasm::AnnotationElement> &elements,
50                                                         const std::string &annotation_elem_name, uint32_t value)
51 {
52     panda_file::LiteralDataAccessor lit_data_accessor(*file_, file_->GetLiteralArraysId());
53     AbcLiteralArrayProcessor lit_array_proc(panda_file::File::EntityId{value}, entity_container_,
54                                             lit_data_accessor);
55     lit_array_proc.FillProgramData();
56     std::string name = entity_container_.GetLiteralArrayIdName(value);
57     pandasm::AnnotationElement annotation_element(
58         annotation_elem_name, std::make_unique<pandasm::ScalarValue>(
59         pandasm::ScalarValue::Create<pandasm::Value::Type::LITERALARRAY>(name)));
60     elements.emplace_back(annotation_element);
61 }
62 
FillAnnotationElements(std::vector<pandasm::AnnotationElement> & elements)63 void AbcAnnotationProcessor::FillAnnotationElements(std::vector<pandasm::AnnotationElement> &elements)
64 {
65     for (uint32_t i = 0; i < annotation_data_accessor_->GetCount(); ++i) {
66         auto annotation_data_accessor_elem = annotation_data_accessor_->GetElement(i);
67         auto annotation_elem_name = GetStringById(annotation_data_accessor_elem.GetNameId());
68         auto value_type = pandasm::Value::GetCharAsType(annotation_data_accessor_->GetTag(i).GetItem());
69         switch (value_type) {
70             case pandasm::Value::Type::U1: {
71                 auto value = annotation_data_accessor_elem.GetScalarValue().Get<bool>();
72                 pandasm::AnnotationElement annotation_element(
73                     annotation_elem_name, std::make_unique<pandasm::ScalarValue>(
74                     pandasm::ScalarValue::Create<pandasm::Value::Type::U1>(value)));
75                 elements.emplace_back(annotation_element);
76                 break;
77             }
78             case pandasm::Value::Type::U32: {
79                 auto value = annotation_data_accessor_elem.GetScalarValue().Get<uint32_t>();
80                 pandasm::AnnotationElement annotation_element(
81                     annotation_elem_name, std::make_unique<pandasm::ScalarValue>(
82                     pandasm::ScalarValue::Create<pandasm::Value::Type::U32>(value)));
83                 elements.emplace_back(annotation_element);
84                 break;
85             }
86             case pandasm::Value::Type::F64: {
87                 auto value = annotation_data_accessor_elem.GetScalarValue().Get<double>();
88                 pandasm::AnnotationElement annotation_element(
89                     annotation_elem_name, std::make_unique<pandasm::ScalarValue>(
90                     pandasm::ScalarValue::Create<pandasm::Value::Type::F64>(value)));
91                 elements.emplace_back(annotation_element);
92                 break;
93             }
94             case pandasm::Value::Type::STRING: {
95                 auto value = annotation_data_accessor_elem.GetScalarValue().Get<uint32_t>();
96                 std::string_view string_value {
97                     reinterpret_cast<const char *>(file_->GetStringData(panda_file::File::EntityId(value)).data)};
98                 pandasm::AnnotationElement annotation_element(
99                     annotation_elem_name, std::make_unique<pandasm::ScalarValue>(
100                     pandasm::ScalarValue::Create<pandasm::Value::Type::STRING>(string_value)));
101                 elements.emplace_back(annotation_element);
102                 break;
103             }
104             case pandasm::Value::Type::LITERALARRAY: {
105                 auto value = annotation_data_accessor_elem.GetScalarValue().Get<uint32_t>();
106                 FillLiteralArrayAnnotation(elements, annotation_elem_name, value);
107                 break;
108             }
109             default:
110                 UNREACHABLE();
111         }
112     }
113 }
114 
115 }  // namespace panda::abc2program
116