summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/analysis/IndexSimpleVerifier.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/cuchaz/enigma/analysis/IndexSimpleVerifier.java')
-rw-r--r--src/main/java/cuchaz/enigma/analysis/IndexSimpleVerifier.java154
1 files changed, 0 insertions, 154 deletions
diff --git a/src/main/java/cuchaz/enigma/analysis/IndexSimpleVerifier.java b/src/main/java/cuchaz/enigma/analysis/IndexSimpleVerifier.java
deleted file mode 100644
index 80a7154..0000000
--- a/src/main/java/cuchaz/enigma/analysis/IndexSimpleVerifier.java
+++ /dev/null
@@ -1,154 +0,0 @@
1package cuchaz.enigma.analysis;
2
3import cuchaz.enigma.analysis.index.EntryIndex;
4import cuchaz.enigma.analysis.index.InheritanceIndex;
5import cuchaz.enigma.translation.representation.AccessFlags;
6import cuchaz.enigma.translation.representation.entry.ClassDefEntry;
7import cuchaz.enigma.translation.representation.entry.ClassEntry;
8import cuchaz.enigma.utils.Utils;
9import org.objectweb.asm.Type;
10import org.objectweb.asm.tree.analysis.BasicValue;
11import org.objectweb.asm.tree.analysis.SimpleVerifier;
12
13import java.util.Set;
14
15public class IndexSimpleVerifier extends SimpleVerifier {
16 private static final Type OBJECT_TYPE = Type.getType("Ljava/lang/Object;");
17 private final EntryIndex entryIndex;
18 private final InheritanceIndex inheritanceIndex;
19
20 public IndexSimpleVerifier(EntryIndex entryIndex, InheritanceIndex inheritanceIndex) {
21 super(Utils.ASM_VERSION, null, null, null, false);
22 this.entryIndex = entryIndex;
23 this.inheritanceIndex = inheritanceIndex;
24 }
25
26 @Override
27 protected boolean isSubTypeOf(BasicValue value, BasicValue expected) {
28 Type expectedType = expected.getType();
29 Type type = value.getType();
30 switch (expectedType.getSort()) {
31 case Type.INT:
32 case Type.FLOAT:
33 case Type.LONG:
34 case Type.DOUBLE:
35 return type.equals(expectedType);
36 case Type.ARRAY:
37 case Type.OBJECT:
38 if (type.equals(NULL_TYPE)) {
39 return true;
40 } else if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
41 if (isAssignableFrom(expectedType, type)) {
42 return true;
43 } else if (isInterface(expectedType)) {
44 return isAssignableFrom(OBJECT_TYPE, type);
45 } else {
46 return false;
47 }
48 } else {
49 return false;
50 }
51 default:
52 throw new AssertionError();
53 }
54 }
55
56 @Override
57 protected boolean isInterface(Type type) {
58 AccessFlags classAccess = entryIndex.getClassAccess(new ClassEntry(type.getInternalName()));
59 if (classAccess != null) {
60 return classAccess.isInterface();
61 }
62
63 Class<?> clazz = getClass(type);
64 if (clazz != null) {
65 return clazz.isInterface();
66 }
67
68 return false;
69 }
70
71 @Override
72 protected Type getSuperClass(Type type) {
73 ClassDefEntry definition = entryIndex.getDefinition(new ClassEntry(type.getInternalName()));
74 if (definition != null) {
75 return Type.getType('L' + definition.getSuperClass().getFullName() + ';');
76 }
77
78 Class<?> clazz = getClass(type);
79 if (clazz != null) {
80 return Type.getType(clazz.getSuperclass());
81 }
82
83 return OBJECT_TYPE;
84 }
85
86 @Override
87 protected boolean isAssignableFrom(Type type1, Type type2) {
88 if (type1.equals(type2)) {
89 return true;
90 }
91
92 if (type2.equals(NULL_TYPE)) {
93 return true;
94 }
95
96 if (type1.getSort() == Type.ARRAY) {
97 return type2.getSort() == Type.ARRAY && isAssignableFrom(Type.getType(type1.getDescriptor().substring(1)), Type.getType(type2.getDescriptor().substring(1)));
98 }
99
100 if (type2.getSort() == Type.ARRAY) {
101 return type1.equals(OBJECT_TYPE);
102 }
103
104 if (type1.getSort() == Type.OBJECT && type2.getSort() == Type.OBJECT) {
105 if (type1.equals(OBJECT_TYPE)) {
106 return true;
107 }
108
109 ClassEntry class1 = new ClassEntry(type1.getInternalName());
110 ClassEntry class2 = new ClassEntry(type2.getInternalName());
111
112 if (entryIndex.hasClass(class1) && entryIndex.hasClass(class2)) {
113 return inheritanceIndex.getAncestors(class2).contains(class1);
114 }
115
116 Class<?> class1Class = getClass(Type.getType('L' + class1.getFullName() + ';'));
117 Class<?> class2Class = getClass(Type.getType('L' + class2.getFullName() + ';'));
118
119 if (class1Class == null) {
120 return true; // missing classes to find out
121 }
122
123 if (class2Class != null) {
124 return class1Class.isAssignableFrom(class2Class);
125 }
126
127 if (entryIndex.hasClass(class2)) {
128 Set<ClassEntry> ancestors = inheritanceIndex.getAncestors(class2);
129
130 for (ClassEntry ancestorEntry : ancestors) {
131 Class<?> ancestor = getClass(Type.getType('L' + ancestorEntry.getFullName() + ';'));
132 if (ancestor == null || class1Class.isAssignableFrom(ancestor)) {
133 return true; // assignable, or missing classes to find out
134 }
135 }
136
137 return false;
138 }
139
140 return true; // missing classes to find out
141 }
142
143 return false;
144 }
145
146 @Override
147 protected final Class<?> getClass(Type type) {
148 try {
149 return Class.forName(type.getSort() == Type.ARRAY ? type.getDescriptor().replace('/', '.') : type.getClassName(), false, null);
150 } catch (ClassNotFoundException e) {
151 return null;
152 }
153 }
154}