1# Copyright (c) 2021-2022 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14definitions: 15 - name: PandaAssembly_header 16 template: | 17 .language PandaAssembly 18 .record panda.NullPointerException <external> 19 .record panda.RuntimeException <external> 20 .record panda.Exception <external> 21 .record panda.Throwable <external> 22 .record panda.Object <external> 23 .record E1 <panda.extends=panda.Throwable> {} 24 25 - name: pandasm_header 26 template: | 27 .language PandaAssembly 28 .record panda.NullPointerException <external> 29 .record panda.Object <external> 30 .record E1 {} 31 .record E2 {} 32 .record E3 {} 33 34tests: 35 - file-name: "throw" 36 isa: 37 title: Throw exception 38 description: Throw an exception located in register. 39 instructions: 40 - sig: throw v:in:ref 41 acc: none 42 format: [op_v_8] 43 exceptions: 44 - x_throw 45 commands: 46 47 - file-name: "when_reg_is_invalid" 48 description: Check that compilation fails if register is invalid 49 isa: 50 instructions: 51 - sig: throw v:in:ref 52 acc: none 53 format: [op_v_8] 54 verification: 55 - v1_throw_type 56 runner-options: ['compile-failure'] 57 header-template: [] 58 check-type: empty 59 code-template: | 60 61 .function i32 main() { 62 throw %s 63 } 64 cases: 65 - values: ['v256'] 66 - values: ['v65535'] 67 - values: ['a0'] 68 - values: [''] 69 - values: ['main'] 70 - values: ['i32'] 71 - values: ['throw'] 72 - values: ['v0, v0'] 73 - values: ['}'] 74 - values: ['v255'] 75 runner-options: ['compile-only'] 76 77 - file-name: "when_reg_v_is_uninitialized" 78 description: Check that verifier report error when the register is not initialized 79 isa: 80 instructions: 81 - sig: throw v:in:ref 82 acc: none 83 format: [op_v_8] 84 verification: 85 - v1_throw_type 86 runner-options: ['verifier-failure', 'verifier-config'] 87 tags: ['verifier'] 88 header-template: [] 89 check-type: empty 90 code-template: | 91 92 .function i32 main() { 93 throw %s 94 } 95 cases: 96 - values: ['v0'] 97 - values: ['v255'] 98 99 100 - file-name: "when_reg_a_is_uninitialized" 101 description: Check that compiler reports error when 'a' register is not initialized 102 isa: 103 instructions: 104 - sig: throw v:in:ref 105 acc: none 106 format: [op_v_8] 107 verification: 108 - v1_throw_type 109 runner-options: ['compile-failure'] 110 header-template: [] 111 tags: ['irtoc_ignore'] 112 check-type: empty 113 code-template: | 114 .record E {} 115 116 .function void func(E a0) <static> { 117 throw %s 118 return.void 119 } 120 121 .function i32 main() { 122 newobj v0, E 123 call.short func, v0 124 ldai 0 125 return 126 } 127 cases: 128 - values: ['a0'] 129 runner-options: ['run-failure'] 130 - values: ['a1'] 131 - values: ['a255'] 132 133 134 - file-name: "when_reg_is_null_pa" 135 description: Check that NullPointerException is thrown when register value is null 136 isa: 137 exceptions: [x_null] 138 header-template: ['pandasm_header'] 139 check-type: none 140 tags: ['irtoc_ignore'] 141 code-template: | 142 143 .function i32 main() { 144 jmp try_begin 145 catch_NPE_block_begin: 146 sta.obj v2 147 isinstance panda.NullPointerException 148 jeqz set_failure 149 lda.obj v2 150 isinstance panda.Object 151 jeqz set_failure 152 ldai 0 153 return 154 set_failure: 155 ldai 1 156 return 157 try_begin: 158 mov.null v0 159 throw v0 160 ldai 2 161 return 162 try_end: 163 .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin 164 165 166 - file-name: "when_reg_is_null_j" 167 description: Check that NullPointerException is thrown when register value is null 168 isa: 169 exceptions: [x_null] 170 header-template: ['PandaAssembly_header'] 171 runner-options: ['use-pa'] 172 check-type: none 173 tags: ['tsan', 'irtoc_ignore'] 174 code-template: | 175 176 .function i32 main() { 177 jmp try_begin 178 catch_NPE_block_begin: 179 sta.obj v2 180 isinstance panda.NullPointerException 181 jeqz set_failure 182 lda.obj v2 183 isinstance panda.Object 184 jeqz set_failure 185 ldai 0 186 return 187 set_failure: 188 ldai 1 189 return 190 try_begin: 191 mov.null v0 192 throw v0 193 ldai 2 194 return 195 try_end: 196 .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin 197 198 199 - file-name: "with_wrong_reg_value_pa" 200 description: "Check that VM thread fails when register contains not a Throwable" 201 isa: 202 description: Throw an exception located in register. 203 verification: 204 - v1_throw_type 205 header-template: ['pandasm_header'] 206 check-type: none 207 runner-options: ['verifier-failure', 'verifier-config'] 208 tags: ['verifier'] 209 code-template: | 210 211 .function i32 main() { 212 jmp try_begin 213 catch_all_block_begin: 214 ldai 0 215 return 216 try_begin: 217 %s 218 throw v0 219 try_end: 220 .catchall try_begin, try_end, catch_all_block_begin 221 cases: 222 - values: 223 - movi v0, 100 224 - values: 225 - movi.64 v0, 0x1234567890 226 - values: 227 - fmovi.64 v0, 3.1415926 228 - values: 229 - newobj v0, panda.Object 230 bugid: ['1688'] 231 ignore: true 232 - values: 233 - newobj v0, E1 234 bugid: ['1688'] 235 ignore: true 236 - values: 237 - | 238 # 239 lda.type panda.Object 240 sta.obj v0 241 bugid: ['1688'] 242 ignore: true 243 - values: 244 - | 245 # 246 lda.str "abc" 247 sta.obj v0 248 bugid: ['1688'] 249 ignore: true 250 251 252 - file-name: "with_wrong_reg_value_j" 253 description: "Check that VM thread fails when register contains not a Throwable" 254 isa: 255 description: Throw an exception located in register. 256 verification: 257 - v1_throw_type 258 header-template: ['PandaAssembly_header'] 259 check-type: empty 260 runner-options: ['verifier-failure', 'verifier-config', 'use-pa'] 261 tags: [verifier, pa-verifier] 262 code-template: | 263 264 .function i32 main() { 265 jmp try_begin 266 catch_all_block_begin: 267 ldai 0 268 return 269 try_begin: 270 %s 271 throw v0 272 try_end: 273 .catchall try_begin, try_end, catch_all_block_begin 274 } 275 cases: 276 - values: 277 - movi v0, 100 278 - values: 279 - movi.64 v0, 0x1234567890 280 - values: 281 - fmovi.64 v0, 3.1415926 282 - values: 283 - newobj v0, panda.Object 284 bugid: ['1688'] 285 ignore: true 286 - values: 287 - newobj v0, E1 288 bugid: ['1688'] 289 ignore: true 290 - values: 291 - | 292 # 293 lda.type panda.Object 294 sta.obj v0 295 bugid: ['1688'] 296 ignore: true 297 - values: 298 - | 299 # 300 lda.str "abc" 301 sta.obj v0 302 bugid: ['1688'] 303 ignore: true 304 305 306 - file-name: "with_multiple_catch_blocks_pa" 307 description: "Check that correct catch block is selected" 308 isa: 309 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 310 header-template: ['pandasm_header'] 311 tags: ['irtoc_ignore'] 312 check-type: none 313 code-template: | 314 315 .function i32 main() { 316 jmp try_begin 317 catch_NPE_block_begin: 318 sta.obj v2 319 ldai %s 320 jnez set_failure 321 lda.obj v2 322 isinstance panda.NullPointerException 323 jeqz set_failure 324 lda.obj v2 325 isinstance panda.Object 326 jeqz set_failure 327 lda.obj v2 328 jne.obj v0, set_failure 329 ldai 0 330 return 331 catch_E1_block_begin: 332 sta.obj v2 333 ldai %s 334 jnez set_failure 335 lda.obj v2 336 isinstance E1 337 jeqz set_failure 338 lda.obj v2 339 isinstance panda.Object 340 jeqz set_failure 341 lda.obj v2 342 jne.obj v0, set_failure 343 ldai 0 344 return 345 catch_E2_block_begin: 346 sta.obj v2 347 ldai %s 348 jnez set_failure 349 lda.obj v2 350 isinstance E2 351 jeqz set_failure 352 lda.obj v2 353 isinstance panda.Object 354 jeqz set_failure 355 lda.obj v2 356 jne.obj v0, set_failure 357 ldai 0 358 return 359 catch_E3_block_begin: 360 sta.obj v2 361 ldai %s 362 jnez set_failure 363 lda.obj v2 364 isinstance E3 365 jeqz set_failure 366 lda.obj v2 367 isinstance panda.Object 368 jeqz set_failure 369 lda.obj v2 370 jne.obj v0, set_failure 371 ldai 0 372 return 373 try_begin: 374 newobj v0, %s 375 throw v0 376 try_end: 377 set_failure: 378 ldai 1 379 return 380 .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin 381 .catch E1, try_begin, try_end, catch_E1_block_begin 382 .catch E2, try_begin, try_end, catch_E2_block_begin 383 .catch E3, try_begin, try_end, catch_E3_block_begin 384 cases: 385 - values: [0, 2, 3, 4, panda.NullPointerException] 386 - values: [1, 0, 3, 4, E1] 387 - values: [1, 2, 0, 4, E2] 388 - values: [1, 2, 3, 0, E3] 389 390 391 - file-name: "with_multiple_catch_blocks_j" 392 description: "Check that correct catch block is selected" 393 isa: 394 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 395 header-template: ['PandaAssembly_header'] 396 runner-options: ['use-pa'] 397 check-type: none 398 tags: ['tsan', 'irtoc_ignore'] 399 code-template: | 400 401 .function i32 main() { 402 jmp try_begin 403 catch_NPE_block_begin: 404 sta.obj v2 405 ldai %s 406 jnez set_failure 407 lda.obj v2 408 isinstance panda.NullPointerException 409 jeqz set_failure 410 lda.obj v2 411 isinstance panda.Object 412 jeqz set_failure 413 lda.obj v2 414 jne.obj v0, set_failure 415 ldai 0 416 return 417 catch_RE_block_begin: 418 sta.obj v2 419 ldai %s 420 jnez set_failure 421 lda.obj v2 422 isinstance panda.RuntimeException 423 jeqz set_failure 424 lda.obj v2 425 isinstance panda.Object 426 jeqz set_failure 427 lda.obj v2 428 jne.obj v0, set_failure 429 ldai 0 430 return 431 catch_E1_block_begin: 432 sta.obj v2 433 ldai %s 434 jnez set_failure 435 lda.obj v2 436 isinstance E1 437 jeqz set_failure 438 lda.obj v2 439 isinstance panda.Object 440 jeqz set_failure 441 lda.obj v2 442 jne.obj v0, set_failure 443 ldai 0 444 return 445 catch_Ex_block_begin: 446 sta.obj v2 447 ldai %s 448 jnez set_failure 449 lda.obj v2 450 isinstance panda.Exception 451 jeqz set_failure 452 lda.obj v2 453 isinstance panda.Object 454 jeqz set_failure 455 lda.obj v2 456 jne.obj v0, set_failure 457 ldai 0 458 return 459 try_begin: 460 newobj v0, %s 461 throw v0 462 try_end: 463 set_failure: 464 ldai 1 465 return 466 .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin 467 .catch panda.RuntimeException, try_begin, try_end, catch_RE_block_begin 468 .catch panda.Exception, try_begin, try_end, catch_Ex_block_begin 469 .catch E1, try_begin, try_end, catch_E1_block_begin 470 cases: 471 - values: [0, 2, 3, 4, panda.NullPointerException] 472 - values: [1, 0, 3, 4, panda.RuntimeException] 473 - values: [1, 2, 3, 0, panda.Exception] 474 - values: [1, 2, 0, 0, E1] 475 476 477 - file-name: "with_catchall_pa" 478 description: "Check that catchall block is selected correctly" 479 isa: 480 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 481 header-template: ['pandasm_header'] 482 check-type: empty 483 tags: ['irtoc_ignore'] 484 code-template: | 485 486 .function i32 main() { 487 try_begin: 488 newobj v0, %s 489 throw v0 490 try_end: 491 catch_all_block_begin: 492 ldai %s 493 return 494 catch_E1_block_begin: 495 ldai %s 496 return 497 catch_E2_block_begin: 498 ldai %s 499 return 500 .catch E1, try_begin, try_end, catch_E1_block_begin 501 .catchall try_begin, try_end, catch_all_block_begin 502 .catch E2, try_begin, try_end, catch_E2_block_begin 503 } 504 cases: 505 - values: [E1, 1, 0, 3] 506 - values: [E2, 0, 2, 3] 507 - values: [panda.NullPointerException, 0, 2, 3] 508 509 510 - file-name: "with_catchall_j" 511 description: "Check that catchall block is selected correctly" 512 isa: 513 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 514 header-template: ['PandaAssembly_header'] 515 runner-options: ['use-pa'] 516 tags: ['irtoc_ignore'] 517 code-template: | 518 519 .function i32 main() { 520 try_begin: 521 newobj v0, %s 522 throw v0 523 try_end: 524 catch_RE_block_begin: 525 ldai %s 526 return 527 catch_Ex_block_begin: 528 ldai %s 529 return 530 catch_all_block_begin: 531 ldai %s 532 return 533 catch_E1_block_begin: 534 ldai %s 535 return 536 .catch E1, try_begin, try_end, catch_E1_block_begin 537 .catchall try_begin, try_end, catch_all_block_begin 538 .catch panda.Exception, try_begin, try_end, catch_Ex_block_begin 539 .catch panda.RuntimeException, try_begin, try_end, catch_RE_block_begin 540 check-type: none 541 cases: 542 - values: [E1, 1, 2, 3, 0] 543 - values: [panda.Exception, 1, 2, 0, 4] 544 - values: [panda.RuntimeException, 1, 2, 0, 4] 545 - values: [panda.NullPointerException, 1, 2, 0, 4] 546 547 548 - file-name: "with_reg_value_check_pa" 549 description: "Check that register keeps ref to exception object in catch block" 550 isa: 551 description: Throw an exception located in register. 552 header-template: ['pandasm_header'] 553 check-type: empty 554 tags: ['irtoc_ignore'] 555 bugid: ["3975"] 556 code-template: | 557 558 .function i32 main() { 559 try_begin: 560 newobj v0, %s 561 throw v0 562 try_end: 563 catch_block_begin: 564 jne.obj v0, return_ne_num 565 ldai 0 566 return 567 return_ne_num: 568 ldai 1 569 return 570 .catch E1, try_begin, try_end, catch_block_begin 571 .catch E2, try_begin, try_end, catch_block_begin 572 .catchall try_begin, try_end, catch_block_begin 573 } 574 cases: 575 - values: 576 - E1 577 - values: 578 - E2 579 - values: 580 - panda.NullPointerException 581 582 583 - file-name: "with_reg_value_check_j" 584 description: "Check that register keeps ref to exception object in catch block" 585 isa: 586 description: Throw an exception located in register. 587 header-template: ['PandaAssembly_header'] 588 runner-options: ['use-pa'] 589 check-type: empty 590 tags: ['irtoc_ignore'] 591 bugid: ["3975"] 592 code-template: | 593 594 .function i32 main() { 595 try_begin: 596 newobj v0, %s 597 throw v0 598 try_end: 599 catch_block_begin: 600 jne.obj v0, return_ne_num 601 ldai 0 602 return 603 return_ne_num: 604 ldai 1 605 return 606 .catch panda.NullPointerException, try_begin, try_end, catch_block_begin 607 .catch panda.Exception, try_begin, try_end, catch_block_begin 608 .catchall try_begin, try_end, catch_block_begin 609 } 610 cases: 611 - values: 612 - panda.NullPointerException 613 - values: 614 - panda.Exception 615 - values: 616 - panda.RuntimeException 617 618 619 - file-name: "with_propagation_to_outer_block_pa" 620 description: "Check exception propagation to outer try-catch block" 621 isa: 622 description: The current method is searched for the first exception handler that matches the class of exception. If exception handler is found, control is passed to the exception handler. 623 header-template: ['pandasm_header'] 624 check-type: empty 625 tags: ['tsan', 'irtoc_ignore'] 626 code-template: | 627 628 .function i32 main() { 629 begin3: 630 newobj v0, %s 631 lda.obj v0 632 begin2: 633 mov.obj v1, v0 634 begin1: 635 throw v0 636 end1: 637 end2: 638 end3: 639 ldai 4 640 return 641 catch1: 642 %s 643 return 644 catch2: 645 %s 646 return 647 catch3: 648 %s 649 return 650 .catch E1, begin1, end1, catch1 651 .catch E2, begin2, end2, catch2 652 .catch E3, begin3, end3, catch3 653 } 654 cases: 655 - values: 656 - E1 657 - | 658 # 659 jne.obj v1, return_ne_num 660 ldai 0 661 return 662 return_ne_num: 663 ldai 1 664 - ldai 2 665 - ldai 3 666 - values: 667 - E2 668 - ldai 2 669 - | 670 # 671 jne.obj v1, return_ne_num 672 ldai 0 673 return 674 return_ne_num: 675 ldai 1 676 - ldai 3 677 bugid: ['3975'] 678 - values: 679 - E3 680 - ldai 2 681 - ldai 3 682 - | 683 # 684 jne.obj v1, return_ne_num 685 ldai 0 686 return 687 return_ne_num: 688 ldai 1 689 bugid: ['3975'] 690 691 692 - file-name: "with_propagation_to_outer_block_j" 693 description: "Check exception propagation to outer try-catch block" 694 isa: 695 description: The current method is searched for the first exception handler that matches the class of exception. If exception handler is found, control is passed to the exception handler. 696 header-template: ['PandaAssembly_header'] 697 runner-options: ['use-pa'] 698 check-type: empty 699 tags: ['irtoc_ignore'] 700 code-template: | 701 702 .function i32 main() { 703 begin3: 704 newobj v0, %s 705 lda.obj v0 706 begin2: 707 mov.obj v1, v0 708 begin1: 709 throw v0 710 end1: 711 end2: 712 end3: 713 ldai 4 714 return 715 catch1: 716 %s 717 return 718 catch2: 719 %s 720 return 721 catch3: 722 %s 723 return 724 .catch panda.NullPointerException, begin1, end1, catch1 725 .catch panda.RuntimeException, begin2, end2, catch2 726 .catch panda.Exception, begin3, end3, catch3 727 } 728 cases: 729 - values: 730 - panda.NullPointerException 731 - | 732 # 733 jne.obj v1, return_ne_num 734 ldai 0 735 return 736 return_ne_num: 737 ldai 1 738 - ldai 2 739 - ldai 3 740 - values: 741 - panda.RuntimeException 742 - ldai 2 743 - | 744 # 745 jne.obj v1, return_ne_num 746 ldai 0 747 return 748 return_ne_num: 749 ldai 1 750 - ldai 3 751 bugid: ['3975'] 752 - values: 753 - panda.Exception 754 - ldai 2 755 - ldai 3 756 - | 757 # 758 jne.obj v1, return_ne_num 759 ldai 0 760 return 761 return_ne_num: 762 ldai 1 763 bugid: ['3975'] 764 765 766 - file-name: "with_propagation_to_outer_frame_pa" 767 description: "Check exception propagation to outer frame" 768 isa: 769 description: If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. 770 header-template: ['pandasm_header'] 771 check-type: empty 772 bugid: ["1837"] 773 tags: ['irtoc_ignore'] 774 code-template: | 775 776 .function i32 f2() { 777 newobj v0, %s 778 try2_begin: 779 throw v0 780 try2_end: 781 ldai 0 782 return 783 .catch %s, try2_begin, try2_end, try2_end 784 } 785 786 .function i32 f1() { 787 try1_begin: 788 call f2 789 return 790 try1_end: 791 ldai 0 792 return 793 .catch %s, try1_begin, try1_end, try1_end 794 } 795 796 .function i32 main() { 797 try_begin: 798 call f1 799 ldai %s 800 return 801 try_end: 802 catch_block_begin: 803 ldai %s 804 return 805 .catch %s, try_begin, try_end, catch_block_begin 806 } 807 cases: 808 - values: [E2, E1, E2, 0, 1, E3] 809 - values: [E3, E1, E2, 1, 0, E3] 810 811 812 - file-name: "with_propagation_to_outer_frame_j" 813 description: "Check exception propagation to outer frame" 814 isa: 815 description: If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. 816 header-template: ['PandaAssembly_header'] 817 runner-options: ['use-pa'] 818 check-type: empty 819 tags: ['irtoc_ignore'] 820 bugid: ["1837"] 821 code-template: | 822 823 .function i32 f2() { 824 newobj v0, %s 825 try2_begin: 826 throw v0 827 try2_end: 828 ldai 0 829 return 830 .catch %s, try2_begin, try2_end, try2_end 831 } 832 833 .function i32 f1() { 834 try1_begin: 835 call f2 836 return 837 try1_end: 838 ldai 0 839 return 840 .catch %s, try1_begin, try1_end, try1_end 841 } 842 843 .function i32 main() { 844 try_begin: 845 call f1 846 ldai %s 847 return 848 try_end: 849 catch_block_begin: 850 ldai %s 851 return 852 .catch %s, try_begin, try_end, catch_block_begin 853 } 854 cases: 855 - values: [panda.Exception, panda.NullPointerException, panda.Exception, 0, 1, panda.RuntimeException] 856 - values: [panda.Exception, panda.NullPointerException, panda.RuntimeException, 1, 0, panda.Exception] 857 858 859 - file-name: "with_no_handler_pa" 860 description: "Check exception propagation to outer frame." 861 isa: 862 description: > 863 If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. If no 864 exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. 865 header-template: ['pandasm_header'] 866 tags: ['irtoc_ignore'] 867 check-type: empty 868 code-template: | 869 870 .function i32 f2() { 871 newobj v0, %s 872 try2_begin: 873 throw v0 874 try2_end: 875 ldai 1 876 return 877 .catch %s, try2_begin, try2_end, try2_end 878 } 879 880 .function i32 f1() { 881 try1_begin: 882 call f2 883 return 884 try1_end: 885 ldai 1 886 return 887 .catch %s, try1_begin, try1_end, try1_end 888 } 889 890 .function i32 main() { 891 try_begin: 892 call f1 893 return 894 try_end: 895 catch_block_begin: 896 ldai 0 897 return 898 .catch %s, try_begin, try_end, catch_block_begin 899 } 900 cases: 901 - values: [E2, E1, E3, E2] 902 - values: [E3, E1, E1, E3] 903 904 905 - file-name: "with_no_handler_j" 906 description: "Check exception propagation to outer frame." 907 isa: 908 description: > 909 If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. If no 910 exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. 911 header-template: ['PandaAssembly_header'] 912 check-type: empty 913 runner-options: ['use-pa'] 914 tags: ['irtoc_ignore'] 915 code-template: | 916 917 .function i32 f2() { 918 newobj v0, %s 919 try2_begin: 920 throw v0 921 try2_end: 922 ldai 1 923 return 924 .catch %s, try2_begin, try2_end, try2_end 925 } 926 927 .function i32 f1() { 928 try1_begin: 929 call f2 930 return 931 try1_end: 932 ldai 1 933 return 934 .catch %s, try1_begin, try1_end, try1_end 935 } 936 937 .function i32 main() { 938 try_begin: 939 call f1 940 return 941 try_end: 942 catch_block_begin: 943 ldai 0 944 return 945 .catch %s, try_begin, try_end, catch_block_begin 946 } 947 cases: 948 - values: [panda.Exception, panda.NullPointerException, panda.RuntimeException, panda.Exception] 949 950 951 - file-name: "with_no_handler2_pa" 952 description: "Check thread exit if handler is not found." 953 isa: 954 description: > 955 If no such frame exists, the current VM thread exits. 956 header-template: ['pandasm_header'] 957 check-type: empty 958 runner-options: ['run-failure'] 959 tags: ['irtoc_ignore'] 960 code-template: | 961 962 .function i32 main() { 963 newobj v0, %s 964 throw v0 965 ldai 0 966 return 967 } 968 cases: 969 - values: [E2] 970 - values: [panda.Object] 971 972 973 - file-name: "with_no_handler2_j" 974 description: "Check VM thread exit if handler is not found." 975 isa: 976 description: > 977 If no such frame exists, the current VM thread exits. 978 header-template: ['PandaAssembly_header'] 979 check-type: empty 980 runner-options: ['use-pa', 'run-failure'] 981 bugid: ['5450'] 982 tags: ['arm64-fail', 'irtoc_ignore'] 983 code-template: | 984 985 .function i32 main() { 986 newobj v0, %s 987 throw v0 988 ldai 0 989 return 990 } 991 cases: 992 - values: [panda.Exception] 993 - values: [panda.NullPointerException] 994 995 996 - file-name: "subclass_of_exception_j" 997 description: "Check that exception subclass is successfully caught by its superclass declaration in catch" 998 isa: 999 description: The current method is searched for the first exception handler that matches the class of exception. If exception handler is found, control is passed to the exception handler. 1000 header-template: ['PandaAssembly_header'] 1001 runner-options: ['use-pa'] 1002 check-type: empty 1003 bugid: ['3977'] 1004 tags: ['tsan', 'irtoc_ignore'] 1005 code-template: | 1006 .record MyCustomException <panda.extends=panda.RuntimeException> {} 1007 .record MySecondCustomException <panda.extends=MyCustomException> {} 1008 1009 .function i32 main() { 1010 jmp try_begin 1011 catch_block_begin: 1012 ldai 0 1013 return 1014 catch2_block_begin: 1015 ldai 1 1016 return 1017 try_begin: 1018 newobj v0, %s 1019 throw v0 1020 try_end: 1021 .catch %s, try_begin, try_end, catch_block_begin 1022 .catchall try_begin, try_end, catch2_block_begin 1023 } 1024 cases: 1025 - values: [panda.RuntimeException, panda.Exception] 1026 - values: [MyCustomException, panda.RuntimeException] 1027 - values: [MySecondCustomException, MyCustomException] 1028 - values: [MySecondCustomException, panda.Exception] 1029 1030 1031 - file-name: "superclass_of_exception_j" 1032 description: "Check that exception superclass is not caught by its subclass declaration in catch" 1033 isa: 1034 description: > 1035 If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. If no 1036 exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. 1037 If no such frame exists, the current VM thread exits. 1038 header-template: ['PandaAssembly_header'] 1039 runner-options: ['use-pa'] 1040 tags: ['irtoc_ignore'] 1041 check-type: empty 1042 code-template: | 1043 .record MyCustomException <panda.extends=panda.RuntimeException> {} 1044 .record MySecondCustomException <panda.extends=MyCustomException> {} 1045 1046 .function i32 main() { 1047 jmp try_begin 1048 catch_block_begin: 1049 ldai 1 1050 return 1051 catch2_block_begin: 1052 ldai 0 1053 return 1054 try_begin: 1055 newobj v0, %s 1056 throw v0 1057 try_end: 1058 .catch %s, try_begin, try_end, catch_block_begin 1059 .catchall try_begin, try_end, catch2_block_begin 1060 } 1061 cases: 1062 - values: [panda.Exception, panda.RuntimeException] 1063 - values: [panda.RuntimeException, MyCustomException] 1064 - values: [MyCustomException, MySecondCustomException] 1065 - values: [panda.Exception, MySecondCustomException] 1066 1067 1068 - file-name: "cflow_fallthrough1_pa" 1069 description: "Check that the verifier prohibits a fallthrough to the beginning of open-ended exception handler." 1070 isa: 1071 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1072 header-template: ['pandasm_header'] 1073 tags: ['verifier'] 1074 check-type: none 1075 code-template: | 1076 1077 .function i32 foo(E1 a0) { 1078 throw a0 1079 } 1080 1081 .function i32 main() { 1082 newobj v1, E1 1083 lda.obj v1 1084 %s 1085 catch_all: 1086 ldai 0 1087 return 1088 try_begin: 1089 throw v1 1090 try_end: 1091 ldai 2 1092 return 1093 .catchall try_begin, try_end, catch_all 1094 cases: 1095 - values: 1096 - '' 1097 runner-options: ['verifier-failure', 'verifier-config'] 1098 - values: 1099 - jnez.obj try_begin 1100 runner-options: ['verifier-failure', 'verifier-config'] 1101 - values: 1102 - jmp catch_all 1103 runner-options: ['verifier-failure', 'verifier-config'] 1104 - values: 1105 - call.short foo, v1 1106 runner-options: ['verifier-failure', 'verifier-config'] 1107 - values: 1108 - jmp try_begin 1109 runner-options: ['verifier-only', 'verifier-config'] 1110 - values: 1111 - throw v1 1112 runner-options: ['verifier-only', 'verifier-config'] 1113 - values: 1114 - | 1115 # 1116 ldai 0 1117 return 1118 runner-options: ['verifier-only', 'verifier-config'] 1119 1120 1121 - file-name: "cflow_fallthrough2_pa" 1122 description: "Check that the verifier prohibits a fallthrough to the beginning of close-ended exception handler." 1123 isa: 1124 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1125 header-template: ['pandasm_header'] 1126 tags: ['verifier'] 1127 check-type: none 1128 code-template: | 1129 1130 .function i32 foo(E1 a0) { 1131 throw a0 1132 } 1133 1134 .function i32 main() { 1135 newobj v1, E1 1136 lda.obj v1 1137 %s 1138 catch_begin: 1139 ldai 0 1140 return 1141 catch_end: 1142 try_begin: 1143 throw v1 1144 try_end: 1145 ldai 2 1146 return 1147 .catchall try_begin, try_end, catch_begin, catch_end 1148 cases: 1149 - values: 1150 - '' 1151 runner-options: ['verifier-failure', 'verifier-config'] 1152 - values: 1153 - jnez.obj try_begin 1154 runner-options: ['verifier-failure', 'verifier-config'] 1155 - values: 1156 - jmp catch_begin 1157 runner-options: ['verifier-failure', 'verifier-config'] 1158 - values: 1159 - call.short foo, v1 1160 runner-options: ['verifier-failure', 'verifier-config'] 1161 - values: 1162 - jmp catch_end 1163 runner-options: ['verifier-only', 'verifier-config'] 1164 - values: 1165 - jmp try_begin 1166 runner-options: ['verifier-only', 'verifier-config'] 1167 - values: 1168 - throw v1 1169 runner-options: ['verifier-only', 'verifier-config'] 1170 - values: 1171 - | 1172 # 1173 ldai 0 1174 return 1175 runner-options: ['verifier-only', 'verifier-config'] 1176 1177 1178 - file-name: "cflow_fallthrough3_pa" 1179 description: "Check that the verifier prohibits an open-ended exception handler at the beginning of a function." 1180 isa: 1181 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1182 header-template: ['pandasm_header'] 1183 runner-options: ['verifier-failure', 'verifier-config'] 1184 tags: ['verifier'] 1185 bugid: ['8029'] 1186 ignore: true 1187 check-type: none 1188 code-template: | 1189 1190 .function i32 foo(E1 a0) { 1191 catch_begin: 1192 ldai 0 1193 return 1194 try_begin: 1195 throw a0 1196 try_end: 1197 ldai 2 1198 return 1199 .catchall try_begin, try_end, catch_begin 1200 } 1201 1202 .function i32 main() { 1203 newobj v1, E1 1204 call.short foo, v1 1205 return 1206 1207 1208 - file-name: "cflow_fallthrough4_pa" 1209 description: "Check that the verifier prohibits an close-ended exception handler at the beginning of a function." 1210 isa: 1211 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1212 header-template: ['pandasm_header'] 1213 runner-options: ['verifier-failure', 'verifier-config'] 1214 tags: ['verifier'] 1215 bugid: ['8029'] 1216 ignore: true 1217 check-type: none 1218 code-template: | 1219 1220 .function i32 foo(E1 a0) { 1221 catch_begin: 1222 ldai 0 1223 return 1224 catch_end: 1225 try_begin: 1226 throw a0 1227 try_end: 1228 ldai 2 1229 return 1230 .catchall try_begin, try_end, catch_begin, catch_end 1231 } 1232 1233 .function i32 main() { 1234 newobj v1, E1 1235 call.short foo, v1 1236 return 1237 1238 1239 - file-name: "cflow_fallthrough5_pa" 1240 description: "Check that the verifier prohibits a fallthrough from one handler to the beginning of another exception handler." 1241 isa: 1242 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1243 header-template: ['pandasm_header'] 1244 runner-options: ['verifier-failure', 'verifier-config'] 1245 tags: ['verifier'] 1246 check-type: none 1247 code-template: | 1248 1249 .function i32 foo(E1 a0) { 1250 throw a0 1251 } 1252 1253 .function i32 main() { 1254 try_begin: 1255 newobj v1, E1 1256 lda.obj v1 1257 jeqz.obj fail 1258 throw v1 1259 fail: 1260 ldai 1 1261 return 1262 try_end: 1263 catch_E1: 1264 ldai 2 1265 %s 1266 catch_all: 1267 ldai 3 1268 return 1269 exit: 1270 ldai 4 1271 return 1272 .catch E1, try_begin, try_end, catch_E1 1273 .catchall try_begin, try_end, catch_all 1274 cases: 1275 - values: 1276 - '' 1277 - values: 1278 - call.short foo, v1 1279 - values: 1280 - jmp catch_all 1281 - values: 1282 - jnez.obj exit 1283 - values: 1284 - return 1285 runner-options: ['verifier-only', 'verifier-config'] 1286 - values: 1287 - jmp exit 1288 runner-options: ['verifier-only', 'verifier-config'] 1289 - values: 1290 - throw v1 1291 runner-options: ['verifier-only', 'verifier-config'] 1292 1293 1294 - file-name: "cflow_fallthrough6_pa" 1295 description: "Check that the verifier prohibits a fallthrough from one handler to the beginning of another exception handler." 1296 isa: 1297 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1298 header-template: ['pandasm_header'] 1299 runner-options: ['verifier-failure', 'verifier-config'] 1300 tags: ['verifier'] 1301 check-type: none 1302 code-template: | 1303 1304 .function i32 foo(E1 a0) { 1305 throw a0 1306 } 1307 1308 .function i32 main() { 1309 try_begin: 1310 newobj v1, E1 1311 lda.obj v1 1312 throw v1 1313 try_end: 1314 ldai 1 1315 return 1316 catch_E1: 1317 ldai 2 1318 %s 1319 catch_E1_end: 1320 catch_all: 1321 ldai 3 1322 return 1323 catch_all_end: 1324 exit: 1325 ldai 4 1326 return 1327 .catch E1, try_begin, try_end, catch_E1, catch_E1_end 1328 .catchall try_begin, try_end, catch_all, catch_all_end 1329 cases: 1330 - values: 1331 - '' 1332 - values: 1333 - call.short foo, v1 1334 - values: 1335 - jmp catch_all 1336 - values: 1337 - jnez.obj exit 1338 - values: 1339 - return 1340 runner-options: ['verifier-only', 'verifier-config'] 1341 - values: 1342 - jmp exit 1343 runner-options: ['verifier-only', 'verifier-config'] 1344 - values: 1345 - throw v1 1346 runner-options: ['verifier-only', 'verifier-config'] 1347 1348 1349 - file-name: "cflow_jump1_pa" 1350 description: "Check that the verifier prohibits a jump from code into an open-ended exception handler." 1351 isa: 1352 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1353 header-template: ['pandasm_header'] 1354 tags: ['verifier'] 1355 check-type: none 1356 code-template: | 1357 1358 .function i32 main() { 1359 newobj v1, E1 1360 lda.obj v1 1361 %s 1362 try_begin: 1363 throw v1 1364 try_end: 1365 catch_all: 1366 isinstance E1 1367 catch_fail: 1368 ldai 1 1369 return 1370 catch_ok: 1371 ldai 0 1372 return 1373 .catchall try_begin, try_end, catch_all 1374 cases: 1375 - values: 1376 - '' 1377 runner-options: ['verifier-only', 'verifier-config'] 1378 - values: 1379 - jmp catch_all 1380 runner-options: ['verifier-failure', 'verifier-config'] 1381 - values: 1382 - jmp catch_fail 1383 runner-options: ['verifier-only', 'verifier-config'] 1384 - values: 1385 - jmp catch_ok 1386 runner-options: ['verifier-only', 'verifier-config'] 1387 - values: 1388 - jeqz.obj catch_all 1389 runner-options: ['verifier-failure', 'verifier-config'] 1390 - values: 1391 - jeqz.obj catch_fail 1392 runner-options: ['verifier-only', 'verifier-config'] 1393 - values: 1394 - jeqz.obj catch_ok 1395 runner-options: ['verifier-only', 'verifier-config'] 1396 1397 1398 - file-name: "cflow_jump2_pa" 1399 description: "Check that the verifier prohibits a jump from code into a close-ended exception handler." 1400 isa: 1401 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1402 header-template: ['pandasm_header'] 1403 tags: ['verifier'] 1404 check-type: none 1405 code-template: | 1406 1407 .function i32 main() { 1408 newobj v1, E1 1409 lda.obj v1 1410 %s 1411 try_begin: 1412 throw v1 1413 try_end: 1414 catch_begin: 1415 isinstance E1 1416 catch_fail: 1417 ldai 1 1418 return 1419 catch_ok: 1420 ldai 0 1421 return 1422 catch_end: 1423 .catchall try_begin, try_end, catch_begin, catch_end 1424 cases: 1425 - values: 1426 - '' 1427 runner-options: ['verifier-only', 'verifier-config'] 1428 - values: 1429 - jmp catch_begin 1430 runner-options: ['verifier-failure', 'verifier-config'] 1431 - values: 1432 - jmp catch_fail 1433 runner-options: ['verifier-failure', 'verifier-config'] 1434 - values: 1435 - jmp catch_ok 1436 runner-options: ['verifier-failure', 'verifier-config'] 1437 - values: 1438 - jeqz.obj catch_begin 1439 runner-options: ['verifier-failure', 'verifier-config'] 1440 - values: 1441 - jeqz.obj catch_fail 1442 runner-options: ['verifier-failure', 'verifier-config'] 1443 - values: 1444 - jeqz.obj catch_ok 1445 runner-options: ['verifier-failure', 'verifier-config'] 1446 1447 1448 - file-name: "cflow_jump3_pa" 1449 description: "Check that the verifier prohibits a jump from try block into a open-ended exception handler." 1450 isa: 1451 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1452 header-template: ['pandasm_header'] 1453 tags: ['verifier'] 1454 check-type: none 1455 code-template: | 1456 1457 .function i32 main() { 1458 try_begin: 1459 newobj v1, E1 1460 lda.obj v1 1461 %s 1462 throw v1 1463 try_end: 1464 catch_begin: 1465 isinstance E1 1466 catch_fail: 1467 ldai 1 1468 return 1469 catch_ok: 1470 ldai 0 1471 return 1472 .catchall try_begin, try_end, catch_begin 1473 cases: 1474 - values: 1475 - '' 1476 runner-options: ['verifier-only', 'verifier-config'] 1477 - values: 1478 - jmp catch_begin 1479 runner-options: ['verifier-failure', 'verifier-config'] 1480 - values: 1481 - jmp catch_fail 1482 runner-options: ['verifier-only', 'verifier-config'] 1483 - values: 1484 - jmp catch_ok 1485 runner-options: ['verifier-only', 'verifier-config'] 1486 - values: 1487 - jeqz.obj catch_begin 1488 runner-options: ['verifier-failure', 'verifier-config'] 1489 - values: 1490 - jeqz.obj catch_fail 1491 runner-options: ['verifier-only', 'verifier-config'] 1492 - values: 1493 - jeqz.obj catch_ok 1494 runner-options: ['verifier-only', 'verifier-config'] 1495 1496 1497 - file-name: "cflow_jump4_pa" 1498 description: "Check that the verifier prohibits a jump from try block into a close-ended exception handler." 1499 isa: 1500 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1501 header-template: ['pandasm_header'] 1502 tags: ['verifier'] 1503 check-type: none 1504 code-template: | 1505 1506 .function i32 main() { 1507 try_begin: 1508 newobj v1, E1 1509 lda.obj v1 1510 %s 1511 throw v1 1512 try_end: 1513 catch_begin: 1514 isinstance E1 1515 catch_fail: 1516 ldai 1 1517 return 1518 catch_ok: 1519 ldai 0 1520 return 1521 catch_end: 1522 .catchall try_begin, try_end, catch_begin, catch_end 1523 cases: 1524 - values: 1525 - '' 1526 runner-options: ['verifier-only', 'verifier-config'] 1527 - values: 1528 - jmp catch_begin 1529 runner-options: ['verifier-failure', 'verifier-config'] 1530 - values: 1531 - jmp catch_fail 1532 runner-options: ['verifier-failure', 'verifier-config'] 1533 - values: 1534 - jmp catch_ok 1535 runner-options: ['verifier-failure', 'verifier-config'] 1536 - values: 1537 - jeqz.obj catch_begin 1538 runner-options: ['verifier-failure', 'verifier-config'] 1539 - values: 1540 - jeqz.obj catch_fail 1541 runner-options: ['verifier-failure', 'verifier-config'] 1542 - values: 1543 - jeqz.obj catch_ok 1544 runner-options: ['verifier-failure', 'verifier-config'] 1545 1546 1547 - file-name: "cflow_jump5_pa" 1548 description: "Check that the verifier prohibits a jump from exception handler to another open-ended exception handler." 1549 isa: 1550 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1551 header-template: ['pandasm_header'] 1552 tags: ['verifier'] 1553 check-type: none 1554 code-template: | 1555 1556 .function i32 main() { 1557 newobj v1, E1 1558 lda.obj v1 1559 try_begin: 1560 throw v1 1561 try_end: 1562 catch_E1: 1563 %s 1564 ldai 0 1565 return 1566 catch_all: 1567 ldai 2 1568 fail: 1569 return 1570 .catch E1, try_begin, try_end, catch_E1 1571 .catchall try_begin, try_end, catch_all 1572 cases: 1573 - values: 1574 - '' 1575 runner-options: ['verifier-only', 'verifier-config'] 1576 - values: 1577 - jmp catch_all 1578 runner-options: ['verifier-failure', 'verifier-config'] 1579 - values: 1580 - jmp fail 1581 runner-options: ['verifier-only', 'verifier-config'] 1582 - values: 1583 - jeqz.obj catch_all 1584 runner-options: ['verifier-failure', 'verifier-config'] 1585 - values: 1586 - jeqz.obj fail 1587 runner-options: ['verifier-only', 'verifier-config'] 1588 - values: 1589 - | 1590 # 1591 isinstance E1 1592 jnez e1_ok 1593 ldai 1 1594 return 1595 e1_ok: 1596 runner-options: ['verifier-only', 'verifier-config'] 1597 1598 1599 - file-name: "cflow_jump6_pa" 1600 description: "Check that the verifier prohibits a jump from exception handler to another close-ended exception handler." 1601 isa: 1602 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1603 header-template: ['pandasm_header'] 1604 tags: ['verifier'] 1605 check-type: none 1606 code-template: | 1607 1608 .function i32 main() { 1609 newobj v1, E1 1610 lda.obj v1 1611 try_begin: 1612 throw v1 1613 try_end: 1614 catch_E1: 1615 %s 1616 ldai 0 1617 return 1618 catch_E1_end: 1619 catch_all: 1620 ldai 2 1621 fail: 1622 return 1623 catch_all_end: 1624 .catch E1, try_begin, try_end, catch_E1, catch_E1_end 1625 .catchall try_begin, try_end, catch_all, catch_all_end 1626 cases: 1627 - values: 1628 - '' 1629 runner-options: ['verifier-only', 'verifier-config'] 1630 - values: 1631 - jmp catch_all 1632 runner-options: ['verifier-failure', 'verifier-config'] 1633 - values: 1634 - jmp fail 1635 runner-options: ['verifier-failure', 'verifier-config'] 1636 - values: 1637 - jeqz.obj catch_all 1638 runner-options: ['verifier-failure', 'verifier-config'] 1639 - values: 1640 - jeqz.obj fail 1641 runner-options: ['verifier-failure', 'verifier-config'] 1642 - values: 1643 - | 1644 # 1645 isinstance E1 1646 jnez e1_ok 1647 ldai 1 1648 return 1649 e1_ok: 1650 runner-options: ['verifier-only', 'verifier-config'] 1651 bugid: ['8025'] 1652 ignore: true 1653 1654 1655 - file-name: "cflow_jump7_pa" 1656 description: "Check that the verifier prohibits a jump from a handler into a try block." 1657 isa: 1658 description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. 1659 header-template: ['pandasm_header'] 1660 tags: ['verifier'] 1661 check-type: none 1662 code-template: | 1663 1664 .function i32 main() { 1665 try_begin: 1666 newobj v1, E1 1667 throw v1 1668 try_mid: 1669 ldai 1 1670 return 1671 try_end: 1672 catch_all: 1673 %s 1674 catch_all_end: 1675 .catchall try_begin, try_end, catch_all, catch_all_end 1676 cases: 1677 - values: 1678 - '' 1679 runner-options: ['verifier-failure', 'verifier-config'] 1680 - values: 1681 - | 1682 # 1683 ldai 0 1684 return 1685 runner-options: ['verifier-only', 'verifier-config'] 1686 - values: 1687 - jmp try_begin 1688 runner-options: ['verifier-failure', 'verifier-config'] 1689 bugid: ['8032'] 1690 ignore: true 1691 - values: 1692 - jmp try_mid 1693 runner-options: ['verifier-failure', 'verifier-config'] 1694 bugid: ['8032'] 1695 ignore: true 1696