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: pandasm_header 16 template: | 17 .language PandaAssembly 18 19 .record panda.Object <external> 20 21 .record Q {} 22 .function void Q.ctor(Q a0) <ctor> { 23 return.void 24 } 25 26 .record R { 27 u1 fu1 28 u8 fu8 29 i8 fi8 30 u16 fu16 31 i16 fi16 32 u32 fu32 33 i32 fi32 34 u64 fu64 35 i64 fi64 36 f32 ff32 37 f64 ff64 38 # objects 39 i32[] fi32Array 40 Q fQ 41 Q[] fQArray 42 R fR 43 R[] fRArray 44 panda.Object fObj 45 panda.Object fObj2 46 panda.Object[] fObjArray 47 } 48 .function void R.ctor(R a0) <ctor> { 49 return.void 50 } 51 52 - name: PandaAssembly_header 53 template: | 54 .language PandaAssembly 55 56 .record panda.Object <external> 57 .function void panda.Object.ctor(panda.Object a0) <external, ctor> 58 59 .record I <panda.interface> {} 60 61 .record Q <panda.implements=I> {} 62 .function void Q.ctor(Q a0) <ctor> { 63 return.void 64 } 65 66 .record R <panda.extends=Q> { 67 u1 fu1 68 i8 fi8 69 u16 fu16 70 i16 fi16 71 i32 fi32 72 i64 fi64 73 f32 ff32 74 f64 ff64 75 # objects 76 i32[] fi32Array 77 Q fQ 78 Q[] fQArray 79 R fR 80 R[] fRArray 81 I fI 82 I[] fIArray 83 panda.Object fObj 84 panda.Object fObj2 85 panda.Object[] fObjArray 86 } 87 .function void R.ctor(R a0) <ctor> { 88 return.void 89 } 90 91 92tests: 93 - file-name: "ldobj.v.obj" 94 isa: 95 title: Get field from object to register 96 description: > 97 Get field value from an object by field id and put it into register. 98 instructions: 99 - sig: ldobj.v.obj v1:out:ref, v2:in:ref, field_id 100 acc: none 101 format: [op_v1_4_v2_4_id_16] 102 commands: 103 104 - file-name: "check_if_v2_initialized" 105 description: Check that verifier reports error if source registers are not initialized 106 isa: 107 instructions: 108 - sig: ldobj.v.obj v1:out:ref, v2:in:ref, field_id 109 acc: none 110 format: [op_v1_4_v2_4_id_16] 111 header-template: [pandasm_header] 112 check-type: exit-positive 113 tags: [verifier] 114 bugid: ['1324', '2084', '3257'] 115 runner-options: ['verifier-failure', 'verifier-config'] 116 code-template: | 117 118 .function i32 main() { 119 %s # verifier error expected, because v2 is not initialized 120 121 cases: 122 - values: 123 - 'ldobj.v.obj v1, v0, R.fQ' 124 - values: 125 - 'ldobj.v.obj v1, v1, R.fR' 126 - values: 127 - 'ldobj.v.obj v1, v15, R.fQArray' 128 129 130 - file-name: "with_null_ref_pa" 131 description: Check that NullPointerException is thrown if source ref is null 132 isa: 133 exceptions: 134 - x_null 135 header-template: [pandasm_header] 136 check-type: empty 137 tags: ['tsan', 'irtoc_ignore'] 138 code-template: | 139 .record panda.NullPointerException <external> 140 141 .function R get_null() { 142 lda.null 143 return.obj 144 } 145 146 .function i32 main() { 147 call.short get_null 148 sta.obj v0 149 try_begin: 150 ldobj.v.obj v1, v0, %s 151 ldai 1 152 return 153 try_end: 154 ldai 0 155 return 156 .catch panda.NullPointerException, try_begin, try_end, try_end 157 } 158 cases: 159 - values: 160 - R.fQ 161 - values: 162 - R.fObj 163 - values: 164 - R.fi32Array 165 166 167 - file-name: "with_null_ref_j" 168 description: Check that NullPointerException is thrown if source ref is null 169 isa: 170 exceptions: 171 - x_null 172 header-template: [PandaAssembly_header] 173 tags: ['irtoc_ignore'] 174 runner-options: [use-pa] 175 check-type: empty 176 code-template: | 177 .record panda.NullPointerException <external> 178 179 .function R get_null() { 180 lda.null 181 return.obj 182 } 183 184 .function i32 main() { 185 call.short get_null 186 sta.obj v0 187 try_begin: 188 ldobj.v.obj v15, v0, %s 189 ldai 1 190 return 191 try_end: 192 ldai 0 193 return 194 .catch panda.NullPointerException, try_begin, try_end, try_end 195 } 196 cases: 197 - values: 198 - R.fQ 199 - values: 200 - R.fObj 201 - values: 202 - R.fi32Array 203 204 205 - file-name: "with_non_object_ref" 206 description: Check that verifier reports error when the 2nd operand is not a ref to an object (other than array) 207 isa: 208 verification: 209 - v2_object 210 header-template: [pandasm_header] 211 check-type: exit-positive 212 tags: [verifier] 213 runner-options: ['verifier-failure', 'verifier-config'] 214 bugid: ['2085'] 215 code-template: | 216 217 .function i32 main() { 218 %s 219 ldobj.v.obj v1, v0, R.fQ 220 cases: 221 - values: 222 - movi v0, 0 223 bugid: ['1826'] 224 - values: 225 - movi v0, 1 226 - values: 227 - movi.64 v0, 0x00 228 bugid: ['1826'] 229 - values: 230 - movi.64 v0, 0xCAFECAFECAFECAFE 231 - values: 232 - fmovi.64 v0, 0.0 233 bugid: ['1826'] 234 - values: 235 - fmovi.64 v0, 6.62607015 236 - values: 237 - | 238 # 239 movi v1, 10 240 newarr v0, v1, R[] 241 bugid: ['1827'] 242 243 244 - file-name: "with_static_field_id" 245 description: Check that verifier reports error when the field doesn't resolve to a non-static object field 246 isa: 247 verification: 248 - field_id_non_static 249 header-template: [] 250 check-type: exit-positive 251 code-template: | 252 .record W { 253 W static_field <static> 254 W[] static_array <static> 255 } 256 .function void W.ctor(W a0) <ctor> { 257 return.void 258 } 259 .function void W.object_function(W a0) { 260 return.void 261 } 262 .record random_record_name { 263 W random_field_name 264 } 265 .function void static_function() { 266 return.void 267 } 268 269 .function i32 main() { 270 initobj W.ctor 271 sta.obj v0 272 ldobj.v.obj v1, v0, %s 273 cases: 274 # resolves to a static object field 275 - values: 276 - W.static_field 277 tags: [verifier] 278 runner-options: ['verifier-failure', 'verifier-config'] 279 bugid: ['1324', '1828'] 280 # resolves to a static object array 281 - values: 282 - W.static_array 283 tags: [verifier] 284 runner-options: ['verifier-failure', 'verifier-config'] 285 bugid: ['1324', '1828'] 286 # resolves to a non-existing object field 287 - values: 288 - W.field_not_exists 289 runner-options: [compile-failure] 290 # resolves to object's constructor 291 - values: 292 - W.ctor 293 runner-options: [compile-failure] 294 # resolves to objects's method 295 - values: 296 - W.object_function 297 runner-options: [compile-failure] 298 # resolves to some other object 299 - values: 300 - random_record_name 301 runner-options: [compile-failure] 302 # resolves to some static function 303 - values: 304 - static_function 305 runner-options: [compile-failure] 306 # resolves to a field name in a wrong object 307 - values: 308 - random_record_name.random_field_name 309 tags: [verifier] 310 runner-options: ['verifier-failure', 'verifier-config'] 311 bugid: ['1833', '3536'] 312 # cannot resolve, because it's a i32 number 313 - values: 314 - 0 315 runner-options: [compile-failure] 316 # cannot resolve, because it's a f64 number 317 - values: 318 - -1.1 319 runner-options: [compile-failure] 320 # cannot resolve, because it's a "null" string 321 - values: 322 - "null" 323 runner-options: [compile-failure] 324 325 326 - file-name: "with_wrong_field_size_or_type" 327 description: Check that verifier reports an error when the field resolves to a field with size or type that is not corresponding to bytecode 328 isa: 329 verification: 330 - field_id_size 331 header-template: [pandasm_header] 332 check-type: exit-positive 333 tags: [verifier] 334 runner-options: ['verifier-failure', 'verifier-config'] 335 bugid: ['1834', '2088'] 336 code-template: | 337 338 .function i32 main() { 339 initobj R.ctor 340 sta.obj v0 341 ldobj.v.obj v1, v0, %s 342 cases: 343 - values: 344 - R.fu1 345 - values: 346 - R.fu8 347 - values: 348 - R.fi8 349 - values: 350 - R.fu16 351 - values: 352 - R.fi16 353 - values: 354 - R.fu32 355 - values: 356 - R.fi32 357 - values: 358 - R.fu64 359 - values: 360 - R.fi64 361 - values: 362 - R.ff32 363 - values: 364 - R.ff64 365 366 367 - file-name: "op_v1_4_v2_4_id_16" 368 description: Check that compiler reports error when the register number is out of 4 bit size 369 isa: 370 instructions: 371 - sig: ldobj.v.obj v1:out:ref, v2:in:ref, field_id 372 acc: none 373 format: [op_v1_4_v2_4_id_16] 374 header-template: [pandasm_header] 375 check-type: exit-positive 376 runner-options: [compile-failure] 377 code-template: | 378 379 .function i32 main() { 380 ldobj.v.obj %s, R.fQ 381 cases: 382 - values: ['v15, v15'] 383 runner-options: ['compile-only'] 384 - values: ['v0, v16'] 385 - values: ['v16, v0'] 386 - values: ['v256, v0'] 387 - values: ['v1, v256'] 388 - values: ['v32567, v32567'] 389 - values: ['a0, v1'] 390 - values: ['v0, a1'] 391 - values: ['v0'] 392 - values: ['1'] 393 - values: ['"0"'] 394 395 396 - file-name: "from_all_field_types_pa" 397 description: Check that field value is loaded from field into register. More tests on ldobj.v.obj can be found in stobj.v.obj tests 398 isa: 399 description: Get field value from an object by field id and put it into register. 400 header-template: [pandasm_header] 401 check-type: exit-positive 402 tags: ['tsan'] 403 code-template: | 404 405 .function i32 main() { 406 initobj R.ctor 407 sta.obj v0 408 # store null into Q type field 409 lda.null 410 sta.obj v3 411 stobj.obj v0, R.fQ 412 # store null into Q[] type field 413 lda.null 414 sta.obj v4 415 stobj.obj v0, R.fQArray 416 # store R object into R type field 417 initobj R.ctor 418 sta.obj v5 419 stobj.obj v0, R.fR 420 # store R[] into R[] type field 421 movi v1, 10 422 newarr v6, v1, R[] 423 lda.obj v6 424 stobj.obj v0, R.fRArray 425 # store R object into panda.Object type field 426 initobj R.ctor 427 sta.obj v7 428 stobj.obj v0, R.fObj 429 # store R[] into panda.Object type field 430 movi v1, 10 431 newarr v8, v1, R[] 432 lda.obj v8 433 stobj.obj v0, R.fObj2 434 # store R[] into panda.Object[] type field 435 movi v1, 10 436 newarr v9, v1, R[] 437 lda.obj v9 438 stobj.obj v0, R.fObjArray 439 label0: 440 # load null from Q type field 441 ldobj.v.obj v1, v0, R.fQ 442 lda.obj v1 443 jeq.obj v3, label1 444 ldai 1 445 return 446 label1: 447 # load null from Q[] type field 448 ldobj.v.obj v1, v0, R.fQArray 449 lda.obj v1 450 jeq.obj v4, label2 451 ldai 2 452 return 453 label2: 454 # load R object from R type field 455 ldobj.v.obj v1, v0, R.fR 456 lda.obj v1 457 jeq.obj v5, label3 458 ldai 3 459 return 460 label3: 461 # load R[] from R[] type field 462 ldobj.v.obj v1, v0, R.fRArray 463 lda.obj v1 464 jeq.obj v6, label4 465 ldai 4 466 return 467 label4: 468 # load R object from panda.Object type field 469 ldobj.v.obj v1, v0, R.fObj 470 lda.obj v1 471 jeq.obj v7, label5 472 ldai 5 473 return 474 label5: 475 # load R[] from panda.Object type field 476 ldobj.v.obj v1, v0, R.fObj2 477 lda.obj v1 478 jeq.obj v8, label6 479 ldai 6 480 return 481 label6: 482 # load R[] from panda.Object[] type field 483 ldobj.v.obj v1, v0, R.fObjArray 484 lda.obj v1 485 jeq.obj v9, success 486 ldai 7 487 return 488 success: 489 490 491 - file-name: "from_all_field_types_j" 492 description: Check that field value is loaded from field into register. More tests on ldobj.v.obj can be found in stobj.v.obj tests 493 isa: 494 description: Get field value from an object by field id and put it into register. 495 header-template: [PandaAssembly_header] 496 runner-options: [use-pa] 497 check-type: exit-positive 498 code-template: | 499 500 .function i32 main() { 501 initobj R.ctor 502 sta.obj v0 503 # store subsclass R into Q type field 504 initobj R.ctor 505 sta.obj v3 506 stobj.obj v0, R.fQ 507 # store subsclass R into interface type field 508 initobj R.ctor 509 sta.obj v4 510 stobj.obj v0, R.fI 511 # store subsclass R into base type field 512 initobj R.ctor 513 sta.obj v5 514 stobj.obj v0, R.fObj 515 # store subclass R[] into Q[] type field 516 movi v1, 10 517 newarr v6, v1, R[] 518 lda.obj v6 519 stobj.obj v0, R.fQArray 520 # store subclass R[] into interface [] type field 521 movi v1, 10 522 newarr v7, v1, R[] 523 lda.obj v7 524 stobj.obj v0, R.fIArray 525 # store subclass R[] into base type [] field 526 movi v1, 10 527 newarr v8, v1, R[] 528 lda.obj v8 529 stobj.obj v0, R.fObjArray 530 # store subclass R[] into base type field 531 movi v1, 10 532 newarr v9, v1, R[] 533 lda.obj v9 534 stobj.obj v0, R.fObj2 535 label0: 536 # load R from Q type field 537 ldobj.v.obj v1, v0, R.fQ 538 lda.obj v1 539 jeq.obj v3, label1 540 ldai 1 541 return 542 label1: 543 # load R from interface type field 544 ldobj.v.obj v1, v0, R.fI 545 lda.obj v1 546 jeq.obj v4, label2 547 ldai 2 548 return 549 label2: 550 # load R from base type field 551 ldobj.v.obj v1, v0, R.fObj 552 lda.obj v1 553 jeq.obj v5, label3 554 ldai 3 555 return 556 label3: 557 # load R[] from Q[] type field 558 ldobj.v.obj v1, v0, R.fQArray 559 lda.obj v1 560 jeq.obj v6, label4 561 ldai 4 562 return 563 label4: 564 # load R[] from interface[] type field 565 ldobj.v.obj v1, v0, R.fIArray 566 lda.obj v1 567 jeq.obj v7, label5 568 ldai 5 569 return 570 label5: 571 # load R[] from base type [] field 572 ldobj.v.obj v1, v0, R.fObjArray 573 lda.obj v1 574 jeq.obj v8, label6 575 ldai 6 576 return 577 label6: 578 # load R[] from base type field 579 ldobj.v.obj v1, v0, R.fObj2 580 lda.obj v1 581 jeq.obj v9, success 582 ldai 7 583 return 584 success: 585