Commit 9e25219f authored by pcregut's avatar pcregut

task 316405: filled-new-array/range instruction rewritten as filled-new-aray instruction

http://forge.ow2.org/tracker/?group_id=23&func=detail&atid=100023&aid=316405

Check that the set of integers can be put in a range. Modify also the generation of instruction so that if the set of registers does not describe a range, nothing is written. A test case has been added to the regression suite.
parent 13af93d6
......@@ -177,7 +177,19 @@ public abstract class Instruction {
}
}
/**
/**
* Tests if the given number can be held in 4 bits, throw an IllegalArgumentException otherwise.
*/
public static void testRange(int[] numbers) {
int length = numbers.length;
if (length == 0) throw new IllegalArgumentException("Too short for a range");
int expected = numbers[0];
for(int i=1; i<length; i++) {
if (numbers[i] != ++expected)
throw new IllegalArgumentException("The register at position " + i +" is not consecutive.");
}
}
/**
* Size in bytes of every instructions. Includes 256 opcodes.
*/
final private static byte[] instructionSizeInBytes = new byte[] {
......
......@@ -72,32 +72,6 @@ implements IRegisterArrayInstruction, IIndexInstruction {
return index;
}
/**
* Constructor of the Instruction, using a Reader to parse its bytecode.
* @param reader reader on the Instruction to parse, pointing after the 16-bit opcode.
* @param opcode 16-bit opcode.
*/
// public InstructionFormat35C(IDalvikValueReader reader, int opcode) {
// super(opcode);
//
// // The format is B|A|op CCCC G|F|E|D.
// int nbRegisters = (opcodeHighOrderByte >> 4) & 0xf;
//
// registers = new int[nbRegisters];
// index = (int)reader.ushort();
// int thirdShort = (int)reader.ushort();
// if (nbRegisters > 0) {
// registers[0] = thirdShort & 0xf;
// if (nbRegisters > 1) { registers[1] = (thirdShort >> 4) & 0xf; }
// if (nbRegisters > 2) { registers[2] = (thirdShort >> 8) & 0xf; }
// if (nbRegisters > 3) { registers[3] = (thirdShort >> 12) & 0xf; }
// if (nbRegisters > 4) { registers[4] = opcodeHighOrderByte & 0xf; }
// if (nbRegisters > 5) {
// try { throw new Exception("Abnormal arguments number : " + nbRegisters); }
// catch (Exception e) { e.printStackTrace(); }
// }
// }
// }
/**
* Returns the Index encoded where the Reader points. <i>It must be performed only once after
......@@ -175,16 +149,6 @@ implements IRegisterArrayInstruction, IIndexInstruction {
return INSTRUCTION_SIZE;
}
// @Override
// public int[] getUsedRegisters() {
// return registers;
// }
// @Override
// public int getNbEncodedRegisters() {
// return registers.length;
// }
@Override
public void write(ByteVector out, ConstantPool constantPool) {
int nbRegisters = registers.length;
......
......@@ -75,24 +75,6 @@ implements IRegisterArrayInstruction, IIndexInstruction {
return index;
}
/**
* Constructor of the Instruction, using a Reader to parse its bytecode.
* @param reader reader on the Instruction to parse, pointing after the 16-bit opcode.
* @param opcode 16-bit opcode.
*/
// public InstructionFormat3RC(IDalvikValueReader reader, int opcode) {
// super(opcode);
//
// // The format is AA|op BBBB CCCC.
// int nbRegisters = opcodeHighOrderByte;
// registers = new int[nbRegisters];
// index = (int)reader.ushort();
// int currentRegister = (int)reader.ushort();
// for (int registerIndex = 0; registerIndex < nbRegisters; registerIndex++) {
// registers[registerIndex] = currentRegister;
// currentRegister++;
// }
// }
/**
* Returns the Index encoded where the Reader points. <i>It must be performed only once after
......@@ -154,6 +136,7 @@ implements IRegisterArrayInstruction, IIndexInstruction {
super(opcode);
this.type = type;
this.registers = registers;
Instruction.testRange(registers);
}
@Override
......@@ -161,16 +144,6 @@ implements IRegisterArrayInstruction, IIndexInstruction {
return INSTRUCTION_SIZE;
}
// @Override
// public int[] getUsedRegisters() {
// return registers;
// }
// @Override
// public int getNbEncodedRegisters() {
// return registers.length;
// }
@Override
public void write(ByteVector out, ConstantPool constantPool) {
// The format is AA|op BBBB CCCC.
......
......@@ -348,9 +348,11 @@ public class InstructionEncoder {
*/
public static Instruction encodeMultiANewArrayInsn(String type, int[] registers) {
Instruction insn = null;
int length = registers.length;
// The instruction to create varies according to the number of registers.
if (registers.length <= 5) {
// Bug316405: we have to use a range if register indexes are beyond 16. In that case we assume it is a range and let
// instruction generation catch errors.
if (length <= 5 && length > 0 && registers[length - 1] < 16) {
insn = new InstructionFormat35C(Opcodes.INSN_FILLED_NEW_ARRAY, type, registers);
} else {
insn = new InstructionFormat3RC(Opcodes.INSN_FILLED_NEW_ARRAY_RANGE, type, registers);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment