1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "executed" 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "null object" 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class cast exception thrown, with correct class name" 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class cast exception not thrown on same class" 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class cast exception not thrown on subclass" 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class not resolved" 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class already resolved" 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Check to see if a cast from one class to another is allowed. 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* check-cast vAA, class@BBBB */ 129f601a917c8878204482c37aec7005054b6776fabuzbee movl rSELF,%ecx 13f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee GET_VREG_R rINST,rINST # rINST<- vAA (object) 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project movzwl 2(rPC),%eax # eax<- BBBB 159f601a917c8878204482c37aec7005054b6776fabuzbee movl offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex 16f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee testl rINST,rINST # is oject null? 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project je .L${opcode}_okay # null obj, cast always succeeds 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project movl (%ecx,%eax,4),%eax # eax<- resolved class 20f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project testl %eax,%eax # have we resolved this before? 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project je .L${opcode}_resolve # no, go do it now 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_resolved: 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cmpl %eax,%ecx # same class (trivial success)? 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jne .L${opcode}_fullcheck # no, do full check 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_okay: 27a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee FETCH_INST_OPCODE 2 %ecx 28f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee ADVANCE_PC 2 29a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee GOTO_NEXT_R %ecx 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Trivial test failed, need to perform full check. This is common. 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ecx holds obj->clazz 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * eax holds class resolved from BBBB 35f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee * rINST holds object 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_fullcheck: 38bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes movl %eax,sReg0 # we'll need the desired class on failure 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project movl %eax,OUT_ARG1(%esp) 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project movl %ecx,OUT_ARG0(%esp) 41a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee SPILL(rIBASE) 42bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes call dvmInstanceofNonTrivial # eax<- boolean result 43a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee UNSPILL(rIBASE) 44bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes testl %eax,%eax # failed? 45bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes jne .L${opcode}_okay # no, success 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 47bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes # A cast has failed. We need to throw a ClassCastException. 48f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee EXPORT_PC 49bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes movl offObject_clazz(rINST),%eax 50bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes movl %eax,OUT_ARG0(%esp) # arg0<- obj->clazz 51bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes movl sReg0,%ecx 52bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes movl %ecx,OUT_ARG1(%esp) # arg1<- desired class 53bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes call dvmThrowClassCastException 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jmp common_exceptionThrown 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Resolution required. This is the least-likely path, and we're 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * going to have to recreate some data. 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 60f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee * rINST holds object 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_resolve: 639f601a917c8878204482c37aec7005054b6776fabuzbee movl rSELF,%ecx 64f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee EXPORT_PC 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project movzwl 2(rPC),%eax # eax<- BBBB 669f601a917c8878204482c37aec7005054b6776fabuzbee movl offThread_method(%ecx),%ecx # ecx<- self->method 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project movl %eax,OUT_ARG1(%esp) # arg1<- BBBB 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project movl offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project movl $$0,OUT_ARG2(%esp) # arg2<- false 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project movl %ecx,OUT_ARG0(%esp) # arg0<- method->clazz 71a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee SPILL(rIBASE) 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project call dvmResolveClass # eax<- resolved ClassObject ptr 73a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee UNSPILL(rIBASE) 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project testl %eax,%eax # got null? 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project je common_exceptionThrown # yes, handle exception 76f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee movl offObject_clazz(rINST),%ecx # ecx<- obj->clazz 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project jmp .L${opcode}_resolved # pick up where we left off 78