OP_INSTANCE_OF.S revision a8b91c52fd8a90b784835dfe1f8898035266c4dd
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