| %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 */ |
| movl rSELF,%ecx |
| EXPORT_PC |
| movl offThread_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 rINSTbl,%eax |
| sarl $$4,%eax # eax<- B |
| GET_VREG_R %eax %eax # eax<- vB (array length) |
| andb $$0xf,rINSTbl # rINST<- A |
| testl %eax,%eax |
| js common_errNegativeArraySize # bail, passing len in eax |
| 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: |
| movl rSELF,%ecx |
| SPILL_TMP1(%eax) # save array length |
| movl offThread_method(%ecx),%ecx # ecx<- self->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) |
| call dvmResolveClass # eax<- call(clazz,ref,flag) |
| movl %eax,%ecx |
| UNSPILL_TMP1(%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) |
| call dvmAllocArrayByClass # eax<- call(clazz,length,flags) |
| FETCH_INST_OPCODE 2 %edx |
| testl %eax,%eax # failed? |
| je common_exceptionThrown # yup - go handle |
| SET_VREG %eax rINST |
| ADVANCE_PC 2 |
| GOTO_NEXT_R %edx |