blob: 5d0179447976e03ab25e15ca903a82c706809fb8 [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_OPB(a0) # a0 <- B
FETCH(a2, 1) # a2 <- CCCC
LOAD_rSELF_methodClassDex(a3) # a3 <- pDvmDex
GET_VREG(a1, a0) # a1 <- vB (array length)
LOAD_base_offDvmDex_pResClasses(a3, a3) # a3 <- pDvmDex->pResClasses
LOAD_eas2(a0, a3, a2) # a0 <- resolved class
# check length
bltz a1, common_errNegativeArraySize # negative length, bail - len in a1
EXPORT_PC() # req'd for resolve, alloc
# already resolved?
beqz a0, .L${opcode}_resolve
/*
* Finish allocation.
*
* a0 holds class
* a1 holds array length
*/
.L${opcode}_finish:
li a2, ALLOC_DONT_TRACK # don't track in local refs table
JAL(dvmAllocArrayByClass) # v0 <- call(clazz, length, flags)
GET_OPA4(a2) # a2 <- A+
# failed?
beqz v0, common_exceptionThrown # yes, handle the exception
FETCH_ADVANCE_INST(2) # advance rPC, load rINST
GET_INST_OPCODE(t0) # extract opcode from rINST
SET_VREG(v0, a2) # vA <- v0
GOTO_OPCODE(t0) # jump to next instruction
%break
/*
* Resolve class. (This is an uncommon case.)
*
* a1 holds array length
* a2 holds class ref CCCC
*/
.L${opcode}_resolve:
LOAD_rSELF_method(a3) # a3 <- self->method
move rOBJ, a1 # rOBJ <- length (save)
move a1, a2 # a1 <- CCCC
li a2, 0 # a2 <- false
LOAD_base_offMethod_clazz(a0, a3) # a0 <- method->clazz
JAL(dvmResolveClass) # v0 <- call(clazz, ref)
move a1, rOBJ # a1 <- length (restore)
# got null?
beqz v0, common_exceptionThrown # yes, handle exception
move a0, v0
b .L${opcode}_finish # continue with ${opcode}_finish