1 /* Copyright (C) 2008 The Android Open Source Project 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 /* 17 * File: OP_CHECK_CAST.S 18 * 19 * Code: Checks to see if a cast is allowed. Uses no substitutions. 20 * 21 * For: check-cast 22 * 23 * Description: Throw if the reference in the given register cannot be 24 * cast to the indicated type. The type must be a reference 25 * type (not a primitive type). 26 * 27 * Format: AA|op BBBB (21c) 28 * 29 * Syntax: op vAA, type@BBBB 30 */ 31 32 movl rGLUE, %edx # get MterpGlue pointer 33 movl offGlue_methodClassDex(%edx), %eax # %eax<- pDvmDex 34 GET_VREG rINST # rINST<- vAA 35 movl offDvmDex_pResClasses(%eax), %eax # %eax<- pDvmDex->pResClasses 36 cmp $$0, rINST # check for null reference object 37 je .L${opcode}_okay # can always cast null object 38 FETCH 1, %ecx # %ecx<- BBBB 39 movl (%eax, %ecx, 4), %ecx # %ecx<- resolved class 40 cmp $$0, %ecx # check if classes is resolved before? 41 je .L${opcode}_resolve # resolve class 42 jmp .L${opcode}_resolved # continue 43%break 44 45.L${opcode}_resolved: 46 cmp %ecx, offObject_clazz(rINST) # check for same class 47 jne .L${opcode}_fullcheck # not same class; do full check 48 49.L${opcode}_okay: 50 FINISH 2 # jump to next instruction 51 52 /* 53 * Trivial test failed, need to perform full check. 54 * offObject_clazz(rINST) holds obj->clazz 55 * %ecx holds class resolved from BBBB 56 * rINST holds object 57 */ 58 59.L${opcode}_fullcheck: 60 movl offObject_clazz(rINST), %eax # %eax<- obj->clazz 61 movl %eax, -12(%esp) # push parameter obj->clazz 62 movl %ecx, -8(%esp) # push parameter # push parameter resolved class 63 lea -12(%esp), %esp 64 call dvmInstanceofNonTrivial # call: (ClassObject* instance, ClassObject* clazz) 65 # return: int 66 lea 12(%esp), %esp 67 cmp $$0, %eax # failed? 68 jne .L${opcode}_okay # success 69 70 /* 71 * A cast has failed. We need to throw a ClassCastException with the 72 * class of the object that failed to be cast. 73 */ 74 75 EXPORT_PC # we will throw an exception 76#error BIT ROT!!! 77 /* 78 * TODO: Code here needs to call dvmThrowClassCastException with two 79 * arguments. 80 */ 81#if 0 82 /* old obsolete code that called dvmThrowExceptionWithClassMessage */ 83 movl $$.LstrClassCastExceptionPtr, -8(%esp) # push parameter message 84 movl offObject_clazz(rINST), rINST # rINST<- obj->clazz 85 movl offClassObject_descriptor(rINST), rINST # rINST<- obj->clazz->descriptor 86 movl rINST, -4(%esp) # push parameter obj->clazz->descriptor 87 lea -8(%esp), %esp 88 call dvmThrowExceptionWithClassMessage # call: (const char* exceptionDescriptor, 89 # const char* messageDescriptor, Object* cause) 90 # return: void 91#endif 92 lea 8(%esp), %esp 93 jmp common_exceptionThrown 94 95 /* 96 * Resolution required. This is the least-likely path. 97 * 98 * rINST holds object 99 */ 100 101.L${opcode}_resolve: 102 movl offGlue_method(%edx), %eax # %eax<- glue->method 103 FETCH 1, %ecx # %ecx holds BBBB 104 EXPORT_PC # in case we throw an exception 105 movl $$0, -8(%esp) # push parameter false 106 movl offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz 107 movl %ecx, -12(%esp) # push parameter BBBB 108 movl %eax, -16(%esp) # push parameter glue->method>clazz 109 lea -16(%esp), %esp 110 call dvmResolveClass # resolve ClassObject pointer 111 # call: (const ClassObject* referrer, u4 classIdx, 112 # bool fromUnverifiedConstant) 113 # return ClassObject* 114 lea 16(%esp), %esp 115 cmp $$0, %eax # check for null pointer 116 je common_exceptionThrown # handle excpetion 117 movl %eax, %ecx # %ecx<- resolved class 118 jmp .L${opcode}_resolved 119