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