%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