summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar liach2021-07-03 05:34:39 -0500
committerGravatar GitHub2021-07-03 11:34:39 +0100
commit6046e132892c55081229b795f9ba68d32b681d82 (patch)
tree139313c7d2292c86e9a7f1b08c354e09a5736b40
parentRevert to shadow 5.2.0 for now because it breaks builds (diff)
downloadenigma-6046e132892c55081229b795f9ba68d32b681d82.tar.gz
enigma-6046e132892c55081229b795f9ba68d32b681d82.tar.xz
enigma-6046e132892c55081229b795f9ba68d32b681d82.zip
Update cfr and fixes a few related issues (#414)
* Update cfr and fixes a few related issues fixes #368 context for token references, missing some field and method references * Prevent crash when cfr fails to decompile a lambda and creates a fallback Signed-off-by: liach <liach@users.noreply.github.com> * Fix issue with parameters incorrectly spilling into other methods Signed-off-by: liach <liach@users.noreply.github.com> * try improve performance of cfr source Co-authored-by: liach <liach@users.noreply.github.com>
-rw-r--r--enigma/build.gradle2
-rw-r--r--enigma/src/main/java/cuchaz/enigma/source/cfr/CfrDecompiler.java3
-rw-r--r--enigma/src/main/java/cuchaz/enigma/source/cfr/CfrSource.java33
-rw-r--r--enigma/src/main/java/cuchaz/enigma/source/cfr/EnigmaDumper.java43
4 files changed, 51 insertions, 30 deletions
diff --git a/enigma/build.gradle b/enigma/build.gradle
index ec1c878c..1f53f461 100644
--- a/enigma/build.gradle
+++ b/enigma/build.gradle
@@ -9,7 +9,7 @@ dependencies {
9 implementation 'org.ow2.asm:asm-util:9.2' 9 implementation 'org.ow2.asm:asm-util:9.2'
10 10
11 implementation 'net.fabricmc:procyon-fabric-compilertools:0.5.35.13' 11 implementation 'net.fabricmc:procyon-fabric-compilertools:0.5.35.13'
12 implementation 'net.fabricmc:cfr:0.0.4' 12 implementation 'net.fabricmc:cfr:0.0.6'
13 13
14 proGuard 'com.guardsquare:proguard-base:7.1.0-beta5' 14 proGuard 'com.guardsquare:proguard-base:7.1.0-beta5'
15} 15}
diff --git a/enigma/src/main/java/cuchaz/enigma/source/cfr/CfrDecompiler.java b/enigma/src/main/java/cuchaz/enigma/source/cfr/CfrDecompiler.java
index ffc4788c..91fd5a27 100644
--- a/enigma/src/main/java/cuchaz/enigma/source/cfr/CfrDecompiler.java
+++ b/enigma/src/main/java/cuchaz/enigma/source/cfr/CfrDecompiler.java
@@ -24,7 +24,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
24import org.objectweb.asm.tree.ClassNode; 24import org.objectweb.asm.tree.ClassNode;
25 25
26import java.util.Collection; 26import java.util.Collection;
27import java.util.HashMap;
28import java.util.Map; 27import java.util.Map;
29 28
30public class CfrDecompiler implements Decompiler { 29public class CfrDecompiler implements Decompiler {
@@ -33,7 +32,7 @@ public class CfrDecompiler implements Decompiler {
33 private final SourceSettings settings; 32 private final SourceSettings settings;
34 33
35 public CfrDecompiler(ClassProvider classProvider, SourceSettings sourceSettings) { 34 public CfrDecompiler(ClassProvider classProvider, SourceSettings sourceSettings) {
36 Map<String, String> options = new HashMap<>(); 35 Map<String, String> options = Map.of("trackbytecodeloc", "true");
37 36
38 state = new DCCommonState(OptionsImpl.getFactory().create(options), new ClassFileSource2() { 37 state = new DCCommonState(OptionsImpl.getFactory().create(options), new ClassFileSource2() {
39 @Override 38 @Override
diff --git a/enigma/src/main/java/cuchaz/enigma/source/cfr/CfrSource.java b/enigma/src/main/java/cuchaz/enigma/source/cfr/CfrSource.java
index ba831d76..7c63afcc 100644
--- a/enigma/src/main/java/cuchaz/enigma/source/cfr/CfrSource.java
+++ b/enigma/src/main/java/cuchaz/enigma/source/cfr/CfrSource.java
@@ -13,11 +13,12 @@ import org.checkerframework.checker.nullness.qual.Nullable;
13public class CfrSource implements Source { 13public class CfrSource implements Source {
14 private final SourceSettings settings; 14 private final SourceSettings settings;
15 private final ClassFile tree; 15 private final ClassFile tree;
16 private final SourceIndex index;
17 private final String string;
18 private final DCCommonState state; 16 private final DCCommonState state;
19 private final TypeUsageInformation typeUsage; 17 private final TypeUsageInformation typeUsage;
20 private final Options options; 18 private final Options options;
19 private final EntryRemapper mapper;
20
21 private SourceIndex index;
21 22
22 public CfrSource(SourceSettings settings, ClassFile tree, DCCommonState state, TypeUsageInformation typeUsage, Options options, @Nullable EntryRemapper mapper) { 23 public CfrSource(SourceSettings settings, ClassFile tree, DCCommonState state, TypeUsageInformation typeUsage, Options options, @Nullable EntryRemapper mapper) {
23 this.settings = settings; 24 this.settings = settings;
@@ -25,16 +26,7 @@ public class CfrSource implements Source {
25 this.state = state; 26 this.state = state;
26 this.typeUsage = typeUsage; 27 this.typeUsage = typeUsage;
27 this.options = options; 28 this.options = options;
28 29 this.mapper = mapper;
29 EnigmaDumper dumper = new EnigmaDumper(new StringBuilder(), settings, typeUsage, options, mapper);
30 tree.dump(state.getObfuscationMapping().wrap(dumper));
31 index = dumper.getIndex();
32 string = dumper.getString();
33 }
34
35 @Override
36 public String asString() {
37 return string;
38 } 30 }
39 31
40 @Override 32 @Override
@@ -44,6 +36,23 @@ public class CfrSource implements Source {
44 36
45 @Override 37 @Override
46 public SourceIndex index() { 38 public SourceIndex index() {
39 ensureDecompiled();
47 return index; 40 return index;
48 } 41 }
42
43 @Override
44 public String asString() {
45 ensureDecompiled();
46 return index.getSource();
47 }
48
49 private synchronized void ensureDecompiled() {
50 if (index != null) {
51 return;
52 }
53
54 EnigmaDumper dumper = new EnigmaDumper(new StringBuilder(), settings, typeUsage, options, mapper);
55 tree.dump(state.getObfuscationMapping().wrap(dumper));
56 index = dumper.getIndex();
57 }
49} 58}
diff --git a/enigma/src/main/java/cuchaz/enigma/source/cfr/EnigmaDumper.java b/enigma/src/main/java/cuchaz/enigma/source/cfr/EnigmaDumper.java
index d0734c5e..b85851fa 100644
--- a/enigma/src/main/java/cuchaz/enigma/source/cfr/EnigmaDumper.java
+++ b/enigma/src/main/java/cuchaz/enigma/source/cfr/EnigmaDumper.java
@@ -12,17 +12,16 @@ import cuchaz.enigma.translation.representation.entry.Entry;
12import cuchaz.enigma.translation.representation.entry.FieldEntry; 12import cuchaz.enigma.translation.representation.entry.FieldEntry;
13import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; 13import cuchaz.enigma.translation.representation.entry.LocalVariableEntry;
14import cuchaz.enigma.translation.representation.entry.MethodEntry; 14import cuchaz.enigma.translation.representation.entry.MethodEntry;
15import org.benf.cfr.reader.bytecode.analysis.types.JavaArrayTypeInstance; 15import org.benf.cfr.reader.bytecode.analysis.loc.HasByteCodeLoc;
16import org.benf.cfr.reader.bytecode.analysis.types.JavaGenericBaseInstance;
17import org.benf.cfr.reader.bytecode.analysis.types.JavaRefTypeInstance; 16import org.benf.cfr.reader.bytecode.analysis.types.JavaRefTypeInstance;
18import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance; 17import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
19import org.benf.cfr.reader.bytecode.analysis.types.MethodPrototype; 18import org.benf.cfr.reader.bytecode.analysis.types.MethodPrototype;
20import org.benf.cfr.reader.bytecode.analysis.types.RawJavaType;
21import org.benf.cfr.reader.bytecode.analysis.variables.NamedVariable; 19import org.benf.cfr.reader.bytecode.analysis.variables.NamedVariable;
22import org.benf.cfr.reader.entities.AccessFlag; 20import org.benf.cfr.reader.entities.AccessFlag;
23import org.benf.cfr.reader.entities.ClassFile; 21import org.benf.cfr.reader.entities.ClassFile;
24import org.benf.cfr.reader.entities.ClassFileField; 22import org.benf.cfr.reader.entities.ClassFileField;
25import org.benf.cfr.reader.entities.Field; 23import org.benf.cfr.reader.entities.Field;
24import org.benf.cfr.reader.entities.Method;
26import org.benf.cfr.reader.state.TypeUsageInformation; 25import org.benf.cfr.reader.state.TypeUsageInformation;
27import org.benf.cfr.reader.util.getopt.Options; 26import org.benf.cfr.reader.util.getopt.Options;
28import org.benf.cfr.reader.util.output.Dumper; 27import org.benf.cfr.reader.util.output.Dumper;
@@ -49,6 +48,7 @@ public class EnigmaDumper extends StringStreamDumper {
49 private final TypeUsageInformation typeUsage; 48 private final TypeUsageInformation typeUsage;
50 private final MovableDumperContext dumperContext; 49 private final MovableDumperContext dumperContext;
51 private boolean muteLine = false; 50 private boolean muteLine = false;
51 private MethodEntry contextMethod = null;
52 52
53 public EnigmaDumper(StringBuilder sb, SourceSettings sourceSettings, TypeUsageInformation typeUsage, Options options, 53 public EnigmaDumper(StringBuilder sb, SourceSettings sourceSettings, TypeUsageInformation typeUsage, Options options,
54 @Nullable EntryRemapper mapper) { 54 @Nullable EntryRemapper mapper) {
@@ -68,18 +68,19 @@ public class EnigmaDumper extends StringStreamDumper {
68 } 68 }
69 69
70 private MethodEntry getMethodEntry(MethodPrototype method) { 70 private MethodEntry getMethodEntry(MethodPrototype method) {
71 if (method == null || method.getClassType() == null) { 71 if (method == null || method.getOwner() == null) {
72 return null; 72 return null;
73 } 73 }
74 74
75 MethodDescriptor desc = new MethodDescriptor(method.getOriginalDescriptor()); 75 MethodDescriptor desc = new MethodDescriptor(method.getOriginalDescriptor());
76 76
77 return new MethodEntry(getClassEntry(method.getClassType()), method.getName(), desc); 77 return new MethodEntry(getClassEntry(method.getOwner()), method.getName(), desc);
78 } 78 }
79 79
80 private LocalVariableEntry getParameterEntry(MethodPrototype method, int parameterIndex, String name) { 80 private LocalVariableEntry getParameterEntry(MethodPrototype method, int parameterIndex, String name) {
81 MethodEntry owner = getMethodEntry(method); 81 MethodEntry owner = getMethodEntry(method);
82 if (owner == null) { 82 // params may be not computed if cfr creates a lambda expression fallback, e.g. in PointOfInterestSet
83 if (owner == null || !method.parametersComputed()) {
83 return null; 84 return null;
84 } 85 }
85 86
@@ -253,7 +254,7 @@ public class EnigmaDumper extends StringStreamDumper {
253 if (defines) { 254 if (defines) {
254 index.addDeclaration(token, entry); // override as cfr reuses local vars 255 index.addDeclaration(token, entry); // override as cfr reuses local vars
255 } else { 256 } else {
256 index.addReference(token, entry, null); 257 index.addReference(token, entry, contextMethod);
257 } 258 }
258 } 259 }
259 260
@@ -276,7 +277,7 @@ public class EnigmaDumper extends StringStreamDumper {
276 if (defines) { 277 if (defines) {
277 this.index.addDeclaration(token, entry); 278 this.index.addDeclaration(token, entry);
278 } else { 279 } else {
279 this.index.addReference(token, entry, null); 280 this.index.addReference(token, entry, contextMethod);
280 } 281 }
281 } 282 }
282 283
@@ -293,27 +294,31 @@ public class EnigmaDumper extends StringStreamDumper {
293 public Dumper identifier(String name, Object ref, boolean defines) { 294 public Dumper identifier(String name, Object ref, boolean defines) {
294 super.identifier(name, ref, defines); 295 super.identifier(name, ref, defines);
295 Entry<?> entry; 296 Entry<?> entry;
297 if (defines) {
298 refs.remove(ref);
299 return this;
300 }
296 if ((entry = refs.get(ref)) == null) { 301 if ((entry = refs.get(ref)) == null) {
297 return this; 302 return this;
298 } 303 }
299 int now = sb.length(); 304 int now = sb.length();
300 Token token = new Token(now - name.length(), now, name); 305 Token token = new Token(now - name.length(), now, name);
301 index.addReference(token, entry, null); 306 index.addReference(token, entry, contextMethod);
302 return this; 307 return this;
303 } 308 }
304 309
305 @Override 310 @Override
306 public Dumper fieldName(String name, Field field, JavaTypeInstance owner, boolean hiddenDeclaration, boolean defines) { 311 public Dumper fieldName(String name, String descriptor, JavaTypeInstance owner, boolean hiddenDeclaration, boolean isStatic, boolean defines) {
307 super.fieldName(name, field, owner, hiddenDeclaration, defines); 312 super.fieldName(name, descriptor, owner, hiddenDeclaration, isStatic, defines);
308 int now = sb.length(); 313 int now = sb.length();
309 Token token = new Token(now - name.length(), now, name); 314 Token token = new Token(now - name.length(), now, name);
310 Entry<?> entry = field == null ? null : getFieldEntry(owner, name, field.getDescriptor()); 315 if (descriptor != null) {
316 Entry<?> entry = getFieldEntry(owner, name, descriptor);
311 317
312 if (entry != null) {
313 if (defines) { 318 if (defines) {
314 index.addDeclaration(token, entry); 319 index.addDeclaration(token, entry);
315 } else { 320 } else {
316 index.addReference(token, entry, null); 321 index.addReference(token, entry, contextMethod);
317 } 322 }
318 } 323 }
319 324
@@ -348,7 +353,7 @@ public class EnigmaDumper extends StringStreamDumper {
348 if (defines) { 353 if (defines) {
349 index.addDeclaration(token, getClassEntry(type)); 354 index.addDeclaration(token, getClassEntry(type));
350 } else { 355 } else {
351 index.addReference(token, getClassEntry(type), null); 356 index.addReference(token, getClassEntry(type), contextMethod);
352 } 357 }
353 return; 358 return;
354 } 359 }
@@ -367,6 +372,14 @@ public class EnigmaDumper extends StringStreamDumper {
367 return new EnigmaDumper(this.sb, sourceSettings, innerclassTypeUsageInformation, options, mapper, index, dumperContext); 372 return new EnigmaDumper(this.sb, sourceSettings, innerclassTypeUsageInformation, options, mapper, index, dumperContext);
368 } 373 }
369 374
375 @Override
376 public void informBytecodeLoc(HasByteCodeLoc loc) {
377 Collection<Method> methods = loc.getLoc().getMethods();
378 if (!methods.isEmpty()) {
379 this.contextMethod = getMethodEntry(methods.iterator().next().getMethodPrototype());
380 }
381 }
382
370 public SourceIndex getIndex() { 383 public SourceIndex getIndex() {
371 index.setSource(getString()); 384 index.setSource(getString());
372 return index; 385 return index;