mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-06-12 05:07:45 +02:00
refactor: Add more opcodes to findFreeRegister
This commit is contained in:
@ -269,7 +269,7 @@ val hideLayoutComponentsPatch = bytecodePatch(
|
||||
move-object v$returnEmptyComponentRegister, p1 # Required for 19.47
|
||||
goto :return_empty_component
|
||||
:show
|
||||
const/4 v$freeRegister, 0x0 # Restore register, required for 19.16
|
||||
nop
|
||||
""",
|
||||
ExternalLabel("return_empty_component", returnEmptyComponentInstruction),
|
||||
)
|
||||
|
@ -179,9 +179,6 @@ val returnYouTubeDislikePatch = bytecodePatch(
|
||||
|
||||
// region Hook rolling numbers.
|
||||
|
||||
// Do this last to allow patching old unsupported versions (if the user really wants),
|
||||
// On older unsupported version this will fail to match and throw an exception,
|
||||
// but everything will still work correctly anyway.
|
||||
val dislikesIndex = rollingNumberSetterFingerprint.patternMatch!!.endIndex
|
||||
|
||||
rollingNumberSetterFingerprint.method.apply {
|
||||
|
@ -70,21 +70,53 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
|
||||
}
|
||||
|
||||
val writeOpcodes = EnumSet.of(
|
||||
ARRAY_LENGTH,
|
||||
NEW_INSTANCE, NEW_ARRAY,
|
||||
MOVE, MOVE_FROM16, MOVE_16, MOVE_WIDE, MOVE_WIDE_FROM16, MOVE_WIDE_16, MOVE_OBJECT,
|
||||
MOVE_OBJECT_FROM16, MOVE_OBJECT_16, MOVE_RESULT, MOVE_RESULT_WIDE, MOVE_RESULT_OBJECT, MOVE_EXCEPTION,
|
||||
CONST, CONST_4, CONST_16, CONST_HIGH16, CONST_WIDE_16, CONST_WIDE_32,
|
||||
CONST_WIDE, CONST_WIDE_HIGH16, CONST_STRING, CONST_STRING_JUMBO,
|
||||
IGET, IGET_WIDE, IGET_OBJECT, IGET_BOOLEAN, IGET_BYTE, IGET_CHAR, IGET_SHORT,
|
||||
IGET_VOLATILE, IGET_WIDE_VOLATILE, IGET_OBJECT_VOLATILE,
|
||||
SGET, SGET_WIDE, SGET_OBJECT, SGET_BOOLEAN, SGET_BYTE, SGET_CHAR, SGET_SHORT,
|
||||
SGET_VOLATILE, SGET_WIDE_VOLATILE, SGET_OBJECT_VOLATILE,
|
||||
AGET, AGET_WIDE, AGET_OBJECT, AGET_BOOLEAN, AGET_BYTE, AGET_CHAR, AGET_SHORT,
|
||||
// Arithmetic and logical operations.
|
||||
ADD_DOUBLE_2ADDR, ADD_DOUBLE, ADD_FLOAT_2ADDR, ADD_FLOAT, ADD_INT_2ADDR,
|
||||
ADD_INT_LIT8, ADD_INT, ADD_LONG_2ADDR, ADD_LONG, ADD_INT_LIT16,
|
||||
AND_INT_2ADDR, AND_INT_LIT8, AND_INT_LIT16, AND_INT, AND_LONG_2ADDR, AND_LONG,
|
||||
DIV_DOUBLE_2ADDR, DIV_DOUBLE, DIV_FLOAT_2ADDR, DIV_FLOAT, DIV_INT_2ADDR,
|
||||
DIV_INT_LIT16, DIV_INT_LIT8, DIV_INT, DIV_LONG_2ADDR, DIV_LONG,
|
||||
DOUBLE_TO_FLOAT, DOUBLE_TO_INT, DOUBLE_TO_LONG,
|
||||
FLOAT_TO_DOUBLE, FLOAT_TO_INT, FLOAT_TO_LONG,
|
||||
INT_TO_BYTE, INT_TO_CHAR, INT_TO_DOUBLE, INT_TO_FLOAT, INT_TO_LONG, INT_TO_SHORT,
|
||||
LONG_TO_DOUBLE, LONG_TO_FLOAT, LONG_TO_INT,
|
||||
MUL_DOUBLE_2ADDR, MUL_DOUBLE, MUL_FLOAT_2ADDR, MUL_FLOAT, MUL_INT_2ADDR,
|
||||
MUL_INT_LIT16, MUL_INT_LIT8, MUL_INT, MUL_LONG_2ADDR, MUL_LONG,
|
||||
NEG_DOUBLE, NEG_FLOAT, NEG_INT, NEG_LONG,
|
||||
NOT_INT, NOT_LONG,
|
||||
OR_INT_2ADDR, OR_INT_LIT16, OR_INT_LIT8, OR_INT, OR_LONG_2ADDR, OR_LONG,
|
||||
REM_DOUBLE_2ADDR, REM_DOUBLE, REM_FLOAT_2ADDR, REM_FLOAT, REM_INT_2ADDR,
|
||||
REM_INT_LIT16, REM_INT_LIT8, REM_INT, REM_LONG_2ADDR, REM_LONG,
|
||||
RSUB_INT_LIT8, RSUB_INT,
|
||||
SHL_INT_2ADDR, SHL_INT_LIT8, SHL_INT, SHL_LONG_2ADDR, SHL_LONG,
|
||||
SHR_INT_2ADDR, SHR_INT_LIT8, SHR_INT, SHR_LONG_2ADDR, SHR_LONG,
|
||||
SUB_DOUBLE_2ADDR, SUB_DOUBLE, SUB_FLOAT_2ADDR, SUB_FLOAT, SUB_INT_2ADDR,
|
||||
SUB_INT, SUB_LONG_2ADDR, SUB_LONG,
|
||||
USHR_INT_2ADDR, USHR_INT_LIT8, USHR_INT, USHR_LONG_2ADDR, USHR_LONG,
|
||||
XOR_INT_2ADDR, XOR_INT_LIT16, XOR_INT_LIT8, XOR_INT, XOR_LONG_2ADDR, XOR_LONG,
|
||||
)
|
||||
|
||||
val branchOpcodes = EnumSet.of(
|
||||
GOTO, GOTO_16, GOTO_32,
|
||||
IF_EQ, IF_NE, IF_LT, IF_GE, IF_GT, IF_LE,
|
||||
IF_EQZ, IF_NEZ, IF_LTZ, IF_GEZ, IF_GTZ, IF_LEZ,
|
||||
PACKED_SWITCH_PAYLOAD, SPARSE_SWITCH_PAYLOAD
|
||||
)
|
||||
|
||||
val returnOpcodes = EnumSet.of(
|
||||
RETURN_VOID, RETURN, RETURN_WIDE, RETURN_OBJECT,
|
||||
RETURN_VOID, RETURN, RETURN_WIDE, RETURN_OBJECT, RETURN_VOID_NO_BARRIER,
|
||||
THROW
|
||||
)
|
||||
|
||||
// Highest 4-bit register available, exclusive. Ideally return a free register less than this.
|
||||
@ -94,9 +126,13 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
|
||||
|
||||
for (i in startIndex until instructions.count()) {
|
||||
val instruction = getInstruction(i)
|
||||
val instructionRegisters = instruction.getRegistersUsed()
|
||||
|
||||
if (instruction.opcode in returnOpcodes) {
|
||||
// Method returns. Use lowest register that hasn't been encountered.
|
||||
// Method returns.
|
||||
usedRegisters.addAll(instructionRegisters)
|
||||
|
||||
// Use lowest register that hasn't been encountered.
|
||||
val freeRegister = (0 until implementation!!.registerCount).find {
|
||||
it !in usedRegisters
|
||||
}
|
||||
@ -122,26 +158,32 @@ internal fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude:
|
||||
}
|
||||
|
||||
if (instruction.opcode in writeOpcodes) {
|
||||
val freeRegister = instruction.getRegisterWritten()
|
||||
if (freeRegister !in usedRegisters) {
|
||||
if (freeRegister < maxRegister4Bits) {
|
||||
// Found an ideal register.
|
||||
return freeRegister
|
||||
}
|
||||
val writeRegister = instruction.getRegisterWritten()
|
||||
|
||||
// Continue searching for a 4-bit register if available.
|
||||
if (bestFreeRegisterFound == null || freeRegister < bestFreeRegisterFound) {
|
||||
bestFreeRegisterFound = freeRegister
|
||||
if (writeRegister !in usedRegisters) {
|
||||
// Verify the register is only used for write and not also as a parameter.
|
||||
// If the instruction uses the write register once then it's not also a read register.
|
||||
if (instructionRegisters.count { register -> register == writeRegister } == 1) {
|
||||
if (writeRegister < maxRegister4Bits) {
|
||||
// Found an ideal register.
|
||||
return writeRegister
|
||||
}
|
||||
|
||||
// Continue searching for a 4-bit register if available.
|
||||
if (bestFreeRegisterFound == null || writeRegister < bestFreeRegisterFound) {
|
||||
bestFreeRegisterFound = writeRegister
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usedRegisters.addAll(instruction.getRegistersUsed())
|
||||
usedRegisters.addAll(instructionRegisters)
|
||||
}
|
||||
|
||||
// Cannot be reached since a branch or return statement will
|
||||
// be encountered before the end of the method.
|
||||
throw IllegalStateException()
|
||||
// Some methods can have array payloads at the end of the method after a return statement.
|
||||
// But in normal usage this cannot be reached since a branch or return statement
|
||||
// will be encountered before the end of the method.
|
||||
throw IllegalArgumentException("Start index is outside the range of normal control flow: $startIndex")
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user