Home | History | Annotate | Download | only in x86
      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 vAA, class@BBBB */
     12     movl      rSELF,%ecx
     13     GET_VREG_R  rINST,rINST             # rINST<- vAA (object)
     14     movzwl    2(rPC),%eax               # eax<- BBBB
     15     movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
     16     testl     rINST,rINST               # is oject null?
     17     movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
     18     je        .L${opcode}_okay          # null obj, cast always succeeds
     19     movl      (%ecx,%eax,4),%eax        # eax<- resolved class
     20     movl      offObject_clazz(rINST),%ecx # ecx<- obj->clazz
     21     testl     %eax,%eax                 # have we resolved this before?
     22     je        .L${opcode}_resolve       # no, go do it now
     23 .L${opcode}_resolved:
     24     cmpl      %eax,%ecx                 # same class (trivial success)?
     25     jne       .L${opcode}_fullcheck     # no, do full check
     26 .L${opcode}_okay:
     27     FETCH_INST_OPCODE 2 %ecx
     28     ADVANCE_PC 2
     29     GOTO_NEXT_R %ecx
     30 
     31     /*
     32      * Trivial test failed, need to perform full check.  This is common.
     33      *  ecx holds obj->clazz
     34      *  eax holds class resolved from BBBB
     35      *  rINST holds object
     36      */
     37 .L${opcode}_fullcheck:
     38     movl    %eax,sReg0                 # we'll need the desired class on failure
     39     movl    %eax,OUT_ARG1(%esp)
     40     movl    %ecx,OUT_ARG0(%esp)
     41     SPILL(rIBASE)
     42     call    dvmInstanceofNonTrivial    # eax<- boolean result
     43     UNSPILL(rIBASE)
     44     testl   %eax,%eax                  # failed?
     45     jne     .L${opcode}_okay           # no, success
     46 
     47     # A cast has failed.  We need to throw a ClassCastException.
     48     EXPORT_PC
     49     movl    offObject_clazz(rINST),%eax
     50     movl    %eax,OUT_ARG0(%esp)                 # arg0<- obj->clazz
     51     movl    sReg0,%ecx
     52     movl    %ecx,OUT_ARG1(%esp)                 # arg1<- desired class
     53     call    dvmThrowClassCastException
     54     jmp     common_exceptionThrown
     55 
     56     /*
     57      * Resolution required.  This is the least-likely path, and we're
     58      * going to have to recreate some data.
     59      *
     60      *  rINST holds object
     61      */
     62 .L${opcode}_resolve:
     63     movl    rSELF,%ecx
     64     EXPORT_PC
     65     movzwl  2(rPC),%eax                # eax<- BBBB
     66     movl    offThread_method(%ecx),%ecx  # ecx<- self->method
     67     movl    %eax,OUT_ARG1(%esp)        # arg1<- BBBB
     68     movl    offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz
     69     movl    $$0,OUT_ARG2(%esp)         # arg2<- false
     70     movl    %ecx,OUT_ARG0(%esp)        # arg0<- method->clazz
     71     SPILL(rIBASE)
     72     call    dvmResolveClass            # eax<- resolved ClassObject ptr
     73     UNSPILL(rIBASE)
     74     testl   %eax,%eax                  # got null?
     75     je      common_exceptionThrown     # yes, handle exception
     76     movl    offObject_clazz(rINST),%ecx  # ecx<- obj->clazz
     77     jmp     .L${opcode}_resolved       # pick up where we left off
     78