OP_NEW_INSTANCE.S revision 7365493ad8d360c1dcf9cd8b6eee62747af01cae
1%verify "executed"
2%verify "class not resolved"
3%verify "class cannot be resolved"
4%verify "class not initialized"
5%verify "class fails to initialize"
6%verify "class already resolved/initialized"
7%verify "class is abstract or interface"
8%verify "allocation fails"
9    /*
10     * Create a new instance of a class.
11     */
12    /* new-instance vAA, class@BBBB */
13    GET_GLUE(%ecx)
14    movzwl    2(rPC),%eax               # eax<- BBBB
15    movl      offGlue_methodClassDex(%ecx),%ecx  # ecx<- pDvmDex
16    movzbl    rINST_HI,rINST_FULL       # rINST_FULL<- AA
17    movl      offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses
18    EXPORT_PC()
19    movl      (%ecx,%eax,4),%ecx        # ecx<- resolved class
20    SPILL(rPC)
21    testl     %ecx,%ecx                 # resolved?
22    je        .L${opcode}_resolve       # no, go do it
23.L${opcode}_resolved:  # on entry, ecx<- class
24    cmpb      $$CLASS_INITIALIZED,offClassObject_status(%ecx)
25    je        .L${opcode}_initialized
26    jmp       .L${opcode}_needinit
27%break
28
29.L${opcode}_initialized:  # on entry, ecx<- class
30    /* TODO: remove test for interface/abstract, now done in verifier */
31    testl     $$(ACC_INTERFACE|ACC_ABSTRACT),offClassObject_accessFlags(%ecx)
32    movl      $$ALLOC_DONT_TRACK,OUT_ARG1(%esp)
33    jne       .L${opcode}_abstract
34.L${opcode}_finish: # ecx=class
35    movl     %ecx,OUT_ARG0(%esp)
36    call     dvmAllocObject             # eax<- new object
37    UNSPILL(rPC)
38    movl     rINST_FULL,%ecx
39    FETCH_INST_WORD(2)
40    testl    %eax,%eax                  # success?
41    je       common_exceptionThrown     # no, bail out
42    SET_VREG(%eax,%ecx)
43    ADVANCE_PC(2)
44    GOTO_NEXT
45
46    /*
47     * Class initialization required.
48     *
49     *  ecx holds class object
50     */
51.L${opcode}_needinit:
52    SPILL_TMP(%ecx)                     # save object
53    movl    %ecx,OUT_ARG0(%esp)
54    call    dvmInitClass                # initialize class
55    UNSPILL_TMP(%ecx)                   # restore object
56    testl   %eax,%eax                   # success?
57    jne     .L${opcode}_initialized     # success, continue
58    UNSPILL(rPC)                        # failed, restore PC
59    jmp     common_exceptionThrown      # go deal with init exception
60
61    /*
62     * Resolution required.  This is the least-likely path.
63     *
64     */
65.L${opcode}_resolve:
66    GET_GLUE(%ecx)
67    movzwl  2(rPC),%eax
68    movl    offGlue_method(%ecx),%ecx   # ecx<- glue->method
69    movl    %eax,OUT_ARG1(%esp)
70    movl    offMethod_clazz(%ecx),%ecx  # ecx<- method->clazz
71    movl    $$0,OUT_ARG2(%esp)
72    movl    %ecx,OUT_ARG0(%esp)
73    call    dvmResolveClass             # call(clazz,off,flags)
74    movl    %eax,%ecx                   # ecx<- resolved ClassObject ptr
75    testl   %ecx,%ecx                   # success?
76    jne     .L${opcode}_resolved        # good to go
77    UNSPILL(rPC)
78    jmp     common_exceptionThrown      # no, handle exception
79
80    /*
81     * TODO: remove this
82     * We can't instantiate an abstract class or interface, so throw an
83     * InstantiationError with the class descriptor as the message.
84     *
85     *  ecx holds class object
86     */
87.L${opcode}_abstract:
88    movl    offClassObject_descriptor(%ecx),%eax
89    movl    $$.LstrInstantiationError,OUT_ARG0(%esp)
90    movl    %eax,OUT_ARG1(%esp)
91    call    dvmThrowExceptionWithClassMessage
92    UNSPILL(rPC)
93    jmp     common_exceptionThrown
94