Refactored APF generator to builder pattern for instructions
This commit refactors the APF generator to utilize the builder pattern
when adding instructions. This approach leads to a reduction in code
duplication.
Bug: 293811969
Test: TH
Change-Id: I0eb4474dbd3cbdeccf39d9aafb6c6604a0c4df40
diff --git a/src/android/net/apf/ApfGenerator.java b/src/android/net/apf/ApfGenerator.java
index d038e96..ff00187 100644
--- a/src/android/net/apf/ApfGenerator.java
+++ b/src/android/net/apf/ApfGenerator.java
@@ -292,27 +292,45 @@
mRegister = (byte) register.value;
}
+ Instruction(ExtendedOpcodes extendedOpcodes, Register register) {
+ mOpcode = (byte) Opcodes.EXT.value;
+ mRegister = (byte) register.value;
+ addUnsignedImm(extendedOpcodes.value);
+ }
+
+ Instruction(ExtendedOpcodes extendedOpcodes, int slot, Register register) {
+ mOpcode = (byte) Opcodes.EXT.value;
+ mRegister = (byte) register.value;
+ addUnsignedImm(extendedOpcodes.value + slot);
+ }
+
Instruction(Opcodes opcode) {
this(opcode, Register.R0);
}
- void addUnsignedImm(int imm) {
+ Instruction(ExtendedOpcodes extendedOpcodes) {
+ this(extendedOpcodes, Register.R0);
+ }
+
+ Instruction addUnsignedImm(int imm) {
addImm(new IntImmediate(imm, false));
+ return this;
}
void addUnsignedImm(int imm, byte size) {
addImm(new IntImmediate(imm, false, size));
}
- void addSignedImm(int imm) {
+ Instruction addSignedImm(int imm) {
addImm(new IntImmediate(imm, true));
+ return this;
}
void addImm(IntImmediate imm) {
mIntImms.add(imm);
}
- void setLabel(String label) throws IllegalInstructionException {
+ Instruction setLabel(String label) throws IllegalInstructionException {
if (mLabels.containsKey(label)) {
throw new IllegalInstructionException("duplicate label " + label);
}
@@ -321,18 +339,21 @@
}
mLabel = label;
mLabels.put(label, this);
+ return this;
}
- void setTargetLabel(String label) {
+ Instruction setTargetLabel(String label) {
mTargetLabel = label;
mTargetLabelSize = 4; // May shrink later on in generate().
+ return this;
}
- void setBytesImm(byte[] bytes) {
+ Instruction setBytesImm(byte[] bytes) {
if (mOpcode != Opcodes.JNEBS.value) {
throw new IllegalStateException("adding compare bytes to non-JNEBS instruction");
}
mBytesImm = bytes;
+ return this;
}
/**
@@ -555,11 +576,12 @@
}
}
- private void addInstruction(Instruction instruction) {
+ private ApfGenerator addInstruction(Instruction instruction) {
if (mGenerated) {
throw new IllegalStateException("Program already generated");
}
mInstructions.add(instruction);
+ return this;
}
/**
@@ -578,20 +600,14 @@
* In this case "next_filter" may not have any generated code associated with it.
*/
public ApfGenerator defineLabel(String name) throws IllegalInstructionException {
- Instruction instruction = new Instruction(Opcodes.LABEL);
- instruction.setLabel(name);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.LABEL).setLabel(name));
}
/**
* Add an unconditional jump instruction to the end of the program.
*/
public ApfGenerator addJump(String target) {
- Instruction instruction = new Instruction(Opcodes.JMP);
- instruction.setTargetLabel(target);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JMP).setTargetLabel(target));
}
/**
@@ -599,10 +615,7 @@
* bytes from the beginning of the packet into {@code register}.
*/
public ApfGenerator addLoad8(Register register, int offset) {
- Instruction instruction = new Instruction(Opcodes.LDB, register);
- instruction.addUnsignedImm(offset);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.LDB, register).addUnsignedImm(offset));
}
/**
@@ -610,10 +623,7 @@
* bytes from the beginning of the packet into {@code register}.
*/
public ApfGenerator addLoad16(Register register, int offset) {
- Instruction instruction = new Instruction(Opcodes.LDH, register);
- instruction.addUnsignedImm(offset);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.LDH, register).addUnsignedImm(offset));
}
/**
@@ -621,10 +631,7 @@
* bytes from the beginning of the packet into {@code register}.
*/
public ApfGenerator addLoad32(Register register, int offset) {
- Instruction instruction = new Instruction(Opcodes.LDW, register);
- instruction.addUnsignedImm(offset);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.LDW, register).addUnsignedImm(offset));
}
/**
@@ -633,10 +640,7 @@
* the sum of {@code offset} and the value in register R1.
*/
public ApfGenerator addLoad8Indexed(Register register, int offset) {
- Instruction instruction = new Instruction(Opcodes.LDBX, register);
- instruction.addUnsignedImm(offset);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.LDBX, register).addUnsignedImm(offset));
}
/**
@@ -645,10 +649,7 @@
* the sum of {@code offset} and the value in register R1.
*/
public ApfGenerator addLoad16Indexed(Register register, int offset) {
- Instruction instruction = new Instruction(Opcodes.LDHX, register);
- instruction.addUnsignedImm(offset);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.LDHX, register).addUnsignedImm(offset));
}
/**
@@ -657,70 +658,49 @@
* the sum of {@code offset} and the value in register R1.
*/
public ApfGenerator addLoad32Indexed(Register register, int offset) {
- Instruction instruction = new Instruction(Opcodes.LDWX, register);
- instruction.addUnsignedImm(offset);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.LDWX, register).addUnsignedImm(offset));
}
/**
* Add an instruction to the end of the program to add {@code value} to register R0.
*/
public ApfGenerator addAdd(int value) {
- Instruction instruction = new Instruction(Opcodes.ADD);
- instruction.addUnsignedImm(value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.ADD).addUnsignedImm(value));
}
/**
* Add an instruction to the end of the program to multiply register R0 by {@code value}.
*/
public ApfGenerator addMul(int value) {
- Instruction instruction = new Instruction(Opcodes.MUL);
- instruction.addUnsignedImm(value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.MUL).addUnsignedImm(value));
}
/**
* Add an instruction to the end of the program to divide register R0 by {@code value}.
*/
public ApfGenerator addDiv(int value) {
- Instruction instruction = new Instruction(Opcodes.DIV);
- instruction.addUnsignedImm(value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.DIV).addUnsignedImm(value));
}
/**
* Add an instruction to the end of the program to logically and register R0 with {@code value}.
*/
public ApfGenerator addAnd(int value) {
- Instruction instruction = new Instruction(Opcodes.AND);
- instruction.addUnsignedImm(value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.AND).addUnsignedImm(value));
}
/**
* Add an instruction to the end of the program to logically or register R0 with {@code value}.
*/
public ApfGenerator addOr(int value) {
- Instruction instruction = new Instruction(Opcodes.OR);
- instruction.addUnsignedImm(value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.OR).addUnsignedImm(value));
}
/**
* Add an instruction to the end of the program to shift left register R0 by {@code value} bits.
*/
public ApfGenerator addLeftShift(int value) {
- Instruction instruction = new Instruction(Opcodes.SH);
- instruction.addSignedImm(value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.SH).addSignedImm(value));
}
/**
@@ -728,37 +708,28 @@
* bits.
*/
public ApfGenerator addRightShift(int value) {
- Instruction instruction = new Instruction(Opcodes.SH);
- instruction.addSignedImm(-value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.SH).addSignedImm(-value));
}
/**
* Add an instruction to the end of the program to add register R1 to register R0.
*/
public ApfGenerator addAddR1() {
- Instruction instruction = new Instruction(Opcodes.ADD, Register.R1);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.ADD, Register.R1));
}
/**
* Add an instruction to the end of the program to multiply register R0 by register R1.
*/
public ApfGenerator addMulR1() {
- Instruction instruction = new Instruction(Opcodes.MUL, Register.R1);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.MUL, Register.R1));
}
/**
* Add an instruction to the end of the program to divide register R0 by register R1.
*/
public ApfGenerator addDivR1() {
- Instruction instruction = new Instruction(Opcodes.DIV, Register.R1);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.DIV, Register.R1));
}
/**
@@ -766,9 +737,7 @@
* and store the result back into register R0.
*/
public ApfGenerator addAndR1() {
- Instruction instruction = new Instruction(Opcodes.AND, Register.R1);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.AND, Register.R1));
}
/**
@@ -776,9 +745,7 @@
* and store the result back into register R0.
*/
public ApfGenerator addOrR1() {
- Instruction instruction = new Instruction(Opcodes.OR, Register.R1);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.OR, Register.R1));
}
/**
@@ -786,19 +753,14 @@
* register R1.
*/
public ApfGenerator addLeftShiftR1() {
- Instruction instruction = new Instruction(Opcodes.SH, Register.R1);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.SH, Register.R1));
}
/**
* Add an instruction to the end of the program to move {@code value} into {@code register}.
*/
public ApfGenerator addLoadImmediate(Register register, int value) {
- Instruction instruction = new Instruction(Opcodes.LI, register);
- instruction.addSignedImm(value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.LI, register).addSignedImm(value));
}
/**
@@ -806,11 +768,8 @@
* value equals {@code value}.
*/
public ApfGenerator addJumpIfR0Equals(int value, String target) {
- Instruction instruction = new Instruction(Opcodes.JEQ);
- instruction.addUnsignedImm(value);
- instruction.setTargetLabel(target);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JEQ).addUnsignedImm(value).setTargetLabel(
+ target));
}
/**
@@ -818,11 +777,8 @@
* value does not equal {@code value}.
*/
public ApfGenerator addJumpIfR0NotEquals(int value, String target) {
- Instruction instruction = new Instruction(Opcodes.JNE);
- instruction.addUnsignedImm(value);
- instruction.setTargetLabel(target);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JNE).addUnsignedImm(value).setTargetLabel(
+ target));
}
/**
@@ -830,11 +786,8 @@
* value is greater than {@code value}.
*/
public ApfGenerator addJumpIfR0GreaterThan(int value, String target) {
- Instruction instruction = new Instruction(Opcodes.JGT);
- instruction.addUnsignedImm(value);
- instruction.setTargetLabel(target);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JGT).addUnsignedImm(value).setTargetLabel(
+ target));
}
/**
@@ -842,11 +795,8 @@
* value is less than {@code value}.
*/
public ApfGenerator addJumpIfR0LessThan(int value, String target) {
- Instruction instruction = new Instruction(Opcodes.JLT);
- instruction.addUnsignedImm(value);
- instruction.setTargetLabel(target);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JLT).addUnsignedImm(value).setTargetLabel(
+ target));
}
/**
@@ -854,21 +804,15 @@
* value has any bits set that are also set in {@code value}.
*/
public ApfGenerator addJumpIfR0AnyBitsSet(int value, String target) {
- Instruction instruction = new Instruction(Opcodes.JSET);
- instruction.addUnsignedImm(value);
- instruction.setTargetLabel(target);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JSET).addUnsignedImm(value).setTargetLabel(
+ target));
}
/**
* Add an instruction to the end of the program to jump to {@code target} if register R0's
* value equals register R1's value.
*/
public ApfGenerator addJumpIfR0EqualsR1(String target) {
- Instruction instruction = new Instruction(Opcodes.JEQ, Register.R1);
- instruction.setTargetLabel(target);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JEQ, Register.R1).setTargetLabel(target));
}
/**
@@ -876,10 +820,7 @@
* value does not equal register R1's value.
*/
public ApfGenerator addJumpIfR0NotEqualsR1(String target) {
- Instruction instruction = new Instruction(Opcodes.JNE, Register.R1);
- instruction.setTargetLabel(target);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JNE, Register.R1).setTargetLabel(target));
}
/**
@@ -887,10 +828,7 @@
* value is greater than register R1's value.
*/
public ApfGenerator addJumpIfR0GreaterThanR1(String target) {
- Instruction instruction = new Instruction(Opcodes.JGT, Register.R1);
- instruction.setTargetLabel(target);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JGT, Register.R1).setTargetLabel(target));
}
/**
@@ -898,10 +836,7 @@
* value is less than register R1's value.
*/
public ApfGenerator addJumpIfR0LessThanR1(String target) {
- Instruction instruction = new Instruction(Opcodes.JLT, Register.R1);
- instruction.setTargetLabel(target);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JLT, Register.R1).setTargetLabel(target));
}
/**
@@ -909,10 +844,7 @@
* value has any bits set that are also set in R1's value.
*/
public ApfGenerator addJumpIfR0AnyBitsSetR1(String target) {
- Instruction instruction = new Instruction(Opcodes.JSET, Register.R1);
- instruction.setTargetLabel(target);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JSET, Register.R1).setTargetLabel(target));
}
/**
@@ -925,12 +857,8 @@
if (register == Register.R1) {
throw new IllegalInstructionException("JNEBS fails with R1");
}
- Instruction instruction = new Instruction(Opcodes.JNEBS, register);
- instruction.addUnsignedImm(bytes.length);
- instruction.setTargetLabel(target);
- instruction.setBytesImm(bytes);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.JNEBS, register).addUnsignedImm(
+ bytes.length).setTargetLabel(target).setBytesImm(bytes));
}
/**
@@ -942,10 +870,7 @@
if (slot < 0 || slot > (MEMORY_SLOTS - 1)) {
throw new IllegalInstructionException("illegal memory slot number: " + slot);
}
- Instruction instruction = new Instruction(Opcodes.EXT, register);
- instruction.addUnsignedImm(ExtendedOpcodes.LDM.value + slot);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(ExtendedOpcodes.LDM, slot, register));
}
/**
@@ -957,40 +882,28 @@
if (slot < 0 || slot > (MEMORY_SLOTS - 1)) {
throw new IllegalInstructionException("illegal memory slot number: " + slot);
}
- Instruction instruction = new Instruction(Opcodes.EXT, register);
- instruction.addUnsignedImm(ExtendedOpcodes.STM.value + slot);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(ExtendedOpcodes.STM, slot, register));
}
/**
* Add an instruction to the end of the program to logically not {@code register}.
*/
public ApfGenerator addNot(Register register) {
- Instruction instruction = new Instruction(Opcodes.EXT, register);
- instruction.addUnsignedImm(ExtendedOpcodes.NOT.value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(ExtendedOpcodes.NOT, register));
}
/**
* Add an instruction to the end of the program to negate {@code register}.
*/
public ApfGenerator addNeg(Register register) {
- Instruction instruction = new Instruction(Opcodes.EXT, register);
- instruction.addUnsignedImm(ExtendedOpcodes.NEG.value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(ExtendedOpcodes.NEG, register));
}
/**
* Add an instruction to swap the values in register R0 and register R1.
*/
public ApfGenerator addSwap() {
- Instruction instruction = new Instruction(Opcodes.EXT);
- instruction.addUnsignedImm(ExtendedOpcodes.SWAP.value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(ExtendedOpcodes.SWAP));
}
/**
@@ -998,19 +911,14 @@
* {@code register} from the other register.
*/
public ApfGenerator addMove(Register register) {
- Instruction instruction = new Instruction(Opcodes.EXT, register);
- instruction.addUnsignedImm(ExtendedOpcodes.MOVE.value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(ExtendedOpcodes.MOVE, register));
}
/**
* Add an instruction to the end of the program to let the program immediately return PASS.
*/
public ApfGenerator addPass() throws IllegalInstructionException {
- Instruction instruction = new Instruction(Opcodes.PASS, Register.R0);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.PASS, Register.R0));
}
/**
@@ -1021,10 +929,8 @@
requireApfVersion(MIN_APF_VERSION_IN_DEV);
checkRange("CounterNumber", counterNumber /* value */, 1 /* lowerBound */,
1000 /* upperBound */);
- Instruction instruction = new Instruction(Opcodes.PASS, Register.R0);
- instruction.addUnsignedImm(counterNumber);
- addInstruction(instruction);
- return this;
+ return addInstruction(
+ new Instruction(Opcodes.PASS, Register.R0).addUnsignedImm(counterNumber));
}
/**
@@ -1032,9 +938,7 @@
*/
public ApfGenerator addDrop() throws IllegalInstructionException {
requireApfVersion(MIN_APF_VERSION_IN_DEV);
- Instruction instruction = new Instruction(Opcodes.DROP, Register.R1);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.DROP, Register.R1));
}
/**
@@ -1045,10 +949,8 @@
requireApfVersion(MIN_APF_VERSION_IN_DEV);
checkRange("CounterNumber", counterNumber /* value */, 1 /* lowerBound */,
1000 /* upperBound */);
- Instruction instruction = new Instruction(Opcodes.DROP, Register.R1);
- instruction.addUnsignedImm(counterNumber);
- addInstruction(instruction);
- return this;
+ return addInstruction(
+ new Instruction(Opcodes.DROP, Register.R1).addUnsignedImm(counterNumber));
}
/**
@@ -1058,10 +960,7 @@
*/
public ApfGenerator addAlloc(Register register) throws IllegalInstructionException {
requireApfVersion(5);
- Instruction instruction = new Instruction(Opcodes.EXT, register);
- instruction.addUnsignedImm(ExtendedOpcodes.ALLOC.value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(ExtendedOpcodes.ALLOC));
}
/**
@@ -1069,10 +968,7 @@
*/
public ApfGenerator addTransmit() throws IllegalInstructionException {
requireApfVersion(MIN_APF_VERSION_IN_DEV);
- Instruction instruction = new Instruction(Opcodes.EXT, Register.R0);
- instruction.addUnsignedImm(ExtendedOpcodes.TRANSMIT.value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(ExtendedOpcodes.TRANSMIT, Register.R0));
}
/**
@@ -1080,10 +976,7 @@
*/
public ApfGenerator addDiscard() throws IllegalInstructionException {
requireApfVersion(MIN_APF_VERSION_IN_DEV);
- Instruction instruction = new Instruction(Opcodes.EXT, Register.R1);
- instruction.addUnsignedImm(ExtendedOpcodes.DISCARD.value);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(ExtendedOpcodes.DISCARD, Register.R1));
}
// TODO: add back when support WRITE opcode
@@ -1271,10 +1164,8 @@
public ApfGenerator addLoadData(Register destinationRegister, int offset)
throws IllegalInstructionException {
requireApfVersion(3);
- Instruction instruction = new Instruction(Opcodes.LDDW, destinationRegister);
- instruction.addSignedImm(offset);
- addInstruction(instruction);
- return this;
+ return addInstruction(
+ new Instruction(Opcodes.LDDW, destinationRegister).addSignedImm(offset));
}
/**
@@ -1286,10 +1177,7 @@
public ApfGenerator addStoreData(Register sourceRegister, int offset)
throws IllegalInstructionException {
requireApfVersion(3);
- Instruction instruction = new Instruction(Opcodes.STDW, sourceRegister);
- instruction.addSignedImm(offset);
- addInstruction(instruction);
- return this;
+ return addInstruction(new Instruction(Opcodes.STDW, sourceRegister).addSignedImm(offset));
}
/**