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