void HInstructionBuilder::BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc) {
HInstruction* array = LoadNullCheckedLocal(instruction.VRegA_31t(), dex_pc);
- HInstruction* length = new (arena_) HArrayLength(array, dex_pc);
- AppendInstruction(length);
int32_t payload_offset = instruction.VRegB_31t() + dex_pc;
const Instruction::ArrayDataPayload* payload =
const uint8_t* data = payload->data;
uint32_t element_count = payload->element_count;
+ if (element_count == 0u) {
+ // For empty payload we emit only the null check above.
+ return;
+ }
+
+ HInstruction* length = new (arena_) HArrayLength(array, dex_pc);
+ AppendInstruction(length);
+
// Implementation of this DEX instruction seems to be that the bounds check is
// done before doing any stores.
HInstruction* last_index = graph_->GetIntConstant(payload->element_count - 1, dex_pc);
public static void testSmaliFillArrayData() throws Exception {
Class<?> c = Class.forName("FillArrayData");
{
+ Method m = c.getMethod("emptyIntArray", int[].class);
+ int[] array = new int[0];
+ Object[] args = { array };
+ m.invoke(null, args);
+ assertEquals(0, array.length);
+
+ array = new int[2];
+ args[0] = array;
+ m.invoke(null, args);
+ // Test that nothing has been written to the array.
+ assertEquals(0, array[0]);
+ assertEquals(0, array[1]);
+
+ array = new int[] { 42, -42 };
+ args[0] = array;
+ m.invoke(null, args);
+ // Test that nothing has been written to the array.
+ assertEquals(42, array[0]);
+ assertEquals(-42, array[1]);
+
+ Throwable exception = null;
+ args[0] = null;
+ try {
+ m.invoke(null, args);
+ } catch (InvocationTargetException e) {
+ exception = e.getCause();
+ assertTrue(exception instanceof NullPointerException);
+ }
+ assertNotNull(exception);
+ }
+
+ {
Method m = c.getMethod("intArray", int[].class);
int[] array = new int[7];
Object[] args = { array };
array = new int[2];
args[0] = array;
- Throwable exception = null;
+ Throwable exception = null;
try {
m.invoke(null, args);
} catch (InvocationTargetException e) {
array = new int[2];
args[0] = array;
- Throwable exception = null;
+ Throwable exception = null;
try {
m.invoke(null, args);
} catch (InvocationTargetException e) {
array = new short[2];
args[0] = array;
- Throwable exception = null;
+ Throwable exception = null;
try {
m.invoke(null, args);
} catch (InvocationTargetException e) {
array = new long[2];
args[0] = array;
- Throwable exception = null;
+ Throwable exception = null;
try {
m.invoke(null, args);
} catch (InvocationTargetException e) {
array = new char[2];
args[0] = array;
- Throwable exception = null;
+ Throwable exception = null;
try {
m.invoke(null, args);
} catch (InvocationTargetException e) {
array = new byte[2];
args[0] = array;
- Throwable exception = null;
+ Throwable exception = null;
try {
m.invoke(null, args);
} catch (InvocationTargetException e) {
array = new boolean[2];
args[0] = array;
- Throwable exception = null;
+ Throwable exception = null;
try {
m.invoke(null, args);
} catch (InvocationTargetException e) {