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      .record panda.Object <external>
19      .record Q {}
20      .record R {
21        u1             fu1
22        u8             fu8
23        i8             fi8
24        u16            fu16
25        i16            fi16
26        u32            fu32
27        i32            fi32
28        u64            fu64
29        i64            fi64
30        f32            ff32
31        f64            ff64
32        # objects
33        i32[]          fi32Array
34        Q              fQ
35        Q[]            fQArray
36        R              fR
37        R[]            fRArray
38        panda.Object   fObj
39        panda.Object[] fObjArray
40      }
41
42  - name: PandaAssembly_header
43    template: |
44      .language PandaAssembly
45      .record panda.Object <external>
46      .record I <panda.interface> {}
47      .record Q <panda.implements=I> {}
48      .record R <panda.extends=Q> {
49        u1                 fu1
50        i8                 fi8
51        u16                fu16
52        i16                fi16
53        i32                fi32
54        i64                fi64
55        f32                ff32
56        f64                ff64
57        # objects
58        i32[]              fi32Array
59        Q                  fQ
60        Q[]                fQArray
61        R                  fR
62        R[]                fRArray
63        I                  fI
64        I[]                fIArray
65        panda.Object   fObj
66        panda.Object[] fObjArray
67      }
68
69tests:
70  - file-name: "stobj.v.obj"
71    isa:
72      title: Store register content into object field
73      description: >
74        Store register content into object field by field_id.
75      instructions:
76        - sig: stobj.v.obj v1:in:ref, v2:in:ref, field_id
77          acc: none
78          format: [op_v1_4_v2_4_id_16]
79    commands:
80
81      - file-name: "check_if_regs_initialized"
82        description: Check that verifier reports error if source registers are not initialized.
83        isa:
84          description: Store register content into object field by field_id.
85        header-template: ['pandasm_header']
86        check-type: exit-positive
87        tags: ['verifier']
88        runner-options: ['verifier-failure', 'verifier-config']
89        code-template: |
90
91          %s
92
93          .function i32 main() {
94            newobj v0, R
95            %s
96        cases:
97          - values:
98            - ""
99            - stobj.v.obj v1, v0, R.fR
100          - values:
101            - ""
102            - stobj.v.obj v0, v2, R.fR
103          - values:
104            - |
105              # v0 (value) not initialized in the frame
106              .function void check(R a0) <static> {
107                stobj.v.obj v0, a0, R.fR
108                return.void
109              }
110            - call.short check, v0
111          - values:
112            - |
113              # v0 (object) not initialized in the frame
114              .function void check(R a0) <static> {
115                lda.obj a0
116                stobj.v.obj a0, v0, R.fR
117                return.void
118              }
119            - call.short check, v0
120
121
122      - file-name: "with_null_ref_p"
123        description: Check that NullPointerException is thrown if source ref is null.
124        isa:
125          exceptions:
126            - x_null
127        header-template: ['pandasm_header']
128        tags: ['irtoc_ignore']
129        check-type: empty
130        code-template: |
131          .record panda.NullPointerException <external>
132
133          .function R get_null() {
134            lda.null
135            return.obj
136          }
137
138          .function i32 main() {
139            call.short get_null
140            sta.obj v2
141            %s
142          try_begin:
143            stobj.v.obj v1, v2, %s
144            ldai 1
145            return
146          try_end:
147            ldai 0
148            return
149          .catch panda.NullPointerException, try_begin, try_end, try_end
150          }
151        cases:
152          - values:
153            - mov.null v1
154            - R.fR
155          - values:
156            - newobj v1, Q
157            - R.fQ
158          - values:
159            - |
160              #
161                movi v1, 10
162                newarr v1, v1, i32[]
163            - R.fi32Array
164
165
166      - file-name: "with_null_ref_j"
167        description: Check that NullPointerException is thrown if source ref is null.
168        isa:
169          exceptions:
170            - x_null
171        header-template: ['PandaAssembly_header']
172        runner-options: ['use-pa']
173        tags: ['irtoc_ignore']
174        check-type: empty
175        code-template: |
176          .record panda.NullPointerException <external>
177
178          .function R get_null() {
179            lda.null
180            return.obj
181          }
182
183          .function i32 main() {
184            call.short get_null
185            sta.obj v2
186            %s
187          try_begin:
188            stobj.v.obj v1, v2, %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            - mov.null v1
199            - R.fObj
200          - values:
201            - newobj v1, Q
202            - R.fQ
203          - values:
204            - |
205              #
206                movi v1, 10
207                newarr v1, v1, panda.Object[]
208            - R.fObjArray
209
210
211      - file-name: "with_non_object_ref_p"
212        description: >
213          Check that verifier reports error when the 2nd operand is not a ref to
214          an object (other than array) in PandaAssembly context.
215        isa:
216          verification:
217            - v2_object
218        header-template: ['pandasm_header']
219        check-type: exit-positive
220        tags: ['verifier']
221        runner-options: ['verifier-failure', 'verifier-config']
222        code-template: |
223
224          .function i32 main() {
225            %s
226            newobj v1, Q
227            stobj.v.obj v1, v0, R.fQ   # v0 is not a ref to obj
228        cases:
229          - values:
230            - movi v0, 0
231          - values:
232            - movi v0, 1
233          - values:
234            - movi.64 v0, 0x00
235          - values:
236            - movi.64 v0, 0xCAFECAFECAFECAFE
237          - values:
238            - fmovi.64 v0, 0.0
239          - values:
240            - fmovi.64 v0, 6.62607015
241          - values:
242            - |
243              #
244                movi v1, 10
245                newarr v0, v1, R[]
246
247
248      - file-name: "with_non_object_ref_j"
249        description: >
250          Check that verifier reports error when the 2nd operand is not a ref to
251          an object (other than array) in PandaAssembly context.
252        isa:
253          verification:
254            - v2_object
255        header-template: ['PandaAssembly_header']
256        check-type: exit-positive
257        tags: [verifier, pa-verifier]
258        runner-options: ['use-pa', 'verifier-failure', 'verifier-config']
259        code-template: |
260
261          .function i32 main() {
262            %s
263            newobj v1, panda.Object
264            stobj.v.obj v1, v0, R.fObj   # v0 is not a ref to obj
265        cases:
266          - values:
267            - movi v0, 0
268          - values:
269            - movi v0, 1
270          - values:
271            - movi.64 v0, 0x00
272          - values:
273            - movi.64 v0, 0xCAFECAFECAFECAFE
274          - values:
275            - fmovi.64 v0, 0.0
276          - values:
277            - fmovi.64 v0, 6.62607015
278          - values:
279            - |
280              #
281                movi v1, 10
282                newarr v0, v1, panda.Object[]
283
284
285      - file-name: "with_static_field_id_p"
286        description: >
287          Check that verifier reports error when the field doesn't resolve to
288          a non-static object field.
289        isa:
290          verification:
291            - field_id_non_static
292        header-template: []
293        check-type: exit-positive
294        tags: ['verifier']
295        runner-options: ['verifier-failure', 'verifier-config']
296        code-template: |
297          .record W {
298            W   static_field  <static>
299            W[] static_array  <static>
300          }
301          .function void W.foo(W a0) {
302            return.void
303          }
304          .record random_record {
305            W random_field
306          }
307          .function void random_function() {
308            return.void
309          }
310
311          .function i32 main() {
312            newobj v0, W
313            mov.null v1
314            stobj.v.obj v1, v0, %s
315        cases:
316          # resolves to a static object field
317          - values:
318            - W.static_field
319          # resolves to a static object array
320          - values:
321            - W.static_array
322          # resolves to a non-existing object field
323          - values:
324            - W.field_not_exists
325            runner-options: ['compile-failure']
326          # resolves to objects's method
327          - values:
328            - W.foo
329            runner-options: ['compile-failure']
330          # resolves to some other object
331          - values:
332            - random_record
333            runner-options: ['compile-failure']
334          # resolves to some static function
335          - values:
336            - random_function
337            runner-options: ['compile-failure']
338          # resolves to a field name in a wrong object
339          - values:
340            - random_record.random_field
341          # cannot resolve, because it's a i32 number
342          - values:
343            - 0
344            runner-options: ['compile-failure']
345          # cannot resolve, because it's a f64 number
346          - values:
347            - -1.1
348            runner-options: ['compile-failure']
349          # cannot resolve, because it's a "null" string
350          - values:
351            - "null"
352            runner-options: ['compile-failure']
353
354
355      - file-name: "with_static_field_id_j"
356        description: >
357          Check that verifier reports error when the field doesn't resolve to a non-static
358          valid object field in PandaAssembly context.
359        isa:
360          verification:
361            - field_id_non_static
362        header-template: []
363        check-type: exit-positive
364        runner-options: ['use-pa', 'verifier-failure', 'verifier-config']
365        tags: [verifier, pa-verifier]
366        code-template: |
367          .language PandaAssembly
368          .record A {
369            A   a_field  <static, panda.access=public>
370          }
371          .record B <panda.extends=A> {
372            B   b_field  <static, panda.access=public>
373          }
374          .record C <panda.extends=B> {
375            C   c_field  <static, panda.access=public>
376          }
377
378          .function i32 main() {
379            newobj v0, %s
380            stobj.v.obj v0, v0, %s
381        cases:
382          - values:
383            - C
384            - C.c_field
385          - values:
386            - C
387            - B.b_field
388          - values:
389            - C
390            - A.a_field
391          - values:
392            - B
393            - B.a_field
394            runner-options: ['compile-failure']
395          - values:
396            - B
397            - B.c_field
398            runner-options: ['compile-failure']
399
400
401      - file-name: "with_wrong_v1_type_p"
402        description: >
403          Check that verifier reports error when v1 contains a value of type
404          not corresponding to the bytecode.
405        isa:
406          verification:
407            - v1_type
408        header-template: ['pandasm_header']
409        check-type: exit-positive
410        tags: ['verifier']
411        runner-options: ['verifier-failure', 'verifier-config']
412        code-template: |
413
414          .function i32 main() {
415            newobj v0, R
416            %s
417            stobj.v.obj v1, v0, %s
418        cases:
419          # store into object field
420          - values:
421            - movi v1, 0
422            - R.fQ
423          - values:
424            - movi.64 v1, 1
425            - R.fQ
426          - values:
427            - fmovi.64 v1, 0x7FFFFFFFFFFFFFFF
428            - R.fQ
429          - values:
430            - |
431              #
432                lda.type R
433                sta.obj v1
434            - R.fQ
435          - values:
436            - newobj v1, panda.Object
437            - R.fQ
438          - values:
439            - |
440              #
441                movi v1, 10
442                newarr v1, v1, Q[]
443            - R.fQ
444          # store into object array field
445          - values:
446            - movi v1, 0
447            - R.fQArray
448          - values:
449            - movi.64 v1, 1
450            - R.fQArray
451          - values:
452            - fmovi.64 v1, 0x7FFFFFFFFFFFFFFF
453            - R.fQArray
454          - values:
455            - newobj v1, Q
456            - R.fQArray
457          - values:
458            - newobj v1, panda.Object
459            - R.fQArray
460          - values:
461            - |
462              #
463                movi v1, 10
464                newarr v1, v1, R[]
465            - R.fQArray
466          - values:
467            - |
468              #
469                movi v1, 10
470                newarr v1, v1, panda.Object[]
471            - R.fQArray
472          # store into i32[] array field
473          - values:
474            - movi v1, 0
475            - R.fi32Array
476          - values:
477            - movi.64 v1, 1
478            - R.fi32Array
479          - values:
480            - fmovi.64 v1, 0x7FFFFFFFFFFFFFFF
481            - R.fi32Array
482          - values:
483            - |
484              #
485                lda.type R
486                sta.obj v1
487            - R.fi32Array
488          - values:
489            - |
490              #
491                movi v1, 10
492                newarr v1, v1, Q[]
493            - R.fi32Array
494          # store into panda.Object field
495          - values:
496            - movi v1, 0
497            - R.fObj
498          - values:
499            - movi.64 v1, 1
500            - R.fObj
501          - values:
502            - fmovi.64 v1, 0x7FFFFFFFFFFFFFFF
503            - R.fObj
504          - values:
505            - newobj v1, panda.Object
506            - R.fObj
507            runner-options: ['verifier-only', 'verifier-config']
508          - values:
509            - |
510              #
511                lda.type R
512                sta.obj v1
513            - R.fObj
514            runner-options: ['verifier-only', 'verifier-config']
515            bugid: ['3594']
516            ignore: true
517          - values:
518            - |
519              #
520                lda.str ""
521                sta.obj v1
522            - R.fObj
523            runner-options: ['verifier-only', 'verifier-config']
524          - values:
525            - mov.null v1
526            - R.fObj
527            runner-options: ['verifier-only', 'verifier-config']
528          - values:
529            - |
530              #
531                movi v1, 10
532                newarr v1, v1, Q[]
533            - R.fObj
534            runner-options: ['verifier-only', 'verifier-config']
535          # store into panda.Object[] field
536          - values:
537            - movi v1, 0
538            - R.fObjArray
539          - values:
540            - movi.64 v1, 1
541            - R.fObjArray
542          - values:
543            - fmovi.64 v1, 0x7FFFFFFFFFFFFFFF
544            - R.fObjArray
545          - values:
546            - newobj v1, panda.Object
547            - R.fObjArray
548          - values:
549            - |
550              #
551                lda.type R
552                sta.obj v1
553            - R.fObjArray
554          - values:
555            - |
556              #
557                lda.str ""
558                sta.obj v1
559            - R.fObjArray
560          - values:
561            - mov.null v1
562            - R.fObjArray
563            runner-options: ['verifier-only', 'verifier-config']
564          - values:
565            - |
566              #
567                movi v1, 10
568                newarr v1, v1, Q[]
569            - R.fObjArray
570            runner-options: ['verifier-only', 'verifier-config']
571          - values:
572            - |
573              #
574                movi v1, 10
575                newarr v1, v1, panda.Object[]
576            - R.fObjArray
577            runner-options: ['verifier-only', 'verifier-config']
578
579
580      - file-name: "with_wrong_v1_type_j"
581        description: >
582          Check that verifier reports error when v1 contains a value of type
583          not corresponding to the bytecode.
584        isa:
585          verification:
586            - v1_type
587        header-template: ['PandaAssembly_header']
588        check-type: exit-positive
589        tags: [verifier, pa-verifier]
590        runner-options: ['verifier-failure', 'verifier-config', 'use-pa']
591        code-template: |
592
593          .function i32 main() {
594            newobj v0, R
595            %s
596            stobj.v.obj v1, v0, %s
597        cases:
598          # store into object field
599          - values:
600            - movi v1, 0
601            - R.fObj
602          - values:
603            - movi.64 v1, 1
604            - R.fObj
605          - values:
606            - fmovi.64 v1, 0x7FFFFFFFFFFFFFFF
607            - R.fObj
608          - values:
609            - |
610              #
611                lda.type R # wrong type
612                sta.obj v1
613            - R.fQ
614          - values:
615            - |
616              #
617                lda.str "abc"  # wrong interface
618                sta.obj v1
619            - R.fI
620          - values:
621            - newobj v1, Q  # supertype
622            - R.fR
623          - values:
624            - newobj v1, panda.Object # supertype
625            - R.fQ
626          - values:
627            - |
628              #
629                movi v1, 10
630                newarr v1, v1, R[]
631            - R.fR
632          # store into object array field
633          - values:
634            - movi v1, 0
635            - R.fObjArray
636          - values:
637            - movi.64 v1, 1
638            - R.fObjArray
639          - values:
640            - fmovi.64 v1, 0x7FFFFFFFFFFFFFFF
641            - R.fObjArray
642          - values:
643            - newobj v1, R
644            - R.fRArray
645          - values:
646            - |
647              #
648                lda.type R
649                sta.obj v1
650            - R.fObjArray
651          - values:
652            - | # array of supertypes
653              #
654                movi v1, 10
655                newarr v1, v1, Q[]
656            - R.fRArray
657          # store into panda.Object field
658          - values:
659            - movi v1, 0
660            - R.fObj
661          - values:
662            - movi.64 v1, 1
663            - R.fObj
664          - values:
665            - fmovi.64 v1, 0x7FFFFFFFFFFFFFFF
666            - R.fObj
667          - values:
668            - |
669              #
670                lda.type R
671                sta.obj v1
672            - R.fObj
673            runner-options: ['verifier-only', 'verifier-config', 'use-pa']
674            bugid: ['3594']
675            ignore: true
676          - values:
677            - |
678              #
679                lda.str ""
680                sta.obj v1
681            - R.fObj
682            runner-options: ['verifier-only', 'verifier-config', 'use-pa']
683          - values:
684            - mov.null v1
685            - R.fObj
686            runner-options: ['verifier-only', 'verifier-config', 'use-pa']
687          - values:
688            - |
689                movi v1, 10
690                  newarr v1, v1, Q[]
691                  lda.obj v1
692            - R.fObj
693            runner-options: ['verifier-only', 'verifier-config', 'use-pa']
694          # store into panda.Object[] field
695          - values:
696            - movi v1, 0
697            - R.fObjArray
698          - values:
699            - movi.64 v1, 1
700            - R.fObjArray
701          - values:
702            - fmovi.64 v1, 0x7FFFFFFFFFFFFFFF
703            - R.fObjArray
704          - values:
705            - |
706              #
707                lda.type R
708                sta.obj v1
709            - R.fObjArray
710          - values:
711            - |
712              #
713                lda.str ""
714                sta.obj v1
715            - R.fObjArray
716          - values:
717            - mov.null v1
718            - R.fObjArray
719            runner-options: ['verifier-only', 'verifier-config', 'use-pa']
720          - values:
721            - |
722                movi v1, 10
723                  newarr v1, v1, Q[]
724                  lda.obj v1
725            - R.fObjArray
726            runner-options: ['verifier-only', 'verifier-config', 'use-pa']
727
728
729      - file-name: "op_v1_4_v2_4_id_16"
730        description: >
731          Check that compiler reports error when the register number
732          is out of 4 bit size.
733        isa:
734          instructions:
735            - sig: stobj.v.obj v1:in:ref, v2:in:ref, field_id
736              acc: none
737              format: [op_v1_4_v2_4_id_16]
738        header-template: ['pandasm_header']
739        runner-options: ['compile-failure']
740        check-type: exit-positive
741        code-template: |
742
743          .function i32 main() {
744            stobj.v.obj %s, R.fQ
745        cases:
746          - values: ['v15, v15']
747            runner-options: ['compile-only']
748          - values: ['v16, v15']
749          - values: ['v15, v16']
750          - values: ['v255, v0']
751          - values: ['v15, v256']
752          - values: ['v65535, v65535']
753          - values: ['v32767, v0']
754
755
756      - file-name: "into_all_field_types_p"
757        description: Check that register value is stored in field.
758        isa:
759          description: Store register content into object field by field_id.
760        header-template: ['pandasm_header']
761        check-type: exit-positive
762        tags: ['tsan']
763        code-template: |
764
765          .function i32 main() {
766            movi v6, 12345
767            newobj v0, R
768            %s
769            ldai 12345
770            stobj.v.obj v1, v0, R.%s
771            jeq v6, cont
772            ldai 2
773            return
774          cont:
775            ldobj.v.obj v2, v0, R.%s
776            lda.obj v2
777            jeq.obj v1, success
778            ldai 1
779            return
780          success:
781        cases:
782          - values:
783            - |
784              #
785                # store null into Q type field
786                mov.null v1
787            - fQ
788            - fQ
789          - values:
790            - |
791              #
792                # store null into Q[] type field
793                mov.null v1
794            - fQArray
795            - fQArray
796          - values:
797            - |
798              #
799                # store null into panda.Object type field
800                mov.null v1
801            - fObj
802            - fObj
803          - values:
804            - |
805              #
806                # store null into panda.Object[] type field
807                mov.null v1
808            - fObjArray
809            - fObjArray
810          - values:
811            - |
812              #
813                # store Q into Q type field
814                newobj v1, Q
815            - fQ
816            - fQ
817          - values:
818            - |
819              #
820                # store Q[] into Q[] type field
821                movi v1, 10
822                newarr v1, v1, Q[]
823            - fQArray
824            - fQArray
825          - values:
826            - |
827                # store Q into panda.Object type field
828                  newobj v1, Q
829            - fObj
830            - fObj
831          - values:
832            - |
833                # store Q[] into panda.Object type field
834                  movi v1, 10
835                  newarr v1, v1, Q[]
836            - fObj
837            - fObj
838          - values:
839            - |
840                # store Q[] into panda.Object[] type field
841                  movi v1, 10
842                  newarr v1, v1, Q[]
843            - fObjArray
844            - fObjArray
845
846
847      - file-name: "into_all_field_types_j"
848        description: Check that register value is stored in field.
849        isa:
850          description: Store register content into object field by field_id.
851        header-template: ['PandaAssembly_header']
852        runner-options: ['use-pa']
853        check-type: exit-positive
854        code-template: |
855
856          .function i32 main() {
857            movi v6, 123456
858            newobj v0, R
859            %s
860            ldai 123456
861            stobj.v.obj v1, v0, R.%s
862            jeq v6, cont
863            ldai 2
864            return
865          cont:
866            ldobj.v.obj v2, v0, R.%s
867            lda.obj v2
868            jeq.obj v1, success
869            ldai 1
870            return
871          success:
872        cases:
873          - values:
874            - |
875              #
876                # store null into panda.Object type field
877                mov.null v1
878            - fObj
879            - fObj
880          - values:
881            - |
882              #
883                # store null into panda.Object[] type field
884                mov.null v1
885            - fObjArray
886            - fObjArray
887          - values:
888            - |
889              #
890                # store subsclass R into Q type field
891                newobj v1, R
892            - fQ
893            - fQ
894          - values:
895            - |
896              #
897                # store subsclass R into interface type field
898                newobj v1, R
899            - fI
900            - fI
901          - values:
902            - |
903              #
904                # store subsclass R into base type field
905                newobj v1, R
906            - fObj
907            - fObj
908          - values:
909            - |
910              #
911                # store panda.Object into base type field
912                newobj v1, panda.Object
913            - fObj
914            - fObj
915          - values:
916            - |
917              #
918                # store subclass R[] into Q[] type field
919                movi v1, 10
920                newarr v1, v1, R[]
921            - fQArray
922            - fQArray
923          - values:
924            - |
925              #
926                # store subclass R[] into interface [] type field
927                movi v1, 10
928                newarr v1, v1, R[]
929            - fIArray
930            - fIArray
931          - values:
932            - |
933              #
934                # store subclass R[] into base type [] field
935                movi v1, 10
936                newarr v1, v1, R[]
937            - fObjArray
938            - fObjArray
939          - values:
940            - |
941              #
942                # store subclass R[] into base type field
943                movi v1, 10
944                newarr v1, v1, R[]
945            - fObj
946            - fObj
947          - values:
948            - |
949              #
950                # store i32[] into i32[] type field
951                movi v1, 10
952                newarr v1, v1, i32[]
953            - fi32Array
954            - fi32Array
955          - values:
956            - |
957              #
958                # store i32[] into base type field
959                movi v1, 10
960                newarr v1, v1, i32[]
961            - fObj
962            - fObj
963          - values:
964            - |
965              #
966                # store panda.Object[] into base type [] field
967                movi v1, 10
968                newarr v1, v1, panda.Object[]
969            - fObjArray
970            - fObjArray
971          - values:
972            - |
973              #
974                # store panda.Object[] into base type field
975                movi v1, 10
976                newarr v1, v1, panda.Object[]
977            - fObj
978            - fObj
979