OP_CHECK_CAST_JUMBO.S revision a8b91c52fd8a90b784835dfe1f8898035266c4dd
1%verify "executed" 2%verify "null object" 3%verify "class cast exception thrown, with correct class name" 4%verify "class cast exception not thrown on same class" 5%verify "class cast exception not thrown on subclass" 6%verify "class not resolved" 7%verify "class already resolved" 8 /* 9 * Check to see if a cast from one class to another is allowed. 10 */ 11 /* check-cast/ jumbo vBBBB, class #AAAAAAAA */ 12 FETCH(a0, 1) # a0<- aaaa (lo) 13 FETCH(a2, 2) # a2<- AAAA (hi) 14 FETCH(a3, 3) # a3<- BBBB 15 sll a2,a2,16 16 or a2, a0, a2 # a2<- AAAAaaaa 17 18 GET_VREG(rOBJ, a3) # rOBJ<- object 19 LOAD_rSELF_methodClassDex(a0) # a0<- pDvmDex 20 LOAD_base_offDvmDex_pResClasses(a0, a0) # a0<- pDvmDex->pResClasses 21 # is object null? 22 beqz rOBJ, .L${opcode}_okay # null obj, cast always succeeds 23 LOAD_eas2(a1, a0, a2) # a1<- resolved class 24 LOAD_base_offObject_clazz(a0, rOBJ) # a0<- obj->clazz 25 # have we resolved this before? 26 beqz a1, .L${opcode}_resolve # not resolved, do it now 27.L${opcode}_resolved: 28 # same class (trivial success)? 29 bne a0, a1, .L${opcode}_fullcheck # no, do full check 30 b .L${opcode}_okay # yes, finish up 31 32 /* 33 * Trivial test failed, need to perform full check. This is common. 34 * a0 holds obj->clazz 35 * a1 holds class resolved from BBBB 36 * rOBJ holds object 37 */ 38.L${opcode}_fullcheck: 39 move rBIX,a1 # avoid ClassObject getting clobbered 40 JAL(dvmInstanceofNonTrivial) # v0<- boolean result 41 # failed? 42 bnez v0, .L${opcode}_okay # no, success 43 b .L${opcode}_castfailure 44 45%break 46 47 48.L${opcode}_castfailure: 49 # A cast has failed. We need to throw a ClassCastException with the 50 # class of the object that failed to be cast. 51 EXPORT_PC() # about to throw 52 LOAD_base_offObject_clazz(a0, rOBJ) # a0<- obj->clazz 53 move a1,rBIX # r1<- desired class 54 JAL(dvmThrowClassCastException) 55 b common_exceptionThrown 56 57 /* 58 * Advance PC and get next opcode 59 * 60 */ 61.L${opcode}_okay: 62 FETCH_ADVANCE_INST(4) # advance rPC, load rINST 63 GET_INST_OPCODE(t0) # extract opcode from rINST 64 GOTO_OPCODE(t0) # jump to next instruction 65 /* 66 * Resolution required. This is the least-likely path. 67 * 68 * a2 holds AAAAAAAA 69 * rOBJ holds object 70 */ 71.L${opcode}_resolve: 72 EXPORT_PC() # resolve() could throw 73 LOAD_rSELF_method(a3) # a3<- self->method 74 move a1, a2 # a1<- AAAAAAAA 75 li a2, 0 # a2<- false 76 LOAD_base_offMethod_clazz(a0, a3) # a0<- method->clazz 77 JAL(dvmResolveClass) # v0<- resolved ClassObject ptr 78 # got null? 79 beqz v0, common_exceptionThrown # yes, handle exception 80 move a1, v0 # a1<- class resolved from AAAAAAAA 81 LOAD_base_offObject_clazz(a0, rOBJ) # a0<- obj->clazz 82 b .L${opcode}_resolved # pick up where we left off 83 84 85