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 95 96 97