From 75f383a1956eb19fc838ea647a7e7b24552324cf Mon Sep 17 00:00:00 2001 From: gegy1000 Date: Fri, 10 May 2019 22:21:11 +0200 Subject: Don't remap specialized methods to their bridge partner in bytecode --- .../enigma/analysis/index/BridgeMethodIndex.java | 62 +++++++++++----------- .../cuchaz/enigma/analysis/index/EntryIndex.java | 12 ----- .../enigma/analysis/index/ReferenceIndex.java | 24 +-------- 3 files changed, 33 insertions(+), 65 deletions(-) (limited to 'src/main/java/cuchaz/enigma/analysis') diff --git a/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java b/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java index 649ce25..8a9b459 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/BridgeMethodIndex.java @@ -17,8 +17,8 @@ public class BridgeMethodIndex implements JarIndexer { private final InheritanceIndex inheritanceIndex; private final ReferenceIndex referenceIndex; - private final Set bridgeMethods = Sets.newHashSet(); - private final Map accessedToBridge = Maps.newHashMap(); + private final Set bridgeToSpecialized = Sets.newHashSet(); + private final Map specializedToBridge = Maps.newHashMap(); public BridgeMethodIndex(EntryIndex entryIndex, InheritanceIndex inheritanceIndex, ReferenceIndex referenceIndex) { this.entryIndex = entryIndex; @@ -42,34 +42,34 @@ public class BridgeMethodIndex implements JarIndexer { @Override public void processIndex(JarIndex index) { - Map copiedAccessToBridge = new HashMap<>(accessedToBridge); + Map copiedAccessToBridge = new HashMap<>(specializedToBridge); for (Map.Entry entry : copiedAccessToBridge.entrySet()) { - MethodEntry accessedEntry = entry.getKey(); + MethodEntry specializedEntry = entry.getKey(); MethodEntry bridgeEntry = entry.getValue(); - if (bridgeEntry.getName().equals(accessedEntry.getName())) { + if (bridgeEntry.getName().equals(specializedEntry.getName())) { continue; } - MethodEntry renamedAccessedEntry = accessedEntry.withName(bridgeEntry.getName()); - bridgeMethods.add(renamedAccessedEntry); - accessedToBridge.put(renamedAccessedEntry, accessedToBridge.get(accessedEntry)); + MethodEntry renamedSpecializedEntry = specializedEntry.withName(bridgeEntry.getName()); + bridgeToSpecialized.add(renamedSpecializedEntry); + specializedToBridge.put(renamedSpecializedEntry, specializedToBridge.get(specializedEntry)); } } private void indexSyntheticMethod(MethodDefEntry syntheticMethod, AccessFlags access) { - MethodEntry accessedMethod = findAccessMethod(syntheticMethod); - if (accessedMethod == null) { + MethodEntry specializedMethod = findSpecializedMethod(syntheticMethod); + if (specializedMethod == null) { return; } - if (access.isBridge() || isPotentialBridge(syntheticMethod, accessedMethod)) { - bridgeMethods.add(syntheticMethod); - accessedToBridge.put(accessedMethod, syntheticMethod); + if (access.isBridge() || isPotentialBridge(syntheticMethod, specializedMethod)) { + bridgeToSpecialized.add(syntheticMethod); + specializedToBridge.put(specializedMethod, syntheticMethod); } } - private MethodEntry findAccessMethod(MethodEntry method) { + private MethodEntry findSpecializedMethod(MethodEntry method) { // we want to find all compiler-added methods that directly call another with no processing // get all the methods that we call @@ -83,7 +83,7 @@ public class BridgeMethodIndex implements JarIndexer { return referencedMethods.stream().findFirst().orElse(null); } - private boolean isPotentialBridge(MethodDefEntry bridgeMethod, MethodEntry accessedMethod) { + private boolean isPotentialBridge(MethodDefEntry bridgeMethod, MethodEntry specializedMethod) { // Bridge methods only exist for inheritance purposes, if we're private, final, or static, we cannot be inherited AccessFlags bridgeAccess = bridgeMethod.getAccess(); if (bridgeAccess.isPrivate() || bridgeAccess.isFinal() || bridgeAccess.isStatic()) { @@ -91,35 +91,35 @@ public class BridgeMethodIndex implements JarIndexer { } MethodDescriptor bridgeDesc = bridgeMethod.getDesc(); - MethodDescriptor accessedDesc = accessedMethod.getDesc(); + MethodDescriptor specializedDesc = specializedMethod.getDesc(); List bridgeArguments = bridgeDesc.getArgumentDescs(); - List accessedArguments = accessedDesc.getArgumentDescs(); + List specializedArguments = specializedDesc.getArgumentDescs(); // A bridge method will always have the same number of arguments - if (bridgeArguments.size() != accessedArguments.size()) { + if (bridgeArguments.size() != specializedArguments.size()) { return false; } // Check that all argument types are bridge-compatible for (int i = 0; i < bridgeArguments.size(); i++) { - if (!areTypesBridgeCompatible(bridgeArguments.get(i), accessedArguments.get(i))) { + if (!areTypesBridgeCompatible(bridgeArguments.get(i), specializedArguments.get(i))) { return false; } } // Check that the return type is bridge-compatible - return areTypesBridgeCompatible(bridgeDesc.getReturnDesc(), accessedDesc.getReturnDesc()); + return areTypesBridgeCompatible(bridgeDesc.getReturnDesc(), specializedDesc.getReturnDesc()); } - private boolean areTypesBridgeCompatible(TypeDescriptor bridgeDesc, TypeDescriptor accessedDesc) { - if (bridgeDesc.equals(accessedDesc)) { + private boolean areTypesBridgeCompatible(TypeDescriptor bridgeDesc, TypeDescriptor specializedDesc) { + if (bridgeDesc.equals(specializedDesc)) { return true; } // Either the descs will be equal, or they are both types and different through a generic - if (bridgeDesc.isType() && accessedDesc.isType()) { + if (bridgeDesc.isType() && specializedDesc.isType()) { ClassEntry bridgeType = bridgeDesc.getTypeEntry(); - ClassEntry accessedType = accessedDesc.getTypeEntry(); + ClassEntry accessedType = specializedDesc.getTypeEntry(); // If the given types are completely unrelated to each other, this can't be bridge compatible InheritanceIndex.Relation relation = inheritanceIndex.computeClassRelation(accessedType, bridgeType); @@ -130,19 +130,19 @@ public class BridgeMethodIndex implements JarIndexer { } public boolean isBridgeMethod(MethodEntry entry) { - return bridgeMethods.contains(entry); + return bridgeToSpecialized.contains(entry); } - public boolean isAccessedByBridge(MethodEntry entry) { - return accessedToBridge.containsKey(entry); + public boolean isSpecializedMethod(MethodEntry entry) { + return specializedToBridge.containsKey(entry); } @Nullable - public MethodEntry getBridgeFromAccessed(MethodEntry entry) { - return accessedToBridge.get(entry); + public MethodEntry getBridgeFromSpecialized(MethodEntry specialized) { + return specializedToBridge.get(specialized); } - public Map getAccessedToBridge() { - return Collections.unmodifiableMap(accessedToBridge); + public Map getSpecializedToBridge() { + return Collections.unmodifiableMap(specializedToBridge); } } diff --git a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java index 645110a..773eaf1 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/EntryIndex.java @@ -28,18 +28,6 @@ public class EntryIndex implements JarIndexer { fields.put(fieldEntry, fieldEntry.getAccess()); } - @Override - public void processIndex(JarIndex index) { - Map accessedToBridge = index.getBridgeMethodIndex().getAccessedToBridge(); - for (Map.Entry entry : accessedToBridge.entrySet()) { - MethodEntry accessedEntry = entry.getKey(); - MethodEntry bridgeEntry = entry.getValue(); - - MethodEntry renamedAccessedEntry = accessedEntry.withName(bridgeEntry.getName()); - methods.put(renamedAccessedEntry, methods.remove(accessedEntry)); - } - } - public boolean hasClass(ClassEntry entry) { return classes.containsKey(entry); } diff --git a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java index ee28b3e..2b63c5d 100644 --- a/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java +++ b/src/main/java/cuchaz/enigma/analysis/index/ReferenceIndex.java @@ -8,7 +8,6 @@ import cuchaz.enigma.translation.representation.entry.*; import java.util.Collection; import java.util.Map; -import java.util.Optional; public class ReferenceIndex implements JarIndexer { private Multimap methodReferences = HashMultimap.create(); @@ -58,30 +57,11 @@ public class ReferenceIndex implements JarIndexer { } private > E remap(JarIndex index, E entry) { - E resolvedEntry = index.getEntryResolver().resolveFirstEntry(entry, ResolutionStrategy.RESOLVE_CLOSEST); - - Optional remappedBridge = getRemappedBridge(index, resolvedEntry); - return remappedBridge.orElse(resolvedEntry); + return index.getEntryResolver().resolveFirstEntry(entry, ResolutionStrategy.RESOLVE_CLOSEST); } private , C extends Entry> EntryReference remap(JarIndex index, EntryReference reference) { - EntryReference resolvedReference = index.getEntryResolver().resolveFirstReference(reference, ResolutionStrategy.RESOLVE_CLOSEST); - - getRemappedBridge(index, resolvedReference.entry).ifPresent(e -> resolvedReference.entry = e); - getRemappedBridge(index, resolvedReference.context).ifPresent(e -> resolvedReference.context = e); - - return resolvedReference; - } - - @SuppressWarnings("unchecked") - private > Optional getRemappedBridge(JarIndex index, E entry) { - if (entry instanceof MethodEntry) { - MethodEntry bridgeEntry = index.getBridgeMethodIndex().getBridgeFromAccessed((MethodEntry) entry); - if (bridgeEntry != null) { - return Optional.of((E) entry.withName(bridgeEntry.getName())); - } - } - return Optional.empty(); + return index.getEntryResolver().resolveFirstReference(reference, ResolutionStrategy.RESOLVE_CLOSEST); } public Collection getMethodsReferencedBy(MethodEntry entry) { -- cgit v1.2.3