# 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.Class .record panda.Object .record panda.String .record panda.CharSequence .record panda.io.Serializable .record panda.NullPointerException .record panda.ClassCastException .record R <> {} .record I {} .record Q {} .record A {} .record J {} - name: pandasm_header template: | .language PandaAssembly .record panda.Class .record panda.Object .record panda.String .record panda.ClassCastException .record R {} .record Q {} tests: - file-name: "isinstance" isa: title: Is instance description: > Resolve object type by specified id and if an object in accumulator is an instance of the resolved type, put 1 into accumulator, otherwise put 0. Object of type O is instance of type T if O is the same as T or is subtype of T. For arrays T should be a root type in type hierarchy or T is such array that O array elements are the same or subtype of T array elements. instructions: - sig: isinstance type_id acc: inout:ref->i32 format: [op_id_16] commands: - file-name: "of_null_pa" description: Check that null object reference is not an instance of any class isa: description: > 'null' object is not an instance of any class. header-template: ['pandasm_header'] check-type: empty code-template: | .function i32 main() { lda.null isinstance %s return } cases: - values: ['panda.Class'] - values: ['panda.Object'] - values: ['R'] - file-name: "of_null_j" description: Check that null object reference is not an instance of any class isa: description: > 'null' object is not an instance of any class. header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] check-type: empty code-template: | .function i32 main() { lda.null isinstance %s return } cases: - values: ['panda.Class'] - values: ['panda.Object'] - values: ['R'] - values: ['I'] - values: ['Q'] - values: ['A'] - file-name: "with_wrong_typeid_pa" description: Check that compiler fails when type_id cannot be resolved to object type isa: verification: - type_id_any_object header-template: ['pandasm_header'] runner-options: ['compile-failure'] check-type: exit-positive code-template: | .function i32 main() { %s isinstance %s cases: - values: - lda.null - panda.XYZObj - values: - lda.null - "null" - values: - | newobj v0, panda.Object lda.obj v0 - XYZObj - values: - | newobj v0, panda.Object lda.obj v0 - "\"xyz\"" - values: - | newobj v0, panda.Object lda.obj v0 - i32 - values: - ldai 1 - 1 - values: - ldai.64 0xC0BAC0BAC0BA - 0xC0BAC0BAC0BA - values: - fldai.64 2.7182818284590452353603 - 2.7182818284590452353603 - file-name: "with_valid_typeid_pa" description: Check that verifier succeeds on valid typeid. isa: verification: - type_id_any_object header-template: ['pandasm_header'] check-type: empty code-template: | .function i32 main() { newobj v0, R lda.obj v0 isinstance panda.Object jeqz set_failure lda.obj v0 isinstance panda.Class jnez set_failure lda.obj v0 isinstance panda.String jnez set_failure lda.obj v0 isinstance panda.ClassCastException jnez set_failure lda.obj v0 isinstance R jeqz set_failure ldai 0 return set_failure: ldai 1 return } - file-name: "with_wrong_typeid_j" description: Check that compiler fails when type_id cannot be resolved to object type isa: verification: - type_id_any_object header-template: ['PandaAssembly_header'] runner-options: ['use-pa', 'compile-failure'] check-type: exit-positive code-template: | .function i32 main() { %s isinstance %s cases: - values: - lda.null - panda.XYZObj - values: - | newobj v0, panda.Object lda.obj v0 - panda.XYZObj - values: - | newobj v0, panda.Object lda.obj v0 - "null" - values: - | newobj v0, panda.Object lda.obj v0 - "\"\"" - values: - | newobj v0, panda.Object lda.obj v0 - f64 - values: - ldai 0 - 0 - values: - ldai.64 0x01 - 0x01 - values: - fldai.64 2.7182818284590452353603 - 2.7182818284590452353603 - file-name: "with_valid_typeid_j" description: Check that verifier succeeds on valid typeid. isa: verification: - type_id_any_object header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] tags: ['irtoc_ignore'] check-type: empty code-template: | .function i32 main() { newobj v0, Q lda.obj v0 isinstance panda.Object jeqz set_failure lda.obj v0 isinstance panda.Class jnez set_failure lda.obj v0 isinstance panda.String jnez set_failure lda.obj v0 isinstance panda.ClassCastException jnez set_failure lda.obj v0 isinstance Q jeqz set_failure lda.obj v0 isinstance R jeqz set_failure lda.obj v0 isinstance I jeqz set_failure ldai 0 return set_failure: ldai 1 return } - file-name: "with_wrong_acc_value_pa" description: Check that verifier fails when accumulator contains wrong value - neither object, nor null isa: verification: - acc_obj_or_null header-template: ['pandasm_header'] runner-options: ['verifier-failure', 'verifier-config'] tags: ['verifier'] check-type: exit-positive code-template: | .function i32 main() { %s isinstance %s cases: - values: - ldai 1 - panda.Object - values: - ldai.64 0xC0BAC0BAC0BA - panda.Object - values: - fldai.64 2.7182818284590452353603 - panda.Object - file-name: "with_wrong_acc_value_j" description: Check that verifier fails when accumulator contains wrong value - neither object, nor null isa: verification: - acc_obj_or_null header-template: ['PandaAssembly_header'] runner-options: ['use-pa', 'verifier-failure', 'verifier-config'] tags: [verifier, pa-verifier] bugid: ['3293'] check-type: exit-positive code-template: | .function i32 main() { %s isinstance %s cases: - values: - ldai 1 - panda.Object - values: - ldai.64 0xC0BAC0BAC0BA - panda.Object - values: - fldai.64 2.7182818284590452353603 - panda.Object - file-name: "when_1_is_expected_pa" description: Check that the instruction sets accumulator to 1 when expected isa: description: > Resolve object type by specified id and if an object in accumulator is an instance of the resolved type, put 1 into accumulator, otherwise put 0. Object of type O is instance of type T if O is the same as T or is subtype of T. For arrays T should be a root type in type hierarchy or T is such array that O array elements are the same or subtype of T array elements. header-template: ['pandasm_header'] check-type: empty tags: ['tsan', 'irtoc_ignore'] code-template: | .function i32 main() { %s isinstance %s subi 1 return } cases: # O has a type of T - values: - | # O and T are of the same type, std object newobj v0, panda.Object lda.obj v0 - panda.Object - values: - | # O and T are of the same type, custom object newobj v0, R lda.obj v0 - R - values: - | # O and T are of the same type, string lda.str "xyz" - panda.String - values: - | # O and T are of the same type, type lda.type R - panda.Class # O is a subtype of T - values: - | # O is a subtype of T, std object newobj v0, panda.ClassCastException lda.obj v0 - panda.Object - values: - | # O is a subtype of T, custom object newobj v0, R lda.obj v0 - panda.Object - values: - | # O is a subtype of T, string lda.str "xyz" - panda.Object - values: - | # O is a subtype of T, type lda.type R - panda.Object # O[] has a type of T[] - values: - | # O and T are of the same type, both arrays, std object movi v0, 10 newarr v0, v0, panda.Object[] lda.obj v0 - panda.Object[] bugid: ["1805"] - values: - | # O and T are of the same type, both arrays, custom object movi v0, 10 newarr v0, v0, R[] lda.obj v0 - R[] bugid: ["1805"] - values: - | # O and T are of the same type, both arrays, string movi v0, 10 newarr v0, v0, panda.String[] lda.obj v0 - panda.String[] bugid: ["1805"] # O[] is a subtype of T[] - values: - | # O is a subtype of T, both arrays, std object movi v0, 10 newarr v0, v0, panda.ClassCastException[] lda.obj v0 - panda.Object[] bugid: ["1805"] - values: - | # O is a subtype of T, both arrays, custom object movi v0, 10 newarr v0, v0, R[] lda.obj v0 - panda.Object[] bugid: ["1805"] # T is a root type for O[] - values: - | # T is a root type for O[], std object movi v0, 10 newarr v0, v0, panda.ClassCastException[] lda.obj v0 - panda.Object - values: - | # T is a root type for O[], custom object movi v0, 10 newarr v0, v0, R[] lda.obj v0 - panda.Object - file-name: "when_1_is_expected_j" description: Check that the instruction sets accumulator to 1 when expected isa: description: > Resolve object type by specified id and if an object in accumulator is an instance of the resolved type, put 1 into accumulator, otherwise put 0. Object of type O is instance of type T if O is the same as T or is subtype of T. For arrays T should be a root type in type hierarchy or T is such array that O array elements are the same or subtype of T array elements. header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] check-type: empty tags: ['tsan', 'irtoc_ignore'] code-template: | .function i32 main() { %s isinstance %s subi 1 return } cases: # O type is T - values: - | # O and T are of the same type, std object newobj v0, panda.Object lda.obj v0 - panda.Object - values: - | # O and T are of the same type, custom object newobj v0, R lda.obj v0 - R - values: - | # O and T are of the same type, string lda.str "xyz" - panda.String - values: - | # O and T are of the same type, type lda.type R - panda.Class # O extends or implements T - values: - | # O is a subtype of T, std object newobj v0, panda.NullPointerException lda.obj v0 - panda.Object - values: - | # O implements T, std object newobj v0, panda.NullPointerException lda.obj v0 - panda.io.Serializable ignore: true bugid: ["1806"] - values: - | # O is a subtype of T, custom object newobj v0, Q lda.obj v0 - R - values: - | # O implements T, std object newobj v0, Q lda.obj v0 - I - values: - | # O is a subtype of T, string lda.str "xyz" - panda.Object - values: - | # O implements T, string lda.str "xyz" - panda.CharSequence bugid: ["1806"] - values: - | # O is a subtype of T, type lda.type R - panda.Object - values: - | # O implements T , type lda.type R - panda.io.Serializable # O[] type is T[] - values: - | # O and T are of the same type, both arrays, std object movi v0, 10 newarr v0, v0, panda.Object[] lda.obj v0 - panda.Object[] bugid: ["1805"] - values: - | # O and T are of the same type, both arrays, custom object movi v0, 10 newarr v0, v0, A[] lda.obj v0 - A[] bugid: ["1805"] - values: - | # O and T are of the same type, both arrays, string movi v0, 10 newarr v0, v0, panda.String[] lda.obj v0 - panda.String[] bugid: ["1805"] # O[] extends or implements T[] - values: - | # O is a subtype of T, both arrays, std object movi v0, 10 newarr v0, v0, panda.NullPointerException[] lda.obj v0 - panda.Object[] bugid: ["1805"] - values: - | # O implements T, both arrays, std object movi v0, 10 newarr v0, v0, panda.NullPointerException[] lda.obj v0 - panda.io.Serializable[] ignore: true bugid: ["1806"] - values: - | # O is a subtype of T, both arrays, custom object movi v0, 10 newarr v0, v0, Q[] lda.obj v0 - R[] bugid: ["1805"] - values: - | # O implements T, both arrays, custom object movi v0, 10 newarr v0, v0, Q[] lda.obj v0 - I[] bugid: ["1805"] # T is a root type for O[] - values: - | # T is a root type for O[], std object movi v0, 10 newarr v0, v0, panda.NullPointerException[] lda.obj v0 - panda.Object - values: - | # T is a root type for O[], custom object movi v0, 10 newarr v0, v0, R[] lda.obj v0 - panda.Object - file-name: "when_0_is_expected_pa" description: Check that the instruction sets accumulator to 0 when expected isa: description: > Resolve object type by specified id and if an object in accumulator is an instance of the resolved type, put 1 into accumulator, otherwise put 0. Object of type O is instance of type T if O is the same as T or is subtype of T. For arrays T should be a root type in type hierarchy or T is such array that O array elements are the same or subtype of T array elements. header-template: ['pandasm_header'] check-type: empty code-template: | .function i32 main() { %s isinstance %s return } cases: # O is not related to T - values: - | # O and T are of unrelated types, std object newobj v0, panda.ClassCastException lda.obj v0 - R - values: - | # O and T are of unrelated types, custom object newobj v0, R lda.obj v0 - Q - values: - | # O and T are of unrelated types, string lda.str "xyz" - R - values: - | # O and T are of unrelated types, type lda.type R - panda.ClassCastException # O is a supertype of T - values: - | # O is a supertype of T, std object newobj v0, panda.Object lda.obj v0 - panda.ClassCastException - values: - | # O is a supertype of T, custom object newobj v0, panda.Object lda.obj v0 - R # O[] is not related to T[] - values: - | # O and T are of unrelated types, both arrays, std object movi v0, 10 newarr v0, v0, panda.ClassCastException[] lda.obj v0 - R[] bugid: ["1805"] - values: - | # O and T are of unrelated types, both arrays, custom object movi v0, 10 newarr v0, v0, R[] lda.obj v0 - Q[] bugid: ["1805"] # O[] is a supertype of T[] - values: - | # O is a supertype of T, both arrays, std object movi v0, 10 newarr v0, v0, panda.Object[] lda.obj v0 - panda.ClassCastException[] bugid: ["1805"] - values: - | # O is a supertype of T, both arrays, custom object movi v0, 10 newarr v0, v0, panda.Object[] lda.obj v0 - R[] bugid: ["1805"] # T is not a root type for O[] - values: - | # T is a not a root type for O[], std object movi v0, 10 newarr v0, v0, panda.ClassCastException[] lda.obj v0 - panda.String - values: - | # T is a not a root type for O[], custom object movi v0, 10 newarr v0, v0, R[] lda.obj v0 - panda.ClassCastException - file-name: "when_0_is_expected_j" description: Check that the instruction sets accumulator to 0 when expected isa: description: > Resolve object type by specified id and if an object in accumulator is an instance of the resolved type, put 1 into accumulator, otherwise put 0. Object of type O is instance of type T if O is the same as T or is subtype of T. For arrays T should be a root type in type hierarchy or T is such array that O array elements are the same or subtype of T array elements. header-template: ['PandaAssembly_header'] runner-options: ['use-pa'] check-type: empty tags: ['tsan', 'irtoc_ignore'] code-template: | .function i32 main() { %s isinstance %s return } cases: # O is not related to T - values: - | # O and T are of unrelated types, std object newobj v0, panda.NullPointerException lda.obj v0 - panda.Class - values: - | # O and T are of unrelated types, custom object newobj v0, R lda.obj v0 - A - values: - | # O and T are of unrelated types, string lda.str "xyz" - panda.NullPointerException - values: - | # O and T are of unrelated types, type lda.type R - panda.String # O is a supertype of T - values: - | # O is a supertype of T, std object newobj v0, panda.Object lda.obj v0 - panda.NullPointerException - values: - | # O doesn't implement T, std object newobj v0, panda.NullPointerException lda.obj v0 - I - values: - | # O is a supertype of T, custom object newobj v0, R lda.obj v0 - Q - values: - | # O doesn't implement T, custom object newobj v0, Q lda.obj v0 - J - values: - | # O doesn't implement T, string lda.str "xyz" - I - values: - | # O doesn't implement T, type lda.type R - I # O[] is not related to T[] - values: - | # O and T are of unrelated types, both arrays, std object movi v0, 10 newarr v0, v0, panda.NullPointerException[] lda.obj v0 - R[] bugid: ["1805"] - values: - | # O and T are of unrelated types, both arrays, custom object movi v0, 10 newarr v0, v0, A[] lda.obj v0 - panda.Class[] bugid: ["1805"] # O[] is a supertype of T[] - values: - | # O is a supertype of T, both arrays, std object movi v0, 10 newarr v0, v0, panda.Object[] lda.obj v0 - panda.NullPointerException[] bugid: ["1805"] - values: - | # O doesn't implement T, both arrays, std object movi v0, 10 newarr v0, v0, panda.NullPointerException[] lda.obj v0 - I[] bugid: ["1805"] - values: - | # O is a supertype of T, both arrays, custom object movi v0, 10 newarr v0, v0, R[] lda.obj v0 - Q[] bugid: ["1805"] - values: - | # O doesn't implement T, both arrays, custom object movi v0, 10 newarr v0, v0, Q[] lda.obj v0 - J[] bugid: ["1805"] # T is not a root type for O[] - values: - | # T is not a root type for O[], std object movi v0, 10 newarr v0, v0, panda.NullPointerException[] lda.obj v0 - panda.String - values: - | # T is not a root type for O[], custom object movi v0, 10 newarr v0, v0, Q[] lda.obj v0 - R - file-name: "with_nodef_typeid_pa" description: Check that NoClassDefFoundError is thrown when expected isa: exceptions: - x_classdef header-template: ['pandasm_header'] tags: ['irtoc_ignore'] check-type: empty bugid: ['5385'] code-template: | .record panda.NoClassDefFoundError .record panda.XYZObj .function i32 main() { begin: %s isinstance %s ldai 1 return end: catch_NCDFE: ldai 0 return catch_all: ldai 2 return .catch panda.NoClassDefFoundError, begin, end, catch_NCDFE .catchall begin, end, catch_all } cases: - values: - lda.null - panda.XYZObj - values: - lda.null - panda.XYZObj[] - values: - | # newobj v0, panda.Object lda.obj v0 - panda.XYZObj - values: - | # movi v0, 10 newarr v0, v0, panda.Object[] lda.obj v0 - panda.XYZObj[] - file-name: "with_nodef_typeid_j" description: Check that NoClassDefFoundError is thrown when expected isa: exceptions: - x_classdef header-template: ['PandaAssembly_header'] tags: ['irtoc_ignore'] runner-options: ['use-pa'] check-type: empty bugid: ['5385'] code-template: | .record panda.NoClassDefFoundError .record panda.XYZObj .record panda.XYZSub {} .record panda.XYZInf .function i32 main() { begin: %s isinstance %s ldai 1 return end: catch_NCDFE: ldai 0 return catch_all: ldai 2 return .catch panda.NoClassDefFoundError, begin, end, catch_NCDFE .catchall begin, end, catch_all } cases: - values: - lda.null - panda.XYZObj - values: - lda.null - panda.XYZObj[] - values: - | # newobj v0, panda.Object lda.obj v0 - panda.XYZObj - values: - | # movi v0, 10 newarr v0, v0, panda.Object[] lda.obj v0 - panda.XYZObj[] - values: - lda.null - panda.XYZSub - values: - lda.null - panda.XYZSub[] - values: - | # newobj v0, panda.Object lda.obj v0 - panda.XYZSub - values: - | # movi v0, 10 newarr v0, v0, panda.Object[] lda.obj v0 - panda.XYZSub[] - values: - lda.null - panda.XYZInf - values: - lda.null - panda.XYZInf[] - values: - | # newobj v0, panda.Object lda.obj v0 - panda.XYZInf - values: - | # movi v0, 10 newarr v0, v0, panda.Object[] lda.obj v0 - panda.XYZInf[]