• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2021 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: java
16    template: >
17      .language Java
18  - name: r_A
19    template: |
20      .record A {}
21
22      .function void A.constructor(A a0) <ctor> {
23          return.void
24      }
25  - name: r_B
26    template: |
27      .record B {}
28
29      .function void B.constructor(B a0) <ctor> {
30          return.void
31      }
32tests:
33  - file-name: call.virt.short.negative
34    isa:
35      instructions:
36        - sig: call.virt.short method_id, v1:in:top, v2:in:top
37          acc: out:top
38          format: [op_v1_4_v2_4_id_16]
39      title: Object calls
40      description: >
41        Call indicated object method, i.e. create new frame, pass values of arguments and
42        continue execution from the first instruction of a method.
43        Callee should treat accumulator value as undefined and cannot use it until accumulator
44        definition in the new frame.
45        Result (if any) is returned in accumulator (see 'Calling sequence' chapter for more details).
46        Method, its class and the number of argument is resolved by given method_id in runtime
47        constant-pool based on object reference using language-specific semantics (currently only Java
48        virtual methods are supported, further extensions are TBD).
49        Object reference is passed in the first source register, arguments are passed starting from
50        the second source register in the same order as in method signature.
51        Non-range instructions can be used to pass up to 4 arguments (including object reference).
52        Unused register slot values will be discarded and corresponding registers will not be
53        passed to the callee).
54        For methods with more arguments range kinds of instruction are to be used, which takes
55        the needed number of arguments starting from 'vs' register (including object reference).
56      verification:
57        - method_id_non_static
58        - compatible_arguments
59        - method_id_accessible
60      exceptions:
61        - x_null
62        - x_abstract
63    commands:
64
65      - file-name: wrong_object_1
66        bugid: ['2287', '5271']
67        isa:
68          instructions:
69            - sig: call.virt.short method_id, v1:in:top, v2:in:top
70              acc: out:top
71              format: [op_v1_4_v2_4_id_16]
72          verification:
73            - compatible_arguments
74        header-template: [r_A, r_B]
75        description: Check incorrect usage of `call.virt.short` instruction. First argument is of incorrect type instead of object reference.
76        runner-options: ['verifier-failure', 'verifier-debug-config']
77        tags: ['verifier']
78        code-template: |
79          .function i32 A.foo(A a0%s) {
80              ldai 1
81              return
82          }
83
84          .function i32 main() {
85              %s
86              call.virt.short A.foo%s
87              # check object is equal to original
88              movi v0, 1
89              jne v0, exit_failure
90              ldai 0
91              return
92          exit_failure:
93              ldai 1
94              return
95        check-type: none
96        cases:
97          - values:
98            - ''
99            - ''
100            - ','
101            runner-options: [compile-failure]
102            bugid: ['1855']
103          - values:
104            - ''
105            - 'movi v0, 0'
106            - ', v0'
107          - values:
108            - ''
109            - |
110              #
111                  lda.type A
112                  sta.obj v0
113            - ', v0'
114            bugid: ['2256']
115          - values:
116            - ''
117            - |
118              #
119                  lda.type B
120                  sta.obj v0
121            - ', v0'
122          - values:
123            - ''
124            - 'movi.64 v0, 0'
125            - ', v0'
126          - values:
127            - ''
128            - 'fmovi.64 v0, 0'
129            - ', v0'
130          - values:
131            - ''
132            - |
133              #
134                  lda.str "some string"
135                  sta.obj v0
136            - ', v0'
137          - values:
138            - ''
139            - |
140              #
141                  lda.str "some string"
142                  sta.obj v0
143                  movi v1, 1
144            - ', v0, v1'
145          - values:
146            - ''
147            - |
148              #
149                  lda.str "some string"
150                  sta.obj v0
151                  movi.64 v1, 1
152            - ', v0, v1'
153          - values:
154            - ''
155            - |
156              #
157                  lda.str "some string"
158                  sta.obj v0
159                  fmovi.64 v1, 1
160            - ', v0, v1'
161          - values:
162            - ', i32 a1'
163            - |
164              #
165                  movi v0, 0
166                  movi v1, 1
167            - ', v0, v1'
168          - values:
169            - ', i64 a1'
170            - |
171              #
172                  movi v0, 0
173                  movi.64 v1, 1
174            - ', v0, v1'
175          - values:
176            - ', f64 a1'
177            - |
178              #
179                  movi v0, 0
180                  fmovi.64 v1, 1.1
181            - ', v0, v1'
182
183          - values:
184            - ', i32 a1'
185            - |
186              #
187                  movi.64 v0, 0
188                  movi v1, 1
189            - ', v0, v1'
190          - values:
191            - ', i64 a1'
192            - |
193              #
194                  movi.64 v0, 0
195                  movi.64 v1, 1
196            - ', v0, v1'
197          - values:
198            - ', f64 a1'
199            - |
200              #
201                  movi.64 v0, 0
202                  fmovi.64 v1, 1.1
203            - ', v0, v1'
204
205          - values:
206            - ', i32 a1'
207            - |
208              #
209                  fmovi.64 v0, 0.0
210                  movi v1, 1
211            - ', v0, v1'
212          - values:
213            - ', i64 a1'
214            - |
215              #
216                  fmovi.64 v0, 0
217                  movi.64 v1, 1
218            - ', v0, v1'
219          - values:
220            - ', f64 a1'
221            - |
222              #
223                  fmovi.64 v0, 0
224                  fmovi.64 v1, 1.1
225            - ', v0, v1'
226
227      - file-name: p_wrong_object_2
228        isa:
229          instructions:
230            - sig: call.virt.short method_id, v1:in:top, v2:in:top
231              acc: out:top
232              format: [op_v1_4_v2_4_id_16]
233          verification:
234            - compatible_arguments
235        header-template: [r_A, r_B]
236        description: >
237          Check incorrect usage of `call.virt.short` instruction. First argument is a reference to object of incompatible type.
238          Use PandaAssembly language context.
239        runner-options: ['verifier-failure', 'verifier-debug-config']
240        tags: [verifier]
241        bugid: ['1324']
242        template-cases:
243          - values:
244            - |
245              %s
246              .function i32 A.foo(A a0%s) {
247                  ldai 1
248                  return
249              }
250          - values:
251            - |
252              %s
253              ##- %s
254              .function i32 A.foo(A a0) {
255                  ldai 1
256                  return
257              }
258        code-template: |
259          %s
260
261          .function i32 main() {
262              initobj.short B.constructor
263              sta.obj v0
264              *s
265              call.virt.short A.foo, v0*s
266
267        check-type: exit-positive
268        cases:
269          - values:
270            - ''
271            - ''
272            - ''
273            - ''
274          - values:
275            - ''
276            - ',i32 a1'
277            - 'movi v1, 0'
278            - ', v1'
279          - values:
280            - ''
281            - ',i32 a1'
282            - 'movi v1, 1'
283            - ', v1'
284          - values:
285            - ''
286            - ', i64 a1'
287            - 'movi.64 v1, 0'
288            - ', v1'
289          - values:
290            - ''
291            - ', i64 a1'
292            - 'movi.64 v1, 0x100000000'
293            - ', v1'
294          - values:
295            - ''
296            - ', f64 a1'
297            - 'fmovi.64 v1, 0'
298            - ', v1'
299          - values:
300            - ''
301            - ', f64 a1'
302            - 'fmovi.64 v1, 1.1'
303            - ', v1'
304          - values:
305            - '.record panda.String <external>'
306            - ', panda.String a1'
307            - |
308              #
309                  lda.str "some string"
310                  sta.obj v1
311            - ', v1'
312
313      - file-name: arg_types
314        isa:
315          instructions:
316            - sig: call.virt.short method_id, v1:in:top, v2:in:top
317              acc: out:top
318              format: [op_v1_4_v2_4_id_16]
319          verification:
320            - compatible_arguments
321        header-template: [r_A]
322        description: >
323          Verifier should report when register type does not match function argument type.
324        code-template: |
325            .record panda.Object <external>
326            .record panda.String <external>
327            .function void A.func(A a0, %s) {
328                return.void
329            }
330
331            .function i32 main() {
332                initobj A.constructor
333                sta.obj v0
334                *s
335                call.virt.short A.func, v0, v1
336        template-cases:
337            - values:
338              - 'i32 a1'
339              exclude: [i32]
340            - values:
341              - 'i64 a1'
342              exclude: [i64]
343            - values:
344              - 'f64 a1'
345              exclude: [f64]
346            - values:
347                - 'i32[] a1'
348              exclude: [i32arr]
349            - values:
350                - 'i64[] a1'
351              exclude: [i64arr]
352            - values:
353                - 'f64[] a1'
354              exclude: [f64arr]
355            - values:
356                - 'panda.String a1'
357              exclude: [str]
358            - values:
359                - 'panda.String[] a1'
360              exclude: [strarr]
361            - values:
362                - 'panda.Object a1'
363              exclude: [obj, objarr, i32arr, i64arr, f64arr, str, strarr]
364            - values:
365                - 'panda.Object[] a1'
366              exclude: [objarr, strarr]
367
368        check-type: exit-positive
369        bugid: ['1324']
370        tags: [verifier]
371        runner-options: ['verifier-failure', 'verifier-debug-config']
372        cases:
373          - values:
374            - |
375              #
376                  movi v1, 0
377            id: i32
378          - values:
379            - |
380              #
381                  movi v1, 1
382            id: i32
383          - values:
384            - |
385              #
386                  movi.64 v1, 0
387            id: i64
388          - values:
389            - |
390              #
391                  movi.64 v1, 1
392            id: i64
393          - values:
394            - |
395              #
396                  fmovi.64 v1, 0
397            id: f64
398          - values:
399            - |
400              #
401                  fmovi.64 v1, 3.1415926535
402            id: f64
403          - values:
404            - |
405              #
406                  movi v1, 123
407                  newarr v1, v1, i32[]
408            id: i32arr
409          - values:
410            - |
411              #
412                  movi v1, 123
413                  newarr v1, v1, i64[]
414            id: i64arr
415          - values:
416            - |
417              #
418                  movi v1, 123
419                  newarr v1, v1, f64[]
420            id: f64arr
421          - values:
422            - |
423              #
424                  lda.str "some string"
425                  sta.obj v1
426            id: str
427          - values:
428            - |
429              #
430                  movi v1, 123
431                  newarr v1, v1, panda.String[]
432            id: strarr
433          - values:
434            - |
435              #
436                  newobj v1, panda.Object
437            id: obj
438          - values:
439            - |
440              #
441                  movi v1, 123
442                  newarr v1, v1, panda.Object[]
443            id: objarr
444
445      - file-name: acc_uninitialized
446        isa:
447          instructions:
448            - sig: call.virt.short method_id, v1:in:top, v2:in:top
449              acc: out:top
450              format: [op_v1_4_v2_4_id_16]
451        header-template: [r_A]
452        description: >
453          Verifier should report that uninitialized accumulator is used in function.
454        check-type: exit-positive
455        bugid: ['1324']
456        tags: [verifier]
457        runner-options: ['verifier-failure', 'verifier-debug-config']
458        code-template: |
459            .function void A.func(A a0) {
460                %s
461                return.void
462            }
463
464            .function i32 main() {
465                initobj A.constructor
466                sta.obj v0
467                call.virt.short A.func, v0
468        cases:
469          - values:
470              - sta v0
471          - values:
472              - sta.64 v0
473          - values:
474              - sta.obj v0
475
476      - file-name: reg_uninitialized
477        isa:
478          instructions:
479            - sig: call.virt.short method_id, v1:in:top, v2:in:top
480              acc: out:top
481              format: [op_v1_4_v2_4_id_16]
482        header-template: [r_A]
483        description: >
484          Verifier should report that uninitialized register is used in function.
485        check-type: exit-positive
486        bugid: ['1324']
487        tags: [verifier]
488        runner-options: ['verifier-failure', 'verifier-debug-config']
489        code-template: |
490            .function void A.func(A a0) {
491                %s
492                return.void
493            }
494
495            .function i32 main() {
496                initobj A.constructor
497                sta.obj v0
498                call.virt.short A.func, v0
499        template-cases:
500          - values:
501              - lda %s
502            exclude: [r16]
503          - values:
504              - lda.64 %s
505            exclude: [r16]
506          - values:
507              - lda.obj %s
508            exclude: [r16]
509          - values:
510              - mov v0, %s
511        cases:
512          - values: [v0]
513          - values: [v1]
514          - values: [v128]
515          - values: [v255]
516          - values: [v256]
517            id: r16
518          - values: [v32768]
519            id: r16
520          - values: [v65535]
521            id: r16
522
523      - file-name: p_method_id_accessible
524        isa:
525          instructions:
526            - sig: call.virt.short method_id, v1:in:top, v2:in:top
527              acc: out:top
528              format: [op_v1_4_v2_4_id_16]
529          verification:
530            - method_id_accessible
531        header-template: [r_A]
532        description: >
533          Verifier should report that method is not accessible if method_id is not resolved to existing method. Use PandaAssembly language context.
534        check-type: exit-positive
535        tags: [verifier]
536        runner-options: ['verifier-failure', 'verifier-debug-config']
537        code-template: |
538            .function %s A.func(A a0, *s a1) <external>
539
540            .function i32 main() {
541                initobj A.constructor
542                sta.obj v0
543                *s
544                call.virt.short A.func, v0, v1
545        template-cases:
546          - values:
547              - 'void'
548
549          - values:
550              - 'i32'
551            exclude: [void]
552          - values:
553              - 'i64'
554            exclude: [void]
555          - values:
556              - 'f64'
557            exclude: [void]
558          - values:
559              - 'i32[]'
560            exclude: [void]
561          - values:
562              - 'i64[]'
563            exclude: [void]
564          - values:
565              - 'f64[]'
566            exclude: [void]
567          - values:
568              - 'A'
569            exclude: [void]
570          - values:
571              - 'A[]'
572            exclude: [void]
573        cases:
574          - case-template: |
575              .function void A.func(A a0) <external>
576
577              .function i32 main() {
578                  initobj A.constructor
579                  sta.obj v0
580                  call.virt.short A.func, v0
581            id: void
582          - values: ['i32', 'movi v1, 12345678']
583          - values: ['i64', 'movi.64 v1, 0x123456789ABCDEF']
584          - values: ['f64', 'fmovi.64 v1, 3.1415926535']
585          - values:
586            - 'i32[]'
587            - |
588              #
589                  movi v1, 123
590                  newarr v1, v1, i32[]
591          - values:
592            - 'i64[]'
593            - |
594              #
595                  movi v1, 123
596                  newarr v1, v1, i64[]
597          - values:
598            - 'f64[]'
599            - |
600              #
601                  movi v1, 123
602                  newarr v1, v1, f64[]
603          - values:
604            - 'A'
605            - |
606              #
607                  initobj A.constructor
608                  sta.obj v1
609          - values:
610            - 'A[]'
611            - |
612              #
613                  movi v1, 123
614                  newarr v1, v1, A[]
615
616      - file-name: p_method_id_non_static
617        bugid: ["1324"]
618        isa:
619          instructions:
620            - sig: call.virt.short method_id, v1:in:top, v2:in:top
621              acc: out:top
622              format: [op_v1_4_v2_4_id_16]
623          verification:
624            - method_id_non_static
625        header-template: [r_A]
626        description: >
627          Verifier should report that method is not accessible if method_id is not resolved to existing method. Use PandaAssembly language context.
628        check-type: exit-positive
629        tags: [verifier]
630        runner-options: ['verifier-failure', 'verifier-debug-config']
631        code-template: |
632            .function %s A.func(A a0, *s a1) <static> {
633                %s
634            }
635
636            .function i32 main() {
637                initobj A.constructor
638                sta.obj v0
639                *s
640                call.virt.short A.func, v0, v1
641        template-cases:
642          - values:
643              - 'void'
644              - 'return.void'
645          - values:
646              - 'i32'
647              - |
648                #
649                    ldai 1
650                    return
651            exclude: [void]
652          - values:
653              - 'i64'
654              - |
655                #
656                    ldai.64 1
657                    return.64
658            exclude: [void]
659          - values:
660              - 'f64'
661              - |
662                #
663                    fldai.64 3.1415926535
664                    return.64
665            exclude: [void]
666          - values:
667             - 'i32[]'
668             - |
669               #
670                   movi v1, 123
671                   newarr v1, v1, i32[]
672                   lda.obj v1
673                   return.obj
674            exclude: [void]
675          - values:
676              - 'i64[]'
677              - |
678               #
679                   movi v1, 123
680                   newarr v1, v1, i64[]
681                   lda.obj v1
682                   return.obj
683            exclude: [void]
684          - values:
685              - 'f64[]'
686              - |
687                #
688                    movi v1, 123
689                    newarr v1, v1, f64[]
690                    lda.obj v1
691                    return.obj
692            exclude: [void]
693          - values:
694              - 'A'
695              - |
696                #
697                    initobj A.constructor
698                    sta.obj v1
699                    return.obj
700          - values:
701              - 'A[]'
702              - |
703                #
704                    movi v1, 123
705                    newarr v1, v1, A[]
706                    lda.obj v1
707                    return.obj
708        cases:
709          - case-template: |
710              .function void A.func(A a0) <static> {
711                  return.void
712              }
713
714              .function i32 main() {
715                  initobj A.constructor
716                  sta.obj v0
717                  call.virt.short A.func, v0
718            id: void
719          - values: ['i32', 'movi v1, 12345678']
720          - values: ['i64', 'movi.64 v1, 0x123456789ABCDEF']
721          - values: ['f64', 'fmovi.64 v1, 3.1415926535']
722          - values:
723            - 'i32[]'
724            - |
725              #
726                  movi v1, 123
727                  newarr v1, v1, i32[]
728          - values:
729            - 'i64[]'
730            - |
731              #
732                  movi v1, 123
733                  newarr v1, v1, i64[]
734          - values:
735            - 'f64[]'
736            - |
737              #
738                  movi v1, 123
739                  newarr v1, v1, f64[]
740          - values:
741            - 'A'
742            - |
743              #
744                  initobj A.constructor
745                  sta.obj v1
746          - values:
747            - 'A[]'
748            - |
749              #
750                  movi v1, 123
751                  newarr v1, v1, A[]
752
753      - file-name: match_parameters_amount
754        isa:
755          instructions:
756            - sig: call.virt.short method_id, v1:in:top, v2:in:top
757              acc: out:top
758              format: [op_v1_4_v2_4_id_16]
759        header-template: [r_A]
760        description: >
761          Compiler should check amount of function parameters with corresponding call.virt.short
762        check-type: none
763        runner-options: [compile-failure]
764        code-template: |
765
766            .function void A.func(A a0, i32 a1%s) <external>
767
768            .function i32 main() {
769                call.virt.short A.func, v0%s
770        cases:
771          - values: ['', '']
772          - values: [', i32 a2', ', v1']
773          - values: [', i32 a2, i32 a3', ', v1']
774          - values: [', i32 a2, i32 a3, i32 a4', ', v1']
775