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