%verify "executed" %verify "negative array length" %verify "allocation fails" /* * Allocate an array of objects, specified with the array class * and a count. * * The verifier guarantees that this is an array class, so we don't * check for it here. */ /* new-array vA, vB, class@CCCC */ GET_GLUE(%ecx) EXPORT_PC() movl offGlue_methodClassDex(%ecx),%ecx # ecx<- pDvmDex movzwl 2(rPC),%eax # eax<- CCCC movl offDvmDex_pResClasses(%ecx),%ecx # ecx<- pDvmDex->pResClasses movl (%ecx,%eax,4),%ecx # ecx<- resolved class movzbl rINST_HI,%eax sarl $$4,%eax # eax<- B GET_VREG(%eax,%eax) # eax<- vB (array length) movzbl rINST_HI,rINST_FULL andb $$0xf,rINST_LO # rINST_FULL<- A testl %eax,%eax js common_errNegativeArraySize # bail testl %ecx,%ecx # already resolved? jne .L${opcode}_finish # yes, fast path jmp .L${opcode}_resolve # resolve now %break /* * Resolve class. (This is an uncommon case.) * ecx holds class (null here) * eax holds array length (vB) */ .L${opcode}_resolve: GET_GLUE(%ecx) SPILL_TMP(%eax) # save array length movl offGlue_method(%ecx),%ecx # ecx<- glue->method movzwl 2(rPC),%eax # eax<- CCCC movl offMethod_clazz(%ecx),%ecx # ecx<- method->clazz movl %eax,OUT_ARG1(%esp) movl $$0,OUT_ARG2(%esp) movl %ecx,OUT_ARG0(%esp) SPILL(rPC) call dvmResolveClass # eax<- call(clazz,ref,flag) UNSPILL(rPC) movl %eax,%ecx UNSPILL_TMP(%eax) testl %ecx,%ecx # successful resolution? je common_exceptionThrown # no, bail. # fall through to ${opcode}_finish /* * Finish allocation * * ecx holds class * eax holds array length (vB) */ .L${opcode}_finish: movl %ecx,OUT_ARG0(%esp) movl %eax,OUT_ARG1(%esp) movl $$ALLOC_DONT_TRACK,OUT_ARG2(%esp) SPILL(rPC) call dvmAllocArrayByClass # eax<- call(clazz,length,flags) UNSPILL(rPC) testl %eax,%eax # failed? je common_exceptionThrown # yup - go handle movl rINST_FULL,%ecx FETCH_INST_WORD(2) SET_VREG(%eax,%ecx) ADVANCE_PC(2) GOTO_NEXT