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-parser.h" 19 #include "bytecode_optimizer/ir_interface.h" 20 #include "bytecode_optimizer/runtime_adapter.h" 21 #include "libpandabase/mem/arena_allocator.h" 22 #include "libpandabase/mem/pool_manager.h" 23 #include "libpandafile/class_data_accessor.h" 24 #include "libpandafile/class_data_accessor-inl.h" 25 #include "libpandafile/method_data_accessor.h" 26 #include "libpandafile/file.h" 27 #include "macros.h" 28 #include "optimizer/ir/graph.h" 29 #include "optimizer/ir/inst.h" 30 #include "optimizer/ir/runtime_interface.h" 31 #include "optimizer/ir_builder/ir_builder.h" 32 33 namespace panda::compiler { 34 class IrBuilderTest : public testing::Test { 35 public: SetUpTestCase(void)36 static void SetUpTestCase(void) {}; TearDownTestCase(void)37 static void TearDownTestCase(void) {}; SetUp()38 void SetUp() {}; TearDown()39 void TearDown() {}; 40 IrBuilderTest()41 IrBuilderTest() 42 { 43 PoolManager::Initialize(PoolType::MALLOC); 44 } 45 ~IrBuilderTest()46 ~IrBuilderTest() 47 { 48 PoolManager::Finalize(); 49 } 50 51 template <class Callback> TestBuildGraphFromFunc(pandasm::Program & prog,const char * methodName,const Callback & cb)52 void TestBuildGraphFromFunc(pandasm::Program &prog, const char *methodName, const Callback &cb) 53 { 54 pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps {}; 55 auto pfile = pandasm::AsmEmitter::Emit(prog, &maps); 56 for (uint32_t id : pfile->GetClasses()) { 57 panda_file::File::EntityId record_id {id}; 58 panda_file::ClassDataAccessor cda {*pfile, record_id}; 59 60 cda.EnumerateMethods([&prog, maps, methodName, &cb](panda_file::MethodDataAccessor &mda) { 61 auto ir_interface = panda::bytecodeopt::BytecodeOptIrInterface(&maps, &prog); 62 auto func_name = ir_interface.GetMethodIdByOffset(mda.GetMethodId().GetOffset()); 63 if (func_name != methodName) { 64 return; 65 } 66 67 ArenaAllocator allocator {SpaceType::SPACE_TYPE_COMPILER}; 68 ArenaAllocator local_allocator {SpaceType::SPACE_TYPE_COMPILER, nullptr, true}; 69 70 auto method_ptr = reinterpret_cast<compiler::RuntimeInterface::MethodPtr>( 71 mda.GetMethodId().GetOffset()); 72 panda::BytecodeOptimizerRuntimeAdapter adapter(mda.GetPandaFile()); 73 auto *graph = allocator.New<Graph>(&allocator, &local_allocator, Arch::NONE, method_ptr, &adapter, 74 false, nullptr, true, true); 75 graph->RunPass<panda::compiler::IrBuilder>(); 76 cb(graph); 77 }); 78 } 79 } 80 81 template <class Callback> TestBuildGraphFromFile(const std::string & pFileName,const Callback & cb)82 void TestBuildGraphFromFile(const std::string &pFileName, const Callback &cb) 83 { 84 auto pfile = panda_file::OpenPandaFile(pFileName); 85 for (uint32_t id : pfile->GetClasses()) { 86 panda_file::File::EntityId record_id {id}; 87 88 if (pfile->IsExternal(record_id)) { 89 continue; 90 } 91 92 panda_file::ClassDataAccessor cda {*pfile, record_id}; 93 cda.EnumerateMethods([&pfile, &cb](panda_file::MethodDataAccessor &mda) { 94 if (!mda.IsExternal()) { 95 ArenaAllocator allocator {SpaceType::SPACE_TYPE_COMPILER}; 96 ArenaAllocator local_allocator {SpaceType::SPACE_TYPE_COMPILER, nullptr, true}; 97 98 auto method_ptr = reinterpret_cast<compiler::RuntimeInterface::MethodPtr>( 99 mda.GetMethodId().GetOffset()); 100 panda::BytecodeOptimizerRuntimeAdapter adapter(mda.GetPandaFile()); 101 auto *graph = allocator.New<Graph>(&allocator, &local_allocator, Arch::NONE, method_ptr, &adapter, 102 false, nullptr, true, true); 103 graph->RunPass<panda::compiler::IrBuilder>(); 104 105 auto methodName = std::string(utf::Mutf8AsCString(pfile->GetStringData(mda.GetNameId()).data)); 106 107 cb(graph, methodName); 108 } 109 }); 110 } 111 } 112 }; 113 114 HWTEST_F(IrBuilderTest, simpleTryCatchAsm, testing::ext::TestSize.Level1) 115 { 116 /** 117 * try { 118 * a = 1; 119 * } catch(e) { 120 * a = 2; 121 * } 122 */ 123 const auto source = R"( 124 .language ECMAScript 125 .function any foo(any a0, any a1, any a2) { 126 mov v0, a0 127 mov v1, a1 128 mov v2, a2 129 try_begin: 130 ldai 0x1 131 trystglobalbyname 0x0, "a" 132 try_end: 133 jmp catch_end 134 catch_begin: 135 sta v4 136 tryldglobalbyname 0x1, "a" 137 catch_end: 138 returnundefined 139 } 140 )"; 141 142 panda::pandasm::Parser parser; 143 auto res = parser.Parse(source); 144 auto &prog = res.Value(); 145 for (auto &[name, func] : prog.function_table) { 146 auto &catchBlock = func.catch_blocks.emplace_back(); 147 catchBlock.try_begin_label = "try_begin"; 148 catchBlock.try_end_label = "try_end"; 149 catchBlock.catch_begin_label = "catch_begin"; 150 catchBlock.catch_end_label = "catch_end"; 151 } 152 __anon32a3985d0302(Graph* graph) 153 TestBuildGraphFromFunc(prog, "foo:(any,any,any)", [](Graph* graph) { 154 EXPECT_NE(graph, nullptr); 155 for (auto bb : graph->GetBlocksRPO()) { 156 EXPECT_NE(bb, nullptr); 157 if (bb->IsTryBegin()) { 158 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 159 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 2); 160 EXPECT_TRUE(bb->GetSuccessor(0)->IsTry()); 161 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 162 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 163 164 EXPECT_TRUE(bb->GetFirstInst()->IsTry()); 165 continue; 166 } 167 168 if (bb->IsTry()) { 169 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 170 EXPECT_TRUE(bb->GetPredecessor(0)->IsTryBegin()); 171 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 1); 172 173 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 174 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 175 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 176 RuntimeInterface::IntrinsicId::TRYSTGLOBALBYNAME_IMM8_ID16); 177 continue; 178 } 179 180 if (bb->IsTryEnd()) { 181 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 182 EXPECT_TRUE(bb->GetPredecessor(0)->IsTry()); 183 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 2); 184 EXPECT_TRUE(bb->GetSuccessor(0)->GetGuestPc() == bb->GetGuestPc()); 185 EXPECT_TRUE(!bb->GetSuccessor(0)->IsCatch()); 186 EXPECT_TRUE(!bb->GetSuccessor(0)->IsCatchBegin()); 187 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 188 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 189 190 EXPECT_TRUE(bb->IsEmpty()); 191 continue; 192 } 193 194 if (bb->IsCatchBegin()) { 195 EXPECT_TRUE(bb->GetPredsBlocks().size() == 2); 196 EXPECT_TRUE(bb->GetPredecessor(0)->IsTryBegin()); 197 EXPECT_TRUE(bb->GetPredecessor(1)->IsTryEnd()); 198 EXPECT_TRUE(bb->GetSuccessor(0)->IsCatch()); 199 200 EXPECT_TRUE(bb->IsEmpty()); 201 continue; 202 } 203 204 if (bb->IsCatch() && !bb->IsCatchBegin()) { 205 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 206 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatchBegin()); 207 208 EXPECT_TRUE(bb->GetSuccessor(0)->GetFirstInst()->IsSaveState()); 209 EXPECT_TRUE(bb->GetSuccessor(0)->GetLastInst()->IsIntrinsic()); 210 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetSuccessor(0)->GetLastInst()))->GetIntrinsicId() == 211 RuntimeInterface::IntrinsicId::RETURNUNDEFINED); 212 213 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 214 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 215 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 216 RuntimeInterface::IntrinsicId::TRYLDGLOBALBYNAME_IMM8_ID16); 217 continue; 218 } 219 } 220 }); 221 } 222 223 HWTEST_F(IrBuilderTest, nestedTryCatchAsm, testing::ext::TestSize.Level1) 224 { 225 /** 226 * try { 227 * try { 228 * a = 1; 229 * } catch(e) { 230 * a; 231 * } 232 * } catch(e) { 233 * print(e); 234 * } 235 */ 236 const auto source = R"( 237 .language ECMAScript 238 .function any foo(any a0, any a1, any a2) { 239 mov v2, a2 240 mov v1, a1 241 mov v0, a0 242 lda.str "use strict" 243 LABEL_0: 244 LABEL_1: 245 ldai 1 246 trystglobalbyname 0, "a" 247 LABEL_2: 248 jmp LABEL_3 249 LABEL_4: 250 sta v3 251 tryldglobalbyname 1, "a" 252 LABEL_3: 253 LABEL_5: 254 jmp LABEL_6 255 LABEL_7: 256 sta v4 257 tryldglobalbyname 2, "print" 258 sta v5 259 lda v4 260 sta v6 261 lda v5 262 callarg1 3, v6 263 LABEL_6: 264 returnundefined 265 } 266 )"; 267 268 panda::pandasm::Parser parser; 269 auto res = parser.Parse(source); 270 auto &prog = res.Value(); 271 EXPECT_TRUE(prog.function_table.size() == 1); 272 for (auto &[name, func] : prog.function_table) { 273 auto &catchBlock1 = func.catch_blocks.emplace_back(); 274 catchBlock1.try_begin_label = "LABEL_0"; 275 catchBlock1.try_end_label = "LABEL_1"; 276 catchBlock1.catch_begin_label = "LABEL_7"; 277 catchBlock1.catch_end_label = "LABEL_6"; 278 279 auto &catchBlock2 = func.catch_blocks.emplace_back(); 280 catchBlock2.try_begin_label = "LABEL_1"; 281 catchBlock2.try_end_label = "LABEL_2"; 282 catchBlock2.catch_begin_label = "LABEL_4"; 283 catchBlock2.catch_end_label = "LABEL_3"; 284 285 auto &catchBlock3 = func.catch_blocks.emplace_back(); 286 catchBlock3.try_begin_label = "LABEL_2"; 287 catchBlock3.try_end_label = "LABEL_5"; 288 catchBlock3.catch_begin_label = "LABEL_7"; 289 catchBlock3.catch_end_label = "LABEL_6"; 290 } 291 __anon32a3985d0402(Graph* graph) 292 TestBuildGraphFromFunc(prog, "foo:(any,any,any)", [](Graph* graph) { 293 EXPECT_NE(graph, nullptr); 294 int32_t numOfTry = 0; 295 for (auto bb : graph->GetBlocksRPO()) { 296 EXPECT_NE(bb, nullptr); 297 if (bb->IsTryBegin()) { 298 numOfTry++; 299 300 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 301 302 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 2); 303 EXPECT_TRUE(bb->GetSuccessor(0)->IsTry()); 304 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 305 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 306 307 EXPECT_TRUE(bb->GetSuccessor(0)->GetTryId() == bb->GetTryId()); 308 continue; 309 } 310 311 if (bb->IsTry()) { 312 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 313 if (!bb->GetPredecessor(0)->IsTryBegin()) { 314 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatchBegin()); 315 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatch()); 316 317 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 318 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 319 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 320 RuntimeInterface::IntrinsicId::TRYLDGLOBALBYNAME_IMM8_ID16); 321 continue; 322 } 323 324 325 EXPECT_TRUE(bb->GetPredecessor(0)->GetTryId() == bb->GetTryId()); 326 EXPECT_TRUE(bb->GetPredecessor(0)->GetGuestPc() == bb->GetGuestPc()); 327 if (bb->GetPredecessor(0)->GetTryId() == 1) { 328 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 1); 329 EXPECT_TRUE(bb->GetSuccessor(0)->IsTryEnd()); 330 331 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 332 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 333 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 334 RuntimeInterface::IntrinsicId::TRYSTGLOBALBYNAME_IMM8_ID16); 335 continue; 336 } 337 338 EXPECT_TRUE(bb->GetPredecessor(0)->GetTryId() == 2); 339 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 1); 340 EXPECT_TRUE(bb->IsEmpty()); 341 342 for (auto inst : bb->GetSuccessor(0)->AllInsts()) { 343 EXPECT_TRUE(inst->IsPhi()); 344 } 345 continue; 346 } 347 348 if (bb->IsTryEnd()) { 349 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 350 EXPECT_TRUE(bb->GetPredecessor(0)->IsTry()); 351 EXPECT_TRUE(bb->GetPredecessor(0)->GetTryId() == bb->GetTryId()); 352 353 EXPECT_TRUE(bb->IsEmpty()); 354 355 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 2); 356 if (bb->GetTryId() == 1) { 357 EXPECT_TRUE(bb->GetSuccessor(0)->IsTryBegin()); 358 EXPECT_TRUE(bb->GetSuccessor(0)->GetGuestPc() == bb->GetGuestPc()); 359 360 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 361 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 362 363 for (auto inst : bb->GetSuccessor(1)->AllInsts()) { 364 EXPECT_TRUE(inst->IsCatchPhi()); 365 } 366 continue; 367 } 368 369 EXPECT_TRUE(bb->GetTryId() == 2); 370 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 371 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 372 for (auto inst : bb->GetSuccessor(0)->AllInsts()) { 373 EXPECT_TRUE(inst->IsPhi()); 374 } 375 continue; 376 } 377 378 if (bb->IsCatchBegin()) { 379 EXPECT_TRUE(bb->GetPredsBlocks().size() == 2); 380 EXPECT_TRUE(bb->GetPredecessor(0)->IsTryBegin()); 381 EXPECT_TRUE(bb->GetPredecessor(1)->IsTryEnd()); 382 383 EXPECT_TRUE(bb->GetSuccessor(0)->IsCatch()); 384 continue; 385 } 386 387 if (bb->IsCatch() && !bb->IsCatchBegin()) { 388 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 389 390 if (bb->IsTry()) { 391 EXPECT_TRUE(bb->GetTryId() == 2); 392 393 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 1); 394 EXPECT_TRUE(bb->GetSuccessor(0)->IsTryEnd()); 395 EXPECT_TRUE(bb->GetSuccessor(0)->IsCatch()); 396 397 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 398 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 399 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 400 RuntimeInterface::IntrinsicId::TRYLDGLOBALBYNAME_IMM8_ID16); 401 continue; 402 } 403 404 if (bb->IsTryEnd()) { 405 EXPECT_TRUE(bb->GetPredecessor(0)->IsTry()); 406 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatch()); 407 408 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 2); 409 for (auto inst : bb->GetSuccessor(0)->AllInsts()) { 410 EXPECT_TRUE(inst->IsPhi()); 411 } 412 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 413 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 414 415 EXPECT_TRUE(bb->IsEmpty()); 416 continue; 417 } 418 419 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatchBegin()); 420 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatch()); 421 422 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 1); 423 auto *successor = bb->GetSuccessor(0); 424 EXPECT_TRUE(successor->GetFirstInst()->IsSaveState()); 425 EXPECT_TRUE(successor->GetLastInst()->IsIntrinsic()); 426 EXPECT_TRUE((static_cast<IntrinsicInst *>(successor->GetLastInst()))->GetIntrinsicId() == 427 RuntimeInterface::IntrinsicId::RETURNUNDEFINED); 428 for (auto inst : successor->GetPredecessor(0)->AllInsts()) { 429 EXPECT_TRUE(inst->IsPhi()); 430 } 431 432 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 433 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 434 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 435 RuntimeInterface::IntrinsicId::CALLARG1_IMM8_V8); 436 } 437 } 438 439 EXPECT_EQ(numOfTry, 2); 440 }); 441 } 442 443 HWTEST_F(IrBuilderTest, simpleTryCatchAbc, testing::ext::TestSize.Level1) 444 { 445 std::string pFile = GRAPH_TEST_ABC_DIR "simpleTryCatch.abc"; 446 const char *testMethodName = "func_main_0"; __anon32a3985d0502(Graph* graph, std::string &methodName) 447 TestBuildGraphFromFile(pFile, [&testMethodName](Graph* graph, std::string &methodName) { 448 if (testMethodName != methodName) { 449 return; 450 } 451 452 EXPECT_NE(graph, nullptr); 453 for (auto bb : graph->GetBlocksRPO()) { 454 EXPECT_NE(bb, nullptr); 455 if (bb->IsTryBegin()) { 456 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 457 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 2); 458 EXPECT_TRUE(bb->GetSuccessor(0)->IsTry()); 459 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 460 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 461 462 EXPECT_TRUE(bb->GetFirstInst()->IsTry()); 463 continue; 464 } 465 466 if (bb->IsTry()) { 467 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 468 EXPECT_TRUE(bb->GetPredecessor(0)->IsTryBegin()); 469 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 1); 470 471 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 472 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 473 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 474 RuntimeInterface::IntrinsicId::TRYSTGLOBALBYNAME_IMM8_ID16); 475 continue; 476 } 477 478 if (bb->IsTryEnd()) { 479 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 480 EXPECT_TRUE(bb->GetPredecessor(0)->IsTry()); 481 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 2); 482 EXPECT_TRUE(bb->GetSuccessor(0)->GetGuestPc() == bb->GetGuestPc()); 483 EXPECT_TRUE(!bb->GetSuccessor(0)->IsCatch()); 484 EXPECT_TRUE(!bb->GetSuccessor(0)->IsCatchBegin()); 485 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 486 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 487 488 EXPECT_TRUE(bb->IsEmpty()); 489 continue; 490 } 491 492 if (bb->IsCatchBegin()) { 493 EXPECT_TRUE(bb->GetPredsBlocks().size() == 2); 494 EXPECT_TRUE(bb->GetPredecessor(0)->IsTryBegin()); 495 EXPECT_TRUE(bb->GetPredecessor(1)->IsTryEnd()); 496 EXPECT_TRUE(bb->GetSuccessor(0)->IsCatch()); 497 498 EXPECT_TRUE(bb->IsEmpty()); 499 continue; 500 } 501 502 if (bb->IsCatch() && !bb->IsCatchBegin()) { 503 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 504 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatchBegin()); 505 506 EXPECT_TRUE(bb->GetSuccessor(0)->GetFirstInst()->IsSaveState()); 507 EXPECT_TRUE(bb->GetSuccessor(0)->GetLastInst()->IsIntrinsic()); 508 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetSuccessor(0)->GetLastInst()))->GetIntrinsicId() == 509 RuntimeInterface::IntrinsicId::RETURNUNDEFINED); 510 511 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 512 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 513 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 514 RuntimeInterface::IntrinsicId::TRYLDGLOBALBYNAME_IMM8_ID16); 515 continue; 516 } 517 } 518 }); 519 } 520 521 HWTEST_F(IrBuilderTest, nestedTryCatchAbc, testing::ext::TestSize.Level1) 522 { 523 std::string pFile = GRAPH_TEST_ABC_DIR "nestedTryCatch.abc"; 524 const char *testMethodName = "func_main_0"; __anon32a3985d0602(Graph* graph, std::string &methodName) 525 TestBuildGraphFromFile(pFile, [testMethodName](Graph* graph, std::string &methodName) { 526 if (testMethodName != methodName) { 527 return; 528 } 529 530 EXPECT_NE(graph, nullptr); 531 int32_t numOfTry = 0; 532 for (auto bb : graph->GetBlocksRPO()) { 533 EXPECT_NE(bb, nullptr); 534 if (bb->IsTryBegin()) { 535 numOfTry++; 536 537 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 538 539 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 2); 540 541 if (bb->GetTryId() == 0) { 542 EXPECT_TRUE(bb->GetSuccessor(0)->IsTry()); 543 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 544 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 545 EXPECT_TRUE(bb->GetSuccessor(0)->GetTryId() == bb->GetTryId()); 546 } 547 548 if (bb->GetTryId() == 1) { 549 EXPECT_TRUE(bb->GetSuccessor(0)->IsTryBegin()); 550 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 551 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 552 } 553 554 continue; 555 } 556 557 if (bb->IsTry()) { 558 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 559 if (bb->GetPredecessor(0)->IsTryBegin()) { 560 EXPECT_TRUE(bb->GetPredecessor(0)->GetTryId() == bb->GetTryId()); 561 EXPECT_TRUE(bb->GetPredecessor(0)->GetTryId() == 0); 562 EXPECT_TRUE(bb->GetPredecessor(0)->GetGuestPc() == bb->GetGuestPc()); 563 564 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 1); 565 EXPECT_TRUE(bb->GetSuccessor(0)->IsTryEnd()); 566 567 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 568 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 569 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 570 RuntimeInterface::IntrinsicId::TRYSTGLOBALBYNAME_IMM8_ID16); 571 continue; 572 } 573 574 if (bb->GetPredecessor(0)->IsTryEnd()) { 575 EXPECT_FALSE(bb->GetPredecessor(0)->GetTryId() == bb->GetTryId()); 576 EXPECT_TRUE(bb->GetPredecessor(0)->GetGuestPc() == bb->GetGuestPc()); 577 578 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 1); 579 for (auto inst : bb->GetSuccessor(0)->AllInsts()) { 580 EXPECT_TRUE(inst->IsPhi()); 581 } 582 continue; 583 } 584 585 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatchBegin()); 586 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatch()); 587 588 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 1); 589 EXPECT_TRUE(bb->GetSuccessor(0)->IsCatch()); 590 591 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 592 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 593 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 594 RuntimeInterface::IntrinsicId::TRYLDGLOBALBYNAME_IMM8_ID16); 595 continue; 596 } 597 598 if (bb->IsTryEnd()) { 599 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 600 EXPECT_TRUE(bb->GetPredecessor(0)->IsTry()); 601 EXPECT_TRUE(bb->GetPredecessor(0)->GetTryId() == bb->GetTryId()); 602 603 EXPECT_TRUE(bb->IsEmpty()); 604 605 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 2); 606 if (bb->GetTryId() == 0) { 607 EXPECT_TRUE(bb->GetSuccessor(0)->IsTry()); 608 EXPECT_TRUE(bb->GetSuccessor(0)->GetGuestPc() == bb->GetGuestPc()); 609 610 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 611 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 612 613 for (auto inst : bb->GetSuccessor(1)->AllInsts()) { 614 EXPECT_TRUE(inst->IsCatchPhi()); 615 } 616 continue; 617 } 618 619 EXPECT_TRUE(bb->GetTryId() == 1); 620 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 621 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 622 for (auto inst : bb->GetSuccessor(0)->AllInsts()) { 623 EXPECT_TRUE(inst->IsPhi()); 624 } 625 continue; 626 } 627 628 if (bb->IsCatchBegin()) { 629 EXPECT_TRUE(bb->GetPredsBlocks().size() == 2); 630 EXPECT_TRUE(bb->GetPredecessor(0)->IsTryBegin()); 631 EXPECT_TRUE(bb->GetPredecessor(1)->IsTryEnd()); 632 633 EXPECT_TRUE(bb->GetSuccessor(0)->IsCatch()); 634 continue; 635 } 636 637 if (bb->IsCatch() && !bb->IsCatchBegin()) { 638 EXPECT_TRUE(bb->GetPredsBlocks().size() == 1); 639 640 if (bb->IsTry()) { 641 EXPECT_TRUE(bb->GetTryId() == 2); 642 643 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 1); 644 EXPECT_TRUE(bb->GetSuccessor(0)->IsTryEnd()); 645 EXPECT_TRUE(bb->GetSuccessor(0)->IsCatch()); 646 647 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 648 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 649 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 650 RuntimeInterface::IntrinsicId::TRYLDGLOBALBYNAME_IMM8_ID16); 651 continue; 652 } 653 654 if (bb->IsTryEnd()) { 655 EXPECT_TRUE(bb->GetPredecessor(0)->IsTry()); 656 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatch()); 657 658 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 2); 659 for (auto inst : bb->GetSuccessor(0)->AllInsts()) { 660 EXPECT_TRUE(inst->IsPhi()); 661 } 662 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatchBegin()); 663 EXPECT_TRUE(bb->GetSuccessor(1)->IsCatch()); 664 665 EXPECT_TRUE(bb->IsEmpty()); 666 continue; 667 } 668 669 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatchBegin()); 670 EXPECT_TRUE(bb->GetPredecessor(0)->IsCatch()); 671 672 EXPECT_TRUE(bb->GetSuccsBlocks().size() == 1); 673 auto *successor = bb->GetSuccessor(0); 674 EXPECT_TRUE(successor->GetFirstInst()->IsSaveState()); 675 EXPECT_TRUE(successor->GetLastInst()->IsIntrinsic()); 676 EXPECT_TRUE((static_cast<IntrinsicInst *>(successor->GetLastInst()))->GetIntrinsicId() == 677 RuntimeInterface::IntrinsicId::RETURNUNDEFINED); 678 for (auto inst : successor->GetPredecessor(0)->AllInsts()) { 679 EXPECT_TRUE(inst->IsPhi()); 680 } 681 682 EXPECT_TRUE(bb->GetFirstInst()->IsSaveState()); 683 EXPECT_TRUE(bb->GetLastInst()->IsIntrinsic()); 684 EXPECT_TRUE((static_cast<IntrinsicInst *>(bb->GetLastInst()))->GetIntrinsicId() == 685 RuntimeInterface::IntrinsicId::CALLARG1_IMM8_V8); 686 } 687 } 688 689 EXPECT_EQ(numOfTry, 2); 690 }); 691 } 692 } // namespace panda::compiler