122d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch /* Copyright (C) 2008 The Android Open Source Project 222d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * 322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * Licensed under the Apache License, Version 2.0 (the "License"); 422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * you may not use this file except in compliance with the License. 522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * You may obtain a copy of the License at 622d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * 722d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * http://www.apache.org/licenses/LICENSE-2.0 822d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * 922d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * Unless required by applicable law or agreed to in writing, software 1022d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * distributed under the License is distributed on an "AS IS" BASIS, 1122d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1222d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * See the License for the specific language governing permissions and 1322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * limitations under the License. 1422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch */ 1522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch 1622d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch /* 1722d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * File: OP_CHECK_CAST.S 1822d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * 1922d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * Code: Checks to see if a cast is allowed. Uses no substitutions. 2022d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * 2122d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * For: check-cast 2222d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * 2322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * Description: Throw if the reference in the given register cannot be 2422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * cast to the indicated type. The type must be a reference 2522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * type (not a primitive type). 2622d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * 2722d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * Format: AA|op BBBB (21c) 2822d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * 2922d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * Syntax: op vAA, type@BBBB 3022d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch */ 3122d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch 3222d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl rGLUE, %edx # get MterpGlue pointer 3322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl offGlue_methodClassDex(%edx), %eax # %eax<- pDvmDex 3422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch GET_VREG rINST # rINST<- vAA 3522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl offDvmDex_pResClasses(%eax), %eax # %eax<- pDvmDex->pResClasses 3622d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch cmp $$0, rINST # check for null reference object 3722d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch je .L${opcode}_okay # can always cast null object 3822d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch FETCH 1, %ecx # %ecx<- BBBB 3922d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl (%eax, %ecx, 4), %ecx # %ecx<- resolved class 4022d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch cmp $$0, %ecx # check if classes is resolved before? 4122d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch je .L${opcode}_resolve # resolve class 4222d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch jmp .L${opcode}_resolved # continue 4322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch%break 4422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch 4522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch.L${opcode}_resolved: 4622d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch cmp %ecx, offObject_clazz(rINST) # check for same class 4722d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch jne .L${opcode}_fullcheck # not same class; do full check 4822d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch 4922d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch.L${opcode}_okay: 5022d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch FINISH 2 # jump to next instruction 5122d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch 5222d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch /* 5322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * Trivial test failed, need to perform full check. 5422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * offObject_clazz(rINST) holds obj->clazz 5522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * %ecx holds class resolved from BBBB 5622d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * rINST holds object 5722d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch */ 5822d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch 5922d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch.L${opcode}_fullcheck: 6022d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl offObject_clazz(rINST), %eax # %eax<- obj->clazz 6122d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl %eax, -12(%esp) # push parameter obj->clazz 6222d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl %ecx, -8(%esp) # push parameter # push parameter resolved class 6322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch lea -12(%esp), %esp 6422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch call dvmInstanceofNonTrivial # call: (ClassObject* instance, ClassObject* clazz) 6522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch # return: int 6622d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch lea 12(%esp), %esp 6722d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch cmp $$0, %eax # failed? 6822d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch jne .L${opcode}_okay # success 6922d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch 7022d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch /* 7122d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * A cast has failed. We need to throw a ClassCastException with the 7222d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * class of the object that failed to be cast. 7322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch */ 7422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch 7522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch EXPORT_PC # we will throw an exception 766d167a4b02f310700a55fc9a24fccce999e0fdf2Dan Bornstein#error BIT ROT!!! 776d167a4b02f310700a55fc9a24fccce999e0fdf2Dan Bornstein /* 786d167a4b02f310700a55fc9a24fccce999e0fdf2Dan Bornstein * TODO: Code here needs to call dvmThrowClassCastException with two 796d167a4b02f310700a55fc9a24fccce999e0fdf2Dan Bornstein * arguments. 806d167a4b02f310700a55fc9a24fccce999e0fdf2Dan Bornstein */ 816d167a4b02f310700a55fc9a24fccce999e0fdf2Dan Bornstein#if 0 826d167a4b02f310700a55fc9a24fccce999e0fdf2Dan Bornstein /* old obsolete code that called dvmThrowExceptionWithClassMessage */ 8322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl $$.LstrClassCastExceptionPtr, -8(%esp) # push parameter message 8422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl offObject_clazz(rINST), rINST # rINST<- obj->clazz 8522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl offClassObject_descriptor(rINST), rINST # rINST<- obj->clazz->descriptor 8622d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl rINST, -4(%esp) # push parameter obj->clazz->descriptor 8722d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch lea -8(%esp), %esp 8822d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch call dvmThrowExceptionWithClassMessage # call: (const char* exceptionDescriptor, 8922d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch # const char* messageDescriptor, Object* cause) 9022d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch # return: void 916d167a4b02f310700a55fc9a24fccce999e0fdf2Dan Bornstein#endif 9222d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch lea 8(%esp), %esp 9322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch jmp common_exceptionThrown 9422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch 9522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch /* 9622d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * Resolution required. This is the least-likely path. 9722d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * 9822d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch * rINST holds object 9922d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch */ 10022d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch 10122d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch.L${opcode}_resolve: 10222d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl offGlue_method(%edx), %eax # %eax<- glue->method 10322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch FETCH 1, %ecx # %ecx holds BBBB 10422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch EXPORT_PC # in case we throw an exception 10522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl $$0, -8(%esp) # push parameter false 10622d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl offMethod_clazz(%eax), %eax # %eax<- glue->method->clazz 10722d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl %ecx, -12(%esp) # push parameter BBBB 10822d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl %eax, -16(%esp) # push parameter glue->method>clazz 10922d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch lea -16(%esp), %esp 11022d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch call dvmResolveClass # resolve ClassObject pointer 11122d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch # call: (const ClassObject* referrer, u4 classIdx, 11222d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch # bool fromUnverifiedConstant) 11322d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch # return ClassObject* 11422d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch lea 16(%esp), %esp 11522d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch cmp $$0, %eax # check for null pointer 11622d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch je common_exceptionThrown # handle excpetion 11722d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch movl %eax, %ecx # %ecx<- resolved class 11822d404a75a00cda0b0ebed1034c2808ba060b05fJohnnie Birch jmp .L${opcode}_resolved 119