1 /**
2  * Copyright (c) 2021-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 "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 panda::panda_file::test {
28 
HWTEST(LineNumberProgramItem, EmitSpecialOpcode, testing::ext::TestSize.Level0)29 HWTEST(LineNumberProgramItem, EmitSpecialOpcode, testing::ext::TestSize.Level0)
30 {
31     LineNumberProgramItem item(nullptr);
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 
HWTEST(LineNumberProgramItem, LanguageFromAndToString, testing::ext::TestSize.Level0)55 HWTEST(LineNumberProgramItem, LanguageFromAndToString, testing::ext::TestSize.Level0)
56 {
57     ASSERT_EQ(LanguageFromString("not ECMAScript"), static_cast<SourceLang>(1U));
58     ASSERT_STREQ(LanguageToString(SourceLang::ECMASCRIPT), "ECMAScript");
59     ASSERT_STREQ(LanguageToString(SourceLang::PANDA_ASSEMBLY), "PandaAssembly");
60 }
61 
HWTEST(LineNumberProgramItem, GetStringClassDescriptor, testing::ext::TestSize.Level0)62 HWTEST(LineNumberProgramItem, GetStringClassDescriptor, testing::ext::TestSize.Level0)
63 {
64     ASSERT_STREQ(GetStringClassDescriptor(SourceLang::ECMASCRIPT), "Lpanda/JSString;");
65     ASSERT_STREQ(GetStringClassDescriptor(SourceLang::PANDA_ASSEMBLY), "Lpanda/String;");
66 }
67 
HWTEST(LineNumberProgramItem, IsDynamicLanguageTest, testing::ext::TestSize.Level0)68 HWTEST(LineNumberProgramItem, IsDynamicLanguageTest, testing::ext::TestSize.Level0)
69 {
70     panda::panda_file::SourceLang lang = panda::panda_file::SourceLang::ECMASCRIPT;
71     ASSERT_TRUE(IsDynamicLanguage(lang));
72 }
73 
HWTEST(LineNumberProgramItem, ItemTypeToStringPart1, testing::ext::TestSize.Level0)74 HWTEST(LineNumberProgramItem, ItemTypeToStringPart1, testing::ext::TestSize.Level0)
75 {
76     for (int i = 0; i <= static_cast<int>(ItemTypes::FIELD_ITEM) - 1; ++i) {
77         ItemTypes type = static_cast<ItemTypes>(i);
78         std::string expected;
79         switch (type) {
80             case ItemTypes::ANNOTATION_ITEM:
81                 expected = "annotation_item";
82                 break;
83             case ItemTypes::CATCH_BLOCK_ITEM:
84                 expected = "catch_block_item";
85                 break;
86             case ItemTypes::CLASS_INDEX_ITEM:
87                 expected = "class_index_item";
88                 break;
89             case ItemTypes::CLASS_ITEM:
90                 expected = "class_item";
91                 break;
92             case ItemTypes::CODE_ITEM:
93                 expected = "code_item";
94                 break;
95             case ItemTypes::DEBUG_INFO_ITEM:
96                 expected = "debug_info_item";
97                 break;
98             case ItemTypes::END_ITEM:
99                 expected = "end_item";
100                 break;
101             case ItemTypes::FIELD_INDEX_ITEM:
102                 expected = "field_index_item";
103                 break;
104             case ItemTypes::FIELD_ITEM:
105                 expected = "field_item";
106                 break;
107             default:
108                 expected = "";
109                 break;
110         }
111         EXPECT_EQ(ItemTypeToString(type), expected);
112     }
113 }
114 
HWTEST(LineNumberProgramItem, ItemTypeToStringPart2, testing::ext::TestSize.Level0)115 HWTEST(LineNumberProgramItem, ItemTypeToStringPart2, testing::ext::TestSize.Level0)
116 {
117     for (int i = static_cast<int>(ItemTypes::FOREIGN_CLASS_ITEM);
118          i <= static_cast<int>(ItemTypes::LITERAL_ITEM) - 1; ++i) {
119         ItemTypes type = static_cast<ItemTypes>(i);
120         std::string expected;
121         switch (type) {
122             case ItemTypes::FOREIGN_CLASS_ITEM:
123                 expected = "foreign_class_item";
124                 break;
125             case ItemTypes::FOREIGN_FIELD_ITEM:
126                 expected = "foreign_field_item";
127                 break;
128             case ItemTypes::FOREIGN_METHOD_ITEM:
129                 expected = "foreign_method_item";
130                 break;
131             case ItemTypes::INDEX_HEADER:
132                 expected = "index_header";
133                 break;
134             case ItemTypes::INDEX_SECTION:
135                 expected = "index_section";
136                 break;
137             case ItemTypes::LINE_NUMBER_PROGRAM_INDEX_ITEM:
138                 expected = "line_number_program_index_item";
139                 break;
140             case ItemTypes::LINE_NUMBER_PROGRAM_ITEM:
141                 expected = "line_number_program_item";
142                 break;
143             case ItemTypes::LITERAL_ARRAY_ITEM:
144                 expected = "literal_array_item";
145                 break;
146             case ItemTypes::LITERAL_ITEM:
147                 expected = "literal_item";
148                 break;
149             default:
150                 expected = "";
151                 break;
152         }
153         EXPECT_EQ(ItemTypeToString(type), expected);
154     }
155 }
156 
HWTEST(LineNumberProgramItem, ItemTypeToStringPart3, testing::ext::TestSize.Level0)157 HWTEST(LineNumberProgramItem, ItemTypeToStringPart3, testing::ext::TestSize.Level0)
158 {
159     for (int i = static_cast<int>(ItemTypes::METHOD_HANDLE_ITEM);
160          i <= static_cast<int>(ItemTypes::VALUE_ITEM); ++i) {
161         ItemTypes type = static_cast<ItemTypes>(i);
162         std::string expected;
163         switch (type) {
164             case ItemTypes::METHOD_HANDLE_ITEM:
165                 expected = "method_handle_item";
166                 break;
167             case ItemTypes::METHOD_INDEX_ITEM:
168                 expected = "method_index_item";
169                 break;
170             case ItemTypes::METHOD_ITEM:
171                 expected = "method_item";
172                 break;
173             case ItemTypes::PARAM_ANNOTATIONS_ITEM:
174                 expected = "param_annotations_item";
175                 break;
176             case ItemTypes::PRIMITIVE_TYPE_ITEM:
177                 expected = "primitive_type_item";
178                 break;
179             case ItemTypes::PROTO_INDEX_ITEM:
180                 expected = "proto_index_item";
181                 break;
182             case ItemTypes::PROTO_ITEM:
183                 expected = "proto_item";
184                 break;
185             case ItemTypes::STRING_ITEM:
186                 expected = "string_item";
187                 break;
188             case ItemTypes::TRY_BLOCK_ITEM:
189                 expected = "try_block_item";
190                 break;
191             case ItemTypes::VALUE_ITEM:
192                 expected = "value_item";
193                 break;
194             default:
195                 expected = "";
196                 break;
197         }
198         EXPECT_EQ(ItemTypeToString(type), expected);
199     }
200 }
201 
HWTEST(LineNumberProgramItem, GetULeb128EncodedSizeTest, testing::ext::TestSize.Level0)202 HWTEST(LineNumberProgramItem, GetULeb128EncodedSizeTest, testing::ext::TestSize.Level0)
203 {
204     ItemContainer container;
205     const uint32_t kTestIntegerValue = 1;
206     const uint64_t kTestLongValue = 1234567890;
207 
208     ScalarValueItem *int_item = container.GetOrCreateIntegerValueItem(kTestIntegerValue);
209     EXPECT_EQ(int_item, container.GetOrCreateIntegerValueItem(kTestIntegerValue));
210     EXPECT_EQ(int_item->GetULeb128EncodedSize(), leb128::UnsignedEncodingSize(kTestIntegerValue));
211 
212     ScalarValueItem *long_item = container.GetOrCreateLongValueItem(kTestLongValue);
213     EXPECT_EQ(long_item, container.GetOrCreateLongValueItem(kTestLongValue));
214     EXPECT_EQ(long_item->GetULeb128EncodedSize(), leb128::UnsignedEncodingSize(kTestLongValue));
215 }
216 }  // namespace panda::panda_file::test
217