• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023 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 <gtest/gtest.h>
17 
18 #include "assembly-ins.h"
19 #include "assembly-parser.h"
20 #include "ide_helpers.h"
21 #include "ins_to_string.cpp"
22 #include "operand_types_print.h"
23 #include "extensions/ecmascript_meta.h"
24 #include "meta.h"
25 
26 using namespace testing::ext;
27 
28 namespace panda::pandasm {
29 class AssemblerInsTest : public testing::Test {
30 };
31 
32 /**
33  * @tc.name: assembler_ins_test_001
34  * @tc.desc: Verify the Parse function.
35  * @tc.type: FUNC
36  * @tc.require: issueNumber
37  */
38 HWTEST_F(AssemblerInsTest, assembler_ins_test_001, TestSize.Level1)
39 {
40     Parser p;
41     const auto source = R"(
42         .function any foo(){}
43         .function any func(any a0, any a1, any a2) <static> {
44             mov v0, a0
45             mov v1, a1
46             mov v2, a2
47             ldglobalvar 0x0, "foo"
48             sta v4
49             lda v4
50             callarg0 0x1
51             return
52         }
53     )";
54     auto item = p.Parse(source);
55     const std::string func_name = "func:(any,any,any)";
56     auto it = item.Value().function_table.find(func_name);
57     EXPECT_NE(it, item.Value().function_table.end());
58     const auto &func_value = item.Value().function_table.at(func_name).ins;
59     size_t user_size = 6;
60     size_t json_size = 280;
61     EXPECT_EQ(func_value[3].OperandListLength(), 2ULL);
62     EXPECT_EQ(func_value[3].HasFlag(InstFlags::TYPE_ID), false);
63     EXPECT_EQ(func_value[3].CanThrow(), true);
64     EXPECT_EQ(func_value[3].IsJump(), false);
65     EXPECT_EQ(func_value[3].IsConditionalJump(), false);
66     EXPECT_EQ(func_value[3].IsCall(), false);
67     EXPECT_EQ(func_value[3].IsCallRange(), false);
68     EXPECT_EQ(func_value[3].IsPseudoCall(), false);
69     EXPECT_EQ(func_value[7].IsReturn(), true);
70     EXPECT_EQ(func_value[7].MaxRegEncodingWidth(), 0);
71     EXPECT_EQ(func_value[7].HasDebugInfo(), true);
72     EXPECT_EQ(func_value[7].Uses().size(), user_size);
73     EXPECT_EQ(func_value[7].Def(), std::nullopt);
74     EXPECT_EQ(func_value[7].IsValidToEmit(), true);
75     EXPECT_EQ(item.Value().JsonDump().size(), json_size);
76     EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected";
77 }
78 
79 /**
80  * @tc.name: assembler_ins_test_002
81  * @tc.desc: Verify the Parse function.
82  * @tc.type: FUNC
83  * @tc.require: issueNumber
84  */
85 HWTEST_F(AssemblerInsTest, assembler_ins_test_002, TestSize.Level1)
86 {
87     Parser p;
88     const auto source = R"(
89         .function any func() {
90             sta v4
91             lda.str "xxx"
92             ldglobalvar 0x7, "oDiv"
93             callarg1 0x1, v0
94             return
95         }
96     )";
97     auto item = p.Parse(source);
98     const std::string func_name = "func:()";
99     auto it = item.Value().function_table.find(func_name);
100     EXPECT_NE(it, item.Value().function_table.end());
101     const auto &function_value = item.Value().function_table.at(func_name).ins;
102     std::string ret = function_value[0].ToString("test", true, 0);
103     EXPECT_EQ(ret, "sta a4test");
104     ret = function_value[0].ToString("test", false, 0);
105     EXPECT_EQ(ret, "sta v4test");
106 
107     ret = function_value[1].ToString("test", true, 0);
108     EXPECT_EQ(ret, "lda.str xxxtest");
109     ret = function_value[1].ToString("test", false, 0);
110     EXPECT_EQ(ret, "lda.str xxxtest");
111 
112     ret = function_value[2].ToString("test", true, 0);
113     EXPECT_EQ(ret, "ldglobalvar 0x7, oDivtest");
114     ret = function_value[2].ToString("test", false, 0);
115     EXPECT_EQ(ret, "ldglobalvar 0x7, oDivtest");
116 }
117 
118 /**
119  * @tc.name: assembler_ins_test_003
120  * @tc.desc: Verify the ToString function.
121  * @tc.type: FUNC
122  * @tc.require: issueNumber
123  */
124 HWTEST_F(AssemblerInsTest, assembler_ins_test_003, TestSize.Level1)
125 {
126     panda::pandasm::Ins ins;
127     uint16_t reg1 = 2U;
128     uint16_t reg2 = 3U;
129     ins.opcode = Opcode::DEPRECATED_LDMODULEVAR;
130     ins.regs.push_back(reg1);
131     ins.regs.push_back(reg2);
132     ins.imms.push_back(Ins::IType(int64_t(0x1)));
133     ins.ids.push_back("a1");
134     ins.set_label = false;
135     ins.label = "label";
136 
137     std::string ret = ins.ToString("test", true, 0);
138     EXPECT_EQ(ret, "deprecated.ldmodulevar a1, 0x1test");
139     ret = ins.ToString("test", false, 0);
140     EXPECT_EQ(ret, "deprecated.ldmodulevar a1, 0x1test");
141 
142     ins.opcode = Opcode::MOVX;
143     ret = ins.ToString("test", true, 0);
144     EXPECT_EQ(ret, "MOVX a2, a3, 0x1, a1test");
145     ret = ins.ToString("test", false, 0);
146     EXPECT_EQ(ret, "MOVX v2, v3, 0x1, a1test");
147 
148     ins.opcode = Opcode::DEFINEFUNC;
149     ret = ins.ToString("test", true, 0);
150     EXPECT_EQ(ret, "definefunc 0x1, a1test");
151     ret = ins.ToString("test", false, 0);
152     EXPECT_EQ(ret, "definefunc 0x1, a1test");
153     EXPECT_TRUE(ins.CanThrow());
154 
155     ins.opcode = Opcode::JEQZ;
156     EXPECT_TRUE(ins.IsConditionalJump());
157 
158     ins.opcode = Opcode::SUPERCALLARROWRANGE;
159     ret = ins.ToString("test", true, 0);
160     EXPECT_EQ(ret, "supercallarrowrange 0x1, a2test");
161     ret = ins.ToString("test", false, 0);
162     EXPECT_EQ(ret, "supercallarrowrange 0x1, v2test");
163 
164     ins.opcode = Opcode::NEWOBJRANGE;
165     ret = ins.ToString("test", true, 0);
166     EXPECT_EQ(ret, "newobjrange 0x1, a2test");
167     ret = ins.ToString("test", false, 0);
168     EXPECT_EQ(ret, "newobjrange 0x1, v2test");
169 
170     ins.imms.clear();
171     ins.opcode = Opcode::DEFINECLASSWITHBUFFER;
172     ret = ins.ToString("test", true, 0);
173     EXPECT_EQ(ret, "defineclasswithbuffer, a1, a2test");
174     ret = ins.ToString("test", false, 0);
175     EXPECT_EQ(ret, "defineclasswithbuffer, a1, v2test");
176 
177     ins.opcode = Opcode::CALLX;
178     auto unit = ins.Uses();
179     EXPECT_GT(unit.size(), 0);
180 
181     ins.regs.clear();
182     ins.opcode = Opcode::STOBJBYVALUE;
183     ret = ins.ToString("test", true, 0);
184     EXPECT_EQ(ret, "stobjbyvaluetest");
185     ret = ins.ToString("test", false, 0);
186     EXPECT_EQ(ret, "stobjbyvaluetest");
187 
188     EXPECT_EQ(ins.Def(), std::nullopt);
189 
190     ins.opcode = Opcode::INVALID;
191     ret = ins.MaxRegEncodingWidth();
192     auto unit1 = ins.Uses();
193     EXPECT_EQ(unit1.size(), 0);
194 
195     EXPECT_EQ(ins.Def(), std::nullopt);
196 
197     ins.regs.push_back(1);
198     EXPECT_FALSE(ins.IsValidToEmit());
199 }
200 
201 /**
202  * @tc.name: assembler_ins_test_004
203  * @tc.desc: Verify the JsonDump function.
204  * @tc.type: FUNC
205  * @tc.require: issueNumber
206  */
207 HWTEST_F(AssemblerInsTest, assembler_ins_test_004, TestSize.Level1)
208 {
209     panda::pandasm::Ins ins;
210     uint16_t reg1 = 2U;
211     uint16_t reg2 = 3U;
212     ins.opcode = Opcode::DEPRECATED_LDMODULEVAR;
213     ins.regs.push_back(reg1);
214     ins.regs.push_back(reg2);
215     ins.imms.push_back(Ins::IType(int64_t(0x1)));
216     ins.ids.push_back("a1");
217     ins.set_label = false;
218     ins.label = "label";
219     panda::pandasm::Program pro;
220     std::string ret = pro.JsonDump();
221     EXPECT_EQ(ret, "{ \"functions\": [  ], \"records\": [  ] }");
222 
223     std::string_view component_name = "u8";
224     size_t rank = 0;
225     panda::pandasm::Type type(component_name, rank);
226     bool bo = type.IsArrayContainsPrimTypes();
227     EXPECT_TRUE(bo);
228 
229     ret = type.GetDescriptor(false);
230     EXPECT_EQ(ret, "H");
231 
232     EXPECT_EQ(panda::pandasm::Type::GetId(component_name, true), panda_file::Type::TypeId::REFERENCE);
233     component_name = "[]";
234     EXPECT_EQ(panda::pandasm::Type::FromDescriptor(component_name).GetName(), component_name);
235     EXPECT_EQ(panda::pandasm::Type::FromName(component_name, false).GetName(), component_name);
236     panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
237 
238     std::string name = "test";
239     EXPECT_FALSE(panda::pandasm::Type::IsStringType(name, language));
240     ins.opcode = Opcode::CALLRANGE;
241     size_t ins_def = 65535;
242     EXPECT_EQ(ins.Def(), ins_def);
243     auto unit2 = ins.Uses();
244     EXPECT_GT(unit2.size(), 0);
245 
246     component_name = "test";
247     rank = 0;
248     panda::pandasm::Type type1(component_name, rank);
249     bo = type1.IsArrayContainsPrimTypes();
250     EXPECT_FALSE(bo);
251 }
252 
253 /**
254  * @tc.name: assembler_ins_test_005
255  * @tc.desc: Verify the JsonSerializeProgramItems function.
256  * @tc.type: FUNC
257  * @tc.require: issueNumber
258  */
259 HWTEST_F(AssemblerInsTest, assembler_ins_test_005, TestSize.Level1)
260 {
261     Parser p;
262     const auto source = R"(
263         .function any func() {
264             sta v4
265             lda.str "xxx"
266             ldglobalvar 0x7, "oDiv"
267             callarg1 0x1, v0
268             return
269         }
270     )";
271     auto item = p.Parse(source);
272     const std::string func_name = "func:()";
273     panda::panda_file::SourceLang language1 {panda::panda_file::SourceLang::PANDA_ASSEMBLY};
274     panda::pandasm::Function function("fun", language1);
275     function.file_location->is_defined = false;
276     panda::pandasm::Function function1("fun", language1, 0, 10, "func", false, 10);
277 
278     std::string ret = JsonSerializeItemBody(function);
279     EXPECT_EQ(ret, "{ \"name\": \"fun\" }");
280 
281     std::map<std::string, panda::pandasm::Function> function_table;
282     ret = JsonSerializeProgramItems(function_table);
283     EXPECT_EQ(ret, "[  ]");
284 
285     std::string test = "test";
286     function_table.emplace(test, std::move(function1));
287 
288     ret = JsonSerializeProgramItems(function_table);
289     EXPECT_EQ(ret, "[ { \"name\": \"fun\" } ]");
290 
291     ret = item.Value().function_table.at(func_name).ins[3].ToString("test", true, 0);
292     EXPECT_EQ(ret, "callarg1 0x1, a0test");
293     ret = item.Value().function_table.at(func_name).ins[3].ToString("test", false, 0);
294     EXPECT_EQ(ret, "callarg1 0x1, v0test");
295 }
296 
297 /**
298  * @tc.name: assembler_ins_test_006
299  * @tc.desc: Verify the NextMask function.
300  * @tc.type: FUNC
301  * @tc.require: issueNumber
302  */
303 HWTEST_F(AssemblerInsTest, assembler_ins_test_006, TestSize.Level1)
304 {
305     Context con;
306     con.token = "test";
307 
308     EXPECT_GT(con.Len(), 0);
309     size_t number_of_params_already_is = 65535;
310     EXPECT_FALSE(con.ValidateParameterName(number_of_params_already_is));
311     number_of_params_already_is = 4;
312     EXPECT_FALSE(con.ValidateParameterName(number_of_params_already_is));
313 
314     panda::pandasm::Token token1;
315     con.tokens.push_back(token1);
316     panda::pandasm::Token token2;
317     con.tokens.push_back(token2);
318     EXPECT_EQ(con.Next(), Token::Type::ID_BAD);
319     size_t line_size = 3;
320     con.number = line_size;
321     con.end = false;
322     EXPECT_TRUE(con.NextMask());
323     con.end = true;
324     EXPECT_TRUE(con.NextMask());
325 }
326 }