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 json_size = 280; 60 EXPECT_EQ(func_value[3]->OperandListLength(), 2ULL); 61 EXPECT_EQ(func_value[3]->HasFlag(InstFlags::TYPE_ID), false); 62 EXPECT_EQ(func_value[3]->CanThrow(), true); 63 EXPECT_EQ(func_value[3]->IsJump(), false); 64 EXPECT_EQ(func_value[3]->IsConditionalJump(), false); 65 EXPECT_EQ(func_value[3]->IsCall(), false); 66 EXPECT_EQ(func_value[3]->IsCallRange(), false); 67 EXPECT_EQ(func_value[3]->IsPseudoCall(), false); 68 EXPECT_EQ(func_value[7]->IsReturn(), true); 69 EXPECT_EQ(func_value[7]->MaxRegEncodingWidth(), 0); 70 EXPECT_EQ(func_value[7]->HasDebugInfo(), true); 71 EXPECT_EQ(func_value[7]->IsValidToEmit(), true); 72 EXPECT_EQ(item.Value().JsonDump().size(), json_size); 73 EXPECT_EQ(p.ShowError().err, Error::ErrorType::ERR_NONE) << "ERR_NONE expected"; 74 } 75 76 /** 77 * @tc.name: assembler_ins_test_002 78 * @tc.desc: Verify the Parse function. 79 * @tc.type: FUNC 80 * @tc.require: issueNumber 81 */ 82 HWTEST_F(AssemblerInsTest, assembler_ins_test_002, TestSize.Level1) 83 { 84 Parser p; 85 const auto source = R"( 86 .function any func() { 87 sta v4 88 lda.str "xxx" 89 ldglobalvar 0x7, "oDiv" 90 callarg1 0x1, v0 91 return 92 } 93 )"; 94 auto item = p.Parse(source); 95 const std::string func_name = "func:()"; 96 auto it = item.Value().function_table.find(func_name); 97 EXPECT_NE(it, item.Value().function_table.end()); 98 const auto &function_value = item.Value().function_table.at(func_name).ins; 99 std::string ret = function_value[0]->ToString("test", true, 0); 100 EXPECT_EQ(ret, "sta a4test"); 101 ret = function_value[0]->ToString("test", false, 0); 102 EXPECT_EQ(ret, "sta v4test"); 103 104 ret = function_value[1]->ToString("test", true, 0); 105 EXPECT_EQ(ret, "lda.str xxxtest"); 106 ret = function_value[1]->ToString("test", false, 0); 107 EXPECT_EQ(ret, "lda.str xxxtest"); 108 109 ret = function_value[2]->ToString("test", true, 0); 110 EXPECT_EQ(ret, "ldglobalvar 0x7, oDivtest"); 111 ret = function_value[2]->ToString("test", false, 0); 112 EXPECT_EQ(ret, "ldglobalvar 0x7, oDivtest"); 113 } 114 115 /** 116 * @tc.name: assembler_ins_test_003 117 * @tc.desc: Verify the ToString function. 118 * @tc.type: FUNC 119 * @tc.require: issueNumber 120 */ 121 HWTEST_F(AssemblerInsTest, assembler_ins_test_003, TestSize.Level1) 122 { 123 uint16_t reg1 = 2U; 124 uint16_t reg2 = 3U; 125 auto opcode = Opcode::DEPRECATED_LDMODULEVAR; 126 std::vector<uint16_t> regs; 127 regs.push_back(reg1); 128 regs.push_back(reg2); 129 std::vector<IType> imms; 130 imms.push_back(IType(int64_t(0x1))); 131 std::vector<std::string> ids; 132 ids.push_back("a1"); 133 panda::pandasm::Ins *ins = Ins::CreateIns(opcode, regs, imms, ids); 134 135 std::string ret = ins->ToString("test", true, 0); 136 EXPECT_EQ(ret, "deprecated.ldmodulevar a1, 0x1test"); 137 ret = ins->ToString("test", false, 0); 138 EXPECT_EQ(ret, "deprecated.ldmodulevar a1, 0x1test"); 139 delete ins; 140 141 opcode = Opcode::DEFINEFUNC; 142 imms.push_back(IType(int64_t(0x2))); 143 ins = Ins::CreateIns(opcode, regs, imms, ids); 144 ret = ins->ToString("test", true, 0); 145 EXPECT_EQ(ret, "definefunc 0x1, a1, 0x2test"); 146 ret = ins->ToString("test", false, 0); 147 EXPECT_EQ(ret, "definefunc 0x1, a1, 0x2test"); 148 EXPECT_TRUE(ins->CanThrow()); 149 delete ins; 150 151 opcode = Opcode::JEQZ; 152 ins = Ins::CreateIns(opcode, regs, imms, ids); 153 EXPECT_TRUE(ins->IsConditionalJump()); 154 delete ins; 155 } 156 157 /** 158 * @tc.name: assembler_ins_test_004 159 * @tc.desc: Verify the JsonDump function. 160 * @tc.type: FUNC 161 * @tc.require: issueNumber 162 */ 163 HWTEST_F(AssemblerInsTest, assembler_ins_test_004, TestSize.Level1) 164 { 165 panda::pandasm::Program pro; 166 std::string ret = pro.JsonDump(); 167 EXPECT_EQ(ret, "{ \"functions\": [ ], \"records\": [ ] }"); 168 169 std::string_view component_name = "u8"; 170 size_t rank = 0; 171 panda::pandasm::Type type(component_name, rank); 172 bool bo = type.IsArrayContainsPrimTypes(); 173 EXPECT_TRUE(bo); 174 175 ret = type.GetDescriptor(false); 176 EXPECT_EQ(ret, "H"); 177 178 EXPECT_EQ(panda::pandasm::Type::GetId(component_name, true), panda_file::Type::TypeId::REFERENCE); 179 component_name = "[]"; 180 EXPECT_EQ(panda::pandasm::Type::FromDescriptor(component_name).GetName(), component_name); 181 EXPECT_EQ(panda::pandasm::Type::FromName(component_name, false).GetName(), component_name); 182 panda::panda_file::SourceLang language {panda::panda_file::SourceLang::PANDA_ASSEMBLY}; 183 184 std::string name = "test"; 185 EXPECT_FALSE(panda::pandasm::Type::IsStringType(name, language)); 186 187 component_name = "test"; 188 rank = 0; 189 panda::pandasm::Type type1(component_name, rank); 190 bo = type1.IsArrayContainsPrimTypes(); 191 EXPECT_FALSE(bo); 192 } 193 194 /** 195 * @tc.name: assembler_ins_test_005 196 * @tc.desc: Verify the JsonSerializeProgramItems function. 197 * @tc.type: FUNC 198 * @tc.require: issueNumber 199 */ 200 HWTEST_F(AssemblerInsTest, assembler_ins_test_005, TestSize.Level1) 201 { 202 Parser p; 203 const auto source = R"( 204 .function any func() { 205 sta v4 206 lda.str "xxx" 207 ldglobalvar 0x7, "oDiv" 208 callarg1 0x1, v0 209 return 210 } 211 )"; 212 auto item = p.Parse(source); 213 const std::string func_name = "func:()"; 214 panda::panda_file::SourceLang language1 {panda::panda_file::SourceLang::PANDA_ASSEMBLY}; 215 panda::pandasm::Function function("fun", language1); 216 function.file_location->is_defined = false; 217 panda::pandasm::Function function1("fun", language1, 0, 10, "func", false, 10); 218 219 std::string ret = JsonSerializeItemBody(function); 220 EXPECT_EQ(ret, "{ \"name\": \"fun\" }"); 221 222 std::map<std::string, panda::pandasm::Function> function_table; 223 ret = JsonSerializeProgramItems(function_table); 224 EXPECT_EQ(ret, "[ ]"); 225 226 std::string test = "test"; 227 function_table.emplace(test, std::move(function1)); 228 229 ret = JsonSerializeProgramItems(function_table); 230 EXPECT_EQ(ret, "[ { \"name\": \"fun\" } ]"); 231 232 ret = item.Value().function_table.at(func_name).ins[3]->ToString("test", true, 0); 233 EXPECT_EQ(ret, "callarg1 0x1, a0test"); 234 ret = item.Value().function_table.at(func_name).ins[3]->ToString("test", false, 0); 235 EXPECT_EQ(ret, "callarg1 0x1, v0test"); 236 } 237 238 /** 239 * @tc.name: assembler_ins_test_006 240 * @tc.desc: Verify the NextMask function. 241 * @tc.type: FUNC 242 * @tc.require: issueNumber 243 */ 244 HWTEST_F(AssemblerInsTest, assembler_ins_test_006, TestSize.Level1) 245 { 246 Context con; 247 con.token = "test"; 248 249 EXPECT_GT(con.Len(), 0); 250 size_t number_of_params_already_is = 65535; 251 EXPECT_FALSE(con.ValidateParameterName(number_of_params_already_is)); 252 number_of_params_already_is = 4; 253 EXPECT_FALSE(con.ValidateParameterName(number_of_params_already_is)); 254 255 panda::pandasm::Token token1; 256 con.tokens.push_back(token1); 257 panda::pandasm::Token token2; 258 con.tokens.push_back(token2); 259 EXPECT_EQ(con.Next(), Token::Type::ID_BAD); 260 size_t line_size = 3; 261 con.number = line_size; 262 con.end = false; 263 EXPECT_TRUE(con.NextMask()); 264 con.end = true; 265 EXPECT_TRUE(con.NextMask()); 266 } 267 }