1 %verify "executed" 2 %verify "negative array length" 3 %verify "allocation fails" 4 /* 5 * Allocate an array of objects, specified with the array class 6 * and a count. 7 * 8 * The verifier guarantees that this is an array class, so we don't 9 * check for it here. 10 */ 11 /* new-array vA, vB, class@CCCC */ 12 mov r0, rINST, lsr #12 @ r0<- B 13 FETCH(r2, 1) @ r2<- CCCC 14 ldr r3, [rSELF, #offThread_methodClassDex] @ r3<- pDvmDex 15 GET_VREG(r1, r0) @ r1<- vB (array length) 16 ldr r3, [r3, #offDvmDex_pResClasses] @ r3<- pDvmDex->pResClasses 17 cmp r1, #0 @ check length 18 ldr r0, [r3, r2, lsl #2] @ r0<- resolved class 19 bmi common_errNegativeArraySize @ negative length, bail - len in r1 20 cmp r0, #0 @ already resolved? 21 EXPORT_PC() @ req'd for resolve, alloc 22 bne .L${opcode}_finish @ resolved, continue 23 b .L${opcode}_resolve @ do resolve now 24 %break 25 26 27 /* 28 * Resolve class. (This is an uncommon case.) 29 * 30 * r1 holds array length 31 * r2 holds class ref CCCC 32 */ 33 .L${opcode}_resolve: 34 ldr r3, [rSELF, #offThread_method] @ r3<- self->method 35 mov r9, r1 @ r9<- length (save) 36 mov r1, r2 @ r1<- CCCC 37 mov r2, #0 @ r2<- false 38 ldr r0, [r3, #offMethod_clazz] @ r0<- method->clazz 39 bl dvmResolveClass @ r0<- call(clazz, ref) 40 cmp r0, #0 @ got null? 41 mov r1, r9 @ r1<- length (restore) 42 beq common_exceptionThrown @ yes, handle exception 43 @ fall through to ${opcode}_finish 44 45 /* 46 * Finish allocation. 47 * 48 * r0 holds class 49 * r1 holds array length 50 */ 51 .L${opcode}_finish: 52 mov r2, #ALLOC_DONT_TRACK @ don't track in local refs table 53 bl dvmAllocArrayByClass @ r0<- call(clazz, length, flags) 54 cmp r0, #0 @ failed? 55 mov r2, rINST, lsr #8 @ r2<- A+ 56 beq common_exceptionThrown @ yes, handle the exception 57 FETCH_ADVANCE_INST(2) @ advance rPC, load rINST 58 and r2, r2, #15 @ r2<- A 59 GET_INST_OPCODE(ip) @ extract opcode from rINST 60 SET_VREG(r0, r2) @ vA<- r0 61 GOTO_OPCODE(ip) @ jump to next instruction 62