From d410f8724042e6d341a5fdbaa1c835d377528775 Mon Sep 17 00:00:00 2001 From: Graham Date: Sat, 6 Jun 2020 15:59:15 +0100 Subject: [PATCH] Consider static and instance fields separately in FieldWriteAnalyzer This fixes a bug where fields could never become static if a class had a mixture of static and non-static fields and constructors. Signed-off-by: Graham --- .../dev/openrs2/deob/analysis/FieldWriteAnalyzer.kt | 11 +++++++++-- .../openrs2/deob/transform/FinalFieldTransformer.kt | 11 ++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/deob/src/main/java/dev/openrs2/deob/analysis/FieldWriteAnalyzer.kt b/deob/src/main/java/dev/openrs2/deob/analysis/FieldWriteAnalyzer.kt index 9d6d6310..6bf41fae 100644 --- a/deob/src/main/java/dev/openrs2/deob/analysis/FieldWriteAnalyzer.kt +++ b/deob/src/main/java/dev/openrs2/deob/analysis/FieldWriteAnalyzer.kt @@ -15,11 +15,16 @@ class FieldWriteAnalyzer( private val classPath: ClassPath, private val frames: Array> ) : DataFlowAnalyzer>(clazz.name, method) { + private val methodStatic = (method.access and Opcodes.ACC_STATIC) != 0 + override fun createEntrySet(): Map { val set = mutableMapOf() for (field in clazz.fields) { - set[MemberDesc(field)] = FieldWriteCount.NEVER + val fieldStatic = (field.access and Opcodes.ACC_STATIC) != 0 + if (methodStatic == fieldStatic) { + set[MemberDesc(field)] = FieldWriteCount.NEVER + } } return set @@ -60,7 +65,9 @@ class FieldWriteAnalyzer( ): Map { if (insn !is FieldInsnNode) { return set - } else if (insn.opcode != Opcodes.PUTFIELD && insn.opcode != Opcodes.PUTSTATIC) { + } else if (methodStatic && insn.opcode != Opcodes.PUTSTATIC) { + return set + } else if (!methodStatic && insn.opcode != Opcodes.PUTFIELD) { return set } diff --git a/deob/src/main/java/dev/openrs2/deob/transform/FinalFieldTransformer.kt b/deob/src/main/java/dev/openrs2/deob/transform/FinalFieldTransformer.kt index 4b6a5ebe..1e3df671 100644 --- a/deob/src/main/java/dev/openrs2/deob/transform/FinalFieldTransformer.kt +++ b/deob/src/main/java/dev/openrs2/deob/transform/FinalFieldTransformer.kt @@ -29,7 +29,8 @@ class FinalFieldTransformer : Transformer() { override fun transformCode(classPath: ClassPath, library: Library, clazz: ClassNode, method: MethodNode): Boolean { val constructor = method.name == "" || method.name == "" - val thisCall = if (constructor && method.name == "") { + val constructorStatic = (method.access and Opcodes.ACC_STATIC) != 0 + val thisCall = if (constructor && !constructorStatic) { method.instructions.filterIsInstance() .any { it.opcode == Opcodes.INVOKESPECIAL && it.owner == clazz.name && it.name == "" } } else { @@ -61,7 +62,8 @@ class FinalFieldTransformer : Transformer() { } val declaredOwner = classPath[insn.owner]!!.resolveField(MemberDesc(insn))!!.name - if (isThis && declaredOwner == clazz.name) { + val fieldStatic = insn.opcode == Opcodes.PUTSTATIC + if (isThis && declaredOwner == clazz.name && fieldStatic == constructorStatic) { /* * Writes inside constructors without a this(...) call to * fields owned by the same class are analyzed separately - if @@ -84,10 +86,9 @@ class FinalFieldTransformer : Transformer() { for (insn in exits) { val counts = analyzer.getOutSet(insn) ?: emptyMap() - for (field in clazz.fields) { - val count = counts.getOrDefault(MemberDesc(field), FieldWriteCount.NEVER) + for ((field, count) in counts) { if (count != FieldWriteCount.EXACTLY_ONCE) { - val partition = inheritedFieldSets[MemberRef(clazz, field)]!! + val partition = inheritedFieldSets[MemberRef(clazz.name, field)]!! nonFinalFields += partition } }