1a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%verify "executed" 2a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%verify "null object" 3a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%verify "class cast exception thrown, with correct class name" 4a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%verify "class cast exception not thrown on same class" 5a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%verify "class cast exception not thrown on subclass" 6a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%verify "class not resolved" 7a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%verify "class already resolved" 8a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 9a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Check to see if an object reference is an instance of a class. 10a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 11a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Most common situation is a non-null object, being compared against 12a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * an already-resolved class. 13a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 14a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * TODO: convert most of this into a common subroutine, shared with 15a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * OP_INSTANCE_OF.S. 16a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 17a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* instance-of/jumbo vBBBB, vCCCC, class@AAAAAAAA */ 18a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH(a3, 4) # a3<- vCCCC 19a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH(rOBJ, 3) # rOBJ<- vBBBB 20a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_VREG(a0, a3) # a0 <- vCCCC (object) 21a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham LOAD_rSELF_methodClassDex(a2) # a2 <- pDvmDex 22a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # is object null? 23a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beqz a0, .L${opcode}_store # null obj, not an instance, store a0 24a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH(a1, 1) # r1<- aaaa (lo) 25a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH(a3, 2) # r3<- AAAA (hi) 26a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham LOAD_base_offDvmDex_pResClasses(a2, a2) # a2 <- pDvmDex->pResClasses 27a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham sll a3,a3,16 28a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham or a3, a1, a3 # a3<- AAAAaaaa 29a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 30a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham LOAD_eas2(a1, a2, a3) # a1 <- resolved class 31a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham LOAD_base_offObject_clazz(a0, a0) # a0 <- obj->clazz 32a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # have we resolved this before? 33a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beqz a1, .L${opcode}_resolve # not resolved, do it now 34a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham b .L${opcode}_resolved # resolved, continue 35a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 36a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham%break 37a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 38a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 39a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Class resolved, determine type of check necessary. This is common. 40a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * r0 holds obj->clazz 41a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * r1 holds class resolved from AAAAAAAA 42a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * r9 holds BBBB 43a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 44a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 45a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham.L${opcode}_resolved: # a0=obj->clazz, a1=resolved class 46a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # same class (trivial success)? 47a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beq a0, a1, .L${opcode}_trivial # yes, trivial finish 48a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # fall through to ${opcode}_fullcheck 49a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 50a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 51a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Trivial test failed, need to perform full check. This is common. 52a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * a0 holds obj->clazz 53a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * a1 holds class resolved from AAAAAAAA 54a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * rOBJ holds BBBB 55a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 56a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham.L${opcode}_fullcheck: 57a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham JAL(dvmInstanceofNonTrivial) # v0 <- boolean result 58a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a0, v0 59a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham b .L${opcode}_store # go to ${opcode}_store 60a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 61a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham.L${opcode}_trivial: 62a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham li a0, 1 # indicate success 63a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # fall thru 64a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 65a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * a0 holds boolean result 66a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * rOBJ holds BBBB 67a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 68a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham.L${opcode}_store: 69a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH_ADVANCE_INST(5) # advance rPC, load rINST 70a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham SET_VREG(a0, rOBJ) # vBBBB <- a0 71a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_INST_OPCODE(t0) # extract opcode from rINST 72a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GOTO_OPCODE(t0) # jump to next instruction 73a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 74a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 75a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Resolution required. This is the least-likely path. 76a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 77a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * a3 holds AAAAAAAA 78a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * rOBJ holds BBBB 79a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 80a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham.L${opcode}_resolve: 81a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham EXPORT_PC() # resolve() could throw 82a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham LOAD_rSELF_method(a0) # a0 <- self->method 83a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a1, a3 # a1 <- AAAAAAAA 84a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham li a2, 1 # a2 <- true 85a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham LOAD_base_offMethod_clazz(a0, a0) # a0 <- method->clazz 86a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham JAL(dvmResolveClass) # v0 <- resolved ClassObject ptr 87a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham # got null? 88a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a1, v0 # a1 <- class resolved from BBB 89a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham beqz v0, common_exceptionThrown # yes, handle exception 90a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham FETCH(ra, 4) # a3<- vCCCC 91a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham move a1, a0 # a1<- class resolved from AAAAAAAA 92a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 93a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham GET_VREG(a0, a3) # a0 <- vCCCC (object) 94a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham LOAD_base_offObject_clazz(a0, a0) # a0 <- obj->clazz 95a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham b .L${opcode}_resolved # pick up where we left off 96a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 97