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 16 template: > 17 .language PandaAssembly 18 - name: r_A 19 template: | 20 .record A {} 21 22 .function void A.constructor(A a0) <ctor> { 23 return.void 24 } 25 - name: r_R 26 template: | 27 # Record to test 28 .record R { 29 i32 fi32 30 i64 fi64 31 f64 ff64 32 panda.String[] fstr 33 panda.Object[] faPO 34 i32[] fai32 35 i64[] fai64 36 f64[] faf64 37 } 38 - name: r_RJ 39 template: | 40 # Record to test 41 .record R { 42 i32 fi32 43 i64 fi64 44 f64 ff64 45 panda.String[] fstr 46 panda.Object[] faPO 47 i32[] fai32 48 i64[] fai64 49 f64[] faf64 50 } 51 - name: NPE 52 template: | 53 .record panda.NullPointerException <external> 54 - name: j_NPE 55 template: | 56 .record panda.NullPointerException <external> 57 - name: AME 58 template: | 59 .record panda.AbstractMethodError <external> 60 .record panda.Class <external> 61 - name: j_AME 62 template: | 63 .record panda.AbstractMethodError <external> 64 .record panda.Class <external> 65tests: 66 - file-name: call.virt.short 67 isa: 68 instructions: 69 - sig: call.virt.short method_id, v1:in:top, v2:in:top 70 acc: out:top 71 format: [op_v1_4_v2_4_id_16] 72 title: Object calls 73 description: > 74 Call indicated object method, i.e. create new frame, pass values of arguments and 75 continue execution from the first instruction of a method. 76 Callee should treat accumulator value as undefined and cannot use it until accumulator 77 definition in the new frame. 78 Result (if any) is returned in accumulator (see 'Calling sequence' chapter for more details). 79 Method, its class and the number of argument is resolved by given method_id in runtime 80 constant-pool based on object reference using language-specific semantics (currently only PandaAssembly 81 virtual methods are supported, further extensions are TBD). 82 Object reference is passed in the first source register, arguments are passed starting from 83 the second source register in the same order as in method signature. 84 Non-range instructions can be used to pass up to 4 arguments (including object reference). 85 Unused register slot values will be discarded and corresponding registers will not be 86 passed to the callee). 87 For methods with more arguments range kinds of instruction are to be used, which takes 88 the needed number of arguments starting from 'vs' register (including object reference). 89 verification: 90 - method_id_non_static 91 - compatible_arguments 92 - method_id_accessible 93 exceptions: 94 - x_null 95 - x_abstract 96 commands: 97 - file-name: method_call 98 isa: 99 instructions: 100 - sig: call.virt.short method_id, v1:in:top, v2:in:top 101 acc: out:top 102 format: [op_v1_4_v2_4_id_16] 103 header-template: [r_A] 104 description: > 105 Invoke virtual method with different amount (0 or 1) and type of argument. Primitives and reference types are used as second argument. 106 Check return value. 107 tags: ['tsan'] 108 code-template: | 109 *s 110 .function %s A.foo(A a0*s) { 111 %s 112 } 113 114 .function i32 main() { 115 initobj.short A.constructor 116 sta.obj v0 117 *s 118 call.virt.short A.foo, v0*s 119 %s 120 template-cases: 121 - values: 122 - i32 123 - | 124 # 125 ldai 123456789 126 return 127 - | 128 # 129 movi v0, 123456789 130 jne v0, exit_failure 131 ldai 0 132 return 133 exit_failure: 134 ldai 1 135 return 136 - values: 137 - i64 138 - | 139 # 140 ldai.64 123456789 141 return.64 142 - | 143 # 144 movi.64 v0, 123456789 145 cmp.64 v0 146 jnez exit_failure 147 ldai 0 148 return 149 exit_failure: 150 ldai 1 151 return 152 - values: 153 - f64 154 - | 155 # 156 fldai.64 1234567.89 157 return.64 158 - | 159 # 160 fmovi.64 v0, 1234567.89 161 fcmpg.64 v0 162 jnez exit_failure 163 ldai 0 164 return 165 exit_failure: 166 ldai 1 167 return 168 check-type: none 169 cases: 170 - values: 171 - '' 172 - '' 173 - '' 174 - '' 175 - values: 176 - '' 177 - ',i32 a1' 178 - 'movi v1, 123' 179 - ', v1' 180 - values: 181 - '' 182 - ',i32[] a1' 183 - | 184 # 185 movi v1, 123 186 newarr v1, v1, i32[] 187 - ', v1' 188 - values: 189 - '' 190 - ',i64 a1' 191 - 'movi.64 v1, 123' 192 - ', v1' 193 - values: 194 - '' 195 - ',i64[] a1' 196 - | 197 # 198 movi v1, 123 199 newarr v1, v1, i64[] 200 - ', v1' 201 - values: 202 - '' 203 - ',A a1' 204 - | 205 # 206 initobj.short A.constructor 207 sta.obj v1 208 - ', v1' 209 - values: 210 - '' 211 - ',A[] a1' 212 - | 213 # 214 movi v1, 123 215 newarr v1, v1, A[] 216 - ', v1' 217 218 - values: 219 - '' 220 - ',f64 a1' 221 - 'fmovi.64 v1, 123.321' 222 - ', v1' 223 - values: 224 - '' 225 - ',f64[] a1' 226 - | 227 # 228 movi v1, 123 229 newarr v1, v1, f64[] 230 - ', v1' 231 - values: 232 - '.record panda.String <external>' 233 - ',panda.String a1' 234 - | 235 # 236 lda.str "some string" 237 sta.obj v1 238 - ', v1' 239 - values: 240 - '.record panda.String <external>' 241 - ',panda.String[] a1' 242 - | 243 # 244 movi v1, 123 245 newarr v1, v1, panda.String[] 246 - ', v1' 247 248 - values: 249 - '.record panda.Object <external>' 250 - ',panda.Object[] a1' 251 - | 252 # 253 movi v1, 123 254 newarr v1, v1, panda.Object[] 255 - ', v1' 256 - values: 257 - '.record panda.Object <external>' 258 - ',panda.Object[] a1' 259 - 'mov.null v1' 260 - ', v1' 261 262 - values: 263 - '.record panda.Object <external>' 264 - ',panda.Object a1' 265 - | 266 # 267 mov.null v1 268 - ', v1' 269 270 - file-name: p_method_call_args 271 isa: 272 instructions: 273 - sig: call.virt.short method_id, v1:in:top, v2:in:top 274 acc: out:top 275 format: [op_v1_4_v2_4_id_16] 276 header-template: [xorshift32, r_R] 277 description: > 278 Invoke virtual method with different pseudo-random values and check if correct value is stored in object field. Check i32, i64, f64 and reference types. 279 Use PandaAssembly language context. 280 tags: ['tsan', 'irtoc_ignore'] 281 code-template: | 282 .record panda.String <external> 283 .record panda.Object <external> 284 285 .function void R.constructor(R a0) <ctor> { 286 return.void 287 } 288 289 .function void R.storeValue(R a0, %s a1) { 290 lda%s a1 291 stobj%s a0, R.%s 292 return.void 293 } 294 295 .function i32 main() { 296 # Create R object 297 initobj.short R.constructor 298 # Keep them in v0 299 sta.obj v0 300 # Iterations 301 movi v2, 10 302 # Start value 303 movi v3, *s 304 305 loop: 306 %s 307 inci v2, -1 308 lda v2 309 jnez loop 310 ldai 0 311 return 312 exit_err: 313 ldai 1 314 return 315 check-type: none 316 template-cases: 317 - values: 318 - i32 319 - '' 320 - '' 321 - fi32 322 - | 323 # Get next random number 324 call.short nextRand, v3 325 sta v3 326 # Store in object 327 call.virt.short R.storeValue, v0, v3 328 # Get object field 329 ldobj v0, R.fi32 330 # Compare field value 331 jne v3, exit_err 332 - values: 333 - i32[] 334 - '.obj' 335 - '.obj' 336 - fai32 337 - | 338 # Get next random number 339 call.short nextRand, v3 340 sta v3 341 andi 0x7f 342 sta v4 343 newarr v4, v4, i32[] 344 # Store in object 345 call.virt.short R.storeValue, v0, v4 346 # Get object field 347 ldobj.obj v0, R.fai32 348 # Compare field value 349 jne.obj v4, exit_err 350 - values: 351 - i64 352 - '.64' 353 - '.64' 354 - fi64 355 - | 356 # Get next random number 357 call.short nextRand, v3 358 sta v3 359 # Convert to i64 to get high 32 bits 360 u32toi64 361 movi.64 v5, 32 362 shl2.64 v5 363 sta.64 v5 364 # Get next random 365 call.short nextRand, v3 366 sta v3 367 # Convert to i64 to get lowest 32 bits 368 u32toi64 369 or2.64 v5 370 sta.64 v4 371 # Store in object 372 call.virt.short R.storeValue, v0, v4 373 # Get object field value 374 ldobj.64 v0, R.fi64 375 # Compare field value 376 cmp.64 v4 377 jnez exit_err 378 - values: 379 - i64[] 380 - '.obj' 381 - '.obj' 382 - fai64 383 - | 384 # Get next random number 385 call.short nextRand, v3 386 sta v3 387 andi 0xff 388 sta v4 389 newarr v4, v4, i64[] 390 # Store in object 391 call.virt.short R.storeValue, v0, v4 392 # Get object field 393 ldobj.obj v0, R.fai64 394 # Compare field value 395 jne.obj v4, exit_err 396 - values: 397 - f64 398 - '.64' 399 - '.64' 400 - ff64 401 - | 402 # 403 call.short nextRand, v3 404 sta v3 405 u32toi64 406 movi.64 v5, 32 407 shl2.64 v5 408 sta.64 v5 409 call.short nextRand, v3 410 sta v3 411 u32toi64 412 or2.64 v5 413 sta.64 v4 414 lda.64 v4 415 # Conver i64 to f64 to check f64 value passed to virtual function. 416 i64tof64 417 sta.64 v4 418 call.virt.short R.storeValue, v0, v4 419 ldobj.64 v0, R.ff64 420 fcmpg.64 v4 421 jnez exit_err 422 - values: 423 - f64[] 424 - '.obj' 425 - '.obj' 426 - faf64 427 - | 428 # Get next random number 429 call.short nextRand, v3 430 sta v3 431 andi 0xff 432 sta v4 433 newarr v4, v4, f64[] 434 # Store in object 435 call.virt.short R.storeValue, v0, v4 436 # Get object field 437 ldobj.obj v0, R.faf64 438 # Compare field value 439 jne.obj v4, exit_err 440 - values: 441 - panda.Object[] 442 - '.obj' 443 - '.obj' 444 - faPO 445 - | 446 # Get next random number 447 call.short nextRand, v3 448 sta v3 449 andi 0x7f 450 sta v4 451 newarr v4, v4, panda.Object[] 452 # Store in object 453 call.virt.short R.storeValue, v0, v4 454 # Get object field 455 ldobj.obj v0, R.faPO 456 # Compare field value 457 jne.obj v4, exit_err 458 - values: 459 - panda.String[] 460 - '.obj' 461 - '.obj' 462 - fstr 463 - | 464 # Get next random number 465 call.short nextRand, v3 466 sta v3 467 andi 0x7f 468 sta v4 469 newarr v4, v4, panda.String[] 470 # Store in object 471 472 call.virt.short R.storeValue, v0, v4 473 # Get object field 474 ldobj.obj v0, R.fstr 475 # Compare field value 476 jne.obj v4, exit_err 477 cases: 478 - values: 479 - "0xBADC0FFE" 480 - values: 481 - "0x12345678" 482 - values: 483 - "0xFEDCBA98" 484 - values: 485 - "1" 486 - values: 487 - "0xFFFFFFFF" 488 - values: 489 - "0x80000000" 490 - values: 491 - "0x7FFFFFFF" 492 493 - file-name: j_method_call_args 494 isa: 495 instructions: 496 - sig: call.virt.short method_id, v1:in:top, v2:in:top 497 acc: out:top 498 format: [op_v1_4_v2_4_id_16] 499 runner-options: [use-pa] 500 tags: ['irtoc_ignore'] 501 header-template: [PandaAssembly, xorshift32, r_RJ] 502 description: > 503 Invoke virtual method with different pseudo-random values and check if correct value is stored in object field. Check i32, i64, f64 and reference types. 504 Use PandaAssembly language context. 505 code-template: | 506 .record panda.String <external> 507 .record panda.Object <external> 508 509 .record S<panda.extends=R> {} 510 511 .function void R.constructor(R a0) <ctor> { 512 return.void 513 } 514 515 .function void S.constructor(S a0) <ctor> { 516 return.void 517 } 518 519 .function void R.storeValue(R a0, %s a1) <noimpl> 520 521 .function void S.storeValue(S a0, %s a1) { 522 lda%s a1 523 stobj%s a0, R.%s 524 return.void 525 } 526 527 .function i32 main() { 528 # Create S object 529 initobj.short S.constructor 530 # Keep them in v0 531 sta.obj v0 532 # Iterations 533 movi v2, 10 534 # Start value 535 movi v3, *s 536 537 loop: 538 %s 539 inci v2, -1 540 lda v2 541 jnez loop 542 ldai 0 543 return 544 exit_err: 545 ldai 1 546 return 547 check-type: none 548 549 template-cases: 550 - values: 551 - i32 552 - i32 553 - '' 554 - '' 555 - fi32 556 - | 557 # Get next random number 558 call.short nextRand, v3 559 sta v3 560 # Store in object 561 call.virt.short %s.storeValue, v0, v3 562 # Get object field 563 ldobj v0, R.fi32 564 # Compare field value 565 jne v3, exit_err 566 - values: 567 - i32[] 568 - i32[] 569 - '.obj' 570 - '.obj' 571 - fai32 572 - | 573 # Get next random number 574 call.short nextRand, v3 575 sta v3 576 andi 0xff 577 sta v4 578 newarr v4, v4, i32[] 579 # Store in object 580 call.virt.short %s.storeValue, v0, v4 581 # Get object field 582 ldobj.obj v0, R.fai32 583 # Compare field value 584 jne.obj v4, exit_err 585 - values: 586 - i64 587 - i64 588 - '.64' 589 - '.64' 590 - fi64 591 - | 592 # Get next random number 593 call.short nextRand, v3 594 sta v3 595 # Convert to i64 to get high 32 bits 596 u32toi64 597 movi.64 v5, 32 598 shl2.64 v5 599 sta.64 v5 600 # Get next random 601 call.short nextRand, v3 602 sta v3 603 # Convert to i64 to get lowest 32 bits 604 u32toi64 605 or2.64 v5 606 sta.64 v4 607 # Store in object 608 call.virt.short %s.storeValue, v0, v4 609 # Get object field value 610 ldobj.64 v0, R.fi64 611 # Compare field value 612 cmp.64 v4 613 jnez exit_err 614 - values: 615 - i64[] 616 - i64[] 617 - '.obj' 618 - '.obj' 619 - fai64 620 - | 621 # Get next random number 622 call.short nextRand, v3 623 sta v4 624 andi 0x7f 625 sta v4 626 newarr v4, v4, i64[] 627 # Store in object 628 call.virt.short %s.storeValue, v0, v4 629 # Get object field 630 ldobj.obj v0, R.fai64 631 # Compare field value 632 jne.obj v4, exit_err 633 - values: 634 - f64 635 - f64 636 - '.64' 637 - '.64' 638 - ff64 639 - | 640 # 641 call.short nextRand, v3 642 sta v3 643 u32toi64 644 movi.64 v5, 32 645 shl2.64 v5 646 sta.64 v5 647 call.short nextRand, v3 648 sta v3 649 u32toi64 650 or2.64 v5 651 sta.64 v4 652 lda.64 v4 653 # Conver i64 to f64 to check f64 value passed to virtual function. 654 i64tof64 655 sta.64 v4 656 call.virt.short %s.storeValue, v0, v4 657 ldobj.64 v0, R.ff64 658 fcmpg.64 v4 659 jnez exit_err 660 - values: 661 - f64[] 662 - f64[] 663 - '.obj' 664 - '.obj' 665 - faf64 666 - | 667 # Get next random number 668 call.short nextRand, v3 669 sta v3 670 andi 0x7f 671 sta v4 672 newarr v4, v4, f64[] 673 # Store in object 674 call.virt.short %s.storeValue, v0, v4 675 # Get object field 676 ldobj.obj v0, R.faf64 677 # Compare field value 678 jne.obj v4, exit_err 679 - values: 680 - panda.Object[] 681 - panda.Object[] 682 - '.obj' 683 - '.obj' 684 - faPO 685 - | 686 # Get next random number 687 call.short nextRand, v3 688 sta v3 689 andi 0x7f 690 sta v4 691 newarr v4, v4, panda.Object[] 692 # Store in object 693 call.virt.short %s.storeValue, v0, v4 694 # Get object field 695 ldobj.obj v0, R.faPO 696 # Compare field value 697 jne.obj v4, exit_err 698 - values: 699 - panda.String[] 700 - panda.String[] 701 - '.obj' 702 - '.obj' 703 - fstr 704 - | 705 # Get next random number 706 call.short nextRand, v3 707 sta v3 708 andi 0x7f 709 sta v4 710 newarr v4, v4, panda.String[] 711 # Store in object 712 713 call.virt.short %s.storeValue, v0, v4 714 # Get object field 715 ldobj.obj v0, R.fstr 716 # Compare field value 717 jne.obj v4, exit_err 718 cases: 719 - values: 720 - "0xBADC0FFE" 721 - "R" 722 description: Call using parent object method. 723 - values: 724 - "0xBADC0FFE" 725 - "S" 726 description: Call using current object method. 727 - values: 728 - "0x12345678" 729 - "R" 730 description: Call using parent object method. 731 - values: 732 - "0x12345678" 733 - "S" 734 description: Call using current object method. 735 - values: 736 - "0xFEDCBA98" 737 - "R" 738 description: Call using parent object method. 739 - values: 740 - "0xFEDCBA98" 741 - "S" 742 description: Call using current object method. 743 - values: 744 - "1" 745 - "R" 746 description: Call using parent object method. 747 - values: 748 - "1" 749 - "S" 750 description: Call using current object method. 751 - values: 752 - "0xFFFFFFFF" 753 - "R" 754 description: Call using parent object method. 755 - values: 756 - "0xFFFFFFFF" 757 - "S" 758 description: Call using current object method. 759 - values: 760 - "0x80000000" 761 - "R" 762 description: Call using parent object method. 763 - values: 764 - "0x80000000" 765 - "S" 766 description: Call using current object method. 767 - values: 768 - "0x7FFFFFFF" 769 - "R" 770 description: Call using parent object method. 771 - values: 772 - "0x7FFFFFFF" 773 - "S" 774 description: Call using current object method. 775 776 - file-name: restore_register 777 isa: 778 instructions: 779 - sig: call.virt.short method_id, v1:in:top, v2:in:top 780 acc: out:top 781 format: [op_v1_4_v2_4_id_16] 782 header-template: [r_A] 783 description: > 784 Invoke virtual method and check if registers after calling is restored. 785 code-template: | 786 .function void A.foo(A a0) { 787 %s 788 lda.null 789 sta.obj v0 790 mov.obj v256, v0 791 return.void 792 } 793 794 .function i32 main() { 795 initobj.short A.constructor 796 sta.obj v0 797 %s 798 mov%s v256, %s 799 call.virt.short A.foo, v0 800 mov%s v100, v256 801 lda%s v100 802 %s 803 cases: 804 - values: 805 - 'movi v1, 123' 806 - 'movi v1, 321' 807 - '' 808 - 'v1' 809 - '' 810 - '' 811 - | 812 # 813 jne v1, set_failure 814 ldai 0 815 jmp done 816 set_failure: 817 ldai 1 818 done: 819 - values: 820 - 'movi.64 v8, 123' 821 - 'movi v8, 321' 822 - '' 823 - 'v8' 824 - '' 825 - '' 826 - | 827 # 828 jne v8, set_failure 829 ldai 0 830 jmp done 831 set_failure: 832 ldai 1 833 done: 834 - values: 835 - 'fmovi.64 v16, 123' 836 - 'movi v16, 321' 837 - '' 838 - 'v16' 839 - '' 840 - '' 841 - | 842 # 843 jne v16, set_failure 844 ldai 0 845 jmp done 846 set_failure: 847 ldai 1 848 done: 849 - values: 850 - 'mov.null v128' 851 - 'movi v128, 321' 852 - '' 853 - 'v128' 854 - '' 855 - '' 856 - | 857 # 858 jne v128, set_failure 859 ldai 0 860 jmp done 861 set_failure: 862 ldai 1 863 done: 864 - values: 865 - | 866 # 867 lda.str "123" 868 sta.obj v255 869 - 'movi v255, 321' 870 - '' 871 - 'v255' 872 - '' 873 - '' 874 - | 875 # 876 jne v255, set_failure 877 ldai 0 878 jmp done 879 set_failure: 880 ldai 1 881 done: 882 - values: ['movi v1, 123', 'movi.64 v1, 321', '.64', 'v1', '.64', '.64', 'cmp.64 v1'] 883 - values: ['movi.64 v8, 123', 'movi.64 v8, 321', '.64', 'v8', '.64', '.64', 'cmp.64 v8'] 884 - values: ['fmovi.64 v16, 123', 'movi.64 v16, 321', '.64', 'v16', '.64', '.64', 'cmp.64 v16'] 885 - values: ['mov.null v128', 'movi.64 v128, 321', '.64', 'v128', '.64', '.64', 'cmp.64 v128'] 886 - values: 887 - | 888 # 889 lda.str "123" 890 sta.obj v255 891 - 'movi.64 v255, 321' 892 - '.64' 893 - 'v255' 894 - '.64' 895 - '.64' 896 - 'cmp.64 v255' 897 - values: ['movi v1, 123', 'fmovi.64 v1, 321', '.64', 'v1', '.64', '.64', 'fcmpg.64 v1'] 898 - values: ['movi.64 v8, 123', 'fmovi.64 v8, 321', '.64', 'v8', '.64', '.64', 'fcmpg.64 v8'] 899 - values: ['fmovi.64 v16, 123', 'fmovi.64 v16, 321', '.64', 'v16', '.64', '.64', 'fcmpg.64 v16'] 900 - values: ['mov.null v128', 'fmovi.64 v128, 321', '.64', 'v128', '.64', '.64', 'fcmpg.64 v128'] 901 - values: 902 - | 903 # 904 lda.str "123" 905 sta.obj v255 906 - 'fmovi.64 v255, 321' 907 - '.64' 908 - 'v255' 909 - '.64' 910 - '.64' 911 - 'fcmpg.64 v255' 912 913 - file-name: regs 914 isa: 915 instructions: 916 - sig: call.virt.short method_id, v1:in:top, v2:in:top 917 acc: out:top 918 format: [op_v1_4_v2_4_id_16] 919 header-template: [r_A] 920 description: > 921 Check available registers number and registers width. 922 code-template: | 923 .function void A.foo(A a0%s) { 924 return.void 925 } 926 927 .function i32 main() { 928 call.virt.short A.foo, %s 929 } 930 check-type: empty 931 runner-options: [compile-only] 932 cases: 933 - values: ['', 'v0'] 934 - values: ['', 'v8'] 935 - values: ['', 'v15'] 936 - values: ['', 'v16'] 937 runner-options: [compile-failure] 938 - values: ['', '0'] 939 runner-options: [compile-failure] 940 - values: [',i32 a1', 'v0, v0'] 941 - values: [',i32 a1', 'v0, v8'] 942 - values: [',i32 a1', 'v0, v15'] 943 - values: [',i32 a1', 'v0, v16'] 944 runner-options: [compile-failure] 945 - values: [',i32 a1', 'v0, 0'] 946 runner-options: [compile-failure] 947 - values: [',i32 a1', 'v16, v0'] 948 runner-options: [compile-failure] 949 - values: [',i32 a1', 'v16, v8'] 950 runner-options: [compile-failure] 951 - values: [',i32 a1', 'v16, v15'] 952 runner-options: [compile-failure] 953 - values: [',i32 a1', 'v16, v16'] 954 runner-options: [compile-failure] 955 - values: [',i32 a1', 'v16, 0'] 956 runner-options: [compile-failure] 957 - values: [',i32 a1', 'v15, v15'] 958 - values: [',i32 a1', 'v15, v16'] 959 runner-options: [compile-failure] 960 - values: [',i32 a1', 'v15, 0'] 961 runner-options: [compile-failure] 962 - values: [',i32 a1', '0, 0'] 963 runner-options: [compile-failure] 964 - values: [',i32 a1, i32 a2', 'v0, v0, v0'] 965 runner-options: [compile-failure] 966 - values: [',i32 a1, i32 a2', 'v0, v0, v15'] 967 runner-options: [compile-failure] 968 - values: [',i32 a1, i32 a2', 'v0, v15, v16'] 969 runner-options: [compile-failure] 970 - values: [',i32 a1, i32 a2', 'v15, v16, v16'] 971 runner-options: [compile-failure] 972 - values: [',i32 a1, i32 a2', 'v16, v16, 0'] 973 runner-options: [compile-failure] 974 - values: [',i32 a1, i32 a2', 'v16, 0, 0'] 975 runner-options: [compile-failure] 976 - values: [',i32 a1, i32 a2', '0, 0, 0'] 977 runner-options: [compile-failure] 978 979 - file-name: panda_npe 980 isa: 981 instructions: 982 - sig: call.virt.short method_id, v1:in:top, v2:in:top 983 acc: out:top 984 format: [op_v1_4_v2_4_id_16] 985 exceptions: 986 - x_null 987 header-template: [NPE] 988 tags: ['irtoc_ignore'] 989 description: > 990 Check incorrect usage of `call.virt.short` instruction. 991 Null reference usage causes to panda.NullPointerException. Method_id points to virtual method of base class. Use PandaAssembly language context. 992 code-template: | 993 %s 994 .record B {} 995 996 .function void B.constructor(B a0) <ctor> { 997 return.void 998 } 999 1000 .function i32 B.func(B a0%s) <noimpl> 1001 1002 .function i32 main() { 1003 mov.null v0 1004 %s 1005 begin: 1006 call.virt.short B.func, v0%s 1007 end: 1008 ldai 1 1009 return 1010 1011 catch_NPE: 1012 ldai 0 # Expected panda.NullPointerException 1013 return 1014 1015 catch_all: 1016 ldai 2 # Unexpected exception, test failed 1017 return 1018 1019 .catch panda.NullPointerException, begin, end, catch_NPE 1020 .catchall begin, end, catch_all 1021 1022 check-type: none 1023 cases: 1024 - values: 1025 - '' 1026 - '' 1027 - '' 1028 - '' 1029 - values: 1030 - '' 1031 - ', i32 a1' 1032 - 'movi v1, 0' 1033 - ', v1' 1034 - values: 1035 - '' 1036 - ', i64 a1' 1037 - 'movi.64 v1, 0' 1038 - ', v1' 1039 - values: 1040 - '' 1041 - ', f64 a1' 1042 - 'fmovi.64 v1, 0' 1043 - ', v1' 1044 - values: 1045 - '' 1046 - ', B a1' 1047 - | 1048 initobj B.constructor 1049 sta.obj v1 1050 - ', v1' 1051 - values: 1052 - '.record panda.String <external>' 1053 - ', panda.String a1' 1054 - | 1055 lda.str "some string" 1056 sta.obj v1 1057 - ', v1' 1058 1059 - values: 1060 - '.record panda.Class <external>' 1061 - ', panda.Class a1' 1062 - | 1063 # 1064 lda.type B 1065 sta.obj v1 1066 - ', v1' 1067 1068 - file-name: PandaAssembly_npe 1069 isa: 1070 instructions: 1071 - sig: call.virt.short method_id, v1:in:top, v2:in:top 1072 acc: out:top 1073 format: [op_v1_4_v2_4_id_16] 1074 exceptions: 1075 - x_null 1076 header-template: [PandaAssembly, j_NPE] 1077 runner-options: [use-pa] 1078 description: > 1079 Check incorrect usage of `call.virt.short` instruction. 1080 Null reference usage causes to panda.NullPointerException. Method_id points to virtual method of base class. Use PandaAssembly language context. 1081 tags: ['tsan', 'irtoc_ignore'] 1082 template-cases: 1083 - values: 1084 - | 1085 *s 1086 .record B {} 1087 1088 .function void B.constructor(B a0) <ctor> { 1089 return.void 1090 } 1091 1092 .function i32 B.func(B a0%s) <noimpl> 1093 ##- %s This line will be removed 1094 - values: 1095 - | 1096 *s 1097 .record A {} 1098 .record B <panda.extends=A> {} 1099 1100 .function void B.constructor(B a0) <ctor> { 1101 return.void 1102 } 1103 1104 .function i32 B.func(B a0*s) <noimpl> 1105 .function i32 A.func(B a0*s) <noimpl> 1106 - values: 1107 - | 1108 *s 1109 .record A {} 1110 .record C <panda.extends=A> {} 1111 .record B <panda.extends=C> {} 1112 1113 .function void B.constructor(B a0) <ctor> { 1114 return.void 1115 } 1116 1117 .function i32 B.func(B a0*s) <noimpl> 1118 .function i32 A.func(B a0*s) <noimpl> 1119 code-template: | 1120 %s 1121 1122 .function i32 main() { 1123 mov.null v0 1124 *s 1125 begin: 1126 call.virt.short B.func, v0*s 1127 end: 1128 ldai 1 1129 return 1130 1131 catch_NPE: 1132 ldai 0 # Expected panda.NullPointerException 1133 return 1134 1135 catch_all: 1136 ldai 2 # Unexpected exception, test failed 1137 return 1138 1139 .catch panda.NullPointerException, begin, end, catch_NPE 1140 .catchall begin, end, catch_all 1141 1142 check-type: none 1143 cases: 1144 - values: 1145 - '' 1146 - '' 1147 - '' 1148 - '' 1149 - '' 1150 - values: 1151 - '' 1152 - ', i32 a1' 1153 - ', i32 a1' 1154 - 'movi v1, 0' 1155 - ', v1' 1156 - values: 1157 - '' 1158 - ', i64 a1' 1159 - ', i64 a1' 1160 - 'movi.64 v1, 0' 1161 - ', v1' 1162 - values: 1163 - '' 1164 - ', f64 a1' 1165 - ', f64 a1' 1166 - 'fmovi.64 v1, 0' 1167 - ', v1' 1168 - values: 1169 - '' 1170 - ', B a1' 1171 - ', B a1' 1172 - | 1173 initobj B.constructor 1174 sta.obj v1 1175 - ', v1' 1176 - values: 1177 - '.record panda.String <external>' 1178 - ', panda.String a1' 1179 - ', panda.String a1' 1180 - | 1181 lda.str "some string" 1182 sta.obj v1 1183 - ', v1' 1184 1185 - values: 1186 - '.record panda.Object <external>' 1187 - ', panda.Object a1' 1188 - ', panda.Object a1' 1189 - | 1190 # 1191 lda.type B 1192 sta.obj v1 1193 - ', v1' 1194 1195 - file-name: panda_ame 1196 isa: 1197 instructions: 1198 - sig: call.virt.short method_id, v1:in:top, v2:in:top 1199 acc: out:top 1200 format: [op_v1_4_v2_4_id_16] 1201 exceptions: 1202 - x_abstract 1203 header-template: [AME] 1204 description: > 1205 Check incorrect usage of `call.virt.short` instruction. Call of abstract method, check if panda.AbstractMethodError is thrown. 1206 Use PandaAssembly language context. 1207 tags: ['tsan', 'irtoc_ignore'] 1208 code-template: | 1209 %s 1210 .record B {} 1211 1212 .function void B.constructor(B a0) <ctor> { 1213 return.void 1214 } 1215 1216 .function i32 B.func(B a0%s) <noimpl> 1217 1218 .function i32 main() { 1219 initobj.short B.constructor 1220 sta.obj v0 1221 %s 1222 begin: 1223 call.virt.short B.func, v0%s 1224 end: 1225 ldai 1 1226 return 1227 1228 catch_AME: 1229 ldai 0 # Expected panda.AbstractMethodError 1230 return 1231 1232 catch_all: 1233 ldai 2 # Unexpected exception, test failed 1234 return 1235 1236 .catch panda.AbstractMethodError, begin, end, catch_AME 1237 .catchall begin, end, catch_all 1238 1239 check-type: none 1240 cases: 1241 - values: 1242 - '' 1243 - '' 1244 - '' 1245 - '' 1246 - values: 1247 - '' 1248 - ', i32 a1' 1249 - 'movi v1, 0' 1250 - ', v1' 1251 - values: 1252 - '' 1253 - ', i64 a1' 1254 - 'movi.64 v1, 0' 1255 - ', v1' 1256 - values: 1257 - '' 1258 - ', f64 a1' 1259 - 'fmovi.64 v1, 0' 1260 - ', v1' 1261 - values: 1262 - '' 1263 - ', B a1' 1264 - | 1265 initobj.short B.constructor 1266 sta.obj v1 1267 - ', v1' 1268 - values: 1269 - '.record panda.String <external>' 1270 - ', panda.String a1' 1271 - | 1272 lda.str "some string" 1273 sta.obj v1 1274 - ', v1' 1275 1276 - values: 1277 - '' 1278 - ', panda.Class a1' 1279 - | 1280 # 1281 lda.type B 1282 sta.obj v1 1283 - ', v1' 1284 1285 - file-name: PandaAssembly_ame 1286 isa: 1287 instructions: 1288 - sig: call.virt.short method_id, v1:in:top, v2:in:top 1289 acc: out:top 1290 format: [op_v1_4_v2_4_id_16] 1291 exceptions: 1292 - x_abstract 1293 header-template: [PandaAssembly, j_AME] 1294 tags: ['irtoc_ignore'] 1295 description: > 1296 Check incorrect usage of `call.virt.short` instruction. Call of abstract method, check if panda.AbstractMethodError is thrown. 1297 Use PandaAssembly language context. 1298 runner-options: [use-pa] 1299 template-cases: 1300 - values: 1301 - | 1302 *s 1303 .record B {} 1304 1305 .function void B.constructor(B a0) <ctor> { 1306 return.void 1307 } 1308 1309 .function i32 B.func(B a0*s) <noimpl> 1310 - values: 1311 - | 1312 *s 1313 .record A {} 1314 .record B <panda.extends=A> {} 1315 1316 .function void B.constructor(B a0) <ctor> { 1317 return.void 1318 } 1319 1320 .function i32 B.func(B a0*s) <noimpl> 1321 - values: 1322 - | 1323 *s 1324 .record A {} 1325 .record C <panda.extends=A> {} 1326 .record B <panda.extends=C> {} 1327 1328 .function void B.constructor(B a0) <ctor> { 1329 return.void 1330 } 1331 1332 .function i32 B.func(B a0*s) <noimpl> 1333 1334 code-template: | 1335 %s 1336 1337 .function i32 main() { 1338 initobj.short B.constructor 1339 sta.obj v0 1340 *s 1341 begin: 1342 call.virt.short B.func, v0*s 1343 end: 1344 ldai 1 1345 return 1346 1347 catch_AME: 1348 ldai 0 # Expected panda.AbstractMethodError 1349 return 1350 1351 catch_all: 1352 ldai 2 # Unexpected exception, test failed 1353 return 1354 1355 .catch panda.AbstractMethodError, begin, end, catch_AME 1356 .catchall begin, end, catch_all 1357 1358 check-type: none 1359 cases: 1360 - values: 1361 - '' 1362 - '' 1363 - '' 1364 - '' 1365 - values: 1366 - '' 1367 - ', i32 a1' 1368 - 'movi v1, 0' 1369 - ', v1' 1370 - values: 1371 - '' 1372 - ', i64 a1' 1373 - 'movi.64 v1, 0' 1374 - ', v1' 1375 - values: 1376 - '' 1377 - ', f64 a1' 1378 - 'fmovi.64 v1, 0' 1379 - ', v1' 1380 - values: 1381 - '' 1382 - ', B a1' 1383 - | 1384 initobj.short B.constructor 1385 sta.obj v1 1386 - ', v1' 1387 - values: 1388 - '.record panda.String <external>' 1389 - ', panda.String a1' 1390 - | 1391 lda.str "some string" 1392 sta.obj v1 1393 - ', v1' 1394 - values: 1395 - '' 1396 - ', panda.Class a1' 1397 - | 1398 # 1399 lda.type B 1400 sta.obj v1 1401 - ', v1' 1402 1403 1404 - file-name: unused_regs 1405 isa: 1406 description: > 1407 Unused register slot values will be discarded and corresponding registers will not be 1408 passed to the callee). 1409 header-template: [] 1410 description: Verifier should ignore unused register slots. 1411 code-template: | 1412 .record A {} 1413 .function void A.ctor(A a0) <ctor> { 1414 return.void 1415 } 1416 .function i32 A.foo(A a0) { 1417 ldai 0 1418 return 1419 } 1420 .function i32 main() { 1421 initobj A.ctor 1422 sta.obj v5 1423 call.virt.short A.foo, v5, v4 1424 check-type: no-check 1425