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: polymorphic-hdr 16 template: | 17 # 18 .language PandaAssembly 19 .record panda.Class <external> 20 .record panda.Object <external> 21 .record panda.Integer <external> 22 .record panda.Long <external> 23 .record panda.Short <external> 24 .record panda.String <external> 25 .record panda.invoke.MethodHandles <external> 26 .record panda.invoke.MethodHandles$Lookup <external> 27 .record panda.invoke.MethodHandle <external> 28 .record panda.invoke.VarHandle <external> 29 .record panda.invoke.MethodType <external> 30 .record panda.NullPointerException <external> 31 .record panda.reflect.Field <external> 32 .function panda.Object panda.reflect.Field.get(panda.reflect.Field a0, panda.Object a1) <external> 33 .function panda.reflect.Field panda.Class.getField(panda.Class a0, panda.String a1) <external> 34 .function panda.Class panda.Class.forName(panda.String a0) <external> 35 .function panda.invoke.MethodHandles$Lookup panda.invoke.MethodHandles.lookup() <external, static> 36 .function panda.invoke.MethodHandle panda.invoke.MethodHandles$Lookup.findStatic(panda.invoke.MethodHandles$Lookup a0, panda.Class a1, panda.String a2, panda.invoke.MethodType a3) <external> 37 .function panda.invoke.MethodHandle panda.invoke.MethodHandles$Lookup.findVirtual(panda.invoke.MethodHandles$Lookup a0, panda.Class a1, panda.String a2, panda.invoke.MethodType a3) <external> 38 .function panda.invoke.VarHandle panda.invoke.MethodHandles$Lookup.findVarHandle(panda.invoke.MethodHandles$Lookup a0, panda.Class a1, panda.String a2, panda.Class a3) <external> 39 .record W <panda.access = public> {} 40 .record R <panda.access = public, panda.extends = W> { 41 u1 f_boolean <panda.access = public> 42 i8 f_byte <panda.access = public> 43 u16 f_char <panda.access = public> 44 i16 f_short <panda.access = public> 45 i32 f_int <panda.access = public> 46 i64 f_long <panda.access = public> 47 f32 f_float <panda.access = protected> 48 f64 f_double <panda.access = private> 49 } 50 .record Q <panda.access = public, panda.extends = R> {} 51 # returns int.class for panda.Integer, can be replaced with panda.Integer.TYPE 52 .function panda.Class R.getPrimitiveType(panda.String a0) <static, panda.access=public> { 53 call.short panda.Class.forName, a0 54 sta.obj v1 55 lda.str "TYPE" 56 call.virt.acc.short panda.Class.getField, v1, 1 57 mov.null v0 58 call.virt.acc.short panda.reflect.Field.get, v0, 0 59 return.obj 60 } 61 .function i32 main() { 62 call.short R.test 63 return 64 } 65 66tests: 67 - file-name: 'calle.polymorphic.range' 68 isa: 69 title: Polymorphic calls 70 description: > 71 TODO 72 73 commands: 74 - file-name: 'syntax' 75 isa: 76 instructions: 77 - sig: calle.polymorphic.range method_id, v:in:top 78 prefix: PandaAssembly 79 acc: out:top 80 format: [pref_op_v_8_id_16] 81 description: Check calle.polymorphic.range syntax. 82 runner-options: [use-pa, compile-failure, ] 83 tags: ['irtoc_ignore'] 84 header-template: [polymorphic-hdr] 85 code-template: | 86 .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, R a1, R a2, R a3) <external> 87 .function i32 R.test() <static, panda.access = public> { 88 calle.polymorphic.range %s 89 check-type: exit-positive 90 cases: 91 - values: 92 - 'panda.invoke.MethodHandle.invokeExact, v0, v1, v2, v3' 93 - values: 94 - 'panda.invoke.MethodHandle.invokeExact, v253' 95 runner-options: [use-pa, verifier-failure, verifier-config, ] 96 tags: [verifier] 97 bugid: ['7636'] 98 ignore: true 99 - values: 100 - 'panda.invoke.MethodHandle.invokeExact, v254' 101 runner-options: [use-pa, verifier-failure, verifier-config, ] 102 tags: [verifier] 103 bugid: ['7636'] 104 ignore: true 105 - values: 106 - 'panda.invoke.MethodHandle.invokeExact, v255' 107 runner-options: [use-pa, verifier-failure, verifier-config, ] 108 tags: [verifier] 109 bugid: ['7636'] 110 ignore: true 111 - values: 112 - 'panda.invoke.MethodHandle.invokeExact, v256' 113 - values: 114 - 'panda.invoke.MethodHandle.invokeExact, v32768' 115 - values: 116 - 'panda.invoke.MethodHandle.invokeExact, v65536' 117 - values: 118 - 'panda.invoke.MethodHandle.invokeExact, v252' 119 runner-options: [use-pa, compile-only, ] 120 121 - file-name: 'uninitialized_regs' 122 isa: 123 instructions: 124 - sig: calle.polymorphic.range method_id, v:in:top 125 prefix: PandaAssembly 126 acc: out:top 127 format: [pref_op_v_8_id_16] 128 description: Check that verifier reports an error on unitialized registers. 129 runner-options: [use-pa, verifier-failure, verifier-config, ] 130 tags: ['verifier', 'irtoc_ignore'] 131 header-template: [polymorphic-hdr] 132 code-template: | 133 .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, R a1, R a2, R a3) <external> 134 .function i32 R.test() <static, panda.access = public> { 135 %s 136 calle.polymorphic.range panda.invoke.MethodHandle.invokeExact, %s 137 check-type: exit-positive 138 cases: 139 - values: 140 # v0, v1, v2, v3 are not initialized 141 - '' 142 - v0 143 bugid: ['7636'] 144 ignore: true 145 - values: 146 # v103 is not initilized 147 - | 148 # 149 newobj v100, R 150 newobj v101, R 151 newobj v102, R 152 - v100 153 bugid: ['7636'] 154 ignore: true 155 - values: 156 # all regs are initialized 157 - | 158 # 159 newobj v252, R 160 newobj v253, R 161 newobj v254, R 162 newobj v255, R 163 - v252 164 runner-options: [use-pa, verifier-only, verifier-config, ] 165 166 - file-name: 'npe' 167 isa: 168 exceptions: [x_null] 169 description: Check that NullPointerException is thrown if v1 is null. 170 runner-options: [use-pa, ] 171 tags: ['irtoc_ignore'] 172 bugid: ['7637'] 173 ignore: true 174 header-template: [polymorphic-hdr] 175 code-template: | 176 .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, R a1) <external> 177 .function i32 R.test() <static, panda.access = public> { 178 mov.null v4 179 newobj v5, R 180 try_begin: 181 calle.polymorphic.range panda.invoke.MethodHandle.invokeExact, v4 182 ldai 4 183 return 184 try_end: 185 catch_begin: 186 ldai 0 187 return 188 catch_end: 189 .catch panda.NullPointerException, try_begin, try_end, catch_begin, catch_end 190 } 191 check-type: empty 192 193 - file-name: 'call_1s' 194 isa: 195 instructions: 196 - sig: calle.polymorphic.range method_id, v:in:top 197 prefix: PandaAssembly 198 acc: out:top 199 format: [pref_op_v_8_id_16] 200 description: Check that polymorphic call is performed for static function with one argument. 201 runner-options: [use-pa, ] 202 tags: ['irtoc_ignore'] 203 bugid: ['7634'] 204 header-template: [polymorphic-hdr] 205 code-template: | 206 .function panda.invoke.MethodType panda.invoke.MethodType.methodType(panda.Class a0, panda.Class a1) <external, static> 207 %s 208 .function i32 R.inc32(i32 a0) { 209 inci a0, 1 210 lda a0 211 return 212 } 213 .function i32 R.inc64(i64 a0) { 214 ldai.64 2 215 add2.64 a0 216 i64toi32 217 return 218 } 219 .function i32 R.inc16(i16 a0) { 220 inci a0, 3 221 lda a0 222 return 223 } 224 .function i32 R.test() <static, panda.access = public> { 225 call.short panda.invoke.MethodHandles.lookup 226 sta.obj v0 # MethodHandles.Lookup object 227 228 lda.str "panda.Integer" 229 sta.obj v1 230 call.short R.getPrimitiveType, v1 231 sta.obj v1 232 lda.str "%s" 233 sta.obj v2 234 call.short R.getPrimitiveType, v2 235 sta.obj v2 236 call.short panda.invoke.MethodType.methodType, v1, v2 237 sta.obj v1 # MethodType object for (i32)i32 238 239 lda.type R 240 sta.obj v2 241 lda.str "%s" 242 sta.obj v3 243 call.virt panda.invoke.MethodHandles$Lookup.findStatic, v0, v2, v3, v1 244 sta.obj v4 # MethodHandle object 245 246 %s 247 calle.polymorphic.range panda.invoke.MethodHandle.invokeExact, v4 248 movi v1, 42 249 jeq v1, ok 250 ldai 1 251 return 252 ok: 253 ldai 0 254 return 255 } 256 check-type: empty 257 cases: 258 - values: 259 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, i32 a1) <external> 260 - panda.Integer 261 - inc32 262 - movi v5, 41 263 - values: 264 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, i64 a1) <external> 265 - panda.Long 266 - inc64 267 - movi.64 v5, 40 268 - values: 269 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, i16 a1) <external> 270 - panda.Short 271 - inc16 272 - movi v5, 39 273 274 - file-name: 'call_3s' 275 isa: 276 instructions: 277 - sig: calle.polymorphic.range method_id, v:in:top 278 prefix: PandaAssembly 279 acc: out:top 280 format: [pref_op_v_8_id_16] 281 description: Check that polymorphic call is performed for static function with three arguments. 282 runner-options: [use-pa, ] 283 tags: ['irtoc_ignore'] 284 bugid: ['7634'] 285 header-template: [polymorphic-hdr] 286 code-template: | 287 .function panda.invoke.MethodType panda.invoke.MethodType.methodType(panda.Class a0, panda.Class[] a1) <external, static> 288 %s 289 .function i32 R.sum32(i32 a0, i32 a1, i32 a2) { 290 add a0, a1 291 add2 a2 292 return 293 } 294 .function i32 R.sum64(i64 a0, i64 a1, i64 a2) { 295 lda.64 a0 296 add2.64 a1 297 add2.64 a2 298 i64toi32 299 return 300 } 301 .function i32 R.sum16(i16 a0, i16 a1, i16 a2) { 302 add a0, a1 303 add2 a2 304 return 305 } 306 .function i32 R.test() <static, panda.access = public> { 307 call.short panda.invoke.MethodHandles.lookup 308 sta.obj v0 # MethodHandles.Lookup object 309 310 lda.str "panda.Integer" 311 sta.obj v1 312 call.short R.getPrimitiveType, v1 313 sta.obj v1 314 lda.str "%s" 315 sta.obj v2 316 call.short R.getPrimitiveType, v2 317 movi v3, 3 # 3 arguments 318 newarr v2, v3, panda.Class[] 319 movi v4, 0 320 starr.obj v2, v4 321 inci v4, 1 322 starr.obj v2, v4 323 inci v4, 1 324 starr.obj v2, v4 325 call panda.invoke.MethodType.methodType, v1, v2 326 sta.obj v1 # MethodType object for (i32, i32, i32)i32 327 328 lda.type R 329 sta.obj v2 330 lda.str "%s" 331 sta.obj v3 332 call.virt panda.invoke.MethodHandles$Lookup.findStatic, v0, v2, v3, v1 333 sta.obj v252 # MethodHandle object 334 335 %s 336 calle.polymorphic.range panda.invoke.MethodHandle.invokeExact, v252 337 movi v1, 42 338 jeq v1, ok 339 ldai 1 340 return 341 ok: 342 ldai 0 343 return 344 } 345 check-type: empty 346 cases: 347 - values: 348 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, i32 a1, i32 a2, i32 a3) <external> 349 - panda.Integer 350 - sum32 351 - | 352 # 353 movi v253, 22 354 movi v254, 15 355 movi v255, 5 356 - values: 357 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, i64 a1, i64 a2, i64 a3) <external> 358 - panda.Long 359 - sum64 360 - | 361 # 362 movi.64 v253, -500 363 movi.64 v254, 1042 364 movi.64 v255, -500 365 - values: 366 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, i16 a1, i16 a2, i16 a3) <external> 367 - panda.Short 368 - sum16 369 - | 370 # 371 movi v253, 1 372 movi v254, 2 373 movi v255, 39 374 375 - file-name: 'call_1v' 376 isa: 377 instructions: 378 - sig: calle.polymorphic.range method_id, v:in:top 379 prefix: PandaAssembly 380 acc: out:top 381 format: [pref_op_v_8_id_16] 382 description: Check that polymorphic call is performed for virtual function with one argument. 383 runner-options: [use-pa, ] 384 tags: ['irtoc_ignore'] 385 bugid: ['7634'] 386 header-template: [polymorphic-hdr] 387 code-template: | 388 .function panda.invoke.MethodType panda.invoke.MethodType.methodType(panda.Class a0, panda.Class a1) <external, static> 389 %s 390 .function i32 R.inc32(R a0, i32 a1) { 391 inci a1, 1 392 lda a1 393 return 394 } 395 .function i32 R.inc64(R a0, i64 a1) { 396 ldai.64 2 397 add2.64 a1 398 i64toi32 399 return 400 } 401 .function i32 R.inc16(R a0, i16 a1) { 402 inci a1, 3 403 lda a1 404 return 405 } 406 .function i32 R.test() <static, panda.access = public> { 407 call.short panda.invoke.MethodHandles.lookup 408 sta.obj v0 # MethodHandles.Lookup object 409 410 lda.str "panda.Integer" 411 sta.obj v1 412 call.short R.getPrimitiveType, v1 413 sta.obj v1 414 lda.str "%s" 415 sta.obj v2 416 call.short R.getPrimitiveType, v2 417 sta.obj v2 418 call.short panda.invoke.MethodType.methodType, v1, v2 419 sta.obj v1 # MethodType object for (i32)i32 420 421 lda.type R 422 sta.obj v2 423 lda.str "%s" 424 sta.obj v3 425 call.virt panda.invoke.MethodHandles$Lookup.findVirtual, v0, v2, v3, v1 426 sta.obj v4 # MethodHandle object 427 428 newobj v5, R 429 %s 430 calle.polymorphic.range panda.invoke.MethodHandle.invokeExact, v4 431 movi v1, 42 432 jeq v1, ok 433 ldai 1 434 return 435 ok: 436 ldai 0 437 return 438 } 439 check-type: empty 440 cases: 441 - values: 442 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, R a1, i32 a2) <external> 443 - panda.Integer 444 - inc32 445 - movi v6, 41 446 - values: 447 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, R a1, i64 a2) <external> 448 - panda.Long 449 - inc64 450 - movi.64 v6, 40 451 - values: 452 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, R a1, i16 a2) <external> 453 - panda.Short 454 - inc16 455 - movi v6, 39 456 457 - file-name: 'call_2v' 458 isa: 459 instructions: 460 - sig: calle.polymorphic.range method_id, v:in:top 461 prefix: PandaAssembly 462 acc: out:top 463 format: [pref_op_v_8_id_16] 464 description: Check that polymorphic call is performed for virtual function with two arguments. 465 runner-options: [use-pa, ] 466 tags: ['irtoc_ignore'] 467 bugid: ['7634'] 468 header-template: [polymorphic-hdr] 469 code-template: | 470 .function panda.invoke.MethodType panda.invoke.MethodType.methodType(panda.Class a0, panda.Class[] a1) <external, static> 471 %s 472 .function i32 R.sum32(R a0, i32 a1, i32 a2) { 473 add a1, a2 474 return 475 } 476 .function i32 R.sum64(R a0, i64 a1, i64 a2) { 477 lda.64 a1 478 add2.64 a2 479 i64toi32 480 return 481 } 482 .function i32 R.sum16(R a0, i16 a1, i16 a2) { 483 add a1, a2 484 return 485 } 486 .function i32 R.test() <static, panda.access = public> { 487 call.short panda.invoke.MethodHandles.lookup 488 sta.obj v0 # MethodHandles.Lookup object 489 490 lda.str "panda.Integer" 491 sta.obj v1 492 call.short R.getPrimitiveType, v1 493 sta.obj v1 494 lda.str "%s" 495 sta.obj v2 496 call.short R.getPrimitiveType, v2 497 movi v3, 2 # 2 arguments 498 newarr v2, v3, panda.Class[] 499 movi v4, 0 500 starr.obj v2, v4 501 inci v4, 1 502 starr.obj v2, v4 503 call.short panda.invoke.MethodType.methodType, v1, v2 504 sta.obj v1 # MethodType object for (i32, i32)i32 505 506 lda.type R 507 sta.obj v2 508 lda.str "%s" 509 sta.obj v3 510 call.virt panda.invoke.MethodHandles$Lookup.findVirtual, v0, v2, v3, v1 511 sta.obj v4 # MethodHandle object 512 513 newobj v5, R 514 %s 515 calle.polymorphic.range panda.invoke.MethodHandle.invokeExact, v4 516 movi v1, 42 517 jeq v1, ok 518 ldai 1 519 return 520 ok: 521 ldai 0 522 return 523 } 524 check-type: empty 525 cases: 526 - values: 527 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, R a1, i32 a2, i32 a3) <external> 528 - panda.Integer 529 - sum32 530 - | 531 # 532 movi v6, 0x800000000039 533 movi v7, 0x7ffffffffff1 534 - values: 535 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, R a1, i64 a2, i64 a3) <external> 536 - panda.Long 537 - sum64 538 - | 539 # 540 movi.64 v6, 0x800000000000002b 541 movi.64 v7, 0x7fffffffffffffff 542 - values: 543 - .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, R a1, i16 a2, i16 a3) <external> 544 - panda.Short 545 - sum16 546 - | 547 # 548 movi v6, 0 549 movi v7, 42 550 551 - file-name: 'call_all_regs_v' 552 isa: 553 instructions: 554 - sig: calle.polymorphic.range method_id, v:in:top 555 prefix: PandaAssembly 556 acc: out:top 557 format: [pref_op_v_8_id_16] 558 description: Check that polymorphic call is performed for virtual function with all register arguments used. 559 runner-options: [use-pa, ] 560 tags: ['irtoc_ignore'] 561 bugid: ['7634'] 562 header-template: [polymorphic-hdr] 563 code-template: | 564 .function panda.invoke.MethodType panda.invoke.MethodType.methodType(panda.Class a0, panda.Class[] a1) <external, static> 565 .function i32 panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, R a1%s) <external> 566 .function i32 R.sum32(R a0%s) { 567 ldai 0 568 %s 569 return 570 } 571 .function i32 R.test() <static, panda.access = public> { 572 call.short panda.invoke.MethodHandles.lookup 573 sta.obj v0 # MethodHandles.Lookup object 574 575 lda.str "panda.Integer" 576 sta.obj v1 577 call.short R.getPrimitiveType, v1 578 sta.obj v1 579 580 movi v5, 254 # array size 581 newarr v2, v5, panda.Class[] 582 583 # fill array from 0 to 253 584 movi v4, 0 # array index 585 loop: 586 lda.obj v1 587 starr.obj v2, v4 588 inci v4, 1 589 lda v4 590 jlt v5, loop 591 592 call.short panda.invoke.MethodType.methodType, v1, v2 593 sta.obj v1 # MethodType object for (i32, i32, ...)i32 594 595 lda.type R 596 sta.obj v2 597 lda.str "sum32" 598 sta.obj v3 599 call.virt panda.invoke.MethodHandles$Lookup.findVirtual, v0, v2, v3, v1 600 sta.obj v0 # MethodHandle object 601 602 newobj v1, R 603 %s 604 calle.polymorphic.range panda.invoke.MethodHandle.invokeExact, v0 605 movi v1, 326390 606 jeq v1, ok 607 ldai 1 608 return 609 ok: 610 ldai 0 611 return 612 } 613 check-type: empty 614 cases: 615 - values: 616 - "#{[*2..255].map do |i| \", i32 a#{i}\" end .join}" 617 - "#{[*1..254].map do |i| \", i32 a#{i}\" end .join}" 618 - "#{[*1..254].map do |i| \" add2 a#{i}\\n\" end .join}" 619 - "#{[*2..255].map do |i| \" movi v#{i}, #{i}0\\n\" end .join}" 620 621 - file-name: 'call_obj' 622 isa: 623 exceptions: [x_call] 624 description: Check that polymorphic call throws right exception on invalid arguments. 625 runner-options: [use-pa, ] 626 tags: ['irtoc_ignore'] 627 bugid: ['7634'] 628 header-template: [polymorphic-hdr] 629 code-template: | 630 .function panda.invoke.MethodType panda.invoke.MethodType.methodType(panda.Class a0, panda.Class a1) <external, static> 631 .function R panda.invoke.MethodHandle.invokeExact(panda.invoke.MethodHandle a0, %s a1) <external> 632 .record panda.Exception <external> 633 .record E <panda.extends = panda.Exception, panda.access = public> {} 634 .record panda.invoke.WrongMethodTypeException <external> 635 .function R R.throwE(R a0) <static> { 636 newobj v0, E 637 throw v0 638 lda.obj a0 639 return.obj 640 } 641 .function i32 R.test() <static, panda.access = public> { 642 call.short panda.invoke.MethodHandles.lookup 643 sta.obj v0 # MethodHandles.Lookup object 644 645 lda.type R 646 sta.obj v1 647 call.short panda.invoke.MethodType.methodType, v1, v1 648 sta.obj v1 # MethodType object for (R)R 649 650 lda.type R 651 sta.obj v2 652 lda.str "throwE" 653 sta.obj v3 654 call.virt panda.invoke.MethodHandles$Lookup.findStatic, v0, v2, v3, v1 655 sta.obj v5 # MethodHandle object 656 657 newobj v6, %s 658 try_begin: 659 calle.polymorphic.range panda.invoke.MethodHandle.invokeExact, v5 660 ldai 1 661 return 662 try_end: 663 catch_begin: 664 ldai 0 665 return 666 catch_end: 667 %s 668 } 669 check-type: empty 670 cases: 671 - values: 672 - E 673 - E 674 - .catch panda.invoke.WrongMethodTypeException, try_begin, try_end, catch_begin, catch_end 675 - values: 676 - W 677 - W 678 - .catch panda.invoke.WrongMethodTypeException, try_begin, try_end, catch_begin, catch_end 679 - values: 680 - R 681 - R 682 - .catch E, try_begin, try_end, catch_begin, catch_end 683 - values: 684 - Q 685 - Q 686 - .catch panda.invoke.WrongMethodTypeException, try_begin, try_end, catch_begin, catch_end 687 688 - file-name: 'call_vh' 689 isa: 690 instructions: 691 - sig: calle.polymorphic.range method_id, v:in:top 692 prefix: PandaAssembly 693 acc: out:top 694 format: [pref_op_v_8_id_16] 695 description: Check that polymorphic call is performed for field access. 696 runner-options: [use-pa, ] 697 tags: ['irtoc_ignore'] 698 bugid: ['7634'] 699 header-template: [polymorphic-hdr] 700 code-template: | 701 %s 702 .function i32 R.test() <static, panda.access = public> { 703 call.short panda.invoke.MethodHandles.lookup 704 sta.obj v0 # MethodHandles.Lookup object 705 706 lda.type R 707 sta.obj v2 708 lda.str "%s" 709 sta.obj v3 710 lda.str "%s" 711 sta.obj v4 712 call.short R.getPrimitiveType, v4 713 sta.obj v4 714 call.virt panda.invoke.MethodHandles$Lookup.findVarHandle, v0, v2, v3, v4 715 sta.obj v5 # VarHandle object 716 717 %s 718 ldai 0 719 return 720 fail: 721 ldai 1 722 return 723 } 724 check-type: empty 725 cases: 726 - values: 727 - .function void panda.invoke.VarHandle.set(panda.invoke.VarHandle a0, R a1, i32 a2) <external> 728 - f_int 729 - panda.Integer 730 - | 731 # 732 newobj v6, R 733 movi v7, 42 734 calle.polymorphic.range panda.invoke.VarHandle.set, v5 735 lda.null 736 ldobj v6, R.f_int 737 jne v7, fail 738 - values: 739 - .function i32 panda.invoke.VarHandle.get(panda.invoke.VarHandle a0, R a1) <external> 740 - f_int 741 - panda.Integer 742 - | 743 # 744 newobj v6, R 745 movi v7, 42 746 lda v7 747 stobj v6, R.f_int 748 lda.null 749 calle.polymorphic.range panda.invoke.VarHandle.get, v5 750 jne v7, fail 751 - values: 752 - .function void panda.invoke.VarHandle.set(panda.invoke.VarHandle a0, R a1, f64 a2) <external> 753 - f_double 754 - panda.Double 755 - | 756 # 757 newobj v6, R 758 fmovi.64 v7, 42.4242 759 calle.polymorphic.range panda.invoke.VarHandle.set, v5 760 lda.null 761 ldobj.64 v6, R.f_double 762 fcmpg.64 v7 763 jnez fail 764 - values: 765 - .function f64 panda.invoke.VarHandle.get(panda.invoke.VarHandle a0, R a1) <external> 766 - f_double 767 - panda.Double 768 - | 769 # 770 newobj v6, R 771 fmovi.64 v7, 42.4242 772 lda.64 v7 773 stobj.64 v6, R.f_double 774 lda.null 775 calle.polymorphic.range panda.invoke.VarHandle.get, v5 776 fcmpg.64 v7 777 jnez fail 778 - values: 779 - .function f32 panda.invoke.VarHandle.getAndSet(panda.invoke.VarHandle a0, R a1, f32 a2) <external> 780 - f_float 781 - panda.Float 782 - | 783 # 784 newobj v6, R 785 fmovi v8, 3.141593 # initial value 786 lda v8 787 stobj v6, R.f_float 788 fmovi v7, 2.718282 # value to set by getAndSet 789 lda.null 790 calle.polymorphic.range panda.invoke.VarHandle.getAndSet, v5 791 fcmpg v8 792 jnez fail 793 ldobj v6, R.f_float 794 fcmpg v7 795 jnez fail 796 - values: 797 - .function i64 panda.invoke.VarHandle.getAndAdd(panda.invoke.VarHandle a0, R a1, i64 a2) <external> 798 - f_long 799 - panda.Long 800 - | 801 # 802 newobj v6, R 803 movi.64 v8, 0x7ffffffffffffffe # initial value 804 lda.64 v8 805 stobj.64 v6, R.f_long 806 movi.64 v7, 1 # value to add by getAndAdd 807 lda.null 808 calle.polymorphic.range panda.invoke.VarHandle.getAndAdd, v5 809 cmp.64 v8 810 jnez fail 811 ldobj.64 v6, R.f_long 812 sub2.64 v7 813 cmp.64 v8 814 jnez fail 815 - values: 816 - .function i32 panda.invoke.VarHandle.getAndBitwiseOr(panda.invoke.VarHandle a0, R a1, i32 a2) <external> 817 - f_int 818 - panda.Integer 819 - | 820 # 821 newobj v6, R 822 movi v8, 0xf0f0f0f0 # initial value 823 lda v8 824 stobj v6, R.f_int 825 movi v7, 0xa5a5a5a5 # value to OR by getAndBitwiseOr 826 lda.null 827 calle.polymorphic.range panda.invoke.VarHandle.getAndBitwiseOr, v5 828 jne v8, fail 829 or2 v7 830 sta v9 831 ldobj v6, R.f_int 832 jne v9, fail 833 - values: 834 - .function i16 panda.invoke.VarHandle.getAndBitwiseAnd(panda.invoke.VarHandle a0, R a1, i16 a2) <external> 835 - f_short 836 - panda.Short 837 - | 838 # 839 newobj v6, R 840 movi v8, 0x5a5a # initial value 841 lda v8 842 stobj v6, R.f_short 843 movi v7, 0x0f0f # value to AND by getAndBitwiseAnd 844 lda.null 845 calle.polymorphic.range panda.invoke.VarHandle.getAndBitwiseAnd, v5 846 jne v8, fail 847 and2 v7 848 sta v9 849 ldobj v6, R.f_short 850 jne v9, fail 851 - values: 852 - .function i8 panda.invoke.VarHandle.getAndBitwiseXor(panda.invoke.VarHandle a0, R a1, i8 a2) <external> 853 - f_byte 854 - panda.Byte 855 - | 856 # 857 newobj v6, R 858 ldai 0x35 # initial value 859 i32toi8 860 sta v8 861 stobj v6, R.f_byte 862 ldai 0x1f # value to XOR by getAndBitwiseXor 863 i32toi8 864 sta v7 865 lda.null 866 calle.polymorphic.range panda.invoke.VarHandle.getAndBitwiseXor, v5 867 jne v8, fail 868 xor2 v7 869 sta v9 870 ldobj v6, R.f_byte 871 jne v9, fail 872 873 874 - file-name: 'call_vh_exc' 875 isa: 876 instructions: 877 - sig: calle.polymorphic.range method_id, v:in:top 878 prefix: PandaAssembly 879 acc: out:top 880 format: [pref_op_v_8_id_16] 881 description: Check that polymorphic call of VarHandle is throwing exceptions as expected. 882 runner-options: [use-pa, ] 883 tags: ['irtoc_ignore'] 884 bugid: ['7634'] 885 header-template: [polymorphic-hdr] 886 code-template: | 887 %s 888 .function panda.invoke.VarHandle panda.invoke.MethodHandles.arrayElementVarHandle(panda.Class a0) <external> 889 .function i32 R.test() <static, panda.access = public> { 890 lda.type R[] 891 sta.obj v1 892 call.short panda.invoke.MethodHandles.arrayElementVarHandle, v1 893 sta.obj v1 # VarHandle object 894 895 movi v3, 3 # array size 896 newarr v2, v3, R[] 897 movi v3, 1 # element index 898 newobj v4, R # object to set in R[1] 899 try_begin: 900 %s 901 try_end: 902 ldai 1 903 return 904 catch_begin: 905 ldai 0 906 return 907 catch_end: 908 } 909 %s 910 check-type: empty 911 cases: 912 - values: 913 # no exceptions case, set R into R[] 914 - .function void panda.invoke.VarHandle.set(panda.invoke.VarHandle a0, R[] a1, i32 a2, R a3) <external> 915 - | 916 # 917 calle.polymorphic.range panda.invoke.VarHandle.set, v1 918 ldai 0 919 ldarr.obj v2 920 jnez.obj try_end 921 ldai 1 922 ldarr.obj v2 923 jeqz.obj try_end 924 isinstance R 925 jeqz try_end 926 ldai 2 927 ldarr.obj v2 928 jeqz.obj catch_begin 929 - '' 930 - values: 931 # no exceptions case. set Q into R[], Q extends R 932 - .function void panda.invoke.VarHandle.set(panda.invoke.VarHandle a0, R[] a1, i32 a2, R a3) <external> 933 - | 934 # 935 newobj v4, Q 936 calle.polymorphic.range panda.invoke.VarHandle.set, v1 937 ldai 0 938 ldarr.obj v2 939 jnez.obj try_end 940 ldai 1 941 ldarr.obj v2 942 jeqz.obj try_end 943 isinstance R 944 jeqz try_end 945 ldai 2 946 ldarr.obj v2 947 jeqz.obj catch_begin 948 - '' 949 - values: 950 # ClassCastException is expected, set W into R[], W is not R 951 - | 952 .function void panda.invoke.VarHandle.set(panda.invoke.VarHandle a0, R[] a1, i32 a2, W a3) <external> 953 .record panda.ClassCastException <external> 954 - | 955 # 956 newobj v4, W 957 calle.polymorphic.range panda.invoke.VarHandle.set, v1 958 - .catch panda.ClassCastException, try_begin, try_end, catch_begin, catch_end 959 - values: 960 # NPE is expected, VarHandle ref is null 961 - .function void panda.invoke.VarHandle.set(panda.invoke.VarHandle a0, R[] a1, i32 a2, R a3) <external> 962 - | 963 # 964 mov.null v1 965 calle.polymorphic.range panda.invoke.VarHandle.set, v1 966 - .catch panda.NullPointerException, try_begin, try_end, catch_begin, catch_end 967 - values: 968 # NPE is expected, target array is null 969 - .function void panda.invoke.VarHandle.set(panda.invoke.VarHandle a0, R[] a1, i32 a2, R a3) <external> 970 - | 971 # 972 mov.null v2 973 calle.polymorphic.range panda.invoke.VarHandle.set, v1 974 - .catch panda.NullPointerException, try_begin, try_end, catch_begin, catch_end 975 - values: 976 # WrongMethodTypeException is expected 977 - | 978 .function void panda.invoke.VarHandle.set(panda.invoke.VarHandle a0, R[] a1, i32 a2) <external> 979 .record panda.invoke.WrongMethodTypeException <external> 980 - | 981 # 982 calle.polymorphic.range panda.invoke.VarHandle.set, v1 983 - .catch panda.invoke.WrongMethodTypeException, try_begin, try_end, catch_begin, catch_end 984 - values: 985 # ArrayIndexOutOfBoundsException is expected 986 - | 987 .function void panda.invoke.VarHandle.set(panda.invoke.VarHandle a0, R[] a1, i32 a2, R a3) <external> 988 .record panda.ArrayIndexOutOfBoundsException <external> 989 - | 990 # 991 movi v3, 100 992 calle.polymorphic.range panda.invoke.VarHandle.set, v1 993 - .catch panda.ArrayIndexOutOfBoundsException, try_begin, try_end, catch_begin, catch_end 994 - values: 995 # UnsupportedOperationException is expected 996 - | 997 .function void panda.invoke.VarHandle.getAndBitwiseAnd(panda.invoke.VarHandle a0, R[] a1, i32 a2, R a3) <external> 998 .record panda.UnsupportedOperationException <external> 999 - | 1000 # 1001 calle.polymorphic.range panda.invoke.VarHandle.getAndBitwiseAnd, v1 1002 - .catch panda.UnsupportedOperationException, try_begin, try_end, catch_begin, catch_end 1003