• 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_header
16    template: |
17      .language Java
18      .record java.lang.NullPointerException <external>
19      .record java.lang.RuntimeException <external>
20      .record java.lang.Exception <external>
21      .record java.lang.Throwable <external>
22      .record java.lang.Object <external>
23      .record E1 <java.extends=java.lang.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    commands:
44
45      - file-name: "when_reg_is_invalid"
46        description: Check that compilation fails if register is invalid
47        isa:
48          instructions:
49            - sig: throw v:in:ref
50              acc: none
51              format: [op_v_8]
52          verification:
53            - v1_throw_type
54        runner-options: ['compile-failure']
55        header-template: []
56        check-type: empty
57        code-template: |
58
59          .function i32 main() {
60            throw %s
61          }
62        cases:
63          - values: ['v256']
64          - values: ['v65535']
65          - values: ['a0']
66          - values: ['']
67          - values: ['main']
68          - values: ['i32']
69          - values: ['throw']
70          - values: ['v0, v0']
71          - values: ['}']
72          - values: ['v255']
73            runner-options: ['compile-only']
74
75      - file-name: "when_reg_v_is_uninitialized"
76        description: Check that verifier report error when the register is not initialized
77        isa:
78          instructions:
79            - sig: throw v:in:ref
80              acc: none
81              format: [op_v_8]
82          verification:
83            - v1_throw_type
84        runner-options: ['verifier-failure', 'verifier-debug-config']
85        tags: ['verifier']
86        header-template: []
87        check-type: empty
88        code-template: |
89
90          .function i32 main() {
91            throw %s
92          }
93        cases:
94          - values: ['v0']
95          - values: ['v255']
96
97
98      - file-name: "when_reg_a_is_uninitialized"
99        description: Check that compiler reports error when 'a' register is not initialized
100        isa:
101          instructions:
102            - sig: throw v:in:ref
103              acc: none
104              format: [op_v_8]
105          verification:
106            - v1_throw_type
107        runner-options: ['compile-failure']
108        header-template: []
109        check-type: empty
110        code-template: |
111          .record E {}
112
113          .function void func(E a0) <static> {
114            throw %s
115            return.void
116          }
117
118          .function i32 main() {
119            newobj v0, E
120            call.short func, v0
121          }
122        cases:
123          - values: ['a0']
124            runner-options: ['run-failure']
125          - values: ['a1']
126          - values: ['a255']
127
128
129      - file-name: "when_reg_is_null_pa"
130        description: Check that NullPointerException is thrown when register value is null
131        isa:
132          exceptions: [x_null]
133        header-template: ['pandasm_header']
134        check-type: empty
135        code-template: |
136
137          .function i32 main() {
138            jmp try_begin
139          catch_NPE_block_begin:
140            ldai 0
141            return
142          try_begin:
143            mov.null v0
144            throw v0
145          try_end:
146          .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin
147          }
148
149
150      - file-name: "with_wrong_reg_value_pa"
151        description: "Check that VM thread fails when register contains not a Throwable"
152        isa:
153          description: Throw an exception located in register.
154          verification:
155            - v1_throw_type
156        header-template: ['pandasm_header']
157        check-type: empty
158        runner-options: ['verifier-failure', 'verifier-debug-config']
159        tags: ['verifier']
160        code-template: |
161
162          .function i32 main() {
163            jmp try_begin
164          catch_all_block_begin:
165            ldai 0
166            return
167          try_begin:
168            %s
169            throw v0
170          try_end:
171          .catchall try_begin, try_end, catch_all_block_begin
172          }
173        cases:
174          - values:
175            - movi v0, 100
176          - values:
177            - movi.64 v0, 0x1234567890
178          - values:
179            - fmovi.64 v0, 3.1415926
180          - values:
181            - newobj v0, panda.Object
182            bugid: ['1688']
183            ignore: true
184          - values:
185            - newobj v0, E1
186            bugid: ['1688']
187            ignore: true
188          - values:
189            - |
190              #
191                lda.type panda.Object
192                sta.obj v0
193            bugid: ['1688']
194            ignore: true
195          - values:
196            - |
197              #
198                lda.str "abc"
199                sta.obj v0
200            bugid: ['1688']
201            ignore: true
202
203
204      - file-name: "with_multiple_catch_blocks_pa"
205        description: "Check that correct catch block is selected"
206        isa:
207          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
208        header-template: ['pandasm_header']
209        check-type: none
210        code-template: |
211
212          .function i32 main() {
213            jmp try_begin
214          catch_NPE_block_begin:
215            ldai %s
216            return
217          catch_E1_block_begin:
218            ldai %s
219            return
220          catch_E2_block_begin:
221            ldai %s
222            return
223          catch_E3_block_begin:
224            ldai %s
225            return
226          try_begin:
227            newobj v0, %s
228            throw v0
229          try_end:
230          .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin
231          .catch E1, try_begin, try_end, catch_E1_block_begin
232          .catch E2, try_begin, try_end, catch_E2_block_begin
233          .catch E3, try_begin, try_end, catch_E3_block_begin
234        cases:
235          - values: [0, 2, 3, 4, panda.NullPointerException]
236          - values: [1, 0, 3, 4, E1]
237          - values: [1, 2, 0, 4, E2]
238          - values: [1, 2, 3, 0, E3]
239
240
241      - file-name: "with_catchall_pa"
242        description: "Check that catchall block is selected correctly"
243        isa:
244          description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception.
245        header-template: ['pandasm_header']
246        check-type: empty
247        code-template: |
248
249          .function i32 main() {
250            jmp try_begin
251          catch_all_block_begin:
252            ldai %s
253            return
254          catch_E1_block_begin:
255            ldai %s
256            return
257          catch_E2_block_begin:
258            ldai %s
259            return
260          try_begin:
261            newobj v0, %s
262            throw v0
263          try_end:
264          .catch E1, try_begin, try_end, catch_E1_block_begin
265          .catchall try_begin, try_end, catch_all_block_begin
266          .catch E2, try_begin, try_end, catch_E2_block_begin
267          }
268        cases:
269          - values: [1, 0, 3, E1]
270          - values: [0, 2, 3, E2]
271          - values: [0, 2, 3, panda.NullPointerException]
272
273
274      - file-name: "with_reg_value_check_pa"
275        description: "Check that register keeps ref to exception object in catch block"
276        isa:
277          description: Throw an exception located in register.
278        header-template: ['pandasm_header']
279        check-type: empty
280        bugid: ["3975"]
281        code-template: |
282
283          .function i32 main() {
284            jmp try_begin
285          catch_block_begin:
286            lda.obj v0
287            jne.obj v1, return_ne_num
288            ldai 0
289            return
290          return_ne_num:
291            ldai 1
292            return
293          try_begin:
294            newobj v0, %s
295            mov.obj v1, v0
296            throw v0
297          try_end:
298          .catch E1, try_begin, try_end, catch_block_begin
299          .catch E2, try_begin, try_end, catch_block_begin
300          .catchall try_begin, try_end, catch_block_begin
301          }
302        cases:
303          - values:
304            - E1
305          - values:
306            - E2
307          - values:
308            - panda.NullPointerException
309
310
311      - file-name: "with_propagation_to_outer_block_pa"
312        description: "Check exception propagation to outer try-catch block"
313        isa:
314          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.
315        header-template: ['pandasm_header']
316        check-type: empty
317        tags: ['tsan']
318        code-template: |
319
320          .function i32 main() {
321          begin3:
322            newobj v0, %s
323            lda.obj v0
324          begin2:
325            mov.obj v1, v0
326          begin1:
327            throw v0
328          end1:
329          end2:
330          end3:
331            ldai 4
332            return
333          catch1:
334            %s
335            return
336          catch2:
337            %s
338            return
339          catch3:
340            %s
341            return
342          .catch E1, begin1, end1, catch1
343          .catch E2, begin2, end2, catch2
344          .catch E3, begin3, end3, catch3
345          }
346        cases:
347          - values:
348            - E1
349            - |
350              #
351                jne.obj v1, return_ne_num
352                ldai 0
353                return
354                return_ne_num:
355                ldai 1
356            - ldai 2
357            - ldai 3
358          - values:
359            - E2
360            - ldai 2
361            - |
362              #
363                jne.obj v1, return_ne_num
364                ldai 0
365                return
366                return_ne_num:
367                ldai 1
368            - ldai 3
369            bugid: ['3975']
370          - values:
371            - E3
372            - ldai 2
373            - ldai 3
374            - |
375              #
376                jne.obj v1, return_ne_num
377                ldai 0
378                return
379                return_ne_num:
380                ldai 1
381            bugid: ['3975']
382
383
384      - file-name: "with_propagation_to_outer_frame_pa"
385        description: "Check exception propagation to outer frame"
386        isa:
387          description: If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown.
388        header-template: ['pandasm_header']
389        check-type: empty
390        bugid: ["1837"]
391        code-template: |
392
393          .function i32 f2() {
394            newobj v0, %s
395          try2_begin:
396            throw v0
397          try2_end:
398            ldai 0
399            return
400          .catch %s, try2_begin, try2_end, try2_end
401          }
402
403          .function i32 f1() {
404          try1_begin:
405            call f2
406            return
407          try1_end:
408            ldai 0
409            return
410          .catch %s, try1_begin, try1_end, try1_end
411          }
412
413          .function i32 main() {
414          try_begin:
415            call f1
416            ldai %s
417            return
418          try_end:
419          catch_block_begin:
420            ldai %s
421            return
422          .catch %s, try_begin, try_end, catch_block_begin
423          }
424        cases:
425          - values: [E2, E1, E2, 0, 1, E3]
426          - values: [E3, E1, E2, 1, 0, E3]
427
428
429      - file-name: "with_no_handler_pa"
430        description: "Check exception propagation to outer frame and VM thread exit if handler is not found."
431        isa:
432          description: >
433            If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. If no
434            exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown.
435            If no such frame exists, the current VM thread exits.
436        header-template: ['pandasm_header']
437        check-type: empty
438        runner-options: ['run-failure']
439        code-template: |
440
441          .function i32 f2() {
442            newobj v0, %s
443          try2_begin:
444            throw v0
445          try2_end:
446            return
447          .catch %s, try2_begin, try2_end, try2_end
448          }
449
450          .function i32 f1() {
451          try1_begin:
452            call f2
453          try1_end:
454            return
455          .catch %s, try1_begin, try1_end, try1_end
456          }
457
458          .function i32 main() {
459          try_begin:
460            call f1
461          try_end:
462            ldai %s
463            return
464          catch_block_begin:
465            ldai %s
466            return
467          .catch %s, try_begin, try_end, catch_block_begin
468          }
469        cases:
470          - values: [E2, E1, E3, 0, 0, E1]
471          - values: [E3, E1, E1, 0, 0, E1]
472
473
474