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_B 26 template: | 27 .record B {} 28 29 .function void B.constructor(B a0) <ctor> { 30 return.void 31 } 32tests: 33 - file-name: call.virt.short.negative 34 isa: 35 instructions: 36 - sig: call.virt.short method_id, v1:in:top, v2:in:top 37 acc: out:top 38 format: [op_v1_4_v2_4_id_16] 39 title: Object calls 40 description: > 41 Call indicated object method, i.e. create new frame, pass values of arguments and 42 continue execution from the first instruction of a method. 43 Callee should treat accumulator value as undefined and cannot use it until accumulator 44 definition in the new frame. 45 Result (if any) is returned in accumulator (see 'Calling sequence' chapter for more details). 46 Method, its class and the number of argument is resolved by given method_id in runtime 47 constant-pool based on object reference using language-specific semantics (currently only PandaAssembly 48 virtual methods are supported, further extensions are TBD). 49 Object reference is passed in the first source register, arguments are passed starting from 50 the second source register in the same order as in method signature. 51 Non-range instructions can be used to pass up to 4 arguments (including object reference). 52 Unused register slot values will be discarded and corresponding registers will not be 53 passed to the callee). 54 For methods with more arguments range kinds of instruction are to be used, which takes 55 the needed number of arguments starting from 'vs' register (including object reference). 56 verification: 57 - method_id_non_static 58 - compatible_arguments 59 - method_id_accessible 60 exceptions: 61 - x_null 62 - x_abstract 63 commands: 64 65 - file-name: wrong_object_1 66 bugid: ['2287', '5271'] 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 verification: 73 - compatible_arguments 74 header-template: [r_A, r_B] 75 description: Check incorrect usage of `call.virt.short` instruction. First argument is of incorrect type instead of object reference. 76 runner-options: ['verifier-failure', 'verifier-config'] 77 tags: ['verifier'] 78 code-template: | 79 .function i32 A.foo(A a0%s) { 80 ldai 1 81 return 82 } 83 84 .function i32 main() { 85 %s 86 call.virt.short A.foo%s 87 # check object is equal to original 88 movi v0, 1 89 jne v0, exit_failure 90 ldai 0 91 return 92 exit_failure: 93 ldai 1 94 return 95 check-type: none 96 cases: 97 - values: 98 - '' 99 - '' 100 - ',' 101 runner-options: [compile-failure] 102 bugid: ['1855'] 103 - values: 104 - '' 105 - 'movi v0, 0' 106 - ', v0' 107 - values: 108 - '' 109 - | 110 # 111 lda.type A 112 sta.obj v0 113 - ', v0' 114 bugid: ['2256'] 115 - values: 116 - '' 117 - | 118 # 119 lda.type B 120 sta.obj v0 121 - ', v0' 122 - values: 123 - '' 124 - 'movi.64 v0, 0' 125 - ', v0' 126 - values: 127 - '' 128 - 'fmovi.64 v0, 0' 129 - ', v0' 130 - values: 131 - '' 132 - | 133 # 134 lda.str "some string" 135 sta.obj v0 136 - ', v0' 137 - values: 138 - '' 139 - | 140 # 141 lda.str "some string" 142 sta.obj v0 143 movi v1, 1 144 - ', v0, v1' 145 - values: 146 - '' 147 - | 148 # 149 lda.str "some string" 150 sta.obj v0 151 movi.64 v1, 1 152 - ', v0, v1' 153 - values: 154 - '' 155 - | 156 # 157 lda.str "some string" 158 sta.obj v0 159 fmovi.64 v1, 1 160 - ', v0, v1' 161 - values: 162 - ', i32 a1' 163 - | 164 # 165 movi v0, 0 166 movi v1, 1 167 - ', v0, v1' 168 - values: 169 - ', i64 a1' 170 - | 171 # 172 movi v0, 0 173 movi.64 v1, 1 174 - ', v0, v1' 175 - values: 176 - ', f64 a1' 177 - | 178 # 179 movi v0, 0 180 fmovi.64 v1, 1.1 181 - ', v0, v1' 182 183 - values: 184 - ', i32 a1' 185 - | 186 # 187 movi.64 v0, 0 188 movi v1, 1 189 - ', v0, v1' 190 - values: 191 - ', i64 a1' 192 - | 193 # 194 movi.64 v0, 0 195 movi.64 v1, 1 196 - ', v0, v1' 197 - values: 198 - ', f64 a1' 199 - | 200 # 201 movi.64 v0, 0 202 fmovi.64 v1, 1.1 203 - ', v0, v1' 204 205 - values: 206 - ', i32 a1' 207 - | 208 # 209 fmovi.64 v0, 0.0 210 movi v1, 1 211 - ', v0, v1' 212 - values: 213 - ', i64 a1' 214 - | 215 # 216 fmovi.64 v0, 0 217 movi.64 v1, 1 218 - ', v0, v1' 219 - values: 220 - ', f64 a1' 221 - | 222 # 223 fmovi.64 v0, 0 224 fmovi.64 v1, 1.1 225 - ', v0, v1' 226 227 - file-name: j_wrong_object_2 228 isa: 229 instructions: 230 - sig: call.virt.short method_id, v1:in:top, v2:in:top 231 acc: out:top 232 format: [op_v1_4_v2_4_id_16] 233 verification: 234 - compatible_arguments 235 header-template: [PandaAssembly, r_A, r_B] 236 description: > 237 Check incorrect usage of `call.virt.short` instruction. First argument is a reference to object of incompatible type. 238 Use PandaAssembly language context. 239 runner-options: [use-pa, verifier-failure, verifier-config] 240 tags: [verifier, pa-verifier] 241 bugid: ['1324', '3293', '5271', '6886'] 242 template-cases: 243 - values: 244 - | 245 %s 246 .function i32 A.foo(A a0%s) { 247 ldai 1 248 return 249 } 250 - values: 251 - | 252 %s 253 ##- %s 254 .function i32 A.foo(A a0) { 255 ldai 1 256 return 257 } 258 code-template: | 259 %s 260 261 .function i32 main() { 262 initobj.short B.constructor 263 sta.obj v0 264 *s 265 call.virt.short A.foo, v0*s 266 267 check-type: exit-positive 268 cases: 269 - values: 270 - '' 271 - '' 272 - '' 273 - '' 274 - values: 275 - '' 276 - ',i32 a1' 277 - 'movi v1, 0' 278 - ', v1' 279 - values: 280 - '' 281 - ',i32 a1' 282 - 'movi v1, 1' 283 - ', v1' 284 - values: 285 - '' 286 - ', i64 a1' 287 - 'movi.64 v1, 0' 288 - ', v1' 289 - values: 290 - '' 291 - ', i64 a1' 292 - 'movi.64 v1, 0x100000000' 293 - ', v1' 294 - values: 295 - '' 296 - ', f64 a1' 297 - 'fmovi.64 v1, 0' 298 - ', v1' 299 - values: 300 - '' 301 - ', f64 a1' 302 - 'fmovi.64 v1, 1.1' 303 - ', v1' 304 - values: 305 - '.record panda.String <external>' 306 - ', panda.String a1' 307 - | 308 # 309 lda.str "some string" 310 sta.obj v1 311 - ', v1' 312 313 - file-name: p_wrong_object_2 314 isa: 315 instructions: 316 - sig: call.virt.short method_id, v1:in:top, v2:in:top 317 acc: out:top 318 format: [op_v1_4_v2_4_id_16] 319 verification: 320 - compatible_arguments 321 header-template: [r_A, r_B] 322 description: > 323 Check incorrect usage of `call.virt.short` instruction. First argument is a reference to object of incompatible type. 324 Use PandaAssembly language context. 325 runner-options: ['verifier-failure', 'verifier-config'] 326 tags: [verifier] 327 bugid: ['1324'] 328 template-cases: 329 - values: 330 - | 331 %s 332 .function i32 A.foo(A a0%s) { 333 ldai 1 334 return 335 } 336 - values: 337 - | 338 %s 339 ##- %s 340 .function i32 A.foo(A a0) { 341 ldai 1 342 return 343 } 344 code-template: | 345 %s 346 347 .function i32 main() { 348 initobj.short B.constructor 349 sta.obj v0 350 *s 351 call.virt.short A.foo, v0*s 352 353 check-type: exit-positive 354 cases: 355 - values: 356 - '' 357 - '' 358 - '' 359 - '' 360 - values: 361 - '' 362 - ',i32 a1' 363 - 'movi v1, 0' 364 - ', v1' 365 - values: 366 - '' 367 - ',i32 a1' 368 - 'movi v1, 1' 369 - ', v1' 370 - values: 371 - '' 372 - ', i64 a1' 373 - 'movi.64 v1, 0' 374 - ', v1' 375 - values: 376 - '' 377 - ', i64 a1' 378 - 'movi.64 v1, 0x100000000' 379 - ', v1' 380 - values: 381 - '' 382 - ', f64 a1' 383 - 'fmovi.64 v1, 0' 384 - ', v1' 385 - values: 386 - '' 387 - ', f64 a1' 388 - 'fmovi.64 v1, 1.1' 389 - ', v1' 390 - values: 391 - '.record panda.String <external>' 392 - ', panda.String a1' 393 - | 394 # 395 lda.str "some string" 396 sta.obj v1 397 - ', v1' 398 399 - file-name: arg_types 400 isa: 401 instructions: 402 - sig: call.virt.short method_id, v1:in:top, v2:in:top 403 acc: out:top 404 format: [op_v1_4_v2_4_id_16] 405 verification: 406 - compatible_arguments 407 header-template: [r_A] 408 description: > 409 Verifier should report when register type does not match function argument type. 410 code-template: | 411 .record panda.Object <external> 412 .record panda.String <external> 413 .function void A.func(A a0, %s) { 414 return.void 415 } 416 417 .function i32 main() { 418 initobj A.constructor 419 sta.obj v0 420 *s 421 call.virt.short A.func, v0, v1 422 template-cases: 423 - values: 424 - 'i32 a1' 425 exclude: [i32] 426 - values: 427 - 'i64 a1' 428 exclude: [i64] 429 - values: 430 - 'f64 a1' 431 exclude: [f64] 432 - values: 433 - 'i32[] a1' 434 exclude: [i32arr] 435 - values: 436 - 'i64[] a1' 437 exclude: [i64arr] 438 - values: 439 - 'f64[] a1' 440 exclude: [f64arr] 441 - values: 442 - 'panda.String a1' 443 exclude: [str] 444 - values: 445 - 'panda.String[] a1' 446 exclude: [strarr] 447 - values: 448 - 'panda.Object a1' 449 exclude: [obj, objarr, i32arr, i64arr, f64arr, str, strarr] 450 - values: 451 - 'panda.Object[] a1' 452 exclude: [objarr, strarr] 453 454 check-type: exit-positive 455 bugid: ['1324'] 456 tags: [verifier] 457 runner-options: ['verifier-failure', 'verifier-config'] 458 cases: 459 - values: 460 - | 461 # 462 movi v1, 0 463 id: i32 464 - values: 465 - | 466 # 467 movi v1, 1 468 id: i32 469 - values: 470 - | 471 # 472 movi.64 v1, 0 473 id: i64 474 - values: 475 - | 476 # 477 movi.64 v1, 1 478 id: i64 479 - values: 480 - | 481 # 482 fmovi.64 v1, 0 483 id: f64 484 - values: 485 - | 486 # 487 fmovi.64 v1, 3.1415926535 488 id: f64 489 - values: 490 - | 491 # 492 movi v1, 123 493 newarr v1, v1, i32[] 494 id: i32arr 495 - values: 496 - | 497 # 498 movi v1, 123 499 newarr v1, v1, i64[] 500 id: i64arr 501 - values: 502 - | 503 # 504 movi v1, 123 505 newarr v1, v1, f64[] 506 id: f64arr 507 - values: 508 - | 509 # 510 lda.str "some string" 511 sta.obj v1 512 id: str 513 - values: 514 - | 515 # 516 movi v1, 123 517 newarr v1, v1, panda.String[] 518 id: strarr 519 - values: 520 - | 521 # 522 newobj v1, panda.Object 523 id: obj 524 - values: 525 - | 526 # 527 movi v1, 123 528 newarr v1, v1, panda.Object[] 529 id: objarr 530 531 - file-name: acc_uninitialized 532 isa: 533 instructions: 534 - sig: call.virt.short method_id, v1:in:top, v2:in:top 535 acc: out:top 536 format: [op_v1_4_v2_4_id_16] 537 header-template: [r_A] 538 description: > 539 Verifier should report that uninitialized accumulator is used in function. 540 check-type: exit-positive 541 bugid: ['1324'] 542 tags: [verifier] 543 runner-options: ['verifier-failure', 'verifier-config'] 544 code-template: | 545 .function void A.func(A a0) { 546 %s 547 return.void 548 } 549 550 .function i32 main() { 551 initobj A.constructor 552 sta.obj v0 553 call.virt.short A.func, v0 554 cases: 555 - values: 556 - sta v0 557 - values: 558 - sta.64 v0 559 - values: 560 - sta.obj v0 561 562 - file-name: reg_uninitialized 563 isa: 564 instructions: 565 - sig: call.virt.short method_id, v1:in:top, v2:in:top 566 acc: out:top 567 format: [op_v1_4_v2_4_id_16] 568 header-template: [r_A] 569 description: > 570 Verifier should report that uninitialized register is used in function. 571 check-type: exit-positive 572 bugid: ['1324'] 573 tags: [verifier] 574 runner-options: ['verifier-failure', 'verifier-config'] 575 code-template: | 576 .function void A.func(A a0) { 577 %s 578 return.void 579 } 580 581 .function i32 main() { 582 initobj A.constructor 583 sta.obj v0 584 call.virt.short A.func, v0 585 template-cases: 586 - values: 587 - lda %s 588 exclude: [r16] 589 - values: 590 - lda.64 %s 591 exclude: [r16] 592 - values: 593 - lda.obj %s 594 exclude: [r16] 595 - values: 596 - mov v0, %s 597 cases: 598 - values: [v0] 599 - values: [v1] 600 - values: [v128] 601 - values: [v255] 602 - values: [v256] 603 id: r16 604 - values: [v32768] 605 id: r16 606 - values: [v65535] 607 id: r16 608 609 - file-name: p_method_id_accessible 610 isa: 611 instructions: 612 - sig: call.virt.short method_id, v1:in:top, v2:in:top 613 acc: out:top 614 format: [op_v1_4_v2_4_id_16] 615 verification: 616 - method_id_accessible 617 header-template: [r_A] 618 description: > 619 Verifier should report that method is not accessible if method_id is not resolved to existing method. Use PandaAssembly language context. 620 check-type: exit-positive 621 tags: [verifier] 622 runner-options: ['verifier-failure', 'verifier-config'] 623 code-template: | 624 .function %s A.func(A a0, *s a1) <external> 625 626 .function i32 main() { 627 initobj A.constructor 628 sta.obj v0 629 *s 630 call.virt.short A.func, v0, v1 631 template-cases: 632 - values: 633 - 'void' 634 635 - values: 636 - 'i32' 637 exclude: [void] 638 - values: 639 - 'i64' 640 exclude: [void] 641 - values: 642 - 'f64' 643 exclude: [void] 644 - values: 645 - 'i32[]' 646 exclude: [void] 647 - values: 648 - 'i64[]' 649 exclude: [void] 650 - values: 651 - 'f64[]' 652 exclude: [void] 653 - values: 654 - 'A' 655 exclude: [void] 656 - values: 657 - 'A[]' 658 exclude: [void] 659 cases: 660 - case-template: | 661 .function void A.func(A a0) <external> 662 663 .function i32 main() { 664 initobj A.constructor 665 sta.obj v0 666 call.virt.short A.func, v0 667 id: void 668 - values: ['i32', 'movi v1, 12345678'] 669 - values: ['i64', 'movi.64 v1, 0x123456789ABCDEF'] 670 - values: ['f64', 'fmovi.64 v1, 3.1415926535'] 671 - values: 672 - 'i32[]' 673 - | 674 # 675 movi v1, 123 676 newarr v1, v1, i32[] 677 - values: 678 - 'i64[]' 679 - | 680 # 681 movi v1, 123 682 newarr v1, v1, i64[] 683 - values: 684 - 'f64[]' 685 - | 686 # 687 movi v1, 123 688 newarr v1, v1, f64[] 689 - values: 690 - 'A' 691 - | 692 # 693 initobj A.constructor 694 sta.obj v1 695 - values: 696 - 'A[]' 697 - | 698 # 699 movi v1, 123 700 newarr v1, v1, A[] 701 702 - file-name: j_method_id_accessible 703 isa: 704 instructions: 705 - sig: call.virt.short method_id, v1:in:top, v2:in:top 706 acc: out:top 707 format: [op_v1_4_v2_4_id_16] 708 verification: 709 - method_id_accessible 710 header-template: [PandaAssembly, r_A] 711 description: > 712 Verifier should report that method is not accessible if method_id is not resolved to existing method. Use PandaAssembly language context. 713 check-type: exit-positive 714 bugid: ['3293', '6886'] 715 tags: [verifier, release, pa-verifier] 716 runner-options: [use-pa, verifier-failure, verifier-config] 717 code-template: | 718 %s 719 .record B<panda.extends = A> {} 720 721 .function void B.constructor(B a0) <ctor> { 722 return.void 723 } 724 725 .function i32 main() { 726 initobj B.constructor 727 sta.obj v0 728 movi v1, 123 729 call.virt.short *s.func, v0, v1 730 template-cases: 731 - values: 732 - | 733 .function void A.func(A a0, i32 a1) <external> 734 .function void B.func(B a0, i32 a1) <external> 735 - values: 736 - | 737 .function void A.func(A a0, i32 a1) <external> 738 .function void B.func(B a0, i32 a1) <noimpl> 739 ignore: true 740 bugid: ['3247'] 741 - values: 742 - | 743 .function void A.func(A a0, i32 a1) <noimpl> 744 .function void B.func(B a0, i32 a1) <external> 745 exclude: [a] 746 ignore: true 747 bugid: ['3247'] 748 cases: 749 - values: 750 - A 751 id: a 752 - values: 753 - B 754 id: b 755 756 - file-name: p_method_id_non_static 757 bugid: ["1324"] 758 isa: 759 instructions: 760 - sig: call.virt.short method_id, v1:in:top, v2:in:top 761 acc: out:top 762 format: [op_v1_4_v2_4_id_16] 763 verification: 764 - method_id_non_static 765 header-template: [r_A] 766 description: > 767 Verifier should report that method is not accessible if method_id is not resolved to existing method. Use PandaAssembly language context. 768 check-type: exit-positive 769 tags: [verifier] 770 runner-options: ['verifier-failure', 'verifier-config'] 771 code-template: | 772 .function %s A.func(A a0, *s a1) <static> { 773 %s 774 } 775 776 .function i32 main() { 777 initobj A.constructor 778 sta.obj v0 779 *s 780 call.virt.short A.func, v0, v1 781 template-cases: 782 - values: 783 - 'void' 784 - 'return.void' 785 - values: 786 - 'i32' 787 - | 788 # 789 ldai 1 790 return 791 exclude: [void] 792 - values: 793 - 'i64' 794 - | 795 # 796 ldai.64 1 797 return.64 798 exclude: [void] 799 - values: 800 - 'f64' 801 - | 802 # 803 fldai.64 3.1415926535 804 return.64 805 exclude: [void] 806 - values: 807 - 'i32[]' 808 - | 809 # 810 movi v1, 123 811 newarr v1, v1, i32[] 812 lda.obj v1 813 return.obj 814 exclude: [void] 815 - values: 816 - 'i64[]' 817 - | 818 # 819 movi v1, 123 820 newarr v1, v1, i64[] 821 lda.obj v1 822 return.obj 823 exclude: [void] 824 - values: 825 - 'f64[]' 826 - | 827 # 828 movi v1, 123 829 newarr v1, v1, f64[] 830 lda.obj v1 831 return.obj 832 exclude: [void] 833 - values: 834 - 'A' 835 - | 836 # 837 initobj A.constructor 838 sta.obj v1 839 return.obj 840 - values: 841 - 'A[]' 842 - | 843 # 844 movi v1, 123 845 newarr v1, v1, A[] 846 lda.obj v1 847 return.obj 848 cases: 849 - case-template: | 850 .function void A.func(A a0) <static> { 851 return.void 852 } 853 854 .function i32 main() { 855 initobj A.constructor 856 sta.obj v0 857 call.virt.short A.func, v0 858 id: void 859 - values: ['i32', 'movi v1, 12345678'] 860 - values: ['i64', 'movi.64 v1, 0x123456789ABCDEF'] 861 - values: ['f64', 'fmovi.64 v1, 3.1415926535'] 862 - values: 863 - 'i32[]' 864 - | 865 # 866 movi v1, 123 867 newarr v1, v1, i32[] 868 - values: 869 - 'i64[]' 870 - | 871 # 872 movi v1, 123 873 newarr v1, v1, i64[] 874 - values: 875 - 'f64[]' 876 - | 877 # 878 movi v1, 123 879 newarr v1, v1, f64[] 880 - values: 881 - 'A' 882 - | 883 # 884 initobj A.constructor 885 sta.obj v1 886 - values: 887 - 'A[]' 888 - | 889 # 890 movi v1, 123 891 newarr v1, v1, A[] 892 893 - file-name: j_method_id_non_static 894 tags: [verifier, pa-verifier] 895 bugid: ['1324', '3293', '5271', '6886'] 896 isa: 897 instructions: 898 - sig: call.virt.short method_id, v1:in:top, v2:in:top 899 acc: out:top 900 format: [op_v1_4_v2_4_id_16] 901 verification: 902 - method_id_non_static 903 header-template: [PandaAssembly, r_A] 904 description: > 905 Verifier should report that method is not accessible if method_id is not resolved to existing method. Use PandaAssembly language context. 906 check-type: exit-positive 907 runner-options: [use-pa, verifier-failure, verifier-config] 908 code-template: | 909 *s 910 .record B<panda.extends = A> {} 911 912 .function void B.constructor(B a0) <ctor> { 913 return.void 914 } 915 916 .function i32 main() { 917 initobj B.constructor 918 sta.obj v0 919 movi v1, 123 920 call.virt.short %s.func, v0, v1 921 template-cases: 922 - values: 923 - A 924 exclude: [virta] # call.virt.short A.func where A.func is virtual 925 - values: 926 - B 927 exclude: [virtb] 928 929 cases: 930 - values: 931 - | 932 .function void A.func(A a0, i32 a1) <static> { 933 return.void 934 } 935 .function void B.func(B a0, i32 a1) <static> { 936 return.void 937 } 938 - values: 939 - | 940 .function void A.func(A a0, i32 a1) { 941 return.void 942 } 943 .function void B.func(B a0, i32 a1) <static> { 944 return.void 945 } 946 id: virta 947 - values: 948 - | 949 .function void A.func(A a0, i32 a1) <static> { 950 return.void 951 } 952 .function void B.func(B a0, i32 a1) { 953 return.void 954 } 955 id: virtb 956 957 - file-name: match_parameters_amount 958 isa: 959 instructions: 960 - sig: call.virt.short method_id, v1:in:top, v2:in:top 961 acc: out:top 962 format: [op_v1_4_v2_4_id_16] 963 header-template: [r_A] 964 description: > 965 Compiler should check amount of function parameters with corresponding call.virt.short 966 check-type: none 967 runner-options: [compile-failure] 968 ignore: true 969 bugid: ['1956','1304'] 970 code-template: | 971 972 .function void A.func(A a0, i32 a1%s) <external> 973 974 .function i32 main() { 975 call.virt.short A.func, v0%s 976 cases: 977 - values: ['', ''] 978 - values: [', i32 a2', ', v1'] 979 - values: [', i32 a2, i32 a3', ', v1'] 980 - values: [', i32 a2, i32 a3, i32 a4', ', v1'] 981