blob: cb07aeddc4d684dc427528344b0c0adf1cd81aef [file] [log] [blame]
%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