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: PandaAssembly_header
16    template: |
17      .language PandaAssembly
18      .record panda.NullPointerException <external>
19      .record panda.RuntimeException <external>
20      .record panda.Exception <external>
21      .record panda.Throwable <external>
22      .record panda.Object <external>
23      .record E1 <panda.extends=panda.Throwable> {}
24
25  - name: pandasm_header
26    template: |
27      .language PandaAssembly
28      .record panda.NullPointerException <external>
29      .record panda.Object <external>
30      .record E1 {}
31      .record E2 {}
32      .record E3 {}
33
34tests:
35  - file-name: "throw"
36    isa:
37      title: Throw exception
38      description: Throw an exception located in register.
39      instructions:
40        - sig: throw v:in:ref
41          acc: none
42          format: [op_v_8]
43      exceptions:
44        - x_throw
45    commands:
46
47      - file-name: "when_reg_is_invalid"
48        description: Check that compilation fails if register is invalid
49        isa:
50          instructions:
51            - sig: throw v:in:ref
52              acc: none
53              format: [op_v_8]
54          verification:
55            - v1_throw_type
56        runner-options: ['compile-failure']
57        header-template: []
58        check-type: empty
59        code-template: |
60
61          .function i32 main() {
62            throw %s
63          }
64        cases:
65          - values: ['v256']
66          - values: ['v65535']
67          - values: ['a0']
68          - values: ['']
69          - values: ['main']
70          - values: ['i32']
71          - values: ['throw']
72          - values: ['v0, v0']
73          - values: ['}']
74          - values: ['v255']
75            runner-options: ['compile-only']
76
77      - file-name: "when_reg_v_is_uninitialized"
78        description: Check that verifier report error when the register is not initialized
79        isa:
80          instructions:
81            - sig: throw v:in:ref
82              acc: none
83              format: [op_v_8]
84          verification:
85            - v1_throw_type
86        runner-options: ['verifier-failure', 'verifier-config']
87        tags: ['verifier']
88        header-template: []
89        check-type: empty
90        code-template: |
91
92          .function i32 main() {
93            throw %s
94          }
95        cases:
96          - values: ['v0']
97          - values: ['v255']
98
99
100      - file-name: "when_reg_a_is_uninitialized"
101        description: Check that compiler reports error when 'a' register is not initialized
102        isa:
103          instructions:
104            - sig: throw v:in:ref
105              acc: none
106              format: [op_v_8]
107          verification:
108            - v1_throw_type
109        runner-options: ['compile-failure']
110        header-template: []
111        tags: ['irtoc_ignore']
112        check-type: empty
113        code-template: |
114          .record E {}
115
116          .function void func(E a0) <static> {
117            throw %s
118            return.void
119          }
120
121          .function i32 main() {
122            newobj v0, E
123            call.short func, v0
124            ldai 0
125            return
126          }
127        cases:
128          - values: ['a0']
129            runner-options: ['run-failure']
130          - values: ['a1']
131          - values: ['a255']
132
133
134      - file-name: "when_reg_is_null_pa"
135        description: Check that NullPointerException is thrown when register value is null
136        isa:
137          exceptions: [x_null]
138        header-template: ['pandasm_header']
139        check-type: none
140        tags: ['irtoc_ignore']
141        code-template: |
142
143          .function i32 main() {
144              jmp try_begin
145          catch_NPE_block_begin:
146              sta.obj v2
147              isinstance panda.NullPointerException
148              jeqz set_failure
149              lda.obj v2
150              isinstance panda.Object
151              jeqz set_failure
152              ldai 0
153              return
154          set_failure:
155              ldai 1
156              return
157          try_begin:
158              mov.null v0
159              throw v0
160              ldai 2
161              return
162          try_end:
163          .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin
164
165
166      - file-name: "when_reg_is_null_j"
167        description: Check that NullPointerException is thrown when register value is null
168        isa:
169          exceptions: [x_null]
170        header-template: ['PandaAssembly_header']
171        runner-options: ['use-pa']
172        check-type: none
173        tags: ['tsan', 'irtoc_ignore']
174        code-template: |
175
176          .function i32 main() {
177              jmp try_begin
178          catch_NPE_block_begin:
179              sta.obj v2
180              isinstance panda.NullPointerException
181              jeqz set_failure
182              lda.obj v2
183              isinstance panda.Object
184              jeqz set_failure
185              ldai 0
186              return
187          set_failure:
188              ldai 1
189              return
190          try_begin:
191              mov.null v0
192              throw v0
193              ldai 2
194              return
195          try_end:
196          .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin
197
198
199      - file-name: "with_wrong_reg_value_pa"
200        description: "Check that VM thread fails when register contains not a Throwable"
201        isa:
202          description: Throw an exception located in register.
203          verification:
204            - v1_throw_type
205        header-template: ['pandasm_header']
206        check-type: none
207        runner-options: ['verifier-failure', 'verifier-config']
208        tags: ['verifier']
209        code-template: |
210
211          .function i32 main() {
212              jmp try_begin
213          catch_all_block_begin:
214              ldai 0
215              return
216          try_begin:
217              %s
218              throw v0
219          try_end:
220          .catchall try_begin, try_end, catch_all_block_begin
221        cases:
222          - values:
223            - movi v0, 100
224          - values:
225            - movi.64 v0, 0x1234567890
226          - values:
227            - fmovi.64 v0, 3.1415926
228          - values:
229            - newobj v0, panda.Object
230            bugid: ['1688']
231            ignore: true
232          - values:
233            - newobj v0, E1
234            bugid: ['1688']
235            ignore: true
236          - values:
237            - |
238              #
239                  lda.type panda.Object
240                  sta.obj v0
241            bugid: ['1688']
242            ignore: true
243          - values:
244            - |
245              #
246                  lda.str "abc"
247                  sta.obj v0
248            bugid: ['1688']
249            ignore: true
250
251
252      - file-name: "with_wrong_reg_value_j"
253        description: "Check that VM thread fails when register contains not a Throwable"
254        isa:
255          description: Throw an exception located in register.
256          verification:
257            - v1_throw_type
258        header-template: ['PandaAssembly_header']
259        check-type: empty
260        runner-options: ['verifier-failure', 'verifier-config', 'use-pa']
261        tags: [verifier, pa-verifier]
262        code-template: |
263
264          .function i32 main() {
265              jmp try_begin
266          catch_all_block_begin:
267              ldai 0
268              return
269          try_begin:
270              %s
271              throw v0
272          try_end:
273          .catchall try_begin, try_end, catch_all_block_begin
274          }
275        cases:
276          - values:
277            - movi v0, 100
278          - values:
279            - movi.64 v0, 0x1234567890
280          - values:
281            - fmovi.64 v0, 3.1415926
282          - values:
283            - newobj v0, panda.Object
284            bugid: ['1688']
285            ignore: true
286          - values:
287            - newobj v0, E1
288            bugid: ['1688']
289            ignore: true
290          - values:
291            - |
292              #
293                  lda.type panda.Object
294                  sta.obj v0
295            bugid: ['1688']
296            ignore: true
297          - values:
298            - |
299              #
300                  lda.str "abc"
301                  sta.obj v0
302            bugid: ['1688']
303            ignore: true
304
305
306      - file-name: "with_multiple_catch_blocks_pa"
307        description: "Check that correct catch block is selected"
308        isa:
309          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
310        header-template: ['pandasm_header']
311        tags: ['irtoc_ignore']
312        check-type: none
313        code-template: |
314
315          .function i32 main() {
316              jmp try_begin
317          catch_NPE_block_begin:
318              sta.obj v2
319              ldai %s
320              jnez set_failure
321              lda.obj v2
322              isinstance panda.NullPointerException
323              jeqz set_failure
324              lda.obj v2
325              isinstance panda.Object
326              jeqz set_failure
327              lda.obj v2
328              jne.obj v0, set_failure
329              ldai 0
330              return
331          catch_E1_block_begin:
332              sta.obj v2
333              ldai %s
334              jnez set_failure
335              lda.obj v2
336              isinstance E1
337              jeqz set_failure
338              lda.obj v2
339              isinstance panda.Object
340              jeqz set_failure
341              lda.obj v2
342              jne.obj v0, set_failure
343              ldai 0
344              return
345          catch_E2_block_begin:
346              sta.obj v2
347              ldai %s
348              jnez set_failure
349              lda.obj v2
350              isinstance E2
351              jeqz set_failure
352              lda.obj v2
353              isinstance panda.Object
354              jeqz set_failure
355              lda.obj v2
356              jne.obj v0, set_failure
357              ldai 0
358              return
359          catch_E3_block_begin:
360              sta.obj v2
361              ldai %s
362              jnez set_failure
363              lda.obj v2
364              isinstance E3
365              jeqz set_failure
366              lda.obj v2
367              isinstance panda.Object
368              jeqz set_failure
369              lda.obj v2
370              jne.obj v0, set_failure
371              ldai 0
372              return
373          try_begin:
374              newobj v0, %s
375              throw v0
376          try_end:
377          set_failure:
378              ldai 1
379              return
380          .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin
381          .catch E1, try_begin, try_end, catch_E1_block_begin
382          .catch E2, try_begin, try_end, catch_E2_block_begin
383          .catch E3, try_begin, try_end, catch_E3_block_begin
384        cases:
385          - values: [0, 2, 3, 4, panda.NullPointerException]
386          - values: [1, 0, 3, 4, E1]
387          - values: [1, 2, 0, 4, E2]
388          - values: [1, 2, 3, 0, E3]
389
390
391      - file-name: "with_multiple_catch_blocks_j"
392        description: "Check that correct catch block is selected"
393        isa:
394          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
395        header-template: ['PandaAssembly_header']
396        runner-options: ['use-pa']
397        check-type: none
398        tags: ['tsan', 'irtoc_ignore']
399        code-template: |
400
401          .function i32 main() {
402              jmp try_begin
403          catch_NPE_block_begin:
404              sta.obj v2
405              ldai %s
406              jnez set_failure
407              lda.obj v2
408              isinstance panda.NullPointerException
409              jeqz set_failure
410              lda.obj v2
411              isinstance panda.Object
412              jeqz set_failure
413              lda.obj v2
414              jne.obj v0, set_failure
415              ldai 0
416              return
417          catch_RE_block_begin:
418              sta.obj v2
419              ldai %s
420              jnez set_failure
421              lda.obj v2
422              isinstance panda.RuntimeException
423              jeqz set_failure
424              lda.obj v2
425              isinstance panda.Object
426              jeqz set_failure
427              lda.obj v2
428              jne.obj v0, set_failure
429              ldai 0
430              return
431          catch_E1_block_begin:
432              sta.obj v2
433              ldai %s
434              jnez set_failure
435              lda.obj v2
436              isinstance E1
437              jeqz set_failure
438              lda.obj v2
439              isinstance panda.Object
440              jeqz set_failure
441              lda.obj v2
442              jne.obj v0, set_failure
443              ldai 0
444              return
445          catch_Ex_block_begin:
446              sta.obj v2
447              ldai %s
448              jnez set_failure
449              lda.obj v2
450              isinstance panda.Exception
451              jeqz set_failure
452              lda.obj v2
453              isinstance panda.Object
454              jeqz set_failure
455              lda.obj v2
456              jne.obj v0, set_failure
457              ldai 0
458              return
459          try_begin:
460              newobj v0, %s
461              throw v0
462          try_end:
463          set_failure:
464              ldai 1
465              return
466          .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin
467          .catch panda.RuntimeException, try_begin, try_end, catch_RE_block_begin
468          .catch panda.Exception, try_begin, try_end, catch_Ex_block_begin
469          .catch E1, try_begin, try_end, catch_E1_block_begin
470        cases:
471          - values: [0, 2, 3, 4, panda.NullPointerException]
472          - values: [1, 0, 3, 4, panda.RuntimeException]
473          - values: [1, 2, 3, 0, panda.Exception]
474          - values: [1, 2, 0, 0, E1]
475
476
477      - file-name: "with_catchall_pa"
478        description: "Check that catchall block is selected correctly"
479        isa:
480          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
481        header-template: ['pandasm_header']
482        check-type: empty
483        tags: ['irtoc_ignore']
484        code-template: |
485
486          .function i32 main() {
487          try_begin:
488            newobj v0, %s
489            throw v0
490          try_end:
491          catch_all_block_begin:
492            ldai %s
493            return
494          catch_E1_block_begin:
495            ldai %s
496            return
497          catch_E2_block_begin:
498            ldai %s
499            return
500          .catch E1, try_begin, try_end, catch_E1_block_begin
501          .catchall try_begin, try_end, catch_all_block_begin
502          .catch E2, try_begin, try_end, catch_E2_block_begin
503          }
504        cases:
505          - values: [E1, 1, 0, 3]
506          - values: [E2, 0, 2, 3]
507          - values: [panda.NullPointerException, 0, 2, 3]
508
509
510      - file-name: "with_catchall_j"
511        description: "Check that catchall block is selected correctly"
512        isa:
513          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
514        header-template: ['PandaAssembly_header']
515        runner-options: ['use-pa']
516        tags: ['irtoc_ignore']
517        code-template: |
518
519          .function i32 main() {
520          try_begin:
521            newobj v0, %s
522            throw v0
523          try_end:
524          catch_RE_block_begin:
525            ldai %s
526            return
527          catch_Ex_block_begin:
528            ldai %s
529            return
530          catch_all_block_begin:
531            ldai %s
532            return
533          catch_E1_block_begin:
534            ldai %s
535            return
536          .catch E1, try_begin, try_end, catch_E1_block_begin
537          .catchall try_begin, try_end, catch_all_block_begin
538          .catch panda.Exception, try_begin, try_end, catch_Ex_block_begin
539          .catch panda.RuntimeException, try_begin, try_end, catch_RE_block_begin
540        check-type: none
541        cases:
542          - values: [E1, 1, 2, 3, 0]
543          - values: [panda.Exception, 1, 2, 0, 4]
544          - values: [panda.RuntimeException, 1, 2, 0, 4]
545          - values: [panda.NullPointerException, 1, 2, 0, 4]
546
547
548      - file-name: "with_reg_value_check_pa"
549        description: "Check that register keeps ref to exception object in catch block"
550        isa:
551          description: Throw an exception located in register.
552        header-template: ['pandasm_header']
553        check-type: empty
554        tags: ['irtoc_ignore']
555        bugid: ["3975"]
556        code-template: |
557
558          .function i32 main() {
559          try_begin:
560            newobj v0, %s
561            throw v0
562          try_end:
563          catch_block_begin:
564            jne.obj v0, return_ne_num
565            ldai 0
566            return
567          return_ne_num:
568            ldai 1
569            return
570          .catch E1, try_begin, try_end, catch_block_begin
571          .catch E2, try_begin, try_end, catch_block_begin
572          .catchall try_begin, try_end, catch_block_begin
573          }
574        cases:
575          - values:
576            - E1
577          - values:
578            - E2
579          - values:
580            - panda.NullPointerException
581
582
583      - file-name: "with_reg_value_check_j"
584        description: "Check that register keeps ref to exception object in catch block"
585        isa:
586          description: Throw an exception located in register.
587        header-template: ['PandaAssembly_header']
588        runner-options: ['use-pa']
589        check-type: empty
590        tags: ['irtoc_ignore']
591        bugid: ["3975"]
592        code-template: |
593
594          .function i32 main() {
595          try_begin:
596            newobj v0, %s
597            throw v0
598          try_end:
599          catch_block_begin:
600            jne.obj v0, return_ne_num
601            ldai 0
602            return
603          return_ne_num:
604            ldai 1
605            return
606          .catch panda.NullPointerException, try_begin, try_end, catch_block_begin
607          .catch panda.Exception, try_begin, try_end, catch_block_begin
608          .catchall try_begin, try_end, catch_block_begin
609          }
610        cases:
611          - values:
612            - panda.NullPointerException
613          - values:
614            - panda.Exception
615          - values:
616            - panda.RuntimeException
617
618
619      - file-name: "with_propagation_to_outer_block_pa"
620        description: "Check exception propagation to outer try-catch block"
621        isa:
622          description: The current method is searched for the first exception handler that matches the class of exception. If exception handler is found, control is passed to the exception handler.
623        header-template: ['pandasm_header']
624        check-type: empty
625        tags: ['tsan', 'irtoc_ignore']
626        code-template: |
627
628          .function i32 main() {
629          begin3:
630            newobj v0, %s
631            lda.obj v0
632          begin2:
633            mov.obj v1, v0
634          begin1:
635            throw v0
636          end1:
637          end2:
638          end3:
639            ldai 4
640            return
641          catch1:
642            %s
643            return
644          catch2:
645            %s
646            return
647          catch3:
648            %s
649            return
650          .catch E1, begin1, end1, catch1
651          .catch E2, begin2, end2, catch2
652          .catch E3, begin3, end3, catch3
653          }
654        cases:
655          - values:
656            - E1
657            - |
658              #
659                jne.obj v1, return_ne_num
660                ldai 0
661                return
662                return_ne_num:
663                ldai 1
664            - ldai 2
665            - ldai 3
666          - values:
667            - E2
668            - ldai 2
669            - |
670              #
671                jne.obj v1, return_ne_num
672                ldai 0
673                return
674                return_ne_num:
675                ldai 1
676            - ldai 3
677            bugid: ['3975']
678          - values:
679            - E3
680            - ldai 2
681            - ldai 3
682            - |
683              #
684                jne.obj v1, return_ne_num
685                ldai 0
686                return
687                return_ne_num:
688                ldai 1
689            bugid: ['3975']
690
691
692      - file-name: "with_propagation_to_outer_block_j"
693        description: "Check exception propagation to outer try-catch block"
694        isa:
695          description: The current method is searched for the first exception handler that matches the class of exception. If exception handler is found, control is passed to the exception handler.
696        header-template: ['PandaAssembly_header']
697        runner-options: ['use-pa']
698        check-type: empty
699        tags: ['irtoc_ignore']
700        code-template: |
701
702          .function i32 main() {
703          begin3:
704            newobj v0, %s
705            lda.obj v0
706          begin2:
707            mov.obj v1, v0
708          begin1:
709            throw v0
710          end1:
711          end2:
712          end3:
713            ldai 4
714            return
715          catch1:
716            %s
717            return
718          catch2:
719            %s
720            return
721          catch3:
722            %s
723            return
724          .catch panda.NullPointerException, begin1, end1, catch1
725          .catch panda.RuntimeException, begin2, end2, catch2
726          .catch panda.Exception, begin3, end3, catch3
727          }
728        cases:
729          - values:
730            - panda.NullPointerException
731            - |
732              #
733                jne.obj v1, return_ne_num
734                ldai 0
735                return
736                return_ne_num:
737                ldai 1
738            - ldai 2
739            - ldai 3
740          - values:
741            - panda.RuntimeException
742            - ldai 2
743            - |
744              #
745                jne.obj v1, return_ne_num
746                ldai 0
747                return
748                return_ne_num:
749                ldai 1
750            - ldai 3
751            bugid: ['3975']
752          - values:
753            - panda.Exception
754            - ldai 2
755            - ldai 3
756            - |
757              #
758                jne.obj v1, return_ne_num
759                ldai 0
760                return
761                return_ne_num:
762                ldai 1
763            bugid: ['3975']
764
765
766      - file-name: "with_propagation_to_outer_frame_pa"
767        description: "Check exception propagation to outer frame"
768        isa:
769          description: If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown.
770        header-template: ['pandasm_header']
771        check-type: empty
772        bugid: ["1837"]
773        tags: ['irtoc_ignore']
774        code-template: |
775
776          .function i32 f2() {
777            newobj v0, %s
778          try2_begin:
779            throw v0
780          try2_end:
781            ldai 0
782            return
783          .catch %s, try2_begin, try2_end, try2_end
784          }
785
786          .function i32 f1() {
787          try1_begin:
788            call f2
789            return
790          try1_end:
791            ldai 0
792            return
793          .catch %s, try1_begin, try1_end, try1_end
794          }
795
796          .function i32 main() {
797          try_begin:
798            call f1
799            ldai %s
800            return
801          try_end:
802          catch_block_begin:
803            ldai %s
804            return
805          .catch %s, try_begin, try_end, catch_block_begin
806          }
807        cases:
808          - values: [E2, E1, E2, 0, 1, E3]
809          - values: [E3, E1, E2, 1, 0, E3]
810
811
812      - file-name: "with_propagation_to_outer_frame_j"
813        description: "Check exception propagation to outer frame"
814        isa:
815          description: If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown.
816        header-template: ['PandaAssembly_header']
817        runner-options: ['use-pa']
818        check-type: empty
819        tags: ['irtoc_ignore']
820        bugid: ["1837"]
821        code-template: |
822
823          .function i32 f2() {
824            newobj v0, %s
825          try2_begin:
826            throw v0
827          try2_end:
828            ldai 0
829            return
830          .catch %s, try2_begin, try2_end, try2_end
831          }
832
833          .function i32 f1() {
834          try1_begin:
835            call f2
836            return
837          try1_end:
838            ldai 0
839            return
840          .catch %s, try1_begin, try1_end, try1_end
841          }
842
843          .function i32 main() {
844          try_begin:
845            call f1
846            ldai %s
847            return
848          try_end:
849          catch_block_begin:
850            ldai %s
851            return
852          .catch %s, try_begin, try_end, catch_block_begin
853          }
854        cases:
855          - values: [panda.Exception, panda.NullPointerException, panda.Exception, 0, 1, panda.RuntimeException]
856          - values: [panda.Exception, panda.NullPointerException, panda.RuntimeException, 1, 0, panda.Exception]
857
858
859      - file-name: "with_no_handler_pa"
860        description: "Check exception propagation to outer frame."
861        isa:
862          description: >
863            If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. If no
864            exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown.
865        header-template: ['pandasm_header']
866        tags: ['irtoc_ignore']
867        check-type: empty
868        code-template: |
869
870          .function i32 f2() {
871            newobj v0, %s
872          try2_begin:
873            throw v0
874          try2_end:
875            ldai 1
876            return
877          .catch %s, try2_begin, try2_end, try2_end
878          }
879
880          .function i32 f1() {
881          try1_begin:
882            call f2
883            return
884          try1_end:
885            ldai 1
886            return
887          .catch %s, try1_begin, try1_end, try1_end
888          }
889
890          .function i32 main() {
891          try_begin:
892            call f1
893            return
894          try_end:
895          catch_block_begin:
896            ldai 0
897            return
898          .catch %s, try_begin, try_end, catch_block_begin
899          }
900        cases:
901          - values: [E2, E1, E3, E2]
902          - values: [E3, E1, E1, E3]
903
904
905      - file-name: "with_no_handler_j"
906        description: "Check exception propagation to outer frame."
907        isa:
908          description: >
909            If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. If no
910            exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown.
911        header-template: ['PandaAssembly_header']
912        check-type: empty
913        runner-options: ['use-pa']
914        tags: ['irtoc_ignore']
915        code-template: |
916
917          .function i32 f2() {
918            newobj v0, %s
919          try2_begin:
920            throw v0
921          try2_end:
922            ldai 1
923            return
924          .catch %s, try2_begin, try2_end, try2_end
925          }
926
927          .function i32 f1() {
928          try1_begin:
929            call f2
930            return
931          try1_end:
932            ldai 1
933            return
934          .catch %s, try1_begin, try1_end, try1_end
935          }
936
937          .function i32 main() {
938          try_begin:
939            call f1
940            return
941          try_end:
942          catch_block_begin:
943            ldai 0
944            return
945          .catch %s, try_begin, try_end, catch_block_begin
946          }
947        cases:
948          - values: [panda.Exception, panda.NullPointerException, panda.RuntimeException, panda.Exception]
949
950
951      - file-name: "with_no_handler2_pa"
952        description: "Check thread exit if handler is not found."
953        isa:
954          description: >
955            If no such frame exists, the current VM thread exits.
956        header-template: ['pandasm_header']
957        check-type: empty
958        runner-options: ['run-failure']
959        tags: ['irtoc_ignore']
960        code-template: |
961
962          .function i32 main() {
963            newobj v0, %s
964            throw v0
965            ldai 0
966            return
967          }
968        cases:
969          - values: [E2]
970          - values: [panda.Object]
971
972
973      - file-name: "with_no_handler2_j"
974        description: "Check VM thread exit if handler is not found."
975        isa:
976          description: >
977            If no such frame exists, the current VM thread exits.
978        header-template: ['PandaAssembly_header']
979        check-type: empty
980        runner-options: ['use-pa', 'run-failure']
981        bugid: ['5450']
982        tags: ['arm64-fail', 'irtoc_ignore']
983        code-template: |
984
985          .function i32 main() {
986            newobj v0, %s
987            throw v0
988            ldai 0
989            return
990          }
991        cases:
992          - values: [panda.Exception]
993          - values: [panda.NullPointerException]
994
995
996      - file-name: "subclass_of_exception_j"
997        description: "Check that exception subclass is successfully caught by its superclass declaration in catch"
998        isa:
999          description: The current method is searched for the first exception handler that matches the class of exception. If exception handler is found, control is passed to the exception handler.
1000        header-template: ['PandaAssembly_header']
1001        runner-options: ['use-pa']
1002        check-type: empty
1003        bugid: ['3977']
1004        tags: ['tsan', 'irtoc_ignore']
1005        code-template: |
1006          .record MyCustomException <panda.extends=panda.RuntimeException> {}
1007          .record MySecondCustomException <panda.extends=MyCustomException> {}
1008
1009          .function i32 main() {
1010            jmp try_begin
1011          catch_block_begin:
1012            ldai 0
1013            return
1014          catch2_block_begin:
1015            ldai 1
1016            return
1017          try_begin:
1018            newobj v0, %s
1019            throw v0
1020          try_end:
1021          .catch %s, try_begin, try_end, catch_block_begin
1022          .catchall try_begin, try_end, catch2_block_begin
1023          }
1024        cases:
1025          - values: [panda.RuntimeException, panda.Exception]
1026          - values: [MyCustomException, panda.RuntimeException]
1027          - values: [MySecondCustomException, MyCustomException]
1028          - values: [MySecondCustomException, panda.Exception]
1029
1030
1031      - file-name: "superclass_of_exception_j"
1032        description: "Check that exception superclass is not caught by its subclass declaration in catch"
1033        isa:
1034          description: >
1035            If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. If no
1036            exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown.
1037            If no such frame exists, the current VM thread exits.
1038        header-template: ['PandaAssembly_header']
1039        runner-options: ['use-pa']
1040        tags: ['irtoc_ignore']
1041        check-type: empty
1042        code-template: |
1043          .record MyCustomException <panda.extends=panda.RuntimeException> {}
1044          .record MySecondCustomException <panda.extends=MyCustomException> {}
1045
1046          .function i32 main() {
1047            jmp try_begin
1048          catch_block_begin:
1049            ldai 1
1050            return
1051          catch2_block_begin:
1052            ldai 0
1053            return
1054          try_begin:
1055            newobj v0, %s
1056            throw v0
1057          try_end:
1058          .catch %s, try_begin, try_end, catch_block_begin
1059          .catchall try_begin, try_end, catch2_block_begin
1060          }
1061        cases:
1062          - values: [panda.Exception, panda.RuntimeException]
1063          - values: [panda.RuntimeException, MyCustomException]
1064          - values: [MyCustomException, MySecondCustomException]
1065          - values: [panda.Exception, MySecondCustomException]
1066
1067
1068      - file-name: "cflow_fallthrough1_pa"
1069        description: "Check that the verifier prohibits a fallthrough to the beginning of open-ended exception handler."
1070        isa:
1071          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1072        header-template: ['pandasm_header']
1073        tags: ['verifier']
1074        check-type: none
1075        code-template: |
1076
1077          .function i32 foo(E1 a0) {
1078              throw a0
1079          }
1080
1081          .function i32 main() {
1082              newobj v1, E1
1083              lda.obj v1
1084              %s
1085          catch_all:
1086              ldai 0
1087              return
1088          try_begin:
1089              throw v1
1090          try_end:
1091              ldai 2
1092              return
1093          .catchall try_begin, try_end, catch_all
1094        cases:
1095          - values:
1096            - ''
1097            runner-options: ['verifier-failure', 'verifier-config']
1098          - values:
1099            - jnez.obj try_begin
1100            runner-options: ['verifier-failure', 'verifier-config']
1101          - values:
1102            - jmp catch_all
1103            runner-options: ['verifier-failure', 'verifier-config']
1104          - values:
1105            - call.short foo, v1
1106            runner-options: ['verifier-failure', 'verifier-config']
1107          - values:
1108            - jmp try_begin
1109            runner-options: ['verifier-only', 'verifier-config']
1110          - values:
1111            - throw v1
1112            runner-options: ['verifier-only', 'verifier-config']
1113          - values:
1114            - |
1115              #
1116                  ldai 0
1117                  return
1118            runner-options: ['verifier-only', 'verifier-config']
1119
1120
1121      - file-name: "cflow_fallthrough2_pa"
1122        description: "Check that the verifier prohibits a fallthrough to the beginning of close-ended exception handler."
1123        isa:
1124          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1125        header-template: ['pandasm_header']
1126        tags: ['verifier']
1127        check-type: none
1128        code-template: |
1129
1130          .function i32 foo(E1 a0) {
1131              throw a0
1132          }
1133
1134          .function i32 main() {
1135              newobj v1, E1
1136              lda.obj v1
1137              %s
1138          catch_begin:
1139              ldai 0
1140              return
1141          catch_end:
1142          try_begin:
1143              throw v1
1144          try_end:
1145              ldai 2
1146              return
1147          .catchall try_begin, try_end, catch_begin, catch_end
1148        cases:
1149          - values:
1150            - ''
1151            runner-options: ['verifier-failure', 'verifier-config']
1152          - values:
1153            - jnez.obj try_begin
1154            runner-options: ['verifier-failure', 'verifier-config']
1155          - values:
1156            - jmp catch_begin
1157            runner-options: ['verifier-failure', 'verifier-config']
1158          - values:
1159            - call.short foo, v1
1160            runner-options: ['verifier-failure', 'verifier-config']
1161          - values:
1162            - jmp catch_end
1163            runner-options: ['verifier-only', 'verifier-config']
1164          - values:
1165            - jmp try_begin
1166            runner-options: ['verifier-only', 'verifier-config']
1167          - values:
1168            - throw v1
1169            runner-options: ['verifier-only', 'verifier-config']
1170          - values:
1171            - |
1172              #
1173                  ldai 0
1174                  return
1175            runner-options: ['verifier-only', 'verifier-config']
1176
1177
1178      - file-name: "cflow_fallthrough3_pa"
1179        description: "Check that the verifier prohibits an open-ended exception handler at the beginning of a function."
1180        isa:
1181          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1182        header-template: ['pandasm_header']
1183        runner-options: ['verifier-failure', 'verifier-config']
1184        tags: ['verifier']
1185        bugid: ['8029']
1186        ignore: true
1187        check-type: none
1188        code-template: |
1189
1190          .function i32 foo(E1 a0) {
1191          catch_begin:
1192              ldai 0
1193              return
1194          try_begin:
1195              throw a0
1196          try_end:
1197              ldai 2
1198              return
1199          .catchall try_begin, try_end, catch_begin
1200          }
1201
1202          .function i32 main() {
1203              newobj v1, E1
1204              call.short foo, v1
1205              return
1206
1207
1208      - file-name: "cflow_fallthrough4_pa"
1209        description: "Check that the verifier prohibits an close-ended exception handler at the beginning of a function."
1210        isa:
1211          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1212        header-template: ['pandasm_header']
1213        runner-options: ['verifier-failure', 'verifier-config']
1214        tags: ['verifier']
1215        bugid: ['8029']
1216        ignore: true
1217        check-type: none
1218        code-template: |
1219
1220          .function i32 foo(E1 a0) {
1221          catch_begin:
1222              ldai 0
1223              return
1224          catch_end:
1225          try_begin:
1226              throw a0
1227          try_end:
1228              ldai 2
1229              return
1230          .catchall try_begin, try_end, catch_begin, catch_end
1231          }
1232
1233          .function i32 main() {
1234              newobj v1, E1
1235              call.short foo, v1
1236              return
1237
1238
1239      - file-name: "cflow_fallthrough5_pa"
1240        description: "Check that the verifier prohibits a fallthrough from one handler to the beginning of another exception handler."
1241        isa:
1242          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1243        header-template: ['pandasm_header']
1244        runner-options: ['verifier-failure', 'verifier-config']
1245        tags: ['verifier']
1246        check-type: none
1247        code-template: |
1248
1249          .function i32 foo(E1 a0) {
1250              throw a0
1251          }
1252
1253          .function i32 main() {
1254          try_begin:
1255              newobj v1, E1
1256              lda.obj v1
1257              jeqz.obj fail
1258              throw v1
1259          fail:
1260              ldai 1
1261              return
1262          try_end:
1263          catch_E1:
1264              ldai 2
1265              %s
1266          catch_all:
1267              ldai 3
1268              return
1269          exit:
1270              ldai 4
1271              return
1272          .catch E1, try_begin, try_end, catch_E1
1273          .catchall try_begin, try_end, catch_all
1274        cases:
1275          - values:
1276            - ''
1277          - values:
1278            - call.short foo, v1
1279          - values:
1280            - jmp catch_all
1281          - values:
1282            - jnez.obj exit
1283          - values:
1284            - return
1285            runner-options: ['verifier-only', 'verifier-config']
1286          - values:
1287            - jmp exit
1288            runner-options: ['verifier-only', 'verifier-config']
1289          - values:
1290            - throw v1
1291            runner-options: ['verifier-only', 'verifier-config']
1292
1293
1294      - file-name: "cflow_fallthrough6_pa"
1295        description: "Check that the verifier prohibits a fallthrough from one handler to the beginning of another exception handler."
1296        isa:
1297          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1298        header-template: ['pandasm_header']
1299        runner-options: ['verifier-failure', 'verifier-config']
1300        tags: ['verifier']
1301        check-type: none
1302        code-template: |
1303
1304          .function i32 foo(E1 a0) {
1305              throw a0
1306          }
1307
1308          .function i32 main() {
1309          try_begin:
1310              newobj v1, E1
1311              lda.obj v1
1312              throw v1
1313          try_end:
1314              ldai 1
1315              return
1316          catch_E1:
1317              ldai 2
1318              %s
1319          catch_E1_end:
1320          catch_all:
1321              ldai 3
1322              return
1323          catch_all_end:
1324          exit:
1325              ldai 4
1326              return
1327          .catch E1, try_begin, try_end, catch_E1, catch_E1_end
1328          .catchall try_begin, try_end, catch_all, catch_all_end
1329        cases:
1330          - values:
1331            - ''
1332          - values:
1333            - call.short foo, v1
1334          - values:
1335            - jmp catch_all
1336          - values:
1337            - jnez.obj exit
1338          - values:
1339            - return
1340            runner-options: ['verifier-only', 'verifier-config']
1341          - values:
1342            - jmp exit
1343            runner-options: ['verifier-only', 'verifier-config']
1344          - values:
1345            - throw v1
1346            runner-options: ['verifier-only', 'verifier-config']
1347
1348
1349      - file-name: "cflow_jump1_pa"
1350        description: "Check that the verifier prohibits a jump from code into an open-ended exception handler."
1351        isa:
1352          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1353        header-template: ['pandasm_header']
1354        tags: ['verifier']
1355        check-type: none
1356        code-template: |
1357
1358          .function i32 main() {
1359              newobj v1, E1
1360              lda.obj v1
1361              %s
1362          try_begin:
1363              throw v1
1364          try_end:
1365          catch_all:
1366              isinstance E1
1367          catch_fail:
1368              ldai 1
1369              return
1370          catch_ok:
1371              ldai 0
1372              return
1373          .catchall try_begin, try_end, catch_all
1374        cases:
1375          - values:
1376            - ''
1377            runner-options: ['verifier-only', 'verifier-config']
1378          - values:
1379            - jmp catch_all
1380            runner-options: ['verifier-failure', 'verifier-config']
1381          - values:
1382            - jmp catch_fail
1383            runner-options: ['verifier-only', 'verifier-config']
1384          - values:
1385            - jmp catch_ok
1386            runner-options: ['verifier-only', 'verifier-config']
1387          - values:
1388            - jeqz.obj catch_all
1389            runner-options: ['verifier-failure', 'verifier-config']
1390          - values:
1391            - jeqz.obj catch_fail
1392            runner-options: ['verifier-only', 'verifier-config']
1393          - values:
1394            - jeqz.obj catch_ok
1395            runner-options: ['verifier-only', 'verifier-config']
1396
1397
1398      - file-name: "cflow_jump2_pa"
1399        description: "Check that the verifier prohibits a jump from code into a close-ended exception handler."
1400        isa:
1401          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1402        header-template: ['pandasm_header']
1403        tags: ['verifier']
1404        check-type: none
1405        code-template: |
1406
1407          .function i32 main() {
1408              newobj v1, E1
1409              lda.obj v1
1410              %s
1411          try_begin:
1412              throw v1
1413          try_end:
1414          catch_begin:
1415              isinstance E1
1416          catch_fail:
1417              ldai 1
1418              return
1419          catch_ok:
1420              ldai 0
1421              return
1422          catch_end:
1423          .catchall try_begin, try_end, catch_begin, catch_end
1424        cases:
1425          - values:
1426            - ''
1427            runner-options: ['verifier-only', 'verifier-config']
1428          - values:
1429            - jmp catch_begin
1430            runner-options: ['verifier-failure', 'verifier-config']
1431          - values:
1432            - jmp catch_fail
1433            runner-options: ['verifier-failure', 'verifier-config']
1434          - values:
1435            - jmp catch_ok
1436            runner-options: ['verifier-failure', 'verifier-config']
1437          - values:
1438            - jeqz.obj catch_begin
1439            runner-options: ['verifier-failure', 'verifier-config']
1440          - values:
1441            - jeqz.obj catch_fail
1442            runner-options: ['verifier-failure', 'verifier-config']
1443          - values:
1444            - jeqz.obj catch_ok
1445            runner-options: ['verifier-failure', 'verifier-config']
1446
1447
1448      - file-name: "cflow_jump3_pa"
1449        description: "Check that the verifier prohibits a jump from try block into a open-ended exception handler."
1450        isa:
1451          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1452        header-template: ['pandasm_header']
1453        tags: ['verifier']
1454        check-type: none
1455        code-template: |
1456
1457          .function i32 main() {
1458          try_begin:
1459              newobj v1, E1
1460              lda.obj v1
1461              %s
1462              throw v1
1463          try_end:
1464          catch_begin:
1465              isinstance E1
1466          catch_fail:
1467              ldai 1
1468              return
1469          catch_ok:
1470              ldai 0
1471              return
1472          .catchall try_begin, try_end, catch_begin
1473        cases:
1474          - values:
1475            - ''
1476            runner-options: ['verifier-only', 'verifier-config']
1477          - values:
1478            - jmp catch_begin
1479            runner-options: ['verifier-failure', 'verifier-config']
1480          - values:
1481            - jmp catch_fail
1482            runner-options: ['verifier-only', 'verifier-config']
1483          - values:
1484            - jmp catch_ok
1485            runner-options: ['verifier-only', 'verifier-config']
1486          - values:
1487            - jeqz.obj catch_begin
1488            runner-options: ['verifier-failure', 'verifier-config']
1489          - values:
1490            - jeqz.obj catch_fail
1491            runner-options: ['verifier-only', 'verifier-config']
1492          - values:
1493            - jeqz.obj catch_ok
1494            runner-options: ['verifier-only', 'verifier-config']
1495
1496
1497      - file-name: "cflow_jump4_pa"
1498        description: "Check that the verifier prohibits a jump from try block into a close-ended exception handler."
1499        isa:
1500          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1501        header-template: ['pandasm_header']
1502        tags: ['verifier']
1503        check-type: none
1504        code-template: |
1505
1506          .function i32 main() {
1507          try_begin:
1508              newobj v1, E1
1509              lda.obj v1
1510              %s
1511              throw v1
1512          try_end:
1513          catch_begin:
1514              isinstance E1
1515          catch_fail:
1516              ldai 1
1517              return
1518          catch_ok:
1519              ldai 0
1520              return
1521          catch_end:
1522          .catchall try_begin, try_end, catch_begin, catch_end
1523        cases:
1524          - values:
1525            - ''
1526            runner-options: ['verifier-only', 'verifier-config']
1527          - values:
1528            - jmp catch_begin
1529            runner-options: ['verifier-failure', 'verifier-config']
1530          - values:
1531            - jmp catch_fail
1532            runner-options: ['verifier-failure', 'verifier-config']
1533          - values:
1534            - jmp catch_ok
1535            runner-options: ['verifier-failure', 'verifier-config']
1536          - values:
1537            - jeqz.obj catch_begin
1538            runner-options: ['verifier-failure', 'verifier-config']
1539          - values:
1540            - jeqz.obj catch_fail
1541            runner-options: ['verifier-failure', 'verifier-config']
1542          - values:
1543            - jeqz.obj catch_ok
1544            runner-options: ['verifier-failure', 'verifier-config']
1545
1546
1547      - file-name: "cflow_jump5_pa"
1548        description: "Check that the verifier prohibits a jump from exception handler to another open-ended exception handler."
1549        isa:
1550          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1551        header-template: ['pandasm_header']
1552        tags: ['verifier']
1553        check-type: none
1554        code-template: |
1555
1556          .function i32 main() {
1557              newobj v1, E1
1558              lda.obj v1
1559          try_begin:
1560              throw v1
1561          try_end:
1562          catch_E1:
1563              %s
1564              ldai 0
1565              return
1566          catch_all:
1567              ldai 2
1568          fail:
1569              return
1570          .catch E1, try_begin, try_end, catch_E1
1571          .catchall try_begin, try_end, catch_all
1572        cases:
1573          - values:
1574            - ''
1575            runner-options: ['verifier-only', 'verifier-config']
1576          - values:
1577            - jmp catch_all
1578            runner-options: ['verifier-failure', 'verifier-config']
1579          - values:
1580            - jmp fail
1581            runner-options: ['verifier-only', 'verifier-config']
1582          - values:
1583            - jeqz.obj catch_all
1584            runner-options: ['verifier-failure', 'verifier-config']
1585          - values:
1586            - jeqz.obj fail
1587            runner-options: ['verifier-only', 'verifier-config']
1588          - values:
1589            - |
1590              #
1591                  isinstance E1
1592                  jnez e1_ok
1593                  ldai 1
1594                  return
1595              e1_ok:
1596            runner-options: ['verifier-only', 'verifier-config']
1597
1598
1599      - file-name: "cflow_jump6_pa"
1600        description: "Check that the verifier prohibits a jump from exception handler to another close-ended exception handler."
1601        isa:
1602          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1603        header-template: ['pandasm_header']
1604        tags: ['verifier']
1605        check-type: none
1606        code-template: |
1607
1608          .function i32 main() {
1609              newobj v1, E1
1610              lda.obj v1
1611          try_begin:
1612              throw v1
1613          try_end:
1614          catch_E1:
1615              %s
1616              ldai 0
1617              return
1618          catch_E1_end:
1619          catch_all:
1620              ldai 2
1621          fail:
1622              return
1623          catch_all_end:
1624          .catch E1, try_begin, try_end, catch_E1, catch_E1_end
1625          .catchall try_begin, try_end, catch_all, catch_all_end
1626        cases:
1627          - values:
1628            - ''
1629            runner-options: ['verifier-only', 'verifier-config']
1630          - values:
1631            - jmp catch_all
1632            runner-options: ['verifier-failure', 'verifier-config']
1633          - values:
1634            - jmp fail
1635            runner-options: ['verifier-failure', 'verifier-config']
1636          - values:
1637            - jeqz.obj catch_all
1638            runner-options: ['verifier-failure', 'verifier-config']
1639          - values:
1640            - jeqz.obj fail
1641            runner-options: ['verifier-failure', 'verifier-config']
1642          - values:
1643            - |
1644              #
1645                  isinstance E1
1646                  jnez e1_ok
1647                  ldai 1
1648                  return
1649              e1_ok:
1650            runner-options: ['verifier-only', 'verifier-config']
1651            bugid: ['8025']
1652            ignore: true
1653
1654
1655      - file-name: "cflow_jump7_pa"
1656        description: "Check that the verifier prohibits a jump from a handler into a try block."
1657        isa:
1658          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
1659        header-template: ['pandasm_header']
1660        tags: ['verifier']
1661        check-type: none
1662        code-template: |
1663
1664          .function i32 main() {
1665          try_begin:
1666              newobj v1, E1
1667              throw v1
1668          try_mid:
1669              ldai 1
1670              return
1671          try_end:
1672          catch_all:
1673              %s
1674          catch_all_end:
1675          .catchall try_begin, try_end, catch_all, catch_all_end
1676        cases:
1677          - values:
1678            - ''
1679            runner-options: ['verifier-failure', 'verifier-config']
1680          - values:
1681            - |
1682              #
1683                  ldai 0
1684                  return
1685            runner-options: ['verifier-only', 'verifier-config']
1686          - values:
1687            - jmp try_begin
1688            runner-options: ['verifier-failure', 'verifier-config']
1689            bugid: ['8032']
1690            ignore: true
1691          - values:
1692            - jmp try_mid
1693            runner-options: ['verifier-failure', 'verifier-config']
1694            bugid: ['8032']
1695            ignore: true
1696