Home | History | Annotate | Download | only in mips
      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 an object reference is an instance of a class.
     10      *
     11      * Most common situation is a non-null object, being compared against
     12      * an already-resolved class.
     13      */
     14     # instance-of vA, vB, class            /* CCCC */
     15     GET_OPB(a3)                            #  a3 <- B
     16     GET_OPA4(rOBJ)                         #  rOBJ <- A+
     17     GET_VREG(a0, a3)                       #  a0 <- vB (object)
     18     LOAD_rSELF_methodClassDex(a2)          #  a2 <- pDvmDex
     19     # is object null?
     20     beqz      a0, .L${opcode}_store        #  null obj, not an instance, store a0
     21     FETCH(a3, 1)                           #  a3 <- CCCC
     22     LOAD_base_offDvmDex_pResClasses(a2, a2) #  a2 <- pDvmDex->pResClasses
     23     LOAD_eas2(a1, a2, a3)                  #  a1 <- resolved class
     24     LOAD_base_offObject_clazz(a0, a0)      #  a0 <- obj->clazz
     25     # have we resolved this before?
     26     beqz      a1, .L${opcode}_resolve      #  not resolved, do it now
     27 .L${opcode}_resolved:                   #  a0=obj->clazz, a1=resolved class
     28     # same class (trivial success)?
     29     beq       a0, a1, .L${opcode}_trivial  #  yes, trivial finish
     30     b         .L${opcode}_fullcheck        #  no, do full check
     31 
     32     /*
     33      * Trivial test succeeded, save and bail.
     34      *  rOBJ holds A
     35      */
     36 .L${opcode}_trivial:
     37     li        a0, 1                        #  indicate success
     38     # fall thru
     39     /*
     40      * a0   holds boolean result
     41      * rOBJ holds A
     42      */
     43 .L${opcode}_store:
     44     FETCH_ADVANCE_INST(2)                  #  advance rPC, load rINST
     45     SET_VREG(a0, rOBJ)                     #  vA <- a0
     46     GET_INST_OPCODE(t0)                    #  extract opcode from rINST
     47     GOTO_OPCODE(t0)                        #  jump to next instruction
     48 
     49 %break
     50 
     51     /*
     52      * Trivial test failed, need to perform full check.  This is common.
     53      *  a0   holds obj->clazz
     54      *  a1   holds class resolved from BBBB
     55      *  rOBJ holds A
     56      */
     57 .L${opcode}_fullcheck:
     58     JAL(dvmInstanceofNonTrivial)           #  v0 <- boolean result
     59     move      a0, v0                       #  fall through to ${opcode}_store
     60     b         .L${opcode}_store
     61 
     62     /*
     63      * Resolution required.  This is the least-likely path.
     64      *
     65      *  a3   holds BBBB
     66      *  rOBJ holds A
     67      */
     68 .L${opcode}_resolve:
     69     EXPORT_PC()                            #  resolve() could throw
     70     LOAD_rSELF_method(a0)                  #  a0 <- self->method
     71     move      a1, a3                       #  a1 <- BBBB
     72     li        a2, 1                        #  a2 <- true
     73     LOAD_base_offMethod_clazz(a0, a0)      #  a0 <- method->clazz
     74     JAL(dvmResolveClass)                   #  v0 <- resolved ClassObject ptr
     75     # got null?
     76     move      a1, v0                       #  a1 <- class resolved from BBB
     77     beqz      v0, common_exceptionThrown   #  yes, handle exception
     78     GET_OPB(a3)                            #  a3 <- B
     79     GET_VREG(a0, a3)                       #  a0 <- vB (object)
     80     LOAD_base_offObject_clazz(a0, a0)      #  a0 <- obj->clazz
     81     b         .L${opcode}_resolved         #  pick up where we left off
     82 
     83