• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2025 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 "file_items.h"
17 #include "file_item_container.h"
18 #include "file_writer.h"
19 
20 #include <cstdint>
21 
22 #include <utility>
23 #include <vector>
24 
25 #include <gtest/gtest.h>
26 
27 namespace ark::panda_file::test {
28 
TEST(LineNumberProgramItem,EmitSpecialOpcode)29 TEST(LineNumberProgramItem, EmitSpecialOpcode)
30 {
31     LineNumberProgramItem item;
32 
33     constexpr int32_t LINE_MAX_INC = LineNumberProgramItem::LINE_RANGE + LineNumberProgramItem::LINE_BASE - 1;
34     constexpr int32_t LINE_MIN_INC = LineNumberProgramItem::LINE_BASE;
35 
36     EXPECT_FALSE(item.EmitSpecialOpcode(0, LINE_MAX_INC + 1));
37     EXPECT_FALSE(item.EmitSpecialOpcode(0, LINE_MIN_INC - 1));
38     EXPECT_FALSE(item.EmitSpecialOpcode(100, LINE_MAX_INC));
39 
40     std::vector<std::pair<int32_t, uint32_t>> incs = {{1, LINE_MIN_INC}, {2, LINE_MAX_INC}};
41     std::vector<uint8_t> data;
42 
43     for (auto [pc_inc, line_inc] : incs) {
44         ASSERT_TRUE(item.EmitSpecialOpcode(pc_inc, line_inc));
45         data.push_back((line_inc - LineNumberProgramItem::LINE_BASE) + (pc_inc * LineNumberProgramItem::LINE_RANGE) +
46                        LineNumberProgramItem::OPCODE_BASE);
47     }
48 
49     MemoryWriter writer;
50     ASSERT_TRUE(item.Write(&writer));
51 
52     EXPECT_EQ(writer.GetData(), data);
53 }
54 
TEST(LineNumberProgramItem,ItemTypeToStringPart1)55 TEST(LineNumberProgramItem, ItemTypeToStringPart1)
56 {
57     for (int i = 0; i <= static_cast<int>(ItemTypes::FIELD_ITEM) - 1; ++i) {
58         auto type = static_cast<ItemTypes>(i);
59         std::string expected;
60         switch (type) {
61             case ItemTypes::ANNOTATION_ITEM:
62                 expected = "annotation_item";
63                 break;
64             case ItemTypes::CATCH_BLOCK_ITEM:
65                 expected = "catch_block_item";
66                 break;
67             case ItemTypes::CLASS_INDEX_ITEM:
68                 expected = "class_index_item";
69                 break;
70             case ItemTypes::CLASS_ITEM:
71                 expected = "class_item";
72                 break;
73             case ItemTypes::CODE_ITEM:
74                 expected = "code_item";
75                 break;
76             case ItemTypes::DEBUG_INFO_ITEM:
77                 expected = "debug_info_item";
78                 break;
79             case ItemTypes::END_ITEM:
80                 expected = "end_item";
81                 break;
82             case ItemTypes::FIELD_INDEX_ITEM:
83                 expected = "field_index_item";
84                 break;
85             case ItemTypes::FIELD_ITEM:
86                 expected = "field_item";
87                 break;
88             default:
89                 expected = "";
90                 break;
91         }
92         EXPECT_EQ(ark::panda_file::ItemTypeToString(type), expected);
93     }
94 }
95 
TEST(LineNumberProgramItem,ItemTypeToStringPart2)96 TEST(LineNumberProgramItem, ItemTypeToStringPart2)
97 {
98     for (int i = static_cast<int>(ItemTypes::FOREIGN_CLASS_ITEM); i <= static_cast<int>(ItemTypes::LITERAL_ITEM) - 1;
99          ++i) {
100         auto type = static_cast<ItemTypes>(i);
101         std::string expected;
102         switch (type) {
103             case ItemTypes::FOREIGN_CLASS_ITEM:
104                 expected = "foreign_class_item";
105                 break;
106             case ItemTypes::FOREIGN_FIELD_ITEM:
107                 expected = "foreign_field_item";
108                 break;
109             case ItemTypes::FOREIGN_METHOD_ITEM:
110                 expected = "foreign_method_item";
111                 break;
112             case ItemTypes::LINE_NUMBER_PROGRAM_INDEX_ITEM:
113                 expected = "line_number_program_index_item";
114                 break;
115             case ItemTypes::LINE_NUMBER_PROGRAM_ITEM:
116                 expected = "line_number_program_item";
117                 break;
118             case ItemTypes::LITERAL_ARRAY_ITEM:
119                 expected = "literal_array_item";
120                 break;
121             case ItemTypes::LITERAL_ITEM:
122                 expected = "literal_item";
123                 break;
124             default:
125                 expected = "";
126                 break;
127         }
128         EXPECT_EQ(ItemTypeToString(type), expected);
129     }
130 }
131 
TEST(LineNumberProgramItem,ItemTypeToStringPart3)132 TEST(LineNumberProgramItem, ItemTypeToStringPart3)
133 {
134     for (int i = static_cast<int>(ItemTypes::METHOD_HANDLE_ITEM); i <= static_cast<int>(ItemTypes::VALUE_ITEM); ++i) {
135         auto type = static_cast<ItemTypes>(i);
136         std::string expected;
137         switch (type) {
138             case ItemTypes::METHOD_HANDLE_ITEM:
139                 expected = "method_handle_item";
140                 break;
141             case ItemTypes::METHOD_INDEX_ITEM:
142                 expected = "method_index_item";
143                 break;
144             case ItemTypes::METHOD_ITEM:
145                 expected = "method_item";
146                 break;
147             case ItemTypes::PARAM_ANNOTATIONS_ITEM:
148                 expected = "param_annotations_item";
149                 break;
150             case ItemTypes::PRIMITIVE_TYPE_ITEM:
151                 expected = "primitive_type_item";
152                 break;
153             case ItemTypes::PROTO_INDEX_ITEM:
154                 expected = "proto_index_item";
155                 break;
156             case ItemTypes::PROTO_ITEM:
157                 expected = "proto_item";
158                 break;
159             case ItemTypes::REGION_HEADER:
160                 expected = "region_header";
161                 break;
162             case ItemTypes::REGION_SECTION:
163                 expected = "region_section";
164                 break;
165             case ItemTypes::STRING_ITEM:
166                 expected = "string_item";
167                 break;
168             case ItemTypes::TRY_BLOCK_ITEM:
169                 expected = "try_block_item";
170                 break;
171             case ItemTypes::VALUE_ITEM:
172                 expected = "value_item";
173                 break;
174             default:
175                 expected = "";
176                 break;
177         }
178         EXPECT_EQ(ItemTypeToString(type), expected);
179     }
180 }
181 
TEST(LineNumberProgramItem,GetULeb128EncodedSizeTest)182 TEST(LineNumberProgramItem, GetULeb128EncodedSizeTest)
183 {
184     ItemContainer container;
185     const uint32_t kTestIntegerValue = 1;
186     const uint64_t kTestLongValue = 1234567890;
187 
188     ScalarValueItem *intItem = container.GetOrCreateIntegerValueItem(kTestIntegerValue);
189     EXPECT_EQ(intItem, container.GetOrCreateIntegerValueItem(kTestIntegerValue));
190     EXPECT_EQ(intItem->GetULeb128EncodedSize(), leb128::UnsignedEncodingSize(kTestIntegerValue));
191 
192     ScalarValueItem *longItem = container.GetOrCreateLongValueItem(kTestLongValue);
193     EXPECT_EQ(longItem, container.GetOrCreateLongValueItem(kTestLongValue));
194     EXPECT_EQ(longItem->GetULeb128EncodedSize(), leb128::UnsignedEncodingSize(kTestLongValue));
195 }
196 }  // namespace ark::panda_file::test
197