From ef56e5ba094dc7bc485c0f7cf063b8eec72188c0 Mon Sep 17 00:00:00 2001 From: Caleb Fenton Date: Tue, 16 Oct 2018 17:23:16 -0700 Subject: [PATCH] Correctly track parameter register when collapsing Reference https://github.com/CalebFenton/simplify/issues/76 --- .../java/org/cf/smalivm/VirtualMachine.java | 11 ++++------- .../org/cf/smalivm/opcode/InvokeOpTest.java | 8 ++++++++ .../smali/ops/invoke_static_test.smali | 19 +++++++++++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/smalivm/src/main/java/org/cf/smalivm/VirtualMachine.java b/smalivm/src/main/java/org/cf/smalivm/VirtualMachine.java index c078b59f1..fbd868d55 100644 --- a/smalivm/src/main/java/org/cf/smalivm/VirtualMachine.java +++ b/smalivm/src/main/java/org/cf/smalivm/VirtualMachine.java @@ -229,14 +229,11 @@ private void collapseMultiverse(VirtualMethod calledMethod, ExecutionGraph graph int parameterRegister = graph.getNodePile(0).get(0).getContext().getMethodState().getParameterStart(); for (int parameterIndex = 0; parameterIndex < parameterTypes.size(); parameterIndex++) { String type = parameterTypes.get(parameterIndex); - if (configuration.isImmutable(type)) { - continue; + if (configuration.isMutable(type)) { + HeapItem item = getMutableParameterConsensus(terminatingAddresses, graph, parameterRegister); + int register = parameterRegisters[parameterIndex]; + callerMethodState.assignRegisterAndUpdateIdentities(register, item); } - - HeapItem item = getMutableParameterConsensus(terminatingAddresses, graph, parameterRegister); - int register = parameterRegisters[parameterIndex]; - callerMethodState.assignRegisterAndUpdateIdentities(register, item); - parameterRegister += Utils.getRegisterSize(type); } } diff --git a/smalivm/src/test/java/org/cf/smalivm/opcode/InvokeOpTest.java b/smalivm/src/test/java/org/cf/smalivm/opcode/InvokeOpTest.java index a27b26919..b36bf3ce5 100644 --- a/smalivm/src/test/java/org/cf/smalivm/opcode/InvokeOpTest.java +++ b/smalivm/src/test/java/org/cf/smalivm/opcode/InvokeOpTest.java @@ -209,6 +209,14 @@ public void invokeMutateStringBuilderDoesMutateParameter() { VMTester.test(CLASS_NAME, "invokeMutateStringBuilder()V", initial, expected); } + @Test + public void invokeMutateStringBuilderAsThirdParameterAndFirstMutableParameterDoesMutateParameter() { + initial.setRegisters(0, 0x10, "I", 1, 0x20, "I", 2, new StringBuilder("i have been"), "Ljava/lang/StringBuilder;"); + expected.setRegisters(0, 0x10, "I", 1, 0x20, "I", 2, new StringBuilder("i have been mutated"), "Ljava/lang/StringBuilder;"); + + VMTester.test(CLASS_NAME, "invokeMutateStringBuilderAsThirdParameterAndFirstMutableParameter()V", initial, expected); + } + @Test public void invokeMutateStringDoesNotMutateParameter() { initial.setRegisters(0, "not mutated", "Ljava/lang/String;"); diff --git a/smalivm/src/test/resources/smali/ops/invoke_static_test.smali b/smalivm/src/test/resources/smali/ops/invoke_static_test.smali index 837469e53..4feea44a7 100644 --- a/smalivm/src/test/resources/smali/ops/invoke_static_test.smali +++ b/smalivm/src/test/resources/smali/ops/invoke_static_test.smali @@ -54,6 +54,14 @@ return-void .end method +.method public static invokeMutateStringBuilderAsThirdParameterAndFirstMutableParameter()V + .locals 3 + + invoke-static {v0, v1, v2}, Linvoke_static_test;->mutateStringBuilderAsThirdParameterAndFirstMutableParameter(IILjava/lang/StringBuilder;)V + + return-void +.end method + .method public static invokeNonExistentMethod()V .locals 0 @@ -250,6 +258,17 @@ return-void .end method +.method private static mutateStringBuilderAsThirdParameterAndFirstMutableParameter(IILjava/lang/StringBuilder;)V + .locals 1 + + const-string v0, " mutated" + invoke-virtual {p2, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; + + const/4 p2, 0x1 + + return-void +.end method + # test assume maximum unknown .method private static set0thElementOfFirstParameterTo0IfSecondParameterIs0([II)V .locals 1