# 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: pandasm_header template: | .language PandaAssembly .record panda.Object .record Q {} .function void Q.ctor(Q a0) { return.void } .record R { u1 fu1 u8 fu8 i8 fi8 u16 fu16 i16 fi16 u32 fu32 i32 fi32 u64 fu64 i64 fi64 f32 ff32 f64 ff64 # objects i32[] fi32Array Q fQ Q[] fQArray R fR R[] fRArray panda.Object fObj panda.Object fObj2 panda.Object[] fObjArray } .function void R.ctor(R a0) { return.void } - name: PandaAssembly_header template: | .language PandaAssembly .record panda.Object .function void panda.Object.ctor(panda.Object a0) .record I {} .record Q {} .function void Q.ctor(Q a0) { return.void } .record R { u1 fu1 i8 fi8 u16 fu16 i16 fi16 i32 fi32 i64 fi64 f32 ff32 f64 ff64 # objects i32[] fi32Array Q fQ Q[] fQArray R fR R[] fRArray I fI I[] fIArray panda.Object fObj panda.Object fObj2 panda.Object[] fObjArray } .function void R.ctor(R a0) { return.void } tests: - file-name: "ldobj.v.obj" isa: title: Get field from object to register description: > Get field value from an object by field id and put it into register. instructions: - sig: ldobj.v.obj v1:out:ref, v2:in:ref, field_id acc: none format: [op_v1_4_v2_4_id_16] commands: - file-name: "check_if_v2_initialized" description: Check that verifier reports error if source registers are not initialized isa: instructions: - sig: ldobj.v.obj v1:out:ref, v2:in:ref, field_id acc: none format: [op_v1_4_v2_4_id_16] header-template: [pandasm_header] check-type: exit-positive tags: [verifier] bugid: ['1324', '2084', '3257'] runner-options: ['verifier-failure', 'verifier-config'] code-template: | .function i32 main() { %s # verifier error expected, because v2 is not initialized cases: - values: - 'ldobj.v.obj v1, v0, R.fQ' - values: - 'ldobj.v.obj v1, v1, R.fR' - values: - 'ldobj.v.obj v1, v15, R.fQArray' - file-name: "with_null_ref_pa" description: Check that NullPointerException is thrown if source ref is null isa: exceptions: - x_null header-template: [pandasm_header] check-type: empty tags: ['tsan', 'irtoc_ignore'] code-template: | .record panda.NullPointerException .function R get_null() { lda.null return.obj } .function i32 main() { call.short get_null sta.obj v0 try_begin: ldobj.v.obj v1, v0, %s ldai 1 return try_end: ldai 0 return .catch panda.NullPointerException, try_begin, try_end, try_end } cases: - values: - R.fQ - values: - R.fObj - values: - R.fi32Array - file-name: "with_null_ref_j" description: Check that NullPointerException is thrown if source ref is null isa: exceptions: - x_null header-template: [PandaAssembly_header] tags: ['irtoc_ignore'] runner-options: [use-pa] check-type: empty code-template: | .record panda.NullPointerException .function R get_null() { lda.null return.obj } .function i32 main() { call.short get_null sta.obj v0 try_begin: ldobj.v.obj v15, v0, %s ldai 1 return try_end: ldai 0 return .catch panda.NullPointerException, try_begin, try_end, try_end } cases: - values: - R.fQ - values: - R.fObj - values: - R.fi32Array - file-name: "with_non_object_ref" description: Check that verifier reports error when the 2nd operand is not a ref to an object (other than array) isa: verification: - v2_object header-template: [pandasm_header] check-type: exit-positive tags: [verifier] runner-options: ['verifier-failure', 'verifier-config'] bugid: ['2085'] code-template: | .function i32 main() { %s ldobj.v.obj v1, v0, R.fQ cases: - values: - movi v0, 0 bugid: ['1826'] - values: - movi v0, 1 - values: - movi.64 v0, 0x00 bugid: ['1826'] - values: - movi.64 v0, 0xCAFECAFECAFECAFE - values: - fmovi.64 v0, 0.0 bugid: ['1826'] - values: - fmovi.64 v0, 6.62607015 - values: - | # movi v1, 10 newarr v0, v1, R[] bugid: ['1827'] - file-name: "with_static_field_id" description: Check that verifier reports error when the field doesn't resolve to a non-static object field isa: verification: - field_id_non_static header-template: [] check-type: exit-positive code-template: | .record W { W static_field W[] static_array } .function void W.ctor(W a0) { return.void } .function void W.object_function(W a0) { return.void } .record random_record_name { W random_field_name } .function void static_function() { return.void } .function i32 main() { initobj W.ctor sta.obj v0 ldobj.v.obj v1, v0, %s cases: # resolves to a static object field - values: - W.static_field tags: [verifier] runner-options: ['verifier-failure', 'verifier-config'] bugid: ['1324', '1828'] # resolves to a static object array - values: - W.static_array tags: [verifier] runner-options: ['verifier-failure', 'verifier-config'] bugid: ['1324', '1828'] # resolves to a non-existing object field - values: - W.field_not_exists runner-options: [compile-failure] # resolves to object's constructor - values: - W.ctor runner-options: [compile-failure] # resolves to objects's method - values: - W.object_function runner-options: [compile-failure] # resolves to some other object - values: - random_record_name runner-options: [compile-failure] # resolves to some static function - values: - static_function runner-options: [compile-failure] # resolves to a field name in a wrong object - values: - random_record_name.random_field_name tags: [verifier] runner-options: ['verifier-failure', 'verifier-config'] bugid: ['1833', '3536'] # cannot resolve, because it's a i32 number - values: - 0 runner-options: [compile-failure] # cannot resolve, because it's a f64 number - values: - -1.1 runner-options: [compile-failure] # cannot resolve, because it's a "null" string - values: - "null" runner-options: [compile-failure] - file-name: "with_wrong_field_size_or_type" description: Check that verifier reports an error when the field resolves to a field with size or type that is not corresponding to bytecode isa: verification: - field_id_size header-template: [pandasm_header] check-type: exit-positive tags: [verifier] runner-options: ['verifier-failure', 'verifier-config'] bugid: ['1834', '2088'] code-template: | .function i32 main() { initobj R.ctor sta.obj v0 ldobj.v.obj v1, v0, %s cases: - values: - R.fu1 - values: - R.fu8 - values: - R.fi8 - values: - R.fu16 - values: - R.fi16 - values: - R.fu32 - values: - R.fi32 - values: - R.fu64 - values: - R.fi64 - values: - R.ff32 - values: - R.ff64 - file-name: "op_v1_4_v2_4_id_16" description: Check that compiler reports error when the register number is out of 4 bit size isa: instructions: - sig: ldobj.v.obj v1:out:ref, v2:in:ref, field_id acc: none format: [op_v1_4_v2_4_id_16] header-template: [pandasm_header] check-type: exit-positive runner-options: [compile-failure] code-template: | .function i32 main() { ldobj.v.obj %s, R.fQ cases: - values: ['v15, v15'] runner-options: ['compile-only'] - values: ['v0, v16'] - values: ['v16, v0'] - values: ['v256, v0'] - values: ['v1, v256'] - values: ['v32567, v32567'] - values: ['a0, v1'] - values: ['v0, a1'] - values: ['v0'] - values: ['1'] - values: ['"0"'] - file-name: "from_all_field_types_pa" description: Check that field value is loaded from field into register. More tests on ldobj.v.obj can be found in stobj.v.obj tests isa: description: Get field value from an object by field id and put it into register. header-template: [pandasm_header] check-type: exit-positive tags: ['tsan'] code-template: | .function i32 main() { initobj R.ctor sta.obj v0 # store null into Q type field lda.null sta.obj v3 stobj.obj v0, R.fQ # store null into Q[] type field lda.null sta.obj v4 stobj.obj v0, R.fQArray # store R object into R type field initobj R.ctor sta.obj v5 stobj.obj v0, R.fR # store R[] into R[] type field movi v1, 10 newarr v6, v1, R[] lda.obj v6 stobj.obj v0, R.fRArray # store R object into panda.Object type field initobj R.ctor sta.obj v7 stobj.obj v0, R.fObj # store R[] into panda.Object type field movi v1, 10 newarr v8, v1, R[] lda.obj v8 stobj.obj v0, R.fObj2 # store R[] into panda.Object[] type field movi v1, 10 newarr v9, v1, R[] lda.obj v9 stobj.obj v0, R.fObjArray label0: # load null from Q type field ldobj.v.obj v1, v0, R.fQ lda.obj v1 jeq.obj v3, label1 ldai 1 return label1: # load null from Q[] type field ldobj.v.obj v1, v0, R.fQArray lda.obj v1 jeq.obj v4, label2 ldai 2 return label2: # load R object from R type field ldobj.v.obj v1, v0, R.fR lda.obj v1 jeq.obj v5, label3 ldai 3 return label3: # load R[] from R[] type field ldobj.v.obj v1, v0, R.fRArray lda.obj v1 jeq.obj v6, label4 ldai 4 return label4: # load R object from panda.Object type field ldobj.v.obj v1, v0, R.fObj lda.obj v1 jeq.obj v7, label5 ldai 5 return label5: # load R[] from panda.Object type field ldobj.v.obj v1, v0, R.fObj2 lda.obj v1 jeq.obj v8, label6 ldai 6 return label6: # load R[] from panda.Object[] type field ldobj.v.obj v1, v0, R.fObjArray lda.obj v1 jeq.obj v9, success ldai 7 return success: - file-name: "from_all_field_types_j" description: Check that field value is loaded from field into register. More tests on ldobj.v.obj can be found in stobj.v.obj tests isa: description: Get field value from an object by field id and put it into register. header-template: [PandaAssembly_header] runner-options: [use-pa] check-type: exit-positive code-template: | .function i32 main() { initobj R.ctor sta.obj v0 # store subsclass R into Q type field initobj R.ctor sta.obj v3 stobj.obj v0, R.fQ # store subsclass R into interface type field initobj R.ctor sta.obj v4 stobj.obj v0, R.fI # store subsclass R into base type field initobj R.ctor sta.obj v5 stobj.obj v0, R.fObj # store subclass R[] into Q[] type field movi v1, 10 newarr v6, v1, R[] lda.obj v6 stobj.obj v0, R.fQArray # store subclass R[] into interface [] type field movi v1, 10 newarr v7, v1, R[] lda.obj v7 stobj.obj v0, R.fIArray # store subclass R[] into base type [] field movi v1, 10 newarr v8, v1, R[] lda.obj v8 stobj.obj v0, R.fObjArray # store subclass R[] into base type field movi v1, 10 newarr v9, v1, R[] lda.obj v9 stobj.obj v0, R.fObj2 label0: # load R from Q type field ldobj.v.obj v1, v0, R.fQ lda.obj v1 jeq.obj v3, label1 ldai 1 return label1: # load R from interface type field ldobj.v.obj v1, v0, R.fI lda.obj v1 jeq.obj v4, label2 ldai 2 return label2: # load R from base type field ldobj.v.obj v1, v0, R.fObj lda.obj v1 jeq.obj v5, label3 ldai 3 return label3: # load R[] from Q[] type field ldobj.v.obj v1, v0, R.fQArray lda.obj v1 jeq.obj v6, label4 ldai 4 return label4: # load R[] from interface[] type field ldobj.v.obj v1, v0, R.fIArray lda.obj v1 jeq.obj v7, label5 ldai 5 return label5: # load R[] from base type [] field ldobj.v.obj v1, v0, R.fObjArray lda.obj v1 jeq.obj v8, label6 ldai 6 return label6: # load R[] from base type field ldobj.v.obj v1, v0, R.fObj2 lda.obj v1 jeq.obj v9, success ldai 7 return success: