# Copyright (c) 2021-2022 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. definitions: - name: PandaAssembly_header template: | .language PandaAssembly .record panda.NullPointerException .record panda.RuntimeException .record panda.Exception .record panda.Throwable .record panda.Object .record E1 {} - name: pandasm_header template: | .language PandaAssembly .record panda.NullPointerException .record panda.Object .record E1 {} .record E2 {} .record E3 {} tests: - file-name: "throw" isa: title: Throw exception description: Throw an exception located in register. instructions: - sig: throw v:in:ref acc: none format: [op_v_8] exceptions: - x_throw commands: - file-name: "when_reg_is_invalid" description: Check that compilation fails if register is invalid isa: instructions: - sig: throw v:in:ref acc: none format: [op_v_8] verification: - v1_throw_type runner-options: ['compile-failure'] header-template: [] check-type: empty code-template: | .function i32 main() { throw %s } cases: - values: ['v256'] - values: ['v65535'] - values: ['a0'] - values: [''] - values: ['main'] - values: ['i32'] - values: ['throw'] - values: ['v0, v0'] - values: ['}'] - values: ['v255'] runner-options: ['compile-only'] - file-name: "when_reg_v_is_uninitialized" description: Check that verifier report error when the register is not initialized isa: instructions: - sig: throw v:in:ref acc: none format: [op_v_8] verification: - v1_throw_type runner-options: ['verifier-failure', 'verifier-config'] tags: ['verifier'] header-template: [] check-type: empty code-template: | .function i32 main() { throw %s } cases: - values: ['v0'] - values: ['v255'] - file-name: "when_reg_a_is_uninitialized" description: Check that compiler reports error when 'a' register is not initialized isa: instructions: - sig: throw v:in:ref acc: none format: [op_v_8] verification: - v1_throw_type runner-options: ['compile-failure'] header-template: [] tags: ['irtoc_ignore'] check-type: empty code-template: | .record E {} .function void func(E a0) { throw %s return.void } .function i32 main() { newobj v0, E call.short func, v0 ldai 0 return } cases: - values: ['a0'] runner-options: ['run-failure'] - values: ['a1'] - values: ['a255'] - file-name: "when_reg_is_null_pa" description: Check that NullPointerException is thrown when register value is null isa: exceptions: [x_null] header-template: ['pandasm_header'] check-type: none tags: ['irtoc_ignore'] code-template: | .function i32 main() { jmp try_begin catch_NPE_block_begin: sta.obj v2 isinstance panda.NullPointerException jeqz set_failure lda.obj v2 isinstance panda.Object jeqz set_failure ldai 0 return set_failure: ldai 1 return try_begin: mov.null v0 throw v0 ldai 2 return try_end: .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin - file-name: "when_reg_is_null_j" description: Check that NullPointerException is thrown when register value is null isa: exceptions: [x_null] header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] check-type: none tags: ['tsan', 'irtoc_ignore'] code-template: | .function i32 main() { jmp try_begin catch_NPE_block_begin: sta.obj v2 isinstance panda.NullPointerException jeqz set_failure lda.obj v2 isinstance panda.Object jeqz set_failure ldai 0 return set_failure: ldai 1 return try_begin: mov.null v0 throw v0 ldai 2 return try_end: .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin - file-name: "with_wrong_reg_value_pa" description: "Check that VM thread fails when register contains not a Throwable" isa: description: Throw an exception located in register. verification: - v1_throw_type header-template: ['pandasm_header'] check-type: none runner-options: ['verifier-failure', 'verifier-config'] tags: ['verifier'] code-template: | .function i32 main() { jmp try_begin catch_all_block_begin: ldai 0 return try_begin: %s throw v0 try_end: .catchall try_begin, try_end, catch_all_block_begin cases: - values: - movi v0, 100 - values: - movi.64 v0, 0x1234567890 - values: - fmovi.64 v0, 3.1415926 - values: - newobj v0, panda.Object bugid: ['1688'] ignore: true - values: - newobj v0, E1 bugid: ['1688'] ignore: true - values: - | # lda.type panda.Object sta.obj v0 bugid: ['1688'] ignore: true - values: - | # lda.str "abc" sta.obj v0 bugid: ['1688'] ignore: true - file-name: "with_wrong_reg_value_j" description: "Check that VM thread fails when register contains not a Throwable" isa: description: Throw an exception located in register. verification: - v1_throw_type header-template: ['PandaAssembly_header'] check-type: empty runner-options: ['verifier-failure', 'verifier-config', 'use-pa'] tags: [verifier, pa-verifier] code-template: | .function i32 main() { jmp try_begin catch_all_block_begin: ldai 0 return try_begin: %s throw v0 try_end: .catchall try_begin, try_end, catch_all_block_begin } cases: - values: - movi v0, 100 - values: - movi.64 v0, 0x1234567890 - values: - fmovi.64 v0, 3.1415926 - values: - newobj v0, panda.Object bugid: ['1688'] ignore: true - values: - newobj v0, E1 bugid: ['1688'] ignore: true - values: - | # lda.type panda.Object sta.obj v0 bugid: ['1688'] ignore: true - values: - | # lda.str "abc" sta.obj v0 bugid: ['1688'] ignore: true - file-name: "with_multiple_catch_blocks_pa" description: "Check that correct catch block is selected" isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] tags: ['irtoc_ignore'] check-type: none code-template: | .function i32 main() { jmp try_begin catch_NPE_block_begin: sta.obj v2 ldai %s jnez set_failure lda.obj v2 isinstance panda.NullPointerException jeqz set_failure lda.obj v2 isinstance panda.Object jeqz set_failure lda.obj v2 jne.obj v0, set_failure ldai 0 return catch_E1_block_begin: sta.obj v2 ldai %s jnez set_failure lda.obj v2 isinstance E1 jeqz set_failure lda.obj v2 isinstance panda.Object jeqz set_failure lda.obj v2 jne.obj v0, set_failure ldai 0 return catch_E2_block_begin: sta.obj v2 ldai %s jnez set_failure lda.obj v2 isinstance E2 jeqz set_failure lda.obj v2 isinstance panda.Object jeqz set_failure lda.obj v2 jne.obj v0, set_failure ldai 0 return catch_E3_block_begin: sta.obj v2 ldai %s jnez set_failure lda.obj v2 isinstance E3 jeqz set_failure lda.obj v2 isinstance panda.Object jeqz set_failure lda.obj v2 jne.obj v0, set_failure ldai 0 return try_begin: newobj v0, %s throw v0 try_end: set_failure: ldai 1 return .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin .catch E1, try_begin, try_end, catch_E1_block_begin .catch E2, try_begin, try_end, catch_E2_block_begin .catch E3, try_begin, try_end, catch_E3_block_begin cases: - values: [0, 2, 3, 4, panda.NullPointerException] - values: [1, 0, 3, 4, E1] - values: [1, 2, 0, 4, E2] - values: [1, 2, 3, 0, E3] - file-name: "with_multiple_catch_blocks_j" description: "Check that correct catch block is selected" isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] check-type: none tags: ['tsan', 'irtoc_ignore'] code-template: | .function i32 main() { jmp try_begin catch_NPE_block_begin: sta.obj v2 ldai %s jnez set_failure lda.obj v2 isinstance panda.NullPointerException jeqz set_failure lda.obj v2 isinstance panda.Object jeqz set_failure lda.obj v2 jne.obj v0, set_failure ldai 0 return catch_RE_block_begin: sta.obj v2 ldai %s jnez set_failure lda.obj v2 isinstance panda.RuntimeException jeqz set_failure lda.obj v2 isinstance panda.Object jeqz set_failure lda.obj v2 jne.obj v0, set_failure ldai 0 return catch_E1_block_begin: sta.obj v2 ldai %s jnez set_failure lda.obj v2 isinstance E1 jeqz set_failure lda.obj v2 isinstance panda.Object jeqz set_failure lda.obj v2 jne.obj v0, set_failure ldai 0 return catch_Ex_block_begin: sta.obj v2 ldai %s jnez set_failure lda.obj v2 isinstance panda.Exception jeqz set_failure lda.obj v2 isinstance panda.Object jeqz set_failure lda.obj v2 jne.obj v0, set_failure ldai 0 return try_begin: newobj v0, %s throw v0 try_end: set_failure: ldai 1 return .catch panda.NullPointerException, try_begin, try_end, catch_NPE_block_begin .catch panda.RuntimeException, try_begin, try_end, catch_RE_block_begin .catch panda.Exception, try_begin, try_end, catch_Ex_block_begin .catch E1, try_begin, try_end, catch_E1_block_begin cases: - values: [0, 2, 3, 4, panda.NullPointerException] - values: [1, 0, 3, 4, panda.RuntimeException] - values: [1, 2, 3, 0, panda.Exception] - values: [1, 2, 0, 0, E1] - file-name: "with_catchall_pa" description: "Check that catchall block is selected correctly" isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] check-type: empty tags: ['irtoc_ignore'] code-template: | .function i32 main() { try_begin: newobj v0, %s throw v0 try_end: catch_all_block_begin: ldai %s return catch_E1_block_begin: ldai %s return catch_E2_block_begin: ldai %s return .catch E1, try_begin, try_end, catch_E1_block_begin .catchall try_begin, try_end, catch_all_block_begin .catch E2, try_begin, try_end, catch_E2_block_begin } cases: - values: [E1, 1, 0, 3] - values: [E2, 0, 2, 3] - values: [panda.NullPointerException, 0, 2, 3] - file-name: "with_catchall_j" description: "Check that catchall block is selected correctly" isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] tags: ['irtoc_ignore'] code-template: | .function i32 main() { try_begin: newobj v0, %s throw v0 try_end: catch_RE_block_begin: ldai %s return catch_Ex_block_begin: ldai %s return catch_all_block_begin: ldai %s return catch_E1_block_begin: ldai %s return .catch E1, try_begin, try_end, catch_E1_block_begin .catchall try_begin, try_end, catch_all_block_begin .catch panda.Exception, try_begin, try_end, catch_Ex_block_begin .catch panda.RuntimeException, try_begin, try_end, catch_RE_block_begin check-type: none cases: - values: [E1, 1, 2, 3, 0] - values: [panda.Exception, 1, 2, 0, 4] - values: [panda.RuntimeException, 1, 2, 0, 4] - values: [panda.NullPointerException, 1, 2, 0, 4] - file-name: "with_reg_value_check_pa" description: "Check that register keeps ref to exception object in catch block" isa: description: Throw an exception located in register. header-template: ['pandasm_header'] check-type: empty tags: ['irtoc_ignore'] bugid: ["3975"] code-template: | .function i32 main() { try_begin: newobj v0, %s throw v0 try_end: catch_block_begin: jne.obj v0, return_ne_num ldai 0 return return_ne_num: ldai 1 return .catch E1, try_begin, try_end, catch_block_begin .catch E2, try_begin, try_end, catch_block_begin .catchall try_begin, try_end, catch_block_begin } cases: - values: - E1 - values: - E2 - values: - panda.NullPointerException - file-name: "with_reg_value_check_j" description: "Check that register keeps ref to exception object in catch block" isa: description: Throw an exception located in register. header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] check-type: empty tags: ['irtoc_ignore'] bugid: ["3975"] code-template: | .function i32 main() { try_begin: newobj v0, %s throw v0 try_end: catch_block_begin: jne.obj v0, return_ne_num ldai 0 return return_ne_num: ldai 1 return .catch panda.NullPointerException, try_begin, try_end, catch_block_begin .catch panda.Exception, try_begin, try_end, catch_block_begin .catchall try_begin, try_end, catch_block_begin } cases: - values: - panda.NullPointerException - values: - panda.Exception - values: - panda.RuntimeException - file-name: "with_propagation_to_outer_block_pa" description: "Check exception propagation to outer try-catch block" isa: 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. header-template: ['pandasm_header'] check-type: empty tags: ['tsan', 'irtoc_ignore'] code-template: | .function i32 main() { begin3: newobj v0, %s lda.obj v0 begin2: mov.obj v1, v0 begin1: throw v0 end1: end2: end3: ldai 4 return catch1: %s return catch2: %s return catch3: %s return .catch E1, begin1, end1, catch1 .catch E2, begin2, end2, catch2 .catch E3, begin3, end3, catch3 } cases: - values: - E1 - | # jne.obj v1, return_ne_num ldai 0 return return_ne_num: ldai 1 - ldai 2 - ldai 3 - values: - E2 - ldai 2 - | # jne.obj v1, return_ne_num ldai 0 return return_ne_num: ldai 1 - ldai 3 bugid: ['3975'] - values: - E3 - ldai 2 - ldai 3 - | # jne.obj v1, return_ne_num ldai 0 return return_ne_num: ldai 1 bugid: ['3975'] - file-name: "with_propagation_to_outer_block_j" description: "Check exception propagation to outer try-catch block" isa: 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. header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] check-type: empty tags: ['irtoc_ignore'] code-template: | .function i32 main() { begin3: newobj v0, %s lda.obj v0 begin2: mov.obj v1, v0 begin1: throw v0 end1: end2: end3: ldai 4 return catch1: %s return catch2: %s return catch3: %s return .catch panda.NullPointerException, begin1, end1, catch1 .catch panda.RuntimeException, begin2, end2, catch2 .catch panda.Exception, begin3, end3, catch3 } cases: - values: - panda.NullPointerException - | # jne.obj v1, return_ne_num ldai 0 return return_ne_num: ldai 1 - ldai 2 - ldai 3 - values: - panda.RuntimeException - ldai 2 - | # jne.obj v1, return_ne_num ldai 0 return return_ne_num: ldai 1 - ldai 3 bugid: ['3975'] - values: - panda.Exception - ldai 2 - ldai 3 - | # jne.obj v1, return_ne_num ldai 0 return return_ne_num: ldai 1 bugid: ['3975'] - file-name: "with_propagation_to_outer_frame_pa" description: "Check exception propagation to outer frame" isa: description: If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. header-template: ['pandasm_header'] check-type: empty bugid: ["1837"] tags: ['irtoc_ignore'] code-template: | .function i32 f2() { newobj v0, %s try2_begin: throw v0 try2_end: ldai 0 return .catch %s, try2_begin, try2_end, try2_end } .function i32 f1() { try1_begin: call f2 return try1_end: ldai 0 return .catch %s, try1_begin, try1_end, try1_end } .function i32 main() { try_begin: call f1 ldai %s return try_end: catch_block_begin: ldai %s return .catch %s, try_begin, try_end, catch_block_begin } cases: - values: [E2, E1, E2, 0, 1, E3] - values: [E3, E1, E2, 1, 0, E3] - file-name: "with_propagation_to_outer_frame_j" description: "Check exception propagation to outer frame" isa: description: If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] check-type: empty tags: ['irtoc_ignore'] bugid: ["1837"] code-template: | .function i32 f2() { newobj v0, %s try2_begin: throw v0 try2_end: ldai 0 return .catch %s, try2_begin, try2_end, try2_end } .function i32 f1() { try1_begin: call f2 return try1_end: ldai 0 return .catch %s, try1_begin, try1_end, try1_end } .function i32 main() { try_begin: call f1 ldai %s return try_end: catch_block_begin: ldai %s return .catch %s, try_begin, try_end, catch_block_begin } cases: - values: [panda.Exception, panda.NullPointerException, panda.Exception, 0, 1, panda.RuntimeException] - values: [panda.Exception, panda.NullPointerException, panda.RuntimeException, 1, 0, panda.Exception] - file-name: "with_no_handler_pa" description: "Check exception propagation to outer frame." isa: description: > If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. header-template: ['pandasm_header'] tags: ['irtoc_ignore'] check-type: empty code-template: | .function i32 f2() { newobj v0, %s try2_begin: throw v0 try2_end: ldai 1 return .catch %s, try2_begin, try2_end, try2_end } .function i32 f1() { try1_begin: call f2 return try1_end: ldai 1 return .catch %s, try1_begin, try1_end, try1_end } .function i32 main() { try_begin: call f1 return try_end: catch_block_begin: ldai 0 return .catch %s, try_begin, try_end, catch_block_begin } cases: - values: [E2, E1, E3, E2] - values: [E3, E1, E1, E3] - file-name: "with_no_handler_j" description: "Check exception propagation to outer frame." isa: description: > If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. header-template: ['PandaAssembly_header'] check-type: empty runner-options: ['use-pa'] tags: ['irtoc_ignore'] code-template: | .function i32 f2() { newobj v0, %s try2_begin: throw v0 try2_end: ldai 1 return .catch %s, try2_begin, try2_end, try2_end } .function i32 f1() { try1_begin: call f2 return try1_end: ldai 1 return .catch %s, try1_begin, try1_end, try1_end } .function i32 main() { try_begin: call f1 return try_end: catch_block_begin: ldai 0 return .catch %s, try_begin, try_end, catch_block_begin } cases: - values: [panda.Exception, panda.NullPointerException, panda.RuntimeException, panda.Exception] - file-name: "with_no_handler2_pa" description: "Check thread exit if handler is not found." isa: description: > If no such frame exists, the current VM thread exits. header-template: ['pandasm_header'] check-type: empty runner-options: ['run-failure'] tags: ['irtoc_ignore'] code-template: | .function i32 main() { newobj v0, %s throw v0 ldai 0 return } cases: - values: [E2] - values: [panda.Object] - file-name: "with_no_handler2_j" description: "Check VM thread exit if handler is not found." isa: description: > If no such frame exists, the current VM thread exits. header-template: ['PandaAssembly_header'] check-type: empty runner-options: ['use-pa', 'run-failure'] bugid: ['5450'] tags: ['arm64-fail', 'irtoc_ignore'] code-template: | .function i32 main() { newobj v0, %s throw v0 ldai 0 return } cases: - values: [panda.Exception] - values: [panda.NullPointerException] - file-name: "subclass_of_exception_j" description: "Check that exception subclass is successfully caught by its superclass declaration in catch" isa: 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. header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] check-type: empty bugid: ['3977'] tags: ['tsan', 'irtoc_ignore'] code-template: | .record MyCustomException {} .record MySecondCustomException {} .function i32 main() { jmp try_begin catch_block_begin: ldai 0 return catch2_block_begin: ldai 1 return try_begin: newobj v0, %s throw v0 try_end: .catch %s, try_begin, try_end, catch_block_begin .catchall try_begin, try_end, catch2_block_begin } cases: - values: [panda.RuntimeException, panda.Exception] - values: [MyCustomException, panda.RuntimeException] - values: [MySecondCustomException, MyCustomException] - values: [MySecondCustomException, panda.Exception] - file-name: "superclass_of_exception_j" description: "Check that exception superclass is not caught by its subclass declaration in catch" isa: description: > If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. If no exception handler is found, the frame of invoker is restored. If such frame exists, the exception is re-thrown. If no such frame exists, the current VM thread exits. header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] tags: ['irtoc_ignore'] check-type: empty code-template: | .record MyCustomException {} .record MySecondCustomException {} .function i32 main() { jmp try_begin catch_block_begin: ldai 1 return catch2_block_begin: ldai 0 return try_begin: newobj v0, %s throw v0 try_end: .catch %s, try_begin, try_end, catch_block_begin .catchall try_begin, try_end, catch2_block_begin } cases: - values: [panda.Exception, panda.RuntimeException] - values: [panda.RuntimeException, MyCustomException] - values: [MyCustomException, MySecondCustomException] - values: [panda.Exception, MySecondCustomException] - file-name: "cflow_fallthrough1_pa" description: "Check that the verifier prohibits a fallthrough to the beginning of open-ended exception handler." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] tags: ['verifier'] check-type: none code-template: | .function i32 foo(E1 a0) { throw a0 } .function i32 main() { newobj v1, E1 lda.obj v1 %s catch_all: ldai 0 return try_begin: throw v1 try_end: ldai 2 return .catchall try_begin, try_end, catch_all cases: - values: - '' runner-options: ['verifier-failure', 'verifier-config'] - values: - jnez.obj try_begin runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp catch_all runner-options: ['verifier-failure', 'verifier-config'] - values: - call.short foo, v1 runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp try_begin runner-options: ['verifier-only', 'verifier-config'] - values: - throw v1 runner-options: ['verifier-only', 'verifier-config'] - values: - | # ldai 0 return runner-options: ['verifier-only', 'verifier-config'] - file-name: "cflow_fallthrough2_pa" description: "Check that the verifier prohibits a fallthrough to the beginning of close-ended exception handler." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] tags: ['verifier'] check-type: none code-template: | .function i32 foo(E1 a0) { throw a0 } .function i32 main() { newobj v1, E1 lda.obj v1 %s catch_begin: ldai 0 return catch_end: try_begin: throw v1 try_end: ldai 2 return .catchall try_begin, try_end, catch_begin, catch_end cases: - values: - '' runner-options: ['verifier-failure', 'verifier-config'] - values: - jnez.obj try_begin runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp catch_begin runner-options: ['verifier-failure', 'verifier-config'] - values: - call.short foo, v1 runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp catch_end runner-options: ['verifier-only', 'verifier-config'] - values: - jmp try_begin runner-options: ['verifier-only', 'verifier-config'] - values: - throw v1 runner-options: ['verifier-only', 'verifier-config'] - values: - | # ldai 0 return runner-options: ['verifier-only', 'verifier-config'] - file-name: "cflow_fallthrough3_pa" description: "Check that the verifier prohibits an open-ended exception handler at the beginning of a function." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] runner-options: ['verifier-failure', 'verifier-config'] tags: ['verifier'] bugid: ['8029'] ignore: true check-type: none code-template: | .function i32 foo(E1 a0) { catch_begin: ldai 0 return try_begin: throw a0 try_end: ldai 2 return .catchall try_begin, try_end, catch_begin } .function i32 main() { newobj v1, E1 call.short foo, v1 return - file-name: "cflow_fallthrough4_pa" description: "Check that the verifier prohibits an close-ended exception handler at the beginning of a function." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] runner-options: ['verifier-failure', 'verifier-config'] tags: ['verifier'] bugid: ['8029'] ignore: true check-type: none code-template: | .function i32 foo(E1 a0) { catch_begin: ldai 0 return catch_end: try_begin: throw a0 try_end: ldai 2 return .catchall try_begin, try_end, catch_begin, catch_end } .function i32 main() { newobj v1, E1 call.short foo, v1 return - file-name: "cflow_fallthrough5_pa" description: "Check that the verifier prohibits a fallthrough from one handler to the beginning of another exception handler." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] runner-options: ['verifier-failure', 'verifier-config'] tags: ['verifier'] check-type: none code-template: | .function i32 foo(E1 a0) { throw a0 } .function i32 main() { try_begin: newobj v1, E1 lda.obj v1 jeqz.obj fail throw v1 fail: ldai 1 return try_end: catch_E1: ldai 2 %s catch_all: ldai 3 return exit: ldai 4 return .catch E1, try_begin, try_end, catch_E1 .catchall try_begin, try_end, catch_all cases: - values: - '' - values: - call.short foo, v1 - values: - jmp catch_all - values: - jnez.obj exit - values: - return runner-options: ['verifier-only', 'verifier-config'] - values: - jmp exit runner-options: ['verifier-only', 'verifier-config'] - values: - throw v1 runner-options: ['verifier-only', 'verifier-config'] - file-name: "cflow_fallthrough6_pa" description: "Check that the verifier prohibits a fallthrough from one handler to the beginning of another exception handler." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] runner-options: ['verifier-failure', 'verifier-config'] tags: ['verifier'] check-type: none code-template: | .function i32 foo(E1 a0) { throw a0 } .function i32 main() { try_begin: newobj v1, E1 lda.obj v1 throw v1 try_end: ldai 1 return catch_E1: ldai 2 %s catch_E1_end: catch_all: ldai 3 return catch_all_end: exit: ldai 4 return .catch E1, try_begin, try_end, catch_E1, catch_E1_end .catchall try_begin, try_end, catch_all, catch_all_end cases: - values: - '' - values: - call.short foo, v1 - values: - jmp catch_all - values: - jnez.obj exit - values: - return runner-options: ['verifier-only', 'verifier-config'] - values: - jmp exit runner-options: ['verifier-only', 'verifier-config'] - values: - throw v1 runner-options: ['verifier-only', 'verifier-config'] - file-name: "cflow_jump1_pa" description: "Check that the verifier prohibits a jump from code into an open-ended exception handler." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] tags: ['verifier'] check-type: none code-template: | .function i32 main() { newobj v1, E1 lda.obj v1 %s try_begin: throw v1 try_end: catch_all: isinstance E1 catch_fail: ldai 1 return catch_ok: ldai 0 return .catchall try_begin, try_end, catch_all cases: - values: - '' runner-options: ['verifier-only', 'verifier-config'] - values: - jmp catch_all runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp catch_fail runner-options: ['verifier-only', 'verifier-config'] - values: - jmp catch_ok runner-options: ['verifier-only', 'verifier-config'] - values: - jeqz.obj catch_all runner-options: ['verifier-failure', 'verifier-config'] - values: - jeqz.obj catch_fail runner-options: ['verifier-only', 'verifier-config'] - values: - jeqz.obj catch_ok runner-options: ['verifier-only', 'verifier-config'] - file-name: "cflow_jump2_pa" description: "Check that the verifier prohibits a jump from code into a close-ended exception handler." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] tags: ['verifier'] check-type: none code-template: | .function i32 main() { newobj v1, E1 lda.obj v1 %s try_begin: throw v1 try_end: catch_begin: isinstance E1 catch_fail: ldai 1 return catch_ok: ldai 0 return catch_end: .catchall try_begin, try_end, catch_begin, catch_end cases: - values: - '' runner-options: ['verifier-only', 'verifier-config'] - values: - jmp catch_begin runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp catch_fail runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp catch_ok runner-options: ['verifier-failure', 'verifier-config'] - values: - jeqz.obj catch_begin runner-options: ['verifier-failure', 'verifier-config'] - values: - jeqz.obj catch_fail runner-options: ['verifier-failure', 'verifier-config'] - values: - jeqz.obj catch_ok runner-options: ['verifier-failure', 'verifier-config'] - file-name: "cflow_jump3_pa" description: "Check that the verifier prohibits a jump from try block into a open-ended exception handler." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] tags: ['verifier'] check-type: none code-template: | .function i32 main() { try_begin: newobj v1, E1 lda.obj v1 %s throw v1 try_end: catch_begin: isinstance E1 catch_fail: ldai 1 return catch_ok: ldai 0 return .catchall try_begin, try_end, catch_begin cases: - values: - '' runner-options: ['verifier-only', 'verifier-config'] - values: - jmp catch_begin runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp catch_fail runner-options: ['verifier-only', 'verifier-config'] - values: - jmp catch_ok runner-options: ['verifier-only', 'verifier-config'] - values: - jeqz.obj catch_begin runner-options: ['verifier-failure', 'verifier-config'] - values: - jeqz.obj catch_fail runner-options: ['verifier-only', 'verifier-config'] - values: - jeqz.obj catch_ok runner-options: ['verifier-only', 'verifier-config'] - file-name: "cflow_jump4_pa" description: "Check that the verifier prohibits a jump from try block into a close-ended exception handler." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] tags: ['verifier'] check-type: none code-template: | .function i32 main() { try_begin: newobj v1, E1 lda.obj v1 %s throw v1 try_end: catch_begin: isinstance E1 catch_fail: ldai 1 return catch_ok: ldai 0 return catch_end: .catchall try_begin, try_end, catch_begin, catch_end cases: - values: - '' runner-options: ['verifier-only', 'verifier-config'] - values: - jmp catch_begin runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp catch_fail runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp catch_ok runner-options: ['verifier-failure', 'verifier-config'] - values: - jeqz.obj catch_begin runner-options: ['verifier-failure', 'verifier-config'] - values: - jeqz.obj catch_fail runner-options: ['verifier-failure', 'verifier-config'] - values: - jeqz.obj catch_ok runner-options: ['verifier-failure', 'verifier-config'] - file-name: "cflow_jump5_pa" description: "Check that the verifier prohibits a jump from exception handler to another open-ended exception handler." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] tags: ['verifier'] check-type: none code-template: | .function i32 main() { newobj v1, E1 lda.obj v1 try_begin: throw v1 try_end: catch_E1: %s ldai 0 return catch_all: ldai 2 fail: return .catch E1, try_begin, try_end, catch_E1 .catchall try_begin, try_end, catch_all cases: - values: - '' runner-options: ['verifier-only', 'verifier-config'] - values: - jmp catch_all runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp fail runner-options: ['verifier-only', 'verifier-config'] - values: - jeqz.obj catch_all runner-options: ['verifier-failure', 'verifier-config'] - values: - jeqz.obj fail runner-options: ['verifier-only', 'verifier-config'] - values: - | # isinstance E1 jnez e1_ok ldai 1 return e1_ok: runner-options: ['verifier-only', 'verifier-config'] - file-name: "cflow_jump6_pa" description: "Check that the verifier prohibits a jump from exception handler to another close-ended exception handler." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] tags: ['verifier'] check-type: none code-template: | .function i32 main() { newobj v1, E1 lda.obj v1 try_begin: throw v1 try_end: catch_E1: %s ldai 0 return catch_E1_end: catch_all: ldai 2 fail: return catch_all_end: .catch E1, try_begin, try_end, catch_E1, catch_E1_end .catchall try_begin, try_end, catch_all, catch_all_end cases: - values: - '' runner-options: ['verifier-only', 'verifier-config'] - values: - jmp catch_all runner-options: ['verifier-failure', 'verifier-config'] - values: - jmp fail runner-options: ['verifier-failure', 'verifier-config'] - values: - jeqz.obj catch_all runner-options: ['verifier-failure', 'verifier-config'] - values: - jeqz.obj fail runner-options: ['verifier-failure', 'verifier-config'] - values: - | # isinstance E1 jnez e1_ok ldai 1 return e1_ok: runner-options: ['verifier-only', 'verifier-config'] bugid: ['8025'] ignore: true - file-name: "cflow_jump7_pa" description: "Check that the verifier prohibits a jump from a handler into a try block." isa: description: Throw an exception located in register. The current method is searched for the first exception handler that matches the class of exception. header-template: ['pandasm_header'] tags: ['verifier'] check-type: none code-template: | .function i32 main() { try_begin: newobj v1, E1 throw v1 try_mid: ldai 1 return try_end: catch_all: %s catch_all_end: .catchall try_begin, try_end, catch_all, catch_all_end cases: - values: - '' runner-options: ['verifier-failure', 'verifier-config'] - values: - | # ldai 0 return runner-options: ['verifier-only', 'verifier-config'] - values: - jmp try_begin runner-options: ['verifier-failure', 'verifier-config'] bugid: ['8032'] ignore: true - values: - jmp try_mid runner-options: ['verifier-failure', 'verifier-config'] bugid: ['8032'] ignore: true