1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "executed"
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "null object"
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class cast exception thrown, with correct class name"
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class cast exception not thrown on same class"
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class cast exception not thrown on subclass"
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class not resolved"
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class already resolved"
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Check to see if a cast from one class to another is allowed.
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* check-cast vAA, class@BBBB */
129f601a917c8878204482c37aec7005054b6776fabuzbee    movl      rSELF,%ecx
13f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee    GET_VREG_R  rINST,rINST             # rINST<- vAA (object)
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movzwl    2(rPC),%eax               # eax<- BBBB
159f601a917c8878204482c37aec7005054b6776fabuzbee    movl      offThread_methodClassDex(%ecx),%ecx # ecx<- pDvmDex
16f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee    testl     rINST,rINST               # is oject null?
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    je        .L${opcode}_okay          # null obj, cast always succeeds
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movl      (%ecx,%eax,4),%eax        # eax<- resolved class
20f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee    movl      offObject_clazz(rINST),%ecx # ecx<- obj->clazz
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    testl     %eax,%eax                 # have we resolved this before?
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    je        .L${opcode}_resolve       # no, go do it now
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_resolved:
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmpl      %eax,%ecx                 # same class (trivial success)?
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jne       .L${opcode}_fullcheck     # no, do full check
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_okay:
27a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee    FETCH_INST_OPCODE 2 %ecx
28f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee    ADVANCE_PC 2
29a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee    GOTO_NEXT_R %ecx
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Trivial test failed, need to perform full check.  This is common.
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  ecx holds obj->clazz
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  eax holds class resolved from BBBB
35f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee     *  rINST holds object
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_fullcheck:
38bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes    movl    %eax,sReg0                 # we'll need the desired class on failure
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movl    %eax,OUT_ARG1(%esp)
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movl    %ecx,OUT_ARG0(%esp)
41a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee    SPILL(rIBASE)
42bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes    call    dvmInstanceofNonTrivial    # eax<- boolean result
43a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee    UNSPILL(rIBASE)
44bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes    testl   %eax,%eax                  # failed?
45bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes    jne     .L${opcode}_okay           # no, success
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
47bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes    # A cast has failed.  We need to throw a ClassCastException.
48f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee    EXPORT_PC
49bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes    movl    offObject_clazz(rINST),%eax
50bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes    movl    %eax,OUT_ARG0(%esp)                 # arg0<- obj->clazz
51bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes    movl    sReg0,%ecx
52bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes    movl    %ecx,OUT_ARG1(%esp)                 # arg1<- desired class
53bb08b668b174d6babcc3866201aaf1d3b7293adaElliott Hughes    call    dvmThrowClassCastException
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jmp     common_exceptionThrown
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Resolution required.  This is the least-likely path, and we're
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * going to have to recreate some data.
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
60f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee     *  rINST holds object
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_resolve:
639f601a917c8878204482c37aec7005054b6776fabuzbee    movl    rSELF,%ecx
64f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee    EXPORT_PC
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movzwl  2(rPC),%eax                # eax<- BBBB
669f601a917c8878204482c37aec7005054b6776fabuzbee    movl    offThread_method(%ecx),%ecx  # ecx<- self->method
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movl    %eax,OUT_ARG1(%esp)        # arg1<- BBBB
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movl    offMethod_clazz(%ecx),%ecx # ecx<- metho->clazz
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movl    $$0,OUT_ARG2(%esp)         # arg2<- false
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    movl    %ecx,OUT_ARG0(%esp)        # arg0<- method->clazz
71a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee    SPILL(rIBASE)
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    call    dvmResolveClass            # eax<- resolved ClassObject ptr
73a7d59bbafea5430fe81fc21ba94ddf6f6a63b0b3buzbee    UNSPILL(rIBASE)
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    testl   %eax,%eax                  # got null?
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    je      common_exceptionThrown     # yes, handle exception
76f3e177289ac078f18401cfd8eebafe584dd0d01fbuzbee    movl    offObject_clazz(rINST),%ecx  # ecx<- obj->clazz
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jmp     .L${opcode}_resolved       # pick up where we left off
78