) ((Iterable>) this.branches))) {
+ BranchHandle branchHandle = (BranchHandle) this.branch_map.get(branchInstruction);
+ int position = branchHandle.getPosition();
+ String text = "" + branchInstruction.getText() + "_" + position;
+ int position2 = branchHandle.getTarget().getPosition();
+ this._out.println(" " + text + ".setTarget(ih_" + position2 + ");");
+ if (branchInstruction instanceof Select) {
+ InstructionHandle[] targets = ((Select) branchInstruction).getTargets();
+ int value;
+ for (int value2 = value = 0; value2 < targets.length; value2 = value) {
+ int position3 = targets[value].getPosition();
+ PrintWriter printWriter = this._out;
+ StringBuilder stringBuilder =
+ new StringBuilder()
+ .insert(0, " ")
+ .append(text)
+ .append(".setTarget(")
+ .append(value)
+ .append(", ih_")
+ .append(position3);
+ value++;
+ printWriter.println(stringBuilder.append((String) ");").toString());
+ }
+ }
+ }
+ }
+
+ @Override
+ public void visitRET(RET rET) {
+ this._out.println("il.append(new RET(" + rET.getIndex() + ")));");
+ }
+
+ public void updateExceptionHandlers() {
+ CodeExceptionGen[] exceptionHandlers = this._mg.getExceptionHandlers();
+ int value;
+ for (int value2 = value = 0; value2 < exceptionHandlers.length; value2 = value) {
+ CodeExceptionGen codeExceptionGen;
+ String text =
+ (codeExceptionGen = exceptionHandlers[value]).getCatchType() == null
+ ? "null"
+ : BCELifier.printType(codeExceptionGen.getCatchType());
+ PrintWriter printWriter = this._out;
+ StringBuilder stringBuilder =
+ new StringBuilder()
+ .insert(0, " method.addExceptionHandler(ih_")
+ .append(codeExceptionGen.getInstructionHandle2().getPosition())
+ .append(", ")
+ .append("ih_")
+ .append(codeExceptionGen.getInstructionHandle().getPosition())
+ .append(", ")
+ .append("ih_")
+ .append(codeExceptionGen.getInstructionHandle3().getPosition())
+ .append(", ")
+ .append(text);
+ value++;
+ printWriter.println(stringBuilder.append((String) ");").toString());
+ }
+ }
+
+ @Override
+ public void visitINSTANCEOF(INSTANCEOF nSTANCEOF) {
+ Type type = nSTANCEOF.getType(this._cp);
+ this._out.println(
+ "il.append(new INSTANCEOF(_cp.addClass(" + BCELifier.printType(type) + ")));");
+ }
+
+ @Override
+ public void visitArrayInstruction(ArrayInstruction arrayInstruction) {
+ short opcode = arrayInstruction.getOpcode();
+ Type type = arrayInstruction.getType(this._cp);
+ String text = opcode < 79 ? "Load" : "Store";
+ this._out.println(
+ "il.append(_factory.createArray" + text + "(" + BCELifier.printType(type) + "));");
+ }
+
+ @Override
+ public void visitBranchInstruction(BranchInstruction branchInstruction) {
+ BranchHandle branchHandle;
+ int position =
+ (branchHandle = (BranchHandle) this.branch_map.get(branchInstruction)).getPosition();
+ String text = "" + branchInstruction.getText() + "_" + position;
+ BranchHandle branchHandle2;
+ if (branchInstruction instanceof Select) {
+ Select select = (Select) branchInstruction;
+ this.branches.add(branchInstruction);
+ StringBuffer stringBuffer = new StringBuffer("new int[] { ");
+ int[] match = select.getMatch();
+ int value = 0;
+ for (int value2 = value; value2 < match.length; value2 = ++value) {
+ stringBuffer.append(match[value]);
+ if (value < match.length - 1) {
+ stringBuffer.append(", ");
+ }
+ }
+ stringBuffer.append(" }");
+ this._out.print(
+ "Select "
+ + text
+ + " = new "
+ + branchInstruction.getText().toUpperCase(Locale.ENGLISH)
+ + "("
+ + ((Object) stringBuffer)
+ + ", new InstructionHandle[] { ");
+ int value3 = 0;
+ for (int value4 = value3; value4 < match.length; value4 = ++value3) {
+ this._out.print("null");
+ if (value3 < match.length - 1) {
+ this._out.print(", ");
+ }
+ }
+ this._out.println(" }, null);");
+ branchHandle2 = branchHandle;
+ } else {
+ int position2 = branchHandle.getTarget().getPosition();
+ String text2;
+ BCELFactory bCELFactory;
+ if (position > position2) {
+ text2 = "ih_" + position2;
+ bCELFactory = this;
+ } else {
+ bCELFactory = this;
+ this.branches.add(branchInstruction);
+ text2 = "null";
+ }
+ bCELFactory._out.println(
+ " BranchInstruction "
+ + text
+ + " = _factory.createBranchInstruction("
+ + "Constants."
+ + branchInstruction.getText().toUpperCase(Locale.ENGLISH)
+ + ", "
+ + text2
+ + ");");
+ branchHandle2 = branchHandle;
+ }
+ if (branchHandle2.hasTargeters()) {
+ this._out.println(" ih_" + position + " = il.append(" + text + ");");
+ } else {
+ this._out.println(" il.append(" + text + ");");
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/BCELifier.java b/src/main/java/com/allatori/lib/bcel/util/BCELifier.java
new file mode 100644
index 0000000..365fcf3
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/BCELifier.java
@@ -0,0 +1,288 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.Constants;
+import com.allatori.lib.bcel.classfile.ClassParser;
+import com.allatori.lib.bcel.classfile.ConstantValue;
+import com.allatori.lib.bcel.classfile.EmptyVisitor;
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.classfile.Utility;
+import com.allatori.lib.bcel.generic.ArrayType;
+import com.allatori.lib.bcel.generic.ConstantPoolGen;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.generic.Type;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Locale;
+
+public class BCELifier extends EmptyVisitor {
+
+ public static final int FLAG_FOR_UNKNOWN = -1;
+
+ public PrintWriter _out;
+
+ public ConstantPoolGen _cp;
+
+ public static final int FLAG_FOR_CLASS = 0;
+
+ public JavaClass _clazz;
+
+ public static final int FLAG_FOR_METHOD = 1;
+
+ @Override
+ public void visitField(Field field) {
+ this._out.println();
+ this._out.println(
+ " field = new FieldGen("
+ + printFlags(field.getAccess_flags2())
+ + ", "
+ + printType(field.getText2())
+ + ", \""
+ + field.getText()
+ + "\", _cp);");
+ ConstantValue constantValue;
+ if ((constantValue = field.getConstantValue()) != null) {
+ String text = constantValue.toString();
+ this._out.println(" field.setInitValue(" + text + ")");
+ }
+ this._out.println(" _cg.addField(field.getField());");
+ }
+
+ @Override
+ public void visitMethod(Method method) {
+ MethodGen methodGen;
+ MethodGen methodGen2 = methodGen = new MethodGen(method, this._clazz.getText2(), this._cp);
+ Type returnType = methodGen2.getReturnType();
+ Type[] argumentTypes = methodGen2.getArgumentTypes();
+ this._out.println(" InstructionList il = new InstructionList();");
+ this._out.println(
+ " MethodGen method = new MethodGen("
+ + printFlags(method.getAccess_flags2(), 1)
+ + ", "
+ + printType(returnType)
+ + ", "
+ + printArgumentTypes(argumentTypes)
+ + ", "
+ + "new String[] { "
+ + Utility.printArray(methodGen.getArgumentNames(), false, true)
+ + " }, \""
+ + method.getText()
+ + "\", \""
+ + this._clazz.getText2()
+ + "\", il, _cp);");
+ this._out.println();
+ new BCELFactory(methodGen, this._out).start();
+ this._out.println(" method.setMaxStack();");
+ this._out.println(" method.setMaxLocals();");
+ this._out.println(" _cg.addMethod(method.getMethod());");
+ this._out.println(" il.dispose();");
+ }
+
+ public BCELifier(JavaClass javaClass, OutputStream outputStream) {
+ super();
+ this._clazz = javaClass;
+ this._out = new PrintWriter(outputStream);
+ this._cp = new ConstantPoolGen(this._clazz.getConstantPool());
+ }
+
+ public static String printType(Type type) {
+ return printType(type.getSignature());
+ }
+
+ public void start() {
+ this.visitJavaClass(this._clazz);
+ this._out.flush();
+ }
+
+ public static String printArgumentTypes(Type[] types) {
+ if (types.length == 0) {
+ return "Type.NO_ARGS";
+ }
+ StringBuffer stringBuffer = new StringBuffer();
+ int value;
+ for (int value2 = value = 0; value2 < types.length; value2 = ++value) {
+ stringBuffer.append(printType(types[value]));
+ if (value < types.length - 1) {
+ stringBuffer.append(", ");
+ }
+ }
+ return "new Type[] { " + stringBuffer.toString() + " }";
+ }
+
+ @Override
+ public void visitJavaClass(JavaClass javaClass) {
+ String text2 = javaClass.getText2();
+ String text5 = javaClass.getText5();
+ String text4 = javaClass.getText4();
+ String text = Utility.printArray(javaClass.getInterfaceNames(), false, true);
+ if (!"".equals(text4)) {
+ text2 = text2.substring(text4.length() + 1);
+ this._out.println("package " + text4 + ";");
+ this._out.println();
+ }
+ this._out.println("import org.apache.bcel.generic.*;");
+ this._out.println("import org.apache.bcel.classfile.*;");
+ this._out.println("import org.apache.bcel.*;");
+ this._out.println("import java.io.*;");
+ this._out.println();
+ this._out.println("public class " + text2 + "Creator implements Constants {");
+ this._out.println(" private InstructionFactory _factory;");
+ this._out.println(" private ConstantPoolGen _cp;");
+ this._out.println(" private ClassGen _cg;");
+ this._out.println();
+ this._out.println(" public " + text2 + "Creator() {");
+ this._out.println(
+ " _cg = new ClassGen(\""
+ + ("".equals(text4)
+ ? text2
+ : new StringBuilder().insert(0, text4).append(".").append(text2).toString())
+ + "\", \""
+ + text5
+ + "\", "
+ + "\""
+ + javaClass.getText()
+ + "\", "
+ + printFlags(javaClass.getAccess_flags2(), 0)
+ + ", "
+ + "new String[] { "
+ + text
+ + " });");
+ this._out.println();
+ this._out.println(" _cp = _cg.getConstantPool();");
+ this._out.println(" _factory = new InstructionFactory(_cg, _cp);");
+ this._out.println(" }");
+ this._out.println();
+ this.printCreate();
+ Field[] fields;
+ if ((fields = javaClass.getFields()).length > 0) {
+ int value = 0;
+ this._out.println(" private void createFields() {");
+ this._out.println(" FieldGen field;");
+ for (int index = 0; value < fields.length; value = index) {
+ int value2 = index;
+ Field[] fields2 = fields;
+ index++;
+ fields2[value2].accept(this);
+ }
+ this._out.println(" }");
+ this._out.println();
+ }
+ Method[] methods = javaClass.getMethods();
+ int value3;
+ for (int value4 = value3 = 0; value4 < methods.length; value4 = value3) {
+ this._out.println(" private void createMethod_" + value3 + "() {");
+ methods[value3].accept(this);
+ PrintWriter printWriter = this._out;
+ value3++;
+ printWriter.println((String) " }");
+ this._out.println();
+ }
+ this.printMain();
+ this._out.println("}");
+ }
+
+ public static void main(String[] texts) throws Exception {
+ JavaClass javaClass;
+ String text;
+ if ((javaClass = com.allatori.lib.bcel.Repository.lookupClass(text = texts[0])) == null) {
+ javaClass = new ClassParser(text).parse();
+ }
+ new BCELifier(javaClass, System.out).start();
+ }
+
+ public static String printFlags(int value) {
+ return printFlags(value, -1);
+ }
+
+ public void printCreate() {
+ this._out.println(" public void create(OutputStream out) throws IOException {");
+ if (this._clazz.getFields().length > 0) {
+ this._out.println(" createFields();");
+ }
+ Method[] methods = this._clazz.getMethods();
+ int value;
+ for (int value2 = value = 0; value2 < methods.length; value2 = value) {
+ PrintWriter printWriter = this._out;
+ StringBuilder stringBuilder =
+ new StringBuilder().insert(0, " createMethod_").append(value);
+ value++;
+ printWriter.println(stringBuilder.append((String) "();").toString());
+ }
+ this._out.println(" _cg.getJavaClass().dump(out);");
+ this._out.println(" }");
+ this._out.println();
+ }
+
+ public static String printType(String text) {
+ byte value;
+ Type type;
+ if ((value = (type = Type.getType(text)).getType()) <= 12) {
+ return "Type." + Constants.TEXTS[value].toUpperCase(Locale.ENGLISH);
+ } else if (type.toString().equals("java.lang.String")) {
+ return "Type.STRING";
+ } else if (type.toString().equals("java.lang.Object")) {
+ return "Type.OBJECT";
+ } else if (type.toString().equals("java.lang.StringBuffer")) {
+ return "Type.STRINGBUFFER";
+ } else if (type instanceof ArrayType) {
+ ArrayType arrayType = (ArrayType) type;
+ return "new ArrayType("
+ + printType(arrayType.getBasicType())
+ + ", "
+ + arrayType.getDimensions()
+ + ")";
+ } else {
+ return "new ObjectType(\"" + Utility.signatureToString(text, false) + "\")";
+ }
+ }
+
+ public void printMain() {
+ String text2 = this._clazz.getText2();
+ this._out.println(" public static void main(String[] args) throws Exception {");
+ this._out.println(" " + text2 + "Creator creator = new " + text2 + "Creator();");
+ this._out.println(" creator.create(new FileOutputStream(\"" + text2 + ".class\"));");
+ this._out.println(" }");
+ }
+
+ public static String printFlags(int value, int value2) {
+ if (value == 0) {
+ return "0";
+ }
+ StringBuffer stringBuffer = new StringBuffer();
+ int value3 = 0;
+ int value4;
+ for (int value5 = value4 = 1; value5 <= 16384; value5 = value4) {
+ label37:
+ {
+ if ((value & value4) != 0) {
+ if (value4 == 32 && value2 == 0) {
+ value5 = value4;
+ stringBuffer.append("ACC_SUPER | ");
+ break label37;
+ }
+ if (value4 == 64 && value2 == 1) {
+ value5 = value4;
+ stringBuffer.append("ACC_BRIDGE | ");
+ break label37;
+ }
+ if (value4 == 128 && value2 == 1) {
+ value5 = value4;
+ stringBuffer.append("ACC_VARARGS | ");
+ break label37;
+ }
+ stringBuffer
+ .append("ACC_")
+ .append(Constants.TEXTS9[value3].toUpperCase(Locale.ENGLISH))
+ .append(" | ");
+ }
+ value5 = value4;
+ }
+ int value6 = value5;
+ value3++;
+ value4 = value6 << (byte) 1;
+ }
+ String text = stringBuffer.toString();
+ return text.substring(0, text.length() - 3);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ByteSequence$ByteArrayStream.java b/src/main/java/com/allatori/lib/bcel/util/ByteSequence$ByteArrayStream.java
new file mode 100644
index 0000000..470b128
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ByteSequence$ByteArrayStream.java
@@ -0,0 +1,20 @@
+package com.allatori.lib.bcel.util;
+
+import java.io.ByteArrayInputStream;
+
+public final class ByteSequence$ByteArrayStream extends ByteArrayInputStream {
+
+ public final int getPosition() {
+ return this.pos;
+ }
+
+ public ByteSequence$ByteArrayStream(byte[] values) {
+ super(values);
+ }
+
+ public final void unreadByte() {
+ if (this.pos > 0) {
+ this.pos--;
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ByteSequence.java b/src/main/java/com/allatori/lib/bcel/util/ByteSequence.java
new file mode 100644
index 0000000..e06f456
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ByteSequence.java
@@ -0,0 +1,21 @@
+package com.allatori.lib.bcel.util;
+
+import java.io.DataInputStream;
+
+public final class ByteSequence extends DataInputStream {
+
+ public ByteSequence$ByteArrayStream byte_stream;
+
+ public final int getIndex() {
+ return this.byte_stream.getPosition();
+ }
+
+ public ByteSequence(byte[] values) {
+ super(new ByteSequence$ByteArrayStream(values));
+ this.byte_stream = (ByteSequence$ByteArrayStream) this.in;
+ }
+
+ public final void unreadByte() {
+ this.byte_stream.unreadByte();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/Class2HTML.java b/src/main/java/com/allatori/lib/bcel/util/Class2HTML.java
new file mode 100644
index 0000000..826d975
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/Class2HTML.java
@@ -0,0 +1,197 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.Constants;
+import com.allatori.lib.bcel.classfile.Attribute;
+import com.allatori.lib.bcel.classfile.ClassParser;
+import com.allatori.lib.bcel.classfile.ConstantPool;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.classfile.Utility;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+public class Class2HTML implements Constants {
+
+ public static String text;
+
+ public String dir;
+
+ public static ConstantPool constant_pool;
+
+ public static String text2;
+
+ public JavaClass java_class;
+
+ public static final String createText(String text) {
+ String text3 = Utility.getText(text);
+ String text4 = Utility.compactClassName(text3, text2 + ".", true);
+ int value = text.indexOf(91);
+ String text5 = text;
+ if (value > -1) {
+ text5 = text.substring(0, value);
+ }
+ return !text5.equals("int")
+ && !text5.equals("short")
+ && !text5.equals("boolean")
+ && !text5.equals("void")
+ && !text5.equals("char")
+ && !text5.equals("byte")
+ && !text5.equals("long")
+ && !text5.equals("double")
+ && !text5.equals("float")
+ ? ("" + text4 + "")
+ : ("" + text + "");
+ }
+
+ public void writeMainHTML(AttributeHTML attributeHTML) throws IOException {
+ PrintWriter printWriter =
+ new PrintWriter(new FileOutputStream(("" + this.dir + text + ".html")));
+ Attribute[] attributes = this.java_class.getAttributes();
+ int value = 0;
+ printWriter.println(
+ "\nDocumentation for "
+ + text
+ + ""
+ + "\n"
+ + "");
+ printWriter.close();
+ for (int index = 0; value < attributes.length; value = index) {
+ Attribute attribute = attributes[index];
+ StringBuilder stringBuilder = new StringBuilder().insert(0, "class");
+ int value2 = index;
+ index++;
+ attributeHTML.writeAttribute(attribute, stringBuilder.append(value2).toString());
+ }
+ }
+
+ public static String referenceClass(int value) {
+ String text3 = Utility.getText(constant_pool.createText(value, (byte) 7));
+ String text4 = Utility.compactClassName(text3, text2 + ".", true);
+ return "" + text4 + "";
+ }
+
+ public static String createText2(String text) {
+ StringBuffer stringBuffer = new StringBuffer();
+ try {
+ for (int index = 0; index < text.length(); index++) {
+ char value;
+ switch (value = text.charAt(index)) {
+ case '\n':
+ stringBuffer.append("\\n");
+ break;
+ case '\r':
+ stringBuffer.append("\\r");
+ break;
+ case '<':
+ stringBuffer.append("<");
+ break;
+ case '>':
+ stringBuffer.append(">");
+ break;
+ default:
+ stringBuffer.append(value);
+ }
+ }
+ } catch (StringIndexOutOfBoundsException stringIndexOutOfBoundsException) {
+ }
+ return stringBuffer.toString();
+ }
+
+ public Class2HTML(JavaClass javaClass, String dir) throws IOException {
+ Method[] methods = javaClass.getMethods();
+ this.java_class = javaClass;
+ this.dir = dir;
+ text = javaClass.getText2();
+ constant_pool = javaClass.getConstantPool();
+ int value;
+ if ((value = text.lastIndexOf(46)) > -1) {
+ text2 = text.substring(0, value);
+ } else {
+ text2 = "";
+ }
+ ConstantHTML constantHTML = new ConstantHTML(dir, text, text2, methods, constant_pool);
+ AttributeHTML attributeHTML = new AttributeHTML(dir, text, constant_pool, constantHTML);
+ new MethodHTML(dir, text, methods, javaClass.getFields(), constantHTML, attributeHTML);
+ this.writeMainHTML(attributeHTML);
+ new CodeHTML(dir, text, methods, constant_pool, constantHTML);
+ attributeHTML.close();
+ }
+
+ public static void main(String[] texts) throws IOException {
+ String[] texts2 = new String[texts.length];
+ int value = 0;
+ String text = null;
+ char value2 = System.getProperty("file.separator").toCharArray()[0];
+ String text2 = "." + value2;
+ try {
+ int value3;
+ for (int value4 = value3 = 0; value4 < texts.length; value4 = ++value3) {
+ if (texts[value3].charAt(0) == '-') {
+ if (texts[value3].equals("-d")) {
+ text2 = texts[++value3];
+ if (!text2.endsWith("" + value2)) {
+ text2 = "" + text2 + value2;
+ }
+ new File(text2).mkdirs();
+ } else if (texts[value3].equals("-zip")) {
+ text = texts[++value3];
+ } else {
+ System.out.println("Unknown option " + texts[value3]);
+ }
+ } else {
+ int value5 = value3;
+ int value6 = value;
+ value++;
+ texts2[value6] = texts[value5];
+ }
+ }
+ if (value == 0) {
+ System.err.println("Class2HTML: No input files specified.");
+ return;
+ }
+ int value7 = 0;
+ while (value7 < value) {
+ System.out.print("Processing " + texts2[value7] + "...");
+ ClassParser classParser;
+ if (text == null) {
+ classParser = new ClassParser(texts2[value7]);
+ } else {
+ classParser = new ClassParser(text, texts2[value7]);
+ }
+ JavaClass javaClass = classParser.parse();
+ new Class2HTML(javaClass, text2);
+ PrintStream printStream = System.out;
+ value7++;
+ printStream.println("Done.");
+ }
+ } catch (Exception exception) {
+ System.out.println(exception);
+ exception.printStackTrace(System.out);
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassLoader.java b/src/main/java/com/allatori/lib/bcel/util/ClassLoader.java
new file mode 100644
index 0000000..a04d0aa
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassLoader.java
@@ -0,0 +1,120 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.classfile.ClassParser;
+import com.allatori.lib.bcel.classfile.ConstantClass;
+import com.allatori.lib.bcel.classfile.ConstantPool;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.classfile.Utility;
+import java.io.ByteArrayInputStream;
+import java.util.Hashtable;
+
+public class ClassLoader extends java.lang.ClassLoader {
+
+ public static final String[] DEFAULT_IGNORED_PACKAGES = new String[] {"java.", "javax.", "sun."};
+
+ public String[] ignored_packages;
+
+ public Hashtable classes;
+
+ public Repository repository;
+
+ public ClassLoader(java.lang.ClassLoader classLoader) {
+ super(classLoader);
+ this.classes = new Hashtable();
+ this.repository = SyntheticRepository.getInstance();
+ this.ignored_packages = DEFAULT_IGNORED_PACKAGES;
+ this.repository = new ClassLoaderRepository(classLoader);
+ }
+
+ @Override
+ public Class loadClass(String text, boolean matches) throws ClassNotFoundException {
+ boolean matches2;
+ Class classValue;
+ Class classValue2;
+ if ((classValue2 = (Class) this.classes.get(text)) == null) {
+ int value;
+ int value2 = value = 0;
+ while (true) {
+ if (value2 >= this.ignored_packages.length) {
+ classValue = classValue2;
+ break;
+ }
+ if (text.startsWith(this.ignored_packages[value])) {
+ classValue = classValue2 = this.getParent().loadClass(text);
+ break;
+ }
+ value2 = ++value;
+ }
+ label33:
+ {
+ if (classValue == null) {
+ JavaClass javaClass;
+ JavaClass javaClass2;
+ if (text.indexOf("$$BCEL$$") >= 0) {
+ javaClass2 = javaClass = this.createClass(text);
+ } else {
+ JavaClass javaClass3;
+ if ((javaClass3 = this.repository.getJavaClass2(text)) == null) {
+ throw new ClassNotFoundException(text);
+ }
+ javaClass2 = javaClass = this.modifyClass(javaClass3);
+ }
+ if (javaClass2 != null) {
+ byte[] bytes = javaClass.getBytes();
+ classValue2 = this.defineClass(text, bytes, 0, bytes.length);
+ matches2 = matches;
+ break label33;
+ }
+ classValue2 = Class.forName(text);
+ }
+ matches2 = matches;
+ }
+ if (matches2) {
+ this.resolveClass(classValue2);
+ }
+ }
+ this.classes.put(text, classValue2);
+ return classValue2;
+ }
+
+ public JavaClass createClass(String text) {
+ String text2 = text.substring(text.indexOf("$$BCEL$$") + 8);
+ JavaClass javaClass;
+ try {
+ byte[] values = Utility.decode(text2, true);
+ javaClass = new ClassParser(new ByteArrayInputStream(values), "foo").parse();
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
+ return null;
+ }
+ ConstantPool constantPool;
+ ConstantClass constantClass =
+ (ConstantClass)
+ (constantPool = javaClass.getConstantPool())
+ .getConstant(javaClass.getCount(), (byte) 7);
+ ((ConstantUtf8) constantPool.getConstant(constantClass.getNameIndex(), (byte) 1))
+ .setBytes(text.replace('.', '/'));
+ return javaClass;
+ }
+
+ public ClassLoader() {
+ this(DEFAULT_IGNORED_PACKAGES);
+ }
+
+ public ClassLoader(String[] texts) {
+ super();
+ this.classes = new Hashtable();
+ this.repository = SyntheticRepository.getInstance();
+ this.ignored_packages = texts;
+ }
+
+ public JavaClass modifyClass(JavaClass javaClass) {
+ return javaClass;
+ }
+
+ public ClassLoader(java.lang.ClassLoader classLoader, String[] texts) {
+ this(texts);
+ this.repository = new ClassLoaderRepository(classLoader);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassLoaderRepository.java b/src/main/java/com/allatori/lib/bcel/util/ClassLoaderRepository.java
new file mode 100644
index 0000000..8767ed0
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassLoaderRepository.java
@@ -0,0 +1,72 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.classfile.ClassParser;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ClassLoaderRepository implements Repository {
+
+ public Map loadedClasses;
+
+ public java.lang.ClassLoader loader;
+
+ @Override
+ public void processJavaClass2(JavaClass javaClass) {
+ this.loadedClasses.remove(javaClass.getText2());
+ }
+
+ @Override
+ public void processJavaClass(JavaClass javaClass) {
+ this.loadedClasses.put(javaClass.getText2(), javaClass);
+ javaClass.setRepository(this);
+ }
+
+ public ClassLoaderRepository(java.lang.ClassLoader classLoader) {
+ super();
+ this.loadedClasses = new HashMap();
+ this.loader = classLoader;
+ }
+
+ @Override
+ public ClassPath getClassPath() {
+ return null;
+ }
+
+ @Override
+ public JavaClass getJavaClass(String text) {
+ return this.loadedClasses.containsKey(text) ? (JavaClass) this.loadedClasses.get(text) : null;
+ }
+
+ @Override
+ public JavaClass loadClass(Class classValue) throws ClassNotFoundException {
+ return this.getJavaClass2(classValue.getName());
+ }
+
+ @Override
+ public JavaClass getJavaClass2(String text) throws ClassNotFoundException {
+ String text2 = text.replace('.', '/');
+ JavaClass javaClass;
+ if ((javaClass = this.getJavaClass(text)) != null) {
+ return javaClass;
+ }
+ try {
+ InputStream inputStream;
+ if ((inputStream = this.loader.getResourceAsStream("" + text2 + ".class")) == null) {
+ throw new ClassNotFoundException(("" + text + " not found."));
+ }
+ JavaClass javaClass2 = new ClassParser(inputStream, text).parse();
+ this.processJavaClass(javaClass2);
+ return javaClass2;
+ } catch (IOException oException) {
+ throw new ClassNotFoundException(oException.toString());
+ }
+ }
+
+ @Override
+ public void clear() {
+ this.loadedClasses.clear();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassPath$1.java b/src/main/java/com/allatori/lib/bcel/util/ClassPath$1.java
new file mode 100644
index 0000000..d8c9726
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassPath$1.java
@@ -0,0 +1,14 @@
+package com.allatori.lib.bcel.util;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.Locale;
+
+public class ClassPath$1 implements FilenameFilter {
+
+ @Override
+ public boolean accept(File file, String text) {
+ String text2;
+ return (text2 = text.toLowerCase(Locale.ENGLISH)).endsWith(".zip") || text2.endsWith(".jar");
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassPath$ClassFile.java b/src/main/java/com/allatori/lib/bcel/util/ClassPath$ClassFile.java
new file mode 100644
index 0000000..da4733d
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassPath$ClassFile.java
@@ -0,0 +1,17 @@
+package com.allatori.lib.bcel.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public interface ClassPath$ClassFile {
+
+ InputStream getInputStream() throws IOException;
+
+ String getText();
+
+ String getText2();
+
+ long calculateSeed();
+
+ long calculateSeed2();
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassPath$Dir$1.java b/src/main/java/com/allatori/lib/bcel/util/ClassPath$Dir$1.java
new file mode 100644
index 0000000..d25f876
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassPath$Dir$1.java
@@ -0,0 +1,49 @@
+package com.allatori.lib.bcel.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ClassPath$Dir$1 implements ClassPath$ClassFile {
+
+ public final File val$file;
+
+ public final ClassPath$Dir this$0;
+
+ @Override
+ public String getText() {
+ return ClassPath$Dir.access$100(this.this$0);
+ }
+
+ public ClassPath$Dir$1(ClassPath$Dir classPath$Dir, File file) throws FileNotFoundException {
+ super();
+ this.this$0 = classPath$Dir;
+ this.val$file = file;
+ }
+
+ @Override
+ public String getText2() {
+ try {
+ return this.val$file.getCanonicalPath();
+ } catch (IOException oException) {
+ return null;
+ }
+ }
+
+ @Override
+ public long calculateSeed2() {
+ return this.val$file.length();
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return new FileInputStream(this.val$file);
+ }
+
+ @Override
+ public long calculateSeed() {
+ return this.val$file.lastModified();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassPath$Dir.java b/src/main/java/com/allatori/lib/bcel/util/ClassPath$Dir.java
new file mode 100644
index 0000000..89d818e
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassPath$Dir.java
@@ -0,0 +1,59 @@
+package com.allatori.lib.bcel.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class ClassPath$Dir extends ClassPath$PathEntry {
+
+ public String dir;
+
+ @Override
+ public URL getResource(String text) {
+ File file =
+ new File(("" + this.dir + File.separatorChar + text.replace('/', File.separatorChar)));
+ try {
+ return file.exists() ? file.toURL() : null;
+ } catch (MalformedURLException malformedURLException) {
+ return null;
+ }
+ }
+
+ @Override
+ public ClassPath$ClassFile getClassFile(String text, String text2) throws IOException {
+ File file;
+ return (file =
+ new File(
+ (""
+ + this.dir
+ + File.separatorChar
+ + text.replace('.', File.separatorChar)
+ + text2)))
+ .exists()
+ ? new ClassPath$Dir$1(this, file)
+ : null;
+ }
+
+ @Override
+ public InputStream getResourceAsStream(String text) {
+ File file =
+ new File(("" + this.dir + File.separatorChar + text.replace('/', File.separatorChar)));
+ try {
+ return file.exists() ? new FileInputStream(file) : null;
+ } catch (IOException oException) {
+ return null;
+ }
+ }
+
+ public static String access$100(ClassPath$Dir classPath$Dir) {
+ return classPath$Dir.dir;
+ }
+
+ public ClassPath$Dir(String dir) {
+ super(null);
+ this.dir = dir;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassPath$PathEntry.java b/src/main/java/com/allatori/lib/bcel/util/ClassPath$PathEntry.java
new file mode 100644
index 0000000..ae1d949
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassPath$PathEntry.java
@@ -0,0 +1,21 @@
+package com.allatori.lib.bcel.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.net.URL;
+
+public abstract class ClassPath$PathEntry implements Serializable {
+
+ public ClassPath$PathEntry() {}
+
+ public ClassPath$PathEntry(ClassPath$1 classPath$1) {
+ this();
+ }
+
+ public abstract InputStream getResourceAsStream(String text);
+
+ public abstract ClassPath$ClassFile getClassFile(String text, String text2) throws IOException;
+
+ public abstract URL getResource(String text);
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassPath$Zip$1.java b/src/main/java/com/allatori/lib/bcel/util/ClassPath$Zip$1.java
new file mode 100644
index 0000000..cc65fef
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassPath$Zip$1.java
@@ -0,0 +1,43 @@
+package com.allatori.lib.bcel.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+
+public class ClassPath$Zip$1 implements ClassPath$ClassFile {
+
+ public final ZipEntry val$entry;
+
+ public final ClassPath$Zip this$0;
+
+ public ClassPath$Zip$1(ClassPath$Zip classPath$Zip, ZipEntry zipEntry) throws IOException {
+ super();
+ this.this$0 = classPath$Zip;
+ this.val$entry = zipEntry;
+ }
+
+ @Override
+ public String getText() {
+ return ClassPath$Zip.access$200(this.this$0).getName();
+ }
+
+ @Override
+ public String getText2() {
+ return this.val$entry.toString();
+ }
+
+ @Override
+ public long calculateSeed2() {
+ return this.val$entry.getSize();
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return ClassPath$Zip.access$200(this.this$0).getInputStream(this.val$entry);
+ }
+
+ @Override
+ public long calculateSeed() {
+ return this.val$entry.getTime();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassPath$Zip.java b/src/main/java/com/allatori/lib/bcel/util/ClassPath$Zip.java
new file mode 100644
index 0000000..be16b03
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassPath$Zip.java
@@ -0,0 +1,50 @@
+package com.allatori.lib.bcel.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+public class ClassPath$Zip extends ClassPath$PathEntry {
+
+ public ZipFile zip;
+
+ public ClassPath$Zip(ZipFile zipFile) {
+ super(null);
+ this.zip = zipFile;
+ }
+
+ @Override
+ public InputStream getResourceAsStream(String text) {
+ ZipEntry entry = this.zip.getEntry(text);
+ try {
+ return entry != null ? this.zip.getInputStream(entry) : null;
+ } catch (IOException oException) {
+ return null;
+ }
+ }
+
+ @Override
+ public URL getResource(String text) {
+ ZipEntry entry = this.zip.getEntry(text);
+ try {
+ return entry != null ? new URL(("jar:file:" + this.zip.getName() + "!/" + text)) : null;
+ } catch (MalformedURLException malformedURLException) {
+ return null;
+ }
+ }
+
+ @Override
+ public ClassPath$ClassFile getClassFile(String text, String text2) throws IOException {
+ ZipEntry zipEntry;
+ return (zipEntry = this.zip.getEntry("" + text.replace('.', '/') + text2)) == null
+ ? null
+ : new ClassPath$Zip$1(this, zipEntry);
+ }
+
+ public static ZipFile access$200(ClassPath$Zip classPath$Zip) {
+ return classPath$Zip.zip;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassPath.java b/src/main/java/com/allatori/lib/bcel/util/ClassPath.java
new file mode 100644
index 0000000..a41a4f3
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassPath.java
@@ -0,0 +1,215 @@
+package com.allatori.lib.bcel.util;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.zip.ZipFile;
+
+public class ClassPath implements Serializable {
+
+ public ClassPath$PathEntry[] paths;
+
+ public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath();
+
+ public String class_path;
+
+ @Override
+ public int hashCode() {
+ return this.class_path.hashCode();
+ }
+
+ public ClassPath(String class_path) {
+ this.class_path = class_path;
+ ArrayList values = new ArrayList();
+ StringTokenizer stringTokenizer =
+ new StringTokenizer(class_path, System.getProperty("path.separator"));
+ while (stringTokenizer.hasMoreTokens()) {
+ String text2;
+ if (!(text2 = stringTokenizer.nextToken()).equals("")) {
+ File file = new File(text2);
+ try {
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ values.add(new ClassPath$Dir(text2));
+ } else {
+ values.add(new ClassPath$Zip(new ZipFile(file)));
+ }
+ }
+ } catch (IOException oException) {
+ System.err.println("CLASSPATH component " + file + ": " + oException);
+ }
+ }
+ }
+ this.paths = new ClassPath$PathEntry[values.size()];
+ values.toArray(this.paths);
+ }
+
+ public static final void getPathComponents(String text, List values) {
+ if (text != null) {
+ StringTokenizer stringTokenizer = new StringTokenizer(text, File.pathSeparator);
+ while (stringTokenizer.hasMoreTokens()) {
+ String text2 = stringTokenizer.nextToken();
+ if (new File(text2).exists()) {
+ values.add(text2);
+ }
+ }
+ }
+ }
+
+ public byte[] getBytes(String text) throws IOException {
+ return this.getBytes(text, ".class");
+ }
+
+ public InputStream getInputStream(String text, String text2) throws IOException {
+ InputStream inputStream = null;
+ try {
+ inputStream = this.getClass().getClassLoader().getResourceAsStream("" + text + text2);
+ } catch (Exception exception) {
+ return inputStream != null ? inputStream : this.getClassFile(text, text2).getInputStream();
+ }
+ return inputStream != null ? inputStream : this.getClassFile(text, text2).getInputStream();
+ }
+
+ public byte[] getBytes(String text, String text2) throws IOException {
+ DataInputStream dataInputStream = null;
+ boolean matches = false;
+ byte[] values;
+ try {
+ matches = true;
+ InputStream inputStream;
+ if ((inputStream = this.getInputStream(text, text2)) == null) {
+ throw new IOException(("Couldn't find: " + text + text2));
+ }
+ dataInputStream = new DataInputStream(inputStream);
+ byte[] values2 = new byte[inputStream.available()];
+ dataInputStream.readFully(values2);
+ values = values2;
+ matches = false;
+ } finally {
+ if (matches) {
+ if (dataInputStream != null) {
+ dataInputStream.close();
+ }
+ }
+ }
+ dataInputStream.close();
+ return values;
+ }
+
+ public InputStream getInputStream(String text) throws IOException {
+ int value;
+ for (int value2 = value = 0; value2 < this.paths.length; value2 = ++value) {
+ InputStream inputStream;
+ if ((inputStream = this.paths[value].getResourceAsStream(text)) != null) {
+ return inputStream;
+ }
+ }
+ return null;
+ }
+
+ public InputStream getInputStream2(String text) throws IOException {
+ return this.getInputStream(text.replace('.', '/'), ".class");
+ }
+
+ public static final String getClassPath() {
+ String property = System.getProperty("java.class.path");
+ String property2 = System.getProperty("sun.boot.class.path");
+ String property3 = System.getProperty("java.ext.dirs");
+ ArrayList values = new ArrayList();
+ getPathComponents(property, values);
+ getPathComponents(property2, values);
+ ArrayList values2 = new ArrayList();
+ getPathComponents(property3, values2);
+ Iterator iterator2 = values2.iterator();
+ while (iterator2.hasNext()) {
+ File file = new File((String) iterator2.next());
+ int value;
+ String[] texts;
+ if ((texts = file.list(new ClassPath$1())) != null) {
+ for (int value2 = value = 0; value2 < texts.length; value2 = value) {
+ StringBuilder stringBuilder =
+ new StringBuilder().insert(0, file.getPath()).append(File.separatorChar);
+ String text = texts[value];
+ value++;
+ values.add(stringBuilder.append(text).toString());
+ }
+ }
+ }
+ StringBuffer stringBuffer = new StringBuffer();
+ Iterator iterator3 = values.iterator();
+ label23:
+ while (true) {
+ Iterator iterator4 = iterator3;
+ while (iterator4.hasNext()) {
+ stringBuffer.append((String) iterator3.next());
+ if (!iterator3.hasNext()) {
+ continue label23;
+ }
+ iterator4 = iterator3;
+ stringBuffer.append(File.pathSeparatorChar);
+ }
+ return stringBuffer.toString().intern();
+ }
+ }
+
+ public String getPath(String text) throws IOException {
+ int value = text.lastIndexOf(46);
+ String text2 = "";
+ if (value > 0) {
+ text2 = text.substring(value);
+ text = text.substring(0, value);
+ }
+ return this.getPath(text, text2);
+ }
+
+ public ClassPath$ClassFile getClassFile(String text) throws IOException {
+ return this.getClassFile(text, ".class");
+ }
+
+ public ClassPath$ClassFile getClassFile(String text, String text2) throws IOException {
+ int value;
+ for (int value2 = value = 0; value2 < this.paths.length; value2 = ++value) {
+ ClassPath$ClassFile classPath$ClassFile;
+ if ((classPath$ClassFile = this.paths[value].getClassFile(text, text2)) != null) {
+ return classPath$ClassFile;
+ }
+ }
+ throw new IOException(("Couldn't find: " + text + text2));
+ }
+
+ @Override
+ public boolean equals(Object result) {
+ return result instanceof ClassPath
+ ? this.class_path.equals(((ClassPath) result).class_path)
+ : false;
+ }
+
+ /**
+ * @deprecated
+ */
+ public ClassPath() {
+ this(getClassPath());
+ }
+
+ public URL getURL(String text) {
+ int value;
+ for (int value2 = value = 0; value2 < this.paths.length; value2 = ++value) {
+ URL uRL;
+ if ((uRL = this.paths[value].getResource(text)) != null) {
+ return uRL;
+ }
+ }
+ return null;
+ }
+
+ public String getPath(String text, String text2) throws IOException {
+ return this.getClassFile(text, text2).getText2();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassQueue.java b/src/main/java/com/allatori/lib/bcel/util/ClassQueue.java
new file mode 100644
index 0000000..d826978
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassQueue.java
@@ -0,0 +1,22 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.classfile.JavaClass;
+import java.io.Serializable;
+import java.util.LinkedList;
+
+public class ClassQueue implements Serializable {
+
+ public LinkedList vec = new LinkedList();
+
+ public boolean empty() {
+ return this.vec.isEmpty();
+ }
+
+ public JavaClass dequeue() {
+ return (JavaClass) this.vec.removeFirst();
+ }
+
+ public void enqueue(JavaClass javaClass) {
+ this.vec.addLast(javaClass);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassSet.java b/src/main/java/com/allatori/lib/bcel/util/ClassSet.java
new file mode 100644
index 0000000..30aa685
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassSet.java
@@ -0,0 +1,40 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.classfile.JavaClass;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ClassSet implements Serializable {
+
+ public Map _map = new HashMap();
+
+ public JavaClass[] toArray() {
+ Collection values2;
+ JavaClass[] javaClasss = new JavaClass[(values2 = this._map.values()).size()];
+ values2.toArray(javaClasss);
+ return javaClasss;
+ }
+
+ public boolean empty() {
+ return this._map.isEmpty();
+ }
+
+ public String[] getClassNames() {
+ return (String[]) this._map.keySet().toArray(new String[this._map.keySet().size()]);
+ }
+
+ public boolean add(JavaClass javaClass) {
+ byte value = 0;
+ if (!this._map.containsKey(javaClass.getText2())) {
+ value = 1;
+ this._map.put(javaClass.getText2(), javaClass);
+ }
+ return value != 0;
+ }
+
+ public void remove(JavaClass javaClass) {
+ this._map.remove(javaClass.getText2());
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassStack.java b/src/main/java/com/allatori/lib/bcel/util/ClassStack.java
new file mode 100644
index 0000000..6445898
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassStack.java
@@ -0,0 +1,26 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.classfile.JavaClass;
+import java.io.Serializable;
+import java.util.Stack;
+
+public class ClassStack implements Serializable {
+
+ public Stack stack = new Stack();
+
+ public JavaClass pop() {
+ return (JavaClass) this.stack.pop();
+ }
+
+ public void push(JavaClass javaClass) {
+ this.stack.push(javaClass);
+ }
+
+ public JavaClass top() {
+ return (JavaClass) this.stack.peek();
+ }
+
+ public boolean empty() {
+ return this.stack.empty();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ClassVector.java b/src/main/java/com/allatori/lib/bcel/util/ClassVector.java
new file mode 100644
index 0000000..acb9cbd
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ClassVector.java
@@ -0,0 +1,32 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.classfile.JavaClass;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @deprecated
+ */
+public class ClassVector implements Serializable {
+
+ public List vec = new ArrayList();
+
+ public void addElement(JavaClass javaClass) {
+ this.vec.add(javaClass);
+ }
+
+ public void removeElementAt(int value) {
+ this.vec.remove(value);
+ }
+
+ public JavaClass elementAt(int value) {
+ return (JavaClass) this.vec.get(value);
+ }
+
+ public JavaClass[] toArray() {
+ JavaClass[] javaClasss = new JavaClass[this.vec.size()];
+ this.vec.toArray(javaClasss);
+ return javaClasss;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/CodeHTML.java b/src/main/java/com/allatori/lib/bcel/util/CodeHTML.java
new file mode 100644
index 0000000..181233e
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/CodeHTML.java
@@ -0,0 +1,827 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.Constants;
+import com.allatori.lib.bcel.classfile.Attribute;
+import com.allatori.lib.bcel.classfile.Code;
+import com.allatori.lib.bcel.classfile.CodeException;
+import com.allatori.lib.bcel.classfile.ConstantFieldref;
+import com.allatori.lib.bcel.classfile.ConstantInterfaceMethodref;
+import com.allatori.lib.bcel.classfile.ConstantMethodref;
+import com.allatori.lib.bcel.classfile.ConstantNameAndType;
+import com.allatori.lib.bcel.classfile.ConstantPool;
+import com.allatori.lib.bcel.classfile.LocalVariable;
+import com.allatori.lib.bcel.classfile.LocalVariableTable;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.classfile.Utility;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.BitSet;
+
+public final class CodeHTML implements Constants {
+
+ public String class_name;
+
+ public Method[] methods;
+
+ public PrintWriter file;
+
+ public ConstantHTML constant_html;
+
+ public static boolean wide = false;
+
+ public ConstantPool constant_pool;
+
+ public BitSet goto_set;
+
+ public final String codeToHTML(ByteSequence byteSequence, int value) throws IOException {
+ short value2 = (short) byteSequence.readUnsignedByte();
+ int value3 = 0;
+ byte value4 = 0;
+ StringBuffer stringBuffer;
+ (stringBuffer = new StringBuffer(256))
+ .append("")
+ .append(TEXTS8[value2])
+ .append("");
+ if (value2 == 170 || value2 == 171) {
+ int value5;
+ value4 = (byte) ((value5 = byteSequence.getIndex() % 4) == 0 ? 0 : 4 - value5);
+ int value6;
+ for (int value7 = value6 = 0; value7 < value4; value7 = value6) {
+ value6++;
+ byteSequence.readByte();
+ }
+ value3 = byteSequence.readInt();
+ }
+ StringBuffer stringBuffer2;
+ switch (value2) {
+ case 18:
+ int value8 = byteSequence.readUnsignedByte();
+ stringBuffer2 = stringBuffer;
+ stringBuffer
+ .append("")
+ .append(
+ Class2HTML.createText2(
+ this.constant_pool.getText(
+ value8, this.constant_pool.getConstant(value8).getTag())))
+ .append("");
+ break;
+ case 19:
+ case 20:
+ short value9 = byteSequence.readShort();
+ stringBuffer2 = stringBuffer;
+ stringBuffer
+ .append("")
+ .append(
+ Class2HTML.createText2(
+ this.constant_pool.getText(
+ value9, this.constant_pool.getConstant(value9).getTag())))
+ .append("");
+ break;
+ case 21:
+ case 22:
+ case 23:
+ case 24:
+ case 25:
+ case 54:
+ case 55:
+ case 56:
+ case 57:
+ case 58:
+ case 169:
+ int value10;
+ if (wide) {
+ value10 = byteSequence.readShort();
+ wide = false;
+ stringBuffer2 = stringBuffer;
+ } else {
+ value10 = byteSequence.readUnsignedByte();
+ stringBuffer2 = stringBuffer;
+ }
+ stringBuffer2.append("%").append(value10);
+ stringBuffer2 = stringBuffer;
+ break;
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ case 30:
+ case 31:
+ case 32:
+ case 33:
+ case 34:
+ case 35:
+ case 36:
+ case 37:
+ case 38:
+ case 39:
+ case 40:
+ case 41:
+ case 42:
+ case 43:
+ case 44:
+ case 45:
+ case 46:
+ case 47:
+ case 48:
+ case 49:
+ case 50:
+ case 51:
+ case 52:
+ case 53:
+ case 59:
+ case 60:
+ case 61:
+ case 62:
+ case 63:
+ case 64:
+ case 65:
+ case 66:
+ case 67:
+ case 68:
+ case 69:
+ case 70:
+ case 71:
+ case 72:
+ case 73:
+ case 74:
+ case 75:
+ case 76:
+ case 77:
+ case 78:
+ case 79:
+ case 80:
+ case 81:
+ case 82:
+ case 83:
+ case 84:
+ case 85:
+ case 86:
+ case 87:
+ case 88:
+ case 89:
+ case 90:
+ case 91:
+ case 92:
+ case 93:
+ case 94:
+ case 95:
+ case 96:
+ case 97:
+ case 98:
+ case 99:
+ case 100:
+ case 101:
+ case 102:
+ case 103:
+ case 104:
+ case 105:
+ case 106:
+ case 107:
+ case 108:
+ case 109:
+ case 110:
+ case 111:
+ case 112:
+ case 113:
+ case 114:
+ case 115:
+ case 116:
+ case 117:
+ case 118:
+ case 119:
+ case 120:
+ case 121:
+ case 122:
+ case 123:
+ case 124:
+ case 125:
+ case 126:
+ case 127:
+ case 128:
+ case 129:
+ case 130:
+ case 131:
+ case 133:
+ case 134:
+ case 135:
+ case 136:
+ case 137:
+ case 138:
+ case 139:
+ case 140:
+ case 141:
+ case 142:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ case 147:
+ case 148:
+ case 149:
+ case 150:
+ case 151:
+ case 152:
+ case 172:
+ case 173:
+ case 174:
+ case 175:
+ case 176:
+ case 177:
+ case 186:
+ case 190:
+ case 191:
+ case 194:
+ case 195:
+ default:
+ int value11;
+ if (NO_OF_OPERANDS[value2] > 0) {
+ for (int value12 = value11 = 0;
+ value12 < TYPE_OF_OPERANDS[value2].length;
+ value12 = value11) {
+ switch (TYPE_OF_OPERANDS[value2][value11]) {
+ case 8:
+ stringBuffer2 = stringBuffer;
+ stringBuffer.append(byteSequence.readUnsignedByte());
+ break;
+ case 9:
+ stringBuffer2 = stringBuffer;
+ stringBuffer.append(byteSequence.readShort());
+ break;
+ case 10:
+ stringBuffer2 = stringBuffer;
+ stringBuffer.append(byteSequence.readInt());
+ break;
+ default:
+ System.err.println("Unreachable default case reached!");
+ System.exit(-1);
+ stringBuffer2 = stringBuffer;
+ }
+ StringBuffer stringBuffer3 = stringBuffer2;
+ value11++;
+ stringBuffer3.append(" ");
+ }
+ }
+ stringBuffer2 = stringBuffer;
+ break;
+ case 132:
+ int value13;
+ short value14;
+ if (wide) {
+ value13 = byteSequence.readShort();
+ stringBuffer2 = stringBuffer;
+ value14 = byteSequence.readShort();
+ wide = false;
+ } else {
+ value13 = byteSequence.readUnsignedByte();
+ stringBuffer2 = stringBuffer;
+ value14 = byteSequence.readByte();
+ }
+ stringBuffer2.append("%").append(value13).append(" ").append(value14);
+ stringBuffer2 = stringBuffer;
+ break;
+ case 153:
+ case 154:
+ case 155:
+ case 156:
+ case 157:
+ case 158:
+ case 159:
+ case 160:
+ case 161:
+ case 162:
+ case 163:
+ case 164:
+ case 165:
+ case 166:
+ case 167:
+ case 168:
+ case 198:
+ case 199:
+ int value15 = byteSequence.getIndex() + byteSequence.readShort() - 1;
+ stringBuffer2 = stringBuffer;
+ stringBuffer
+ .append("")
+ .append(value15)
+ .append("");
+ break;
+ case 170:
+ int value16 = byteSequence.readInt();
+ int value17 = byteSequence.readInt();
+ int value18 = byteSequence.getIndex() - 12 - value4 - 1;
+ int value19 = value3 + value18;
+ stringBuffer.append("");
+ int[] values = new int[value17 - value16 + 1];
+ int value20 = 0;
+ for (int value21 = value20; value21 < values.length; value21 = value20) {
+ values[value20] = value18 + byteSequence.readInt();
+ StringBuffer stringBuffer4 = stringBuffer.append("| ").append(value16 + value20);
+ value20++;
+ stringBuffer4.append(" | ");
+ }
+ stringBuffer.append("default | \n");
+ int value22 = 0;
+ for (int value23 = value22; value23 < values.length; value23 = value22) {
+ StringBuffer stringBuffer5 =
+ stringBuffer
+ .append("| ")
+ .append(values[value22]);
+ value22++;
+ stringBuffer5.append(" | ");
+ }
+ stringBuffer2 = stringBuffer;
+ stringBuffer
+ .append("")
+ .append(value19)
+ .append(" | \n \n");
+ break;
+ case 171:
+ int value24 = byteSequence.readInt();
+ int value25 = byteSequence.getIndex() - 8 - value4 - 1;
+ int[] values2 = new int[value24];
+ int value26 = value3 + value25;
+ stringBuffer.append("");
+ int value27 = 0;
+ for (int value28 = value27; value28 < value24; value28 = value27) {
+ int value29 = byteSequence.readInt();
+ values2[value27] = value25 + byteSequence.readInt();
+ StringBuffer stringBuffer6 = stringBuffer.append("| ").append(value29);
+ value27++;
+ stringBuffer6.append(" | ");
+ }
+ stringBuffer.append("default | \n");
+ int value30 = 0;
+ for (int value31 = value30; value31 < value24; value31 = value30) {
+ StringBuffer stringBuffer7 =
+ stringBuffer
+ .append("| ")
+ .append(values2[value30]);
+ value30++;
+ stringBuffer7.append(" | ");
+ }
+ stringBuffer2 = stringBuffer;
+ stringBuffer
+ .append("")
+ .append(value26)
+ .append(" | \n \n");
+ break;
+ case 178:
+ case 179:
+ case 180:
+ case 181:
+ short value32 = byteSequence.readShort();
+ ConstantFieldref constantFieldref =
+ (ConstantFieldref) this.constant_pool.getConstant(value32, (byte) 9);
+ int class_index = constantFieldref.getClass_index();
+ String text = Utility.getText(this.constant_pool.createText(class_index, (byte) 7), false);
+ int name_and_type_index = constantFieldref.getName_and_type_index();
+ String text2 = this.constant_pool.getText(name_and_type_index, (byte) 12);
+ if (text.equals(this.class_name)) {
+ stringBuffer
+ .append("")
+ .append(text2)
+ .append("\n");
+ stringBuffer2 = stringBuffer;
+ } else {
+ stringBuffer
+ .append(this.constant_html.referenceConstant(class_index))
+ .append(".")
+ .append(text2);
+ stringBuffer2 = stringBuffer;
+ }
+ break;
+ case 182:
+ case 183:
+ case 184:
+ case 185:
+ short value33 = byteSequence.readShort();
+ int value34;
+ int value35;
+ if (value2 == 185) {
+ byteSequence.readUnsignedByte();
+ byteSequence.readUnsignedByte();
+ ConstantInterfaceMethodref constantInterfaceMethodref =
+ (ConstantInterfaceMethodref) this.constant_pool.getConstant(value33, (byte) 11);
+ int class_index2 = constantInterfaceMethodref.getClass_index();
+ this.constant_pool.constantToString(constantInterfaceMethodref);
+ value34 = constantInterfaceMethodref.getName_and_type_index();
+ value35 = class_index2;
+ } else {
+ ConstantMethodref constantMethodref =
+ (ConstantMethodref) this.constant_pool.getConstant(value33, (byte) 10);
+ int class_index3 = constantMethodref.getClass_index();
+ this.constant_pool.constantToString(constantMethodref);
+ value34 = constantMethodref.getName_and_type_index();
+ value35 = class_index3;
+ }
+ String text3 = Class2HTML.referenceClass(value35);
+ String text4 =
+ Class2HTML.createText2(
+ this.constant_pool.constantToString(
+ this.constant_pool.getConstant(value34, (byte) 12)));
+ ConstantNameAndType constantNameAndType =
+ (ConstantNameAndType) this.constant_pool.getConstant(value34, (byte) 12);
+ String text5 =
+ this.constant_pool.getText(constantNameAndType.getSignature_index(), (byte) 1);
+ String[] texts = Utility.methodSignatureArgumentTypes(text5, false);
+ String text6 = Utility.createText(text5, false);
+ stringBuffer
+ .append(text3)
+ .append(".")
+ .append(text4)
+ .append("")
+ .append("(");
+ int value36 = 0;
+ for (int value37 = value36; value37 < texts.length; value37 = ++value36) {
+ stringBuffer.append(Class2HTML.createText(texts[value36]));
+ if (value36 < texts.length - 1) {
+ stringBuffer.append(", ");
+ }
+ }
+ stringBuffer2 = stringBuffer;
+ stringBuffer.append("):").append(Class2HTML.createText(text6));
+ break;
+ case 187:
+ case 192:
+ case 193:
+ short value38 = byteSequence.readShort();
+ stringBuffer2 = stringBuffer;
+ stringBuffer.append(this.constant_html.referenceConstant(value38));
+ break;
+ case 188:
+ stringBuffer2 = stringBuffer;
+ stringBuffer
+ .append("")
+ .append(TEXTS[byteSequence.readByte()])
+ .append("");
+ break;
+ case 189:
+ short value39 = byteSequence.readShort();
+ stringBuffer2 = stringBuffer;
+ stringBuffer.append(this.constant_html.referenceConstant(value39));
+ break;
+ case 196:
+ wide = true;
+ stringBuffer2 = stringBuffer;
+ stringBuffer.append("(wide)");
+ break;
+ case 197:
+ short value40 = byteSequence.readShort();
+ byte value41 = byteSequence.readByte();
+ stringBuffer2 = stringBuffer;
+ stringBuffer
+ .append(this.constant_html.referenceConstant(value40))
+ .append(":")
+ .append(value41)
+ .append("-dimensional");
+ break;
+ case 200:
+ case 201:
+ int value42 = byteSequence.getIndex() + byteSequence.readInt() - 1;
+ stringBuffer2 = stringBuffer;
+ stringBuffer
+ .append("")
+ .append(value42)
+ .append("");
+ }
+ stringBuffer2.append(" | ");
+ return stringBuffer.toString();
+ }
+
+ public void writeMethod(Method method, int value) throws IOException {
+ String text2 = method.getText2();
+ String[] texts = Utility.methodSignatureArgumentTypes(text2, false);
+ String text = Utility.createText(text2, false);
+ String text3 = Class2HTML.createText2(method.getText());
+ String text4 = Utility.replace(Utility.getText2(method.getAccess_flags2()), " ", " ");
+ Attribute[] attributes = method.getAttributes();
+ PrintWriter printWriter = this.file;
+ StringBuilder stringBuilder = new StringBuilder();
+ int value2 = 0;
+ printWriter.print(
+ stringBuilder
+ .insert(0, "")
+ .append(text4)
+ .append(" ")
+ .append("")
+ .append(Class2HTML.createText(text))
+ .append(" ")
+ .append(text3)
+ .append("(")
+ .toString());
+ for (int index = 0; value2 < texts.length; value2 = ++index) {
+ this.file.print(Class2HTML.createText(texts[index]));
+ if (index < texts.length - 1) {
+ this.file.print(", ");
+ }
+ }
+ this.file.println(")
");
+ Code code = null;
+ byte[] values = null;
+ if (attributes.length > 0) {
+ int value3 = 0;
+ this.file.print("Attributes
\n");
+ for (int index2 = 0; value3 < attributes.length; value3 = ++index2) {
+ byte value4;
+ byte value5;
+ if ((value4 = attributes[index2].getTag()) != -1) {
+ value5 = value4;
+ this.file.print(
+ "- "
+ + TEXTS4[value4]
+ + "
\n");
+ } else {
+ this.file.print("- " + attributes[index2] + "
");
+ value5 = value4;
+ }
+ if (value5 == 2) {
+ Code code2 = code = (Code) attributes[index2];
+ Attribute[] attributes2 = code2.getAttributes();
+ values = code2.getCode();
+ int value6 = 0;
+ this.file.print("");
+ }
+ }
+ this.file.println("
");
+ }
+ if (values != null) {
+ ByteSequence byteSequence = new ByteSequence(values);
+ ByteSequence byteSequence2 = byteSequence;
+ byteSequence.mark(byteSequence.available());
+ this.findGotos(byteSequence, method, code);
+ byteSequence.reset();
+ this.file.println(
+ "Byte offset | Instruction | Argument | ");
+ int value7 = 0;
+ while (byteSequence2.available() > 0) {
+ int index4 = byteSequence.getIndex();
+ String text5 = this.codeToHTML(byteSequence, value);
+ String text6 = "";
+ if (this.goto_set.get(index4)) {
+ text6 = "";
+ }
+ String text7;
+ CodeHTML codeHTML;
+ if (byteSequence.getIndex() == values.length) {
+ text7 = "" + index4 + "";
+ codeHTML = this;
+ } else {
+ text7 = "" + index4;
+ codeHTML = this;
+ }
+ printWriter = codeHTML.file;
+ StringBuilder stringBuilder3 =
+ new StringBuilder()
+ .insert(0, "
|---|
| ")
+ .append(text7)
+ .append(" | ")
+ .append(text6)
+ .append(text5);
+ PrintWriter printWriter3 = printWriter;
+ value7++;
+ printWriter3.println(stringBuilder3.append((String) " |
").toString());
+ byteSequence2 = byteSequence;
+ }
+ this.file.println("| |
");
+ this.file.println("
");
+ }
+ }
+
+ public final void findGotos(ByteSequence byteSequence, Method method, Code code)
+ throws IOException {
+ this.goto_set = new BitSet(byteSequence.available());
+ if (code != null) {
+ CodeException[] codeExceptions;
+ int value = (codeExceptions = code.getExceptionTable()).length;
+ int value2;
+ for (int value3 = value2 = 0; value3 < value; value3 = value2) {
+ this.goto_set.set(codeExceptions[value2].getStart_pc());
+ this.goto_set.set(codeExceptions[value2].getEnd_pc());
+ int value4 = value2;
+ CodeException[] codeExceptions2 = codeExceptions;
+ BitSet bitSet = this.goto_set;
+ value2++;
+ bitSet.set(codeExceptions2[value4].getHandler_pc());
+ }
+ Attribute[] attributes = code.getAttributes();
+ int value5;
+ for (int value6 = value5 = 0; value6 < attributes.length; value6 = ++value5) {
+ if (attributes[value5].getTag() == 5) {
+ LocalVariable[] localVariableTable =
+ ((LocalVariableTable) attributes[value5]).getLocalVariableTable();
+ int value7;
+ for (int value8 = value7 = 0; value8 < localVariableTable.length; value8 = value7) {
+ int value9;
+ int value10 =
+ (value9 = localVariableTable[value7].getStart_pc())
+ + localVariableTable[value7].getLength();
+ this.goto_set.set(value9);
+ value7++;
+ this.goto_set.set(value10);
+ }
+ break;
+ }
+ }
+ }
+ int value11 = 0;
+ for (ByteSequence byteSequence2 = byteSequence;
+ byteSequence2.available() > 0;
+ byteSequence2 = byteSequence) {
+ int value12;
+ switch (value12 = byteSequence.readUnsignedByte()) {
+ case 153:
+ case 154:
+ case 155:
+ case 156:
+ case 157:
+ case 158:
+ case 159:
+ case 160:
+ case 161:
+ case 162:
+ case 163:
+ case 164:
+ case 165:
+ case 166:
+ case 167:
+ case 168:
+ case 198:
+ case 199:
+ int value13 = byteSequence.getIndex() + byteSequence.readShort() - 1;
+ this.goto_set.set(value13);
+ break;
+ case 169:
+ case 172:
+ case 173:
+ case 174:
+ case 175:
+ case 176:
+ case 177:
+ case 178:
+ case 179:
+ case 180:
+ case 181:
+ case 182:
+ case 183:
+ case 184:
+ case 185:
+ case 186:
+ case 187:
+ case 188:
+ case 189:
+ case 190:
+ case 191:
+ case 192:
+ case 193:
+ case 194:
+ case 195:
+ case 196:
+ case 197:
+ default:
+ byteSequence.unreadByte();
+ this.codeToHTML(byteSequence, 0);
+ break;
+ case 170:
+ case 171:
+ int value14;
+ int value15 = (value14 = byteSequence.getIndex() % 4) == 0 ? 0 : 4 - value14;
+ int value16;
+ for (int value17 = value16 = 0; value17 < value15; value17 = value16) {
+ value16++;
+ byteSequence.readByte();
+ }
+ int value18 = byteSequence.readInt();
+ if (value12 == 170) {
+ int value19 = byteSequence.readInt();
+ int value20 = byteSequence.readInt();
+ int value21 = byteSequence.getIndex() - 12 - value15 - 1;
+ int value22 = value18 + value21;
+ this.goto_set.set(value22);
+ int value23;
+ for (int value24 = value23 = 0; value24 < value20 - value19 + 1; value24 = value23) {
+ int value25 = value21 + byteSequence.readInt();
+ value23++;
+ this.goto_set.set(value25);
+ }
+ } else {
+ int value26 = byteSequence.readInt();
+ int value27 = byteSequence.getIndex() - 8 - value15 - 1;
+ int value28 = value18 + value27;
+ int value29 = 0;
+ this.goto_set.set(value28);
+ for (int index = 0; value29 < value26; value29 = index) {
+ byteSequence.readInt();
+ int value30 = value27 + byteSequence.readInt();
+ index++;
+ this.goto_set.set(value30);
+ }
+ }
+ break;
+ case 200:
+ case 201:
+ int value31 = byteSequence.getIndex() + byteSequence.readInt() - 1;
+ this.goto_set.set(value31);
+ }
+ value11++;
+ }
+ }
+
+ public CodeHTML(
+ String text,
+ String class_name,
+ Method[] methods2,
+ ConstantPool constantPool,
+ ConstantHTML constantHTML)
+ throws IOException {
+ super();
+ int value = 0;
+ this.class_name = class_name;
+ this.methods = methods2;
+ this.constant_pool = constantPool;
+ this.constant_html = constantHTML;
+ this.file = new PrintWriter(new FileOutputStream(("" + text + class_name + "_code.html")));
+ this.file.println("");
+ for (int index = 0; value < methods2.length; value = index) {
+ Method method = methods2[index];
+ int value2 = index;
+ index++;
+ this.writeMethod(method, value2);
+ }
+ this.file.println("");
+ this.file.close();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/ConstantHTML.java b/src/main/java/com/allatori/lib/bcel/util/ConstantHTML.java
new file mode 100644
index 0000000..8279b31
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/ConstantHTML.java
@@ -0,0 +1,334 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.Constants;
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.classfile.ConstantClass;
+import com.allatori.lib.bcel.classfile.ConstantFieldref;
+import com.allatori.lib.bcel.classfile.ConstantInterfaceMethodref;
+import com.allatori.lib.bcel.classfile.ConstantMethodref;
+import com.allatori.lib.bcel.classfile.ConstantNameAndType;
+import com.allatori.lib.bcel.classfile.ConstantPool;
+import com.allatori.lib.bcel.classfile.ConstantString;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.classfile.Utility;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+public final class ConstantHTML implements Constants {
+
+ public PrintWriter file;
+
+ public String class_name;
+
+ public Method[] methods;
+
+ public String[] constant_ref;
+
+ public String class_package;
+
+ public ConstantPool constant_pool;
+
+ public Constant[] constants;
+
+ public String referenceConstant(int value) {
+ return this.constant_ref[value];
+ }
+
+ public final int getMethodNumber(String text) {
+ int value;
+ for (int value2 = value = 0; value2 < this.methods.length; value2 = ++value) {
+ if (("" + this.methods[value].getText() + this.methods[value].getText2()).equals(text)) {
+ return value;
+ }
+ }
+ return -1;
+ }
+
+ public ConstantHTML(
+ String text,
+ String class_name,
+ String class_package,
+ Method[] methods2,
+ ConstantPool constantPool)
+ throws IOException {
+ super();
+ this.class_name = class_name;
+ this.class_package = class_package;
+ this.constant_pool = constantPool;
+ this.methods = methods2;
+ this.constants = constantPool.getConstantPool();
+ this.file = new PrintWriter(new FileOutputStream(("" + text + class_name + "_cp.html")));
+ this.constant_ref = new String[this.constants.length];
+ int value = 1;
+ this.constant_ref[0] = "<unknown>";
+ this.file.println("");
+ for (int index = 1; value < this.constants.length; value = index) {
+ ConstantHTML constantHTML;
+ if (index % 2 == 0) {
+ constantHTML = this;
+ this.file.print("| ");
+ } else {
+ constantHTML = this;
+ this.file.print(" |
| ");
+ }
+ if (constantHTML.constants[index] != null) {
+ this.writeConstant(index);
+ }
+ PrintWriter printWriter = this.file;
+ index++;
+ printWriter.print(" |
\n");
+ }
+ this.file.println("
");
+ this.file.close();
+ }
+
+ public void writeConstant(int value) {
+ byte tag = this.constants[value].getTag();
+ this.file.println("");
+ switch (tag) {
+ case 7:
+ int nameIndex =
+ ((ConstantClass) this.constant_pool.getConstant(value, (byte) 7)).getNameIndex();
+ String text;
+ String text2 =
+ Utility.compactClassName(
+ Utility.getText(text = this.constant_pool.getText(value, tag)),
+ "" + this.class_package + ".",
+ true);
+ String text3 = "" + text2 + "";
+ this.constant_ref[value] =
+ ""
+ + text2
+ + "";
+ this.file.println(
+ ""
+ + text3
+ + "
\n");
+ return;
+ case 8:
+ int stringIndex =
+ ((ConstantString) this.constant_pool.getConstant(value, (byte) 8)).getStringIndex();
+ String text4 = Class2HTML.createText2(this.constant_pool.getText(value, tag));
+ this.file.println(
+ ""
+ + text4
+ + "
\n");
+ return;
+ case 9:
+ ConstantFieldref constantFieldref =
+ (ConstantFieldref) this.constant_pool.getConstant(value, (byte) 9);
+ int class_index = constantFieldref.getClass_index();
+ int name_and_type_index = constantFieldref.getName_and_type_index();
+ String text5;
+ String text6 =
+ Utility.compactClassName(
+ Utility.getText(text5 = this.constant_pool.getText(class_index, (byte) 7)),
+ "" + this.class_package + ".",
+ true);
+ String text7 = this.constant_pool.getText(name_and_type_index, (byte) 12);
+ boolean matches = text5.equals(this.class_name);
+ StringBuilder stringBuilder = new StringBuilder();
+ String text8;
+ ConstantHTML constantHTML;
+ if (matches) {
+ text8 =
+ stringBuilder
+ .insert(0, "")
+ .append(text7)
+ .append("")
+ .toString();
+ constantHTML = this;
+ } else {
+ text8 =
+ stringBuilder
+ .insert(0, "")
+ .append(text6)
+ .append(".")
+ .append(text7)
+ .append("\n")
+ .toString();
+ constantHTML = this;
+ }
+ constantHTML.constant_ref[value] =
+ ""
+ + text6
+ + "."
+ + text7
+ + "";
+ this.file.println(
+ ""
+ + text8
+ + "
\n"
+ + "
");
+ return;
+ case 10:
+ case 11:
+ int value2;
+ int value3;
+ ConstantHTML constantHTML2;
+ if (tag == 10) {
+ ConstantMethodref constantMethodref =
+ (ConstantMethodref) this.constant_pool.getConstant(value, (byte) 10);
+ constantHTML2 = this;
+ value3 = constantMethodref.getClass_index();
+ value2 = constantMethodref.getName_and_type_index();
+ } else {
+ ConstantInterfaceMethodref constantInterfaceMethodref =
+ (ConstantInterfaceMethodref) this.constant_pool.getConstant(value, (byte) 11);
+ constantHTML2 = this;
+ value3 = constantInterfaceMethodref.getClass_index();
+ value2 = constantInterfaceMethodref.getName_and_type_index();
+ }
+ String text9;
+ String text10 =
+ Class2HTML.createText2(text9 = constantHTML2.constant_pool.getText(value2, (byte) 12));
+ String text11;
+ String text12 = text11 = this.constant_pool.getText(value3, (byte) 7);
+ Utility.getText(text12);
+ String text13 = Utility.getText(text12);
+ String text14 = Utility.compactClassName(text13, this.class_package + ".", true);
+ ConstantNameAndType constantNameAndType =
+ (ConstantNameAndType) this.constant_pool.getConstant(value2, (byte) 12);
+ String text15;
+ String text16 =
+ text15 = this.constant_pool.getText(constantNameAndType.getSignature_index(), (byte) 1);
+ String[] texts = Utility.methodSignatureArgumentTypes(text16, false);
+ String text17 = Class2HTML.createText(Utility.createText(text16, false));
+ StringBuffer stringBuffer = new StringBuffer("(");
+ int value4;
+ for (int value5 = value4 = 0; value5 < texts.length; value5 = ++value4) {
+ stringBuffer.append(Class2HTML.createText(texts[value4]));
+ if (value4 < texts.length - 1) {
+ stringBuffer.append(", ");
+ }
+ }
+ stringBuffer.append(")");
+ String text18 = stringBuffer.toString();
+ boolean matches2 = text11.equals(this.class_name);
+ StringBuilder stringBuilder2 = new StringBuilder();
+ String text19;
+ if (matches2) {
+ text19 =
+ stringBuilder2
+ .insert(0, "")
+ .append(text10)
+ .append("")
+ .toString();
+ constantHTML2 = this;
+ } else {
+ text19 =
+ stringBuilder2
+ .insert(0, "")
+ .append(text14)
+ .append(".")
+ .append(text10)
+ .toString();
+ constantHTML2 = this;
+ }
+ constantHTML2.constant_ref[value] =
+ ""
+ + text17
+ + " "
+ + text14
+ + "."
+ + text10
+ + " "
+ + text18;
+ this.file.println(
+ ""
+ + text17
+ + " "
+ + text19
+ + text18
+ + " \n
");
+ return;
+ case 12:
+ ConstantNameAndType constantNameAndType2 =
+ (ConstantNameAndType) this.constant_pool.getConstant(value, (byte) 12);
+ int name_index = constantNameAndType2.getName_index();
+ int signature_index = constantNameAndType2.getSignature_index();
+ this.file.println(
+ ""
+ + Class2HTML.createText2(this.constant_pool.getText(value, tag))
+ + "
\n");
+ return;
+ default:
+ this.file.println(
+ "" + Class2HTML.createText2(this.constant_pool.getText(value, tag)) + "\n");
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/InstructionFinder$CodeConstraint.java b/src/main/java/com/allatori/lib/bcel/util/InstructionFinder$CodeConstraint.java
new file mode 100644
index 0000000..6fe6574
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/InstructionFinder$CodeConstraint.java
@@ -0,0 +1,8 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.generic.InstructionHandle;
+
+public interface InstructionFinder$CodeConstraint {
+
+ boolean checkCode(InstructionHandle[] instructionHandles);
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/InstructionFinder.java b/src/main/java/com/allatori/lib/bcel/util/InstructionFinder.java
new file mode 100644
index 0000000..b6cc5ef
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/InstructionFinder.java
@@ -0,0 +1,293 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.Constants;
+import com.allatori.lib.bcel.generic.ClassGenException;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.InstructionList;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class InstructionFinder {
+
+ public static final int OFFSET = 32767;
+
+ public static final int NO_OPCODES = 256;
+
+ public String il_string;
+
+ public static final Map map = new HashMap();
+
+ public InstructionList il;
+
+ public InstructionHandle[] handles;
+
+ public final void reread() {
+ int value;
+ char[] values = new char[value = this.il.getLength2()];
+ this.handles = this.il.getInstructionHandles();
+ int value2;
+ for (int value3 = value2 = 0; value3 < value; value3 = value2) {
+ char value4 = makeChar(this.handles[value2].getInstruction().getOpcode());
+ int value5 = value2;
+ value2++;
+ values[value5] = value4;
+ }
+ this.il_string = new String(values);
+ }
+
+ public final InstructionList getInstructionList() {
+ return this.il;
+ }
+
+ public final Iterator search(String text) {
+ return this.search(text, this.il.getStart(), null);
+ }
+
+ public static final String getText(String text) {
+ return pattern2string(text, true);
+ }
+
+ public static final String compilePattern(String text) {
+ String text2 = text.toLowerCase(Locale.ENGLISH);
+ StringBuffer stringBuffer = new StringBuffer();
+ int size = text.length();
+ int value;
+ for (int value2 = value = 0; value2 < size; value2 = ++value) {
+ char value3;
+ if (!Character.isLetterOrDigit(value3 = text2.charAt(value))) {
+ if (!Character.isWhitespace(value3)) {
+ stringBuffer.append(value3);
+ }
+ } else {
+ StringBuffer stringBuffer2 = new StringBuffer();
+ for (char value4 = value3;
+ (Character.isLetterOrDigit(value4) || value3 == '_') && value < size;
+ value4 = value3 = text2.charAt(value)) {
+ value++;
+ stringBuffer2.append(value3);
+ if (value >= size) {
+ break;
+ }
+ }
+ value--;
+ stringBuffer.append(createText(stringBuffer2.toString()));
+ }
+ }
+ return stringBuffer.toString();
+ }
+
+ static {
+ map.put(
+ "arithmeticinstruction",
+ "(irem|lrem|iand|ior|ineg|isub|lneg|fneg|fmul|ldiv|fadd|lxor|frem|idiv|land|ixor|ishr|fsub|lshl|fdiv|iadd|lor|dmul|lsub|ishl|imul|lmul|lushr|dneg|iushr|lshr|ddiv|drem|dadd|ladd|dsub)");
+ map.put("invokeinstruction", "(invokevirtual|invokeinterface|invokestatic|invokespecial)");
+ map.put(
+ "arrayinstruction",
+ "(baload|aastore|saload|caload|fastore|lastore|iaload|castore|iastore|aaload|bastore|sastore|faload|laload|daload|dastore)");
+ map.put("gotoinstruction", "(goto|goto_w)");
+ map.put(
+ "conversioninstruction", "(d2l|l2d|i2s|d2i|l2i|i2b|l2f|d2f|f2i|i2d|i2l|f2d|i2c|f2l|i2f)");
+ map.put(
+ "localvariableinstruction",
+ "(fstore|iinc|lload|dstore|dload|iload|aload|astore|istore|fload|lstore)");
+ map.put("loadinstruction", "(fload|dload|lload|iload|aload)");
+ map.put("fieldinstruction", "(getfield|putstatic|getstatic|putfield)");
+ map.put(
+ "cpinstruction",
+ "(ldc2_w|invokeinterface|multianewarray|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|ldc_w|invokestatic|invokevirtual|putfield|ldc|new|anewarray)");
+ map.put("stackinstruction", "(dup2|swap|dup2_x2|pop|pop2|dup|dup2_x1|dup_x2|dup_x1)");
+ map.put(
+ "branchinstruction",
+ "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)");
+ map.put("returninstruction", "(lreturn|ireturn|freturn|dreturn|areturn|return)");
+ map.put("storeinstruction", "(istore|fstore|dstore|astore|lstore)");
+ map.put("select", "(tableswitch|lookupswitch)");
+ map.put(
+ "ifinstruction",
+ "(ifeq|ifgt|if_icmpne|if_icmpeq|ifge|ifnull|ifne|if_icmple|if_icmpge|if_acmpeq|if_icmplt|if_acmpne|ifnonnull|iflt|if_icmpgt|ifle)");
+ map.put("jsrinstruction", "(jsr|jsr_w)");
+ map.put("variablelengthinstruction", "(tableswitch|jsr|goto|lookupswitch)");
+ map.put("unconditionalbranch", "(goto|jsr|jsr_w|athrow|goto_w)");
+ map.put("constantpushinstruction", "(dconst|bipush|sipush|fconst|iconst|lconst)");
+ map.put(
+ "typedinstruction",
+ "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dastore|ret|f2d|f2i|drem|iinc|i2c|checkcast|frem|lreturn|astore|lushr|daload|dneg|fastore|istore|lshl|ldiv|lstore|areturn|ishr|ldc_w|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|faload|sipush|iushr|caload|instanceof|invokespecial|putfield|fmul|ireturn|laload|d2f|lneg|ixor|i2l|fdiv|lastore|multianewarray|i2b|getstatic|i2d|putstatic|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|freturn|ldc|aconst_null|castore|lmul|ldc2_w|dadd|iconst|f2l|ddiv|dstore|land|jsr|anewarray|dmul|bipush|dsub|sastore|d2i|i2s|lshr|iadd|l2i|lload|bastore|fstore|fneg|iload|fadd|baload|fconst|ior|ineg|dreturn|l2f|lconst|getfield|invokevirtual|invokestatic|iastore)");
+ map.put("popinstruction", "(fstore|dstore|pop|pop2|astore|putstatic|istore|lstore)");
+ map.put("allocationinstruction", "(multianewarray|new|anewarray|newarray)");
+ map.put(
+ "indexedinstruction",
+ "(lload|lstore|fload|ldc2_w|invokeinterface|multianewarray|astore|dload|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|dstore|istore|iinc|ldc_w|ret|fstore|invokestatic|iload|putfield|invokevirtual|ldc|new|aload|anewarray)");
+ map.put(
+ "pushinstruction",
+ "(dup|lload|dup2|bipush|fload|ldc2_w|sipush|lconst|fconst|dload|getstatic|ldc_w|aconst_null|dconst|iload|ldc|iconst|aload)");
+ map.put(
+ "stackproducer",
+ "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dup|f2d|f2i|drem|i2c|checkcast|frem|lushr|daload|dneg|lshl|ldiv|ishr|ldc_w|invokeinterface|lxor|ishl|l2d|i2f|faload|sipush|iushr|caload|instanceof|invokespecial|fmul|laload|d2f|lneg|ixor|i2l|fdiv|getstatic|i2b|swap|i2d|dup2|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|ldc|arraylength|aconst_null|tableswitch|lmul|ldc2_w|iconst|dadd|f2l|ddiv|land|jsr|anewarray|dmul|bipush|dsub|d2i|newarray|i2s|lshr|iadd|lload|l2i|fneg|iload|fadd|baload|fconst|lookupswitch|ior|ineg|lconst|l2f|getfield|invokevirtual|invokestatic)");
+ map.put(
+ "stackconsumer",
+ "(imul|lsub|lor|iflt|fcmpg|if_icmpgt|iand|ifeq|if_icmplt|lrem|ifnonnull|idiv|d2l|isub|dcmpg|dastore|if_icmpeq|f2d|f2i|drem|i2c|checkcast|frem|lreturn|astore|lushr|pop2|monitorexit|dneg|fastore|istore|lshl|ldiv|lstore|areturn|if_icmpge|ishr|monitorenter|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|iushr|instanceof|invokespecial|fmul|ireturn|d2f|lneg|ixor|pop|i2l|ifnull|fdiv|lastore|i2b|if_acmpeq|ifge|swap|i2d|putstatic|fcmpl|ladd|irem|dcmpl|fsub|freturn|ifgt|castore|lmul|dadd|f2l|ddiv|dstore|land|if_icmpne|if_acmpne|dmul|dsub|sastore|ifle|d2i|i2s|lshr|iadd|l2i|bastore|fstore|fneg|fadd|ior|ineg|ifne|dreturn|l2f|if_icmple|getfield|invokevirtual|invokestatic|iastore)");
+ map.put(
+ "exceptionthrower",
+ "(irem|lrem|laload|putstatic|baload|dastore|areturn|getstatic|ldiv|anewarray|iastore|castore|idiv|saload|lastore|fastore|putfield|lreturn|caload|getfield|return|aastore|freturn|newarray|instanceof|multianewarray|athrow|faload|iaload|aaload|dreturn|monitorenter|checkcast|bastore|arraylength|new|invokevirtual|sastore|ldc_w|ireturn|invokespecial|monitorexit|invokeinterface|ldc|invokestatic|daload)");
+ map.put(
+ "loadclass",
+ "(multianewarray|invokeinterface|instanceof|invokespecial|putfield|checkcast|putstatic|invokevirtual|new|getstatic|invokestatic|getfield|anewarray)");
+ map.put(
+ "instructiontargeter",
+ "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)");
+ map.put("if_icmp", "(if_icmpne|if_icmpeq|if_icmple|if_icmpge|if_icmplt|if_icmpgt)");
+ map.put("if_acmp", "(if_acmpeq|if_acmpne)");
+ map.put("if", "(ifeq|ifne|iflt|ifge|ifgt|ifle)");
+ map.put("iconst", precompile((short) 3, (short) 8, (short) 2));
+ map.put(
+ "lconst",
+ new String(new char[] {'(', makeChar((short) 9), '|', makeChar((short) 10), ')'}));
+ map.put(
+ "dconst",
+ new String(new char[] {'(', makeChar((short) 14), '|', makeChar((short) 15), ')'}));
+ map.put(
+ "fconst",
+ new String(new char[] {'(', makeChar((short) 11), '|', makeChar((short) 12), ')'}));
+ map.put("iload", precompile((short) 26, (short) 29, (short) 21));
+ map.put("dload", precompile((short) 38, (short) 41, (short) 24));
+ map.put("fload", precompile((short) 34, (short) 37, (short) 23));
+ map.put("aload", precompile((short) 42, (short) 45, (short) 25));
+ map.put("istore", precompile((short) 59, (short) 62, (short) 54));
+ map.put("dstore", precompile((short) 71, (short) 74, (short) 57));
+ map.put("fstore", precompile((short) 67, (short) 70, (short) 56));
+ map.put("astore", precompile((short) 75, (short) 78, (short) 58));
+ for (String text : ((Iterable) ((Iterable>) map.keySet()))) {
+ String text2;
+ if ((text2 = (String) map.get(text)).charAt(1) < 32767) {
+ map.put(text, compilePattern(text2));
+ }
+ }
+ StringBuffer stringBuffer = new StringBuffer("(");
+ short value;
+ for (short value2 = value = 0; value2 < 256; value2 = ++value) {
+ if (Constants.NO_OF_OPERANDS[value] != -1) {
+ stringBuffer.append(makeChar(value));
+ if (value < 255) {
+ stringBuffer.append('|');
+ }
+ }
+ }
+ stringBuffer.append(')');
+ map.put("instruction", stringBuffer.toString());
+ }
+
+ public InstructionFinder(InstructionList instructionList) {
+ super();
+ this.il = instructionList;
+ this.reread();
+ }
+
+ public final Iterator search(
+ String text, InstructionFinder$CodeConstraint instructionFinder$CodeConstraint) {
+ return this.search(text, this.il.getStart(), instructionFinder$CodeConstraint);
+ }
+
+ public final Iterator search(
+ String text,
+ InstructionHandle instructionHandle,
+ InstructionFinder$CodeConstraint instructionFinder$CodeConstraint) {
+ String text2 = compilePattern(text);
+ int value = -1;
+ int value2;
+ int value3 = value2 = 0;
+ while (true) {
+ if (value3 >= this.handles.length) {
+ value3 = value;
+ break;
+ }
+ if (this.handles[value2] == instructionHandle) {
+ value3 = value = value2;
+ break;
+ }
+ value3 = ++value2;
+ }
+ if (value3 == -1) {
+ throw new ClassGenException(
+ ("Instruction handle " + instructionHandle + " not found in instruction list."));
+ }
+ Pattern pattern = Pattern.compile(text2);
+ ArrayList values = new ArrayList();
+ Matcher matcher2 = pattern.matcher(this.il_string);
+ value3 = value;
+ while (value3 < this.il_string.length() && matcher2.find(value)) {
+ int value4 = matcher2.start();
+ int value5;
+ int value6 = (value5 = matcher2.end()) - value4 + 1;
+ InstructionHandle[] match = this.getMatch(value4, value6);
+ if (instructionFinder$CodeConstraint == null
+ || instructionFinder$CodeConstraint.checkCode(match)) {
+ values.add(match);
+ }
+ value3 = value = value5;
+ }
+ return values.iterator();
+ }
+
+ public static final String createText(String text) {
+ String text2;
+ if ((text2 = (String) map.get(text)) != null) {
+ return text2;
+ }
+ int value;
+ for (int value2 = value = 0; value2 < 256; value2 = ++value) {
+ if (text.equals(Constants.TEXTS8[value])) {
+ return "" + makeChar((short) value);
+ }
+ }
+ throw new RuntimeException(("Instruction unknown: " + text));
+ }
+
+ public static final char makeChar(short value) {
+ return (char) (value + 32767);
+ }
+
+ public static String precompile(short value, short value2, short value3) {
+ StringBuffer stringBuffer = new StringBuffer("(");
+ int value4;
+ for (int value5 = value4 = value; value5 <= value2; value5 = ++value4) {
+ stringBuffer.append(makeChar((short) value4));
+ stringBuffer.append('|');
+ }
+ stringBuffer.append(makeChar(value3));
+ stringBuffer.append(")");
+ return stringBuffer.toString();
+ }
+
+ public final Iterator search(String text, InstructionHandle instructionHandle) {
+ return this.search(text, instructionHandle, null);
+ }
+
+ public static final String pattern2string(String text, boolean matches) {
+ StringBuffer stringBuffer = new StringBuffer();
+ int value;
+ for (int value2 = value = 0; value2 < text.length(); value2 = ++value) {
+ char value3;
+ if ((value3 = text.charAt(value)) >= 32767) {
+ if (matches) {
+ stringBuffer.append(Constants.TEXTS8[value3 - 32767]);
+ } else {
+ stringBuffer.append(value3 - 32767);
+ }
+ } else {
+ stringBuffer.append(value3);
+ }
+ }
+ return stringBuffer.toString();
+ }
+
+ public InstructionHandle[] getMatch(int value, int value2) {
+ InstructionHandle[] instructionHandles = new InstructionHandle[value2];
+ System.arraycopy(this.handles, value, instructionHandles, 0, value2);
+ return instructionHandles;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/JavaWrapper.java b/src/main/java/com/allatori/lib/bcel/util/JavaWrapper.java
new file mode 100644
index 0000000..b34e442
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/JavaWrapper.java
@@ -0,0 +1,66 @@
+package com.allatori.lib.bcel.util;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+public class JavaWrapper {
+
+ public java.lang.ClassLoader loader;
+
+ public void runMain(String text, String[] texts) throws ClassNotFoundException {
+ Class classValue = this.loader.loadClass(text);
+ Method method;
+ try {
+ Method method2 = method = classValue.getMethod("main", texts.getClass());
+ int modifiers = method2.getModifiers();
+ Class returnType = method2.getReturnType();
+ if (!Modifier.isPublic(modifiers)
+ || !Modifier.isStatic(modifiers)
+ || Modifier.isAbstract(modifiers)
+ || returnType != void.class) {
+ throw new NoSuchMethodException();
+ }
+ } catch (NoSuchMethodException noSuchMethodException) {
+ System.out.println(
+ "In class " + text + ": public static void main(String[] argv) is not defined");
+ return;
+ }
+ try {
+ method.invoke(null, texts);
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ public static void main(String[] texts) throws Exception {
+ if (texts.length == 0) {
+ System.out.println("Missing class name.");
+ } else {
+ String text = texts[0];
+ String[] texts2 = new String[texts.length - 1];
+ System.arraycopy(texts, 1, texts2, 0, texts2.length);
+ new JavaWrapper().runMain(text, texts2);
+ }
+ }
+
+ public static java.lang.ClassLoader getClassLoader() {
+ String text;
+ if ((text = System.getProperty("bcel.classloader")) == null || "".equals(text)) {
+ text = "com.allatori.lib.bcel.util.ClassLoader";
+ }
+ try {
+ return (java.lang.ClassLoader) Class.forName(text).newInstance();
+ } catch (Exception exception) {
+ throw new RuntimeException(exception.toString());
+ }
+ }
+
+ public JavaWrapper(java.lang.ClassLoader classLoader) {
+ super();
+ this.loader = classLoader;
+ }
+
+ public JavaWrapper() {
+ this(getClassLoader());
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/MethodHTML.java b/src/main/java/com/allatori/lib/bcel/util/MethodHTML.java
new file mode 100644
index 0000000..4799ba9
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/MethodHTML.java
@@ -0,0 +1,195 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.Constants;
+import com.allatori.lib.bcel.classfile.Attribute;
+import com.allatori.lib.bcel.classfile.Code;
+import com.allatori.lib.bcel.classfile.ConstantValue;
+import com.allatori.lib.bcel.classfile.ExceptionTable;
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.classfile.Utility;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+public final class MethodHTML implements Constants {
+
+ public ConstantHTML constant_html;
+
+ public String class_name;
+
+ public AttributeHTML attribute_html;
+
+ public PrintWriter file;
+
+ public final void writeMethod(Method method, int value) throws IOException {
+ String text2 = method.getText2();
+ String[] texts = Utility.methodSignatureArgumentTypes(text2, false);
+ String text = Utility.createText(text2, false);
+ String text3 = method.getText();
+ String text22 = Utility.getText2(method.getAccess_flags2());
+ Attribute[] attributes = method.getAttributes();
+ String text4 = Utility.replace(text22, " ", " ");
+ String text5 = Class2HTML.createText2(text3);
+ this.file.print(
+ "| "
+ + text4
+ + " | ");
+ PrintWriter printWriter = this.file;
+ StringBuilder stringBuilder = new StringBuilder();
+ int value2 = 0;
+ printWriter.print(
+ stringBuilder
+ .insert(0, "")
+ .append(Class2HTML.createText(text))
+ .append(" | ")
+ .append("")
+ .append(text5)
+ .append(" | \n(")
+ .toString());
+ for (int index = 0; value2 < texts.length; value2 = ++index) {
+ this.file.print(Class2HTML.createText(texts[index]));
+ if (index < texts.length - 1) {
+ this.file.print(", ");
+ }
+ }
+ this.file.print(") |
");
+ int value3;
+ for (int value4 = value3 = 0; value4 < attributes.length; value4 = ++value3) {
+ this.attribute_html.writeAttribute(
+ attributes[value3], "method" + value + "@" + value3, value);
+ byte value5;
+ if ((value5 = attributes[value3].getTag()) != 3) {
+ if (value5 == 2) {
+ Attribute[] attributes2 = ((Code) attributes[value3]).getAttributes();
+ int value6;
+ for (int value7 = value6 = 0; value7 < attributes2.length; value7 = value6) {
+ AttributeHTML attributeHTML = this.attribute_html;
+ Attribute attribute = attributes2[value6];
+ StringBuilder stringBuilder2 =
+ new StringBuilder()
+ .insert(0, "method")
+ .append(value)
+ .append("@")
+ .append(value3)
+ .append("@")
+ .append(value6);
+ value6++;
+ attributeHTML.writeAttribute(attribute, stringBuilder2.toString(), value);
+ }
+ }
+ } else {
+ this.file.print(" | throws | ");
+ int[] exceptionIndexTable = ((ExceptionTable) attributes[value3]).getExceptionIndexTable();
+ int value8;
+ for (int value9 = value8 = 0; value9 < exceptionIndexTable.length; value9 = ++value8) {
+ this.file.print(this.constant_html.referenceConstant(exceptionIndexTable[value8]));
+ if (value8 < exceptionIndexTable.length - 1) {
+ this.file.print(", ");
+ }
+ }
+ this.file.println(" |
");
+ }
+ }
+ }
+
+ public void writeField(Field field) throws IOException {
+ MethodHTML methodHTML;
+ String text2 = Utility.getText2(field.getText2());
+ String text = field.getText();
+ String text3 = Utility.replace(Utility.getText2(field.getAccess_flags2()), " ", " ");
+ this.file.print(
+ "| "
+ + text3
+ + " | \n"
+ + Class2HTML.createText(text2)
+ + " | "
+ + text
+ + " | ");
+ Attribute[] attributes = field.getAttributes();
+ int value;
+ for (int value2 = value = 0; value2 < attributes.length; value2 = value) {
+ AttributeHTML attributeHTML = this.attribute_html;
+ Attribute attribute = attributes[value];
+ StringBuilder stringBuilder = new StringBuilder().insert(0, text).append("@");
+ int value3 = value;
+ value++;
+ attributeHTML.writeAttribute(attribute, stringBuilder.append(value3).toString());
+ }
+ int value4;
+ int value5 = value4 = 0;
+ while (true) {
+ if (value5 >= attributes.length) {
+ methodHTML = this;
+ break;
+ }
+ if (attributes[value4].getTag() == 1) {
+ String text4 = ((ConstantValue) attributes[value4]).toString();
+ PrintWriter printWriter = this.file;
+ StringBuilder stringBuilder2 = new StringBuilder().insert(0, "= ")
+ .append(text4)
+ .append(" | \n")
+ .toString());
+ break;
+ }
+ value5 = ++value4;
+ }
+ methodHTML.file.println("
");
+ }
+
+ public MethodHTML(
+ String text,
+ String class_name,
+ Method[] methods,
+ Field[] fields,
+ ConstantHTML constantHTML,
+ AttributeHTML attributeHTML)
+ throws IOException {
+ super();
+ int value = 0;
+ this.class_name = class_name;
+ this.attribute_html = attributeHTML;
+ this.constant_html = constantHTML;
+ this.file = new PrintWriter(new FileOutputStream(("" + text + class_name + "_methods.html")));
+ this.file.println("");
+ this.file.println(
+ "| Access flags | Type | Field name |
");
+ for (int index = 0; value < fields.length; value = index) {
+ int value2 = index;
+ index++;
+ this.writeField(fields[value2]);
+ }
+ this.file.println("
");
+ this.file.println(
+ "| Access flags | Return type | Method name | Arguments |
");
+ int value3;
+ for (int value4 = value3 = 0; value4 < methods.length; value4 = value3) {
+ Method method = methods[value3];
+ int value5 = value3;
+ value3++;
+ this.writeMethod(method, value5);
+ }
+ this.file.println("
");
+ this.file.close();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/Repository.java b/src/main/java/com/allatori/lib/bcel/util/Repository.java
new file mode 100644
index 0000000..3e841e9
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/Repository.java
@@ -0,0 +1,21 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.classfile.JavaClass;
+import java.io.Serializable;
+
+public interface Repository extends Serializable {
+
+ void processJavaClass(JavaClass javaClass);
+
+ ClassPath getClassPath();
+
+ void clear();
+
+ JavaClass loadClass(Class classValue) throws ClassNotFoundException;
+
+ JavaClass getJavaClass(String text);
+
+ void processJavaClass2(JavaClass javaClass);
+
+ JavaClass getJavaClass2(String text) throws ClassNotFoundException;
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/SyntheticRepository.java b/src/main/java/com/allatori/lib/bcel/util/SyntheticRepository.java
new file mode 100644
index 0000000..d53ea31
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/SyntheticRepository.java
@@ -0,0 +1,117 @@
+package com.allatori.lib.bcel.util;
+
+import com.allatori.lib.bcel.classfile.ClassParser;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.SoftReference;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SyntheticRepository implements Repository {
+
+ public static final String DEFAULT_PATH = ClassPath.getClassPath();
+
+ public Map _loadedClasses;
+
+ public static Map _instances = new HashMap();
+
+ public ClassPath _path;
+
+ @Override
+ public void processJavaClass2(JavaClass javaClass) {
+ this._loadedClasses.remove(javaClass.getText2());
+ }
+
+ @Override
+ public JavaClass getJavaClass(String text) {
+ SoftReference softReference;
+ return (softReference = (SoftReference) this._loadedClasses.get(text)) == null
+ ? null
+ : (JavaClass) softReference.get();
+ }
+
+ @Override
+ public JavaClass getJavaClass2(String text) throws ClassNotFoundException {
+ if (text != null && !text.equals("")) {
+ String text2 = text.replace('/', '.');
+ JavaClass javaClass;
+ if ((javaClass = this.getJavaClass(text2)) != null) {
+ return javaClass;
+ }
+ try {
+ return this.loadClass(this._path.getInputStream2(text2), text2);
+ } catch (IOException oException) {
+ throw new ClassNotFoundException(
+ ("Exception while looking for class " + text2 + ": " + oException.toString()));
+ }
+ } else {
+ throw new IllegalArgumentException(("Invalid class name " + text));
+ }
+ }
+
+ public static SyntheticRepository getInstance(ClassPath classPath) {
+ SyntheticRepository syntheticRepository;
+ if ((syntheticRepository = (SyntheticRepository) _instances.get(classPath)) == null) {
+ syntheticRepository = new SyntheticRepository(classPath);
+ _instances.put(classPath, syntheticRepository);
+ }
+ return syntheticRepository;
+ }
+
+ @Override
+ public JavaClass loadClass(Class classValue) throws ClassNotFoundException {
+ String name = classValue.getName();
+ JavaClass javaClass;
+ if ((javaClass = this.getJavaClass(name)) != null) {
+ return javaClass;
+ }
+ String text = name;
+ int value;
+ if ((value = name.lastIndexOf(46)) > 0) {
+ text = text.substring(value + 1);
+ }
+ return this.loadClass(classValue.getResourceAsStream(text + ".class"), name);
+ }
+
+ @Override
+ public void clear() {
+ this._loadedClasses.clear();
+ }
+
+ @Override
+ public ClassPath getClassPath() {
+ return this._path;
+ }
+
+ @Override
+ public void processJavaClass(JavaClass javaClass) {
+ this._loadedClasses.put(javaClass.getText2(), new SoftReference<>(javaClass));
+ javaClass.setRepository(this);
+ }
+
+ public SyntheticRepository(ClassPath classPath) {
+ super();
+ this._path = null;
+ this._loadedClasses = new HashMap();
+ this._path = classPath;
+ }
+
+ public static SyntheticRepository getInstance() {
+ return getInstance(ClassPath.SYSTEM_CLASS_PATH);
+ }
+
+ public JavaClass loadClass(InputStream inputStream, String text) throws ClassNotFoundException {
+ try {
+ if (inputStream != null) {
+ JavaClass javaClass = new ClassParser(inputStream, text).parse();
+ this.processJavaClass(javaClass);
+ return javaClass;
+ }
+ } catch (IOException oException) {
+ throw new ClassNotFoundException(
+ ("Exception while looking for class " + text + ": " + oException.toString()));
+ }
+ throw new ClassNotFoundException(("SyntheticRepository could not load " + text));
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/TypeParserThreadLocal.java b/src/main/java/com/allatori/lib/bcel/util/TypeParserThreadLocal.java
new file mode 100644
index 0000000..6266b40
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/TypeParserThreadLocal.java
@@ -0,0 +1,9 @@
+package com.allatori.lib.bcel.util;
+
+public class TypeParserThreadLocal extends ThreadLocal {
+
+ @Override
+ public Object initialValue() {
+ return new Integer(0);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/TypeParserThreadLocal2.java b/src/main/java/com/allatori/lib/bcel/util/TypeParserThreadLocal2.java
new file mode 100644
index 0000000..c603d74
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/TypeParserThreadLocal2.java
@@ -0,0 +1,9 @@
+package com.allatori.lib.bcel.util;
+
+public class TypeParserThreadLocal2 extends ThreadLocal {
+
+ @Override
+ public Object initialValue() {
+ return new Integer(0);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/comparator/ClassGenComparator.java b/src/main/java/com/allatori/lib/bcel/util/comparator/ClassGenComparator.java
new file mode 100644
index 0000000..795505c
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/comparator/ClassGenComparator.java
@@ -0,0 +1,19 @@
+package com.allatori.lib.bcel.util.comparator;
+
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.util.BCELComparator;
+
+public class ClassGenComparator implements BCELComparator {
+
+ @Override
+ public int hashCode(Object result) {
+ return ((ClassGen) result).getClassName().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object result, Object result2) {
+ ClassGen classGen = (ClassGen) result;
+ ClassGen classGen2 = (ClassGen) result2;
+ return classGen.getClassName().equals(classGen2.getClassName());
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/comparator/ConstantComparator.java b/src/main/java/com/allatori/lib/bcel/util/comparator/ConstantComparator.java
new file mode 100644
index 0000000..d0f0c49
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/comparator/ConstantComparator.java
@@ -0,0 +1,19 @@
+package com.allatori.lib.bcel.util.comparator;
+
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.util.BCELComparator;
+
+public class ConstantComparator implements BCELComparator {
+
+ @Override
+ public boolean equals(Object result, Object result2) {
+ Constant constant = (Constant) result;
+ Constant constant2 = (Constant) result2;
+ return constant.toString().equals(constant2.toString());
+ }
+
+ @Override
+ public int hashCode(Object result) {
+ return ((Constant) result).toString().hashCode();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/comparator/FieldComparator.java b/src/main/java/com/allatori/lib/bcel/util/comparator/FieldComparator.java
new file mode 100644
index 0000000..d2c9741
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/comparator/FieldComparator.java
@@ -0,0 +1,20 @@
+package com.allatori.lib.bcel.util.comparator;
+
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.util.BCELComparator;
+
+public class FieldComparator implements BCELComparator {
+
+ @Override
+ public boolean equals(Object result, Object result2) {
+ Field field = (Field) result;
+ Field field2 = (Field) result2;
+ return field.getText().equals(field2.getText()) && field.getText2().equals(field2.getText2());
+ }
+
+ @Override
+ public int hashCode(Object result) {
+ Field field;
+ return (field = (Field) result).getText2().hashCode() ^ field.getText().hashCode();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/comparator/FieldGenComparator.java b/src/main/java/com/allatori/lib/bcel/util/comparator/FieldGenComparator.java
new file mode 100644
index 0000000..fdfe96e
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/comparator/FieldGenComparator.java
@@ -0,0 +1,21 @@
+package com.allatori.lib.bcel.util.comparator;
+
+import com.allatori.lib.bcel.generic.FieldGen;
+import com.allatori.lib.bcel.util.BCELComparator;
+
+public class FieldGenComparator implements BCELComparator {
+
+ @Override
+ public boolean equals(Object result, Object result2) {
+ FieldGen fieldGen = (FieldGen) result;
+ FieldGen fieldGen2 = (FieldGen) result2;
+ return fieldGen.getName().equals(fieldGen2.getName())
+ && fieldGen.getText().equals(fieldGen2.getText());
+ }
+
+ @Override
+ public int hashCode(Object result) {
+ FieldGen fieldGen;
+ return (fieldGen = (FieldGen) result).getText().hashCode() ^ fieldGen.getName().hashCode();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/comparator/JavaClassComparator.java b/src/main/java/com/allatori/lib/bcel/util/comparator/JavaClassComparator.java
new file mode 100644
index 0000000..aa6b58d
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/comparator/JavaClassComparator.java
@@ -0,0 +1,19 @@
+package com.allatori.lib.bcel.util.comparator;
+
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.util.BCELComparator;
+
+public class JavaClassComparator implements BCELComparator {
+
+ @Override
+ public boolean equals(Object result, Object result2) {
+ JavaClass javaClass = (JavaClass) result;
+ JavaClass javaClass2 = (JavaClass) result2;
+ return javaClass.getText2().equals(javaClass2.getText2());
+ }
+
+ @Override
+ public int hashCode(Object result) {
+ return ((JavaClass) result).getText2().hashCode();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/comparator/MethodComparator.java b/src/main/java/com/allatori/lib/bcel/util/comparator/MethodComparator.java
new file mode 100644
index 0000000..124f924
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/comparator/MethodComparator.java
@@ -0,0 +1,27 @@
+package com.allatori.lib.bcel.util.comparator;
+
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.util.BCELComparator;
+
+public class MethodComparator implements BCELComparator {
+
+ public static MethodComparator methodComparator = new MethodComparator();
+
+ @Override
+ public boolean equals(Object result, Object result2) {
+ Method method = (Method) result;
+ Method method2 = (Method) result2;
+ return method.getText().equals(method2.getText())
+ && method.getText2().equals(method2.getText2());
+ }
+
+ @Override
+ public int hashCode(Object result) {
+ Method method;
+ return (method = (Method) result).getText2().hashCode() ^ method.getText().hashCode();
+ }
+
+ public static MethodComparator getMethodComparator() {
+ return methodComparator;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/comparator/MethodComparator2.java b/src/main/java/com/allatori/lib/bcel/util/comparator/MethodComparator2.java
new file mode 100644
index 0000000..5ee4129
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/comparator/MethodComparator2.java
@@ -0,0 +1,21 @@
+package com.allatori.lib.bcel.util.comparator;
+
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.util.BCELComparator;
+
+public class MethodComparator2 implements BCELComparator {
+
+ @Override
+ public boolean equals(Object result, Object result2) {
+ Method method = (Method) result;
+ Method method2 = (Method) result2;
+ return method.getText().equals(method2.getText())
+ && method.getText2().equals(method2.getText2());
+ }
+
+ @Override
+ public int hashCode(Object result) {
+ Method method;
+ return (method = (Method) result).getText2().hashCode() ^ method.getText().hashCode();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/util/comparator/MethodGenComparator.java b/src/main/java/com/allatori/lib/bcel/util/comparator/MethodGenComparator.java
new file mode 100644
index 0000000..c415454
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/util/comparator/MethodGenComparator.java
@@ -0,0 +1,21 @@
+package com.allatori.lib.bcel.util.comparator;
+
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.util.BCELComparator;
+
+public class MethodGenComparator implements BCELComparator {
+
+ @Override
+ public int hashCode(Object result) {
+ MethodGen methodGen;
+ return (methodGen = (MethodGen) result).getText().hashCode() ^ methodGen.getName().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object result, Object result2) {
+ MethodGen methodGen = (MethodGen) result;
+ MethodGen methodGen2 = (MethodGen) result2;
+ return methodGen.getName().equals(methodGen2.getName())
+ && methodGen.getText().equals(methodGen2.getText());
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/GraphicalVerifier.java b/src/main/java/com/allatori/lib/bcel/verifier/GraphicalVerifier.java
new file mode 100644
index 0000000..c3bea3c
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/GraphicalVerifier.java
@@ -0,0 +1,43 @@
+package com.allatori.lib.bcel.verifier;
+
+import com.allatori.lib.bcel.generic.Type;
+import java.awt.Dimension;
+import java.awt.Toolkit;
+import javax.swing.UIManager;
+
+public class GraphicalVerifier {
+
+ public boolean packFrame = false;
+
+ public GraphicalVerifier() {
+ VerifierAppFrame verifierAppFrame = new VerifierAppFrame();
+ if (this.packFrame) {
+ verifierAppFrame.pack();
+ } else {
+ verifierAppFrame.validate();
+ }
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension dimension;
+ if ((dimension = verifierAppFrame.getSize()).height > screenSize.height) {
+ dimension.height = screenSize.height;
+ }
+ if (dimension.width > screenSize.width) {
+ dimension.width = screenSize.width;
+ }
+ verifierAppFrame.setLocation(
+ (screenSize.width - dimension.width) / 2, (screenSize.height - dimension.height) / 2);
+ verifierAppFrame.setVisible(true);
+ verifierAppFrame.classNamesJList.setModel(new VerifierFactoryListModel());
+ VerifierFactory.getVerifier(Type.OBJECT.getClassName());
+ verifierAppFrame.classNamesJList.setSelectedIndex(0);
+ }
+
+ public static void main(String[] texts) {
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ new GraphicalVerifier();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/NativeVerifier.java b/src/main/java/com/allatori/lib/bcel/verifier/NativeVerifier.java
new file mode 100644
index 0000000..fa287ff
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/NativeVerifier.java
@@ -0,0 +1,36 @@
+package com.allatori.lib.bcel.verifier;
+
+public abstract class NativeVerifier {
+
+ public static void main(String[] texts) {
+ if (texts.length != 1) {
+ System.out.println("Verifier front-end: need exactly one argument.");
+ System.exit(1);
+ }
+ int value;
+ if ((value = texts[0].lastIndexOf(".class")) != -1) {
+ texts[0] = texts[0].substring(0, value);
+ }
+ texts[0] = texts[0].replace('/', '.');
+ try {
+ Class.forName(texts[0]);
+ } catch (ExceptionInInitializerError exceptionInInitializerError) {
+ System.out.println(
+ "NativeVerifier: ExceptionInInitializerError encountered on '" + texts[0] + "'.");
+ System.out.println(exceptionInInitializerError);
+ System.exit(1);
+ } catch (LinkageError linkageError) {
+ System.out.println("NativeVerifier: LinkageError encountered on '" + texts[0] + "'.");
+ System.out.println(linkageError);
+ System.exit(1);
+ } catch (ClassNotFoundException classNotFoundException) {
+ System.out.println("NativeVerifier: FILE NOT FOUND: '" + texts[0] + "'.");
+ System.exit(1);
+ } catch (Throwable throwable) {
+ System.out.println("NativeVerifier: Unspecified verification error on'" + texts[0] + "'.");
+ System.exit(1);
+ }
+ System.out.println("NativeVerifier: Class file '" + texts[0] + "' seems to be okay.");
+ System.exit(0);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/PassVerifier.java b/src/main/java/com/allatori/lib/bcel/verifier/PassVerifier.java
new file mode 100644
index 0000000..bb87cd8
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/PassVerifier.java
@@ -0,0 +1,33 @@
+package com.allatori.lib.bcel.verifier;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class PassVerifier {
+
+ public VerificationResult verificationResult;
+
+ public List messages = new ArrayList();
+
+ public void addMessage(String text) {
+ this.messages.add(text);
+ }
+
+ public abstract VerificationResult getVerificationResult();
+
+ public String[] getMessages() {
+ this.getVerificationResult2();
+ return (String[]) this.messages.toArray(new String[this.messages.size()]);
+ }
+
+ public VerificationResult getVerificationResult2() {
+ if (this.verificationResult == null) {
+ this.verificationResult = this.getVerificationResult();
+ }
+ return this.verificationResult;
+ }
+
+ public PassVerifier() {
+ this.verificationResult = null;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/TransitiveHull.java b/src/main/java/com/allatori/lib/bcel/verifier/TransitiveHull.java
new file mode 100644
index 0000000..0427285
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/TransitiveHull.java
@@ -0,0 +1,87 @@
+package com.allatori.lib.bcel.verifier;
+
+import com.allatori.lib.bcel.Repository;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import java.io.PrintStream;
+
+public class TransitiveHull implements VerifierFactoryObserver {
+
+ public int indent = 0;
+
+ public static void main(String[] texts) {
+ if (texts.length != 1) {
+ System.out.println("Need exactly one argument: The root class to verify.");
+ System.exit(1);
+ }
+ int value;
+ if ((value = texts[0].lastIndexOf(".class")) != -1) {
+ texts[0] = texts[0].substring(0, value);
+ }
+ texts[0] = texts[0].replace('/', '.');
+ TransitiveHull transitiveHull = new TransitiveHull();
+ VerifierFactory.attach(transitiveHull);
+ VerifierFactory.getVerifier(texts[0]);
+ VerifierFactory.detach(transitiveHull);
+ }
+
+ @Override
+ public void update(String text) {
+ System.gc();
+ int value;
+ for (int value2 = value = 0; value2 < this.indent; value2 = value) {
+ PrintStream printStream = System.out;
+ value++;
+ printStream.print(" ");
+ }
+ System.out.println(text);
+ this.indent++;
+ Verifier verifier;
+ VerificationResult verificationResult;
+ if ((verificationResult =
+ (verifier = VerifierFactory.getVerifier(text)).createVerificationResult())
+ != VerificationResult.VERIFICATION_RESULT2) {
+ System.out.println("Pass 1:\n" + verificationResult);
+ }
+ VerificationResult verificationResult2;
+ if ((verificationResult2 = verifier.createVerificationResult2())
+ != VerificationResult.VERIFICATION_RESULT2) {
+ System.out.println("Pass 2:\n" + verificationResult2);
+ }
+ if (verificationResult2 == VerificationResult.VERIFICATION_RESULT2) {
+ try {
+ JavaClass javaClass = Repository.lookupClass(verifier.getClassName());
+ for (int index = 0; index < javaClass.getMethods().length; index++) {
+ VerificationResult verificationResult3;
+ if ((verificationResult3 = verifier.doPass3a(index))
+ != VerificationResult.VERIFICATION_RESULT2) {
+ System.out.println(
+ ""
+ + verifier.getClassName()
+ + ", Pass 3a, method "
+ + index
+ + " ['"
+ + javaClass.getMethods()[index]
+ + "']:\n"
+ + verificationResult3);
+ }
+ VerificationResult verificationResult4;
+ if ((verificationResult4 = verifier.doPass3b(index))
+ != VerificationResult.VERIFICATION_RESULT2) {
+ System.out.println(
+ ""
+ + verifier.getClassName()
+ + ", Pass 3b, method "
+ + index
+ + " ['"
+ + javaClass.getMethods()[index]
+ + "']:\n"
+ + verificationResult4);
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ System.err.println("Could not find class " + verifier.getClassName() + " in Repository");
+ }
+ }
+ this.indent--;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/VerificationResult.java b/src/main/java/com/allatori/lib/bcel/verifier/VerificationResult.java
new file mode 100644
index 0000000..2afb757
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/VerificationResult.java
@@ -0,0 +1,52 @@
+package com.allatori.lib.bcel.verifier;
+
+public class VerificationResult {
+
+ public String detailMessage;
+
+ public static final String TEXT = "Not yet verified.";
+
+ public static final int VERIFIED_NOTYET = 0;
+
+ public static final String TEXT2 = "Passed verification.";
+
+ public static final VerificationResult VERIFICATION_RESULT =
+ new VerificationResult(0, "Not yet verified.");
+
+ public static final int VERIFIED_REJECTED = 2;
+
+ public static final VerificationResult VERIFICATION_RESULT2 =
+ new VerificationResult(1, "Passed verification.");
+
+ public int numeric;
+
+ public static final int VERIFIED_OK = 1;
+
+ public VerificationResult(int numeric, String detailMessage) {
+ super();
+ this.numeric = numeric;
+ this.detailMessage = detailMessage;
+ }
+
+ @Override
+ public boolean equals(Object result) {
+ VerificationResult verificationResult;
+ return !(result instanceof VerificationResult)
+ ? false
+ : (verificationResult = (VerificationResult) result).numeric == this.numeric
+ && verificationResult.detailMessage.equals(this.detailMessage);
+ }
+
+ @Override
+ public int hashCode() {
+ return this.numeric ^ this.detailMessage.hashCode();
+ }
+
+ public int getStatus() {
+ return this.numeric;
+ }
+
+ public String getDetailMessage() {
+ return this.detailMessage;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/Verifier.java b/src/main/java/com/allatori/lib/bcel/verifier/Verifier.java
new file mode 100644
index 0000000..43f42fc
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/Verifier.java
@@ -0,0 +1,216 @@
+package com.allatori.lib.bcel.verifier;
+
+import com.allatori.lib.bcel.Repository;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.verifier.statics.Pass1Verifier;
+import com.allatori.lib.bcel.verifier.statics.Pass2Verifier;
+import com.allatori.lib.bcel.verifier.statics.Pass3aVerifier;
+import com.allatori.lib.bcel.verifier.structurals.Pass3bVerifier;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+public class Verifier {
+
+ public final String classname;
+
+ public Map p3avs;
+
+ public Pass2Verifier p2v;
+
+ public Map p3bvs;
+
+ public Pass1Verifier p1v;
+
+ public void flush() {
+ this.p1v = null;
+ this.p2v = null;
+ this.p3avs.clear();
+ this.p3bvs.clear();
+ }
+
+ public final String getClassName() {
+ return this.classname;
+ }
+
+ public VerificationResult createVerificationResult() {
+ if (this.p1v == null) {
+ this.p1v = new Pass1Verifier(this);
+ }
+ return this.p1v.getVerificationResult2();
+ }
+
+ public static void main(String[] texts) {
+ System.out.println(
+ "JustIce by Enver Haase, (C) 2001-2002.\n"
+ + "\n"
+ + "\n");
+ int value;
+ for (int value2 = value = 0; value2 < texts.length; value2 = ++value) {
+ try {
+ int value3;
+ if (texts[value].endsWith(".class")
+ && (value3 = texts[value].lastIndexOf(".class")) != -1) {
+ texts[value] = texts[value].substring(0, value3);
+ }
+ texts[value] = texts[value].replace('/', '.');
+ System.out.println("Now verifying: " + texts[value] + "\n");
+ Verifier verifier;
+ Verifier verifier2 = verifier = VerifierFactory.getVerifier(texts[value]);
+ VerificationResult verificationResult = verifier2.createVerificationResult();
+ System.out.println("Pass 1:\n" + verificationResult);
+ VerificationResult verificationResult2 = verifier2.createVerificationResult2();
+ System.out.println("Pass 2:\n" + verificationResult2);
+ if (verificationResult2 == VerificationResult.VERIFICATION_RESULT2) {
+ JavaClass javaClass = Repository.lookupClass(texts[value]);
+ int value4;
+ for (int value5 = value4 = 0; value5 < javaClass.getMethods().length; value5 = value4) {
+ VerificationResult verificationResult3 = verifier.doPass3a(value4);
+ System.out.println(
+ "Pass 3a, method number "
+ + value4
+ + " ['"
+ + javaClass.getMethods()[value4]
+ + "']:\n"
+ + verificationResult3);
+ VerificationResult verificationResult4 = verifier.doPass3b(value4);
+ PrintStream printStream = System.out;
+ StringBuilder stringBuilder =
+ new StringBuilder()
+ .insert(0, "Pass 3b, method number ")
+ .append(value4)
+ .append(" ['")
+ .append(javaClass.getMethods()[value4])
+ .append("']:\n");
+ value4++;
+ printStream.println(stringBuilder.append(verificationResult4).toString());
+ }
+ }
+ System.out.println("Warnings:");
+ String[] texts2;
+ if ((texts2 = verifier.getMessages()).length == 0) {
+ System.out.println("");
+ }
+ int value6;
+ for (int value7 = value6 = 0; value7 < texts2.length; value7 = value6) {
+ int value8 = value6;
+ String[] texts3 = texts2;
+ PrintStream printStream2 = System.out;
+ value6++;
+ printStream2.println(texts3[value8]);
+ }
+ System.out.println("\n");
+ verifier.flush();
+ Repository.clearCache();
+ System.gc();
+ } catch (ClassNotFoundException classNotFoundException) {
+ classNotFoundException.printStackTrace();
+ }
+ }
+ }
+
+ public VerificationResult createVerificationResult2() {
+ if (this.p2v == null) {
+ this.p2v = new Pass2Verifier(this);
+ }
+ return this.p2v.getVerificationResult2();
+ }
+
+ public String[] getMessages() throws ClassNotFoundException {
+ ArrayList values2 = new ArrayList();
+ if (this.p1v != null) {
+ String[] messages = this.p1v.getMessages();
+ int value;
+ for (int value2 = value = 0; value2 < messages.length; value2 = value) {
+ StringBuilder stringBuilder = new StringBuilder().append("Pass 1: ");
+ String text = messages[value];
+ value++;
+ values2.add(stringBuilder.append(text).toString());
+ }
+ }
+ if (this.p2v != null) {
+ String[] messages2 = this.p2v.getMessages();
+ int value3;
+ for (int value4 = value3 = 0; value4 < messages2.length; value4 = value3) {
+ StringBuilder stringBuilder2 = new StringBuilder().insert(0, "Pass 2: ");
+ String text2 = messages2[value3];
+ value3++;
+ values2.add(stringBuilder2.append(text2).toString());
+ }
+ }
+ for (Pass3aVerifier pass3aVerifier :
+ ((Iterable) ((Iterable>) this.p3avs.values()))) {
+ String[] messages3 = pass3aVerifier.getMessages();
+ int methodNo = pass3aVerifier.getMethodNo();
+ int value5;
+ for (int value6 = value5 = 0; value6 < messages3.length; value6 = value5) {
+ StringBuilder stringBuilder3 =
+ new StringBuilder()
+ .insert(0, "Pass 3a, method ")
+ .append(methodNo)
+ .append(" ('")
+ .append(Repository.lookupClass(this.classname).getMethods()[methodNo])
+ .append("'): ");
+ String text3 = messages3[value5];
+ value5++;
+ values2.add(stringBuilder3.append(text3).toString());
+ }
+ }
+ for (Pass3bVerifier pass3bVerifier :
+ ((Iterable) ((Iterable>) this.p3bvs.values()))) {
+ String[] messages4 = pass3bVerifier.getMessages();
+ int methodNo2 = pass3bVerifier.getMethodNo();
+ int value7;
+ for (int value8 = value7 = 0; value8 < messages4.length; value8 = value7) {
+ StringBuilder stringBuilder4 =
+ new StringBuilder()
+ .insert(0, "Pass 3b, method ")
+ .append(methodNo2)
+ .append(" ('")
+ .append(Repository.lookupClass(this.classname).getMethods()[methodNo2])
+ .append("'): ");
+ String text4 = messages4[value7];
+ value7++;
+ values2.add(stringBuilder4.append(text4).toString());
+ }
+ }
+ String[] texts = new String[values2.size()];
+ int value9;
+ for (int value10 = value9 = 0; value10 < values2.size(); value10 = value9) {
+ String text5 = (String) values2.get(value9);
+ int value11 = value9;
+ value9++;
+ texts[value11] = text5;
+ }
+ return texts;
+ }
+
+ public VerificationResult doPass3a(int value) {
+ String text = Integer.toString(value);
+ Pass3aVerifier pass3aVerifier = (Pass3aVerifier) this.p3avs.get(text);
+ if (this.p3avs.get(text) == null) {
+ pass3aVerifier = new Pass3aVerifier(this, value);
+ this.p3avs.put(text, pass3aVerifier);
+ }
+ return pass3aVerifier.getVerificationResult2();
+ }
+
+ public Verifier(String classname) {
+ super();
+ this.p3avs = new HashMap();
+ this.p3bvs = new HashMap();
+ this.classname = classname;
+ this.flush();
+ }
+
+ public VerificationResult doPass3b(int value) {
+ String text = Integer.toString(value);
+ Pass3bVerifier pass3bVerifier = (Pass3bVerifier) this.p3bvs.get(text);
+ if (this.p3bvs.get(text) == null) {
+ pass3bVerifier = new Pass3bVerifier(this, value);
+ this.p3bvs.put(text, pass3bVerifier);
+ }
+ return pass3bVerifier.getVerificationResult2();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/VerifierAppFrame.java b/src/main/java/com/allatori/lib/bcel/verifier/VerifierAppFrame.java
new file mode 100644
index 0000000..1f03f68
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/VerifierAppFrame.java
@@ -0,0 +1,440 @@
+package com.allatori.lib.bcel.verifier;
+
+import com.allatori.lib.bcel.Repository;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.verifier.ui.VerifierActionListener;
+import com.allatori.lib.bcel.verifier.ui.VerifierActionListener2;
+import com.allatori.lib.bcel.verifier.ui.VerifierActionListener3;
+import com.allatori.lib.bcel.verifier.ui.VerifierSelectionListener;
+import com.allatori.lib.bcel.verifier.ui.VerifierSelectionListener2;
+import com.allatori.lib.bcel.verifier.ui.VerifierSelectionListener3;
+import java.awt.CardLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowEvent;
+import javax.swing.BorderFactory;
+import javax.swing.JFrame;
+import javax.swing.JList;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTextPane;
+import javax.swing.KeyStroke;
+import javax.swing.event.ListSelectionEvent;
+
+public class VerifierAppFrame extends JFrame {
+
+ public JScrollPane jScrollPane6;
+
+ public JMenu jMenu1;
+
+ public JTextPane messagesTextPane;
+
+ public JScrollPane jScrollPane3;
+
+ public JPanel jPanel;
+
+ public JMenuItem aboutMenuItem;
+
+ public String text;
+
+ public JTextPane pass3aTextPane;
+
+ public JScrollPane jScrollPane5;
+
+ public JMenuItem newFileMenuItem;
+
+ public JPanel jPanel3;
+
+ public JScrollPane jScrollPane7;
+
+ public JPanel jPanel2;
+
+ public JScrollPane jScrollPane1;
+
+ public CardLayout cardLayout1;
+
+ public JList pass3aJList;
+
+ public JPanel messagesPanel;
+
+ public JScrollPane jScrollPane2;
+
+ public JTextPane pass3bTextPane;
+
+ public GridLayout gridLayout4;
+
+ public JScrollPane messagesScrollPane;
+
+ public JTextPane pass2TextPane;
+
+ public GridLayout gridLayout1;
+
+ public JPanel jPanel1;
+
+ public JList classNamesJList;
+
+ public JMenuBar jMenuBar1;
+
+ public GridLayout gridLayout3;
+
+ public JTextPane pass1TextPane;
+
+ public JSplitPane jSplitPane1;
+
+ public GridLayout gridLayout2;
+
+ public String JUSTICE_VERSION;
+
+ public JMenu jMenu2;
+
+ public JMenuItem whatisMenuItem;
+
+ public JSplitPane jSplitPane3;
+
+ public JSplitPane jSplitPane2;
+
+ public JList pass3bJList;
+
+ public JSplitPane jSplitPane4;
+
+ public JScrollPane jScrollPane4;
+
+ public synchronized void pass3bJList_valueChanged(ListSelectionEvent listSelectionEvent) {
+ if (!listSelectionEvent.getValueIsAdjusting()) {
+ Verifier verifier = VerifierFactory.getVerifier(this.text);
+ String text2 = "";
+ byte value = 1;
+ byte value2 = 0;
+ int value3;
+ for (int value4 = value3 = 0;
+ value4 < this.pass3bJList.getModel().getSize();
+ value4 = ++value3) {
+ if (this.pass3bJList.isSelectedIndex(value3)) {
+ VerificationResult verificationResult;
+ if ((verificationResult = verifier.doPass3b(value3)).getStatus() == 2) {
+ value = 0;
+ value2 = 1;
+ }
+ try {
+ JavaClass javaClass = Repository.lookupClass(verifier.getClassName());
+ text2 =
+ ""
+ + text2
+ + "Method '"
+ + javaClass.getMethods()[value3]
+ + "': "
+ + verificationResult.getDetailMessage().replace('\n', ' ')
+ + "\n\n";
+ } catch (ClassNotFoundException classNotFoundException) {
+ classNotFoundException.printStackTrace();
+ }
+ }
+ }
+ this.pass3bTextPane.setText(text2);
+ this.pass3bTextPane.setBackground(
+ value != 0 ? Color.green : (value2 != 0 ? Color.red : Color.yellow));
+ }
+ }
+
+ public synchronized void classNamesJList_valueChanged(ListSelectionEvent listSelectionEvent) {
+ if (!listSelectionEvent.getValueIsAdjusting()) {
+ this.text = this.classNamesJList.getSelectedValue().toString();
+ VerifierAppFrame verifierAppFrame;
+ label15:
+ {
+ try {
+ this.verify();
+ } catch (ClassNotFoundException classNotFoundException) {
+ verifierAppFrame = this;
+ classNotFoundException.printStackTrace();
+ break label15;
+ }
+ verifierAppFrame = this;
+ }
+ verifierAppFrame.classNamesJList.setSelectedValue(this.text, true);
+ }
+ }
+
+ public synchronized void pass3aJList_valueChanged(ListSelectionEvent listSelectionEvent) {
+ if (!listSelectionEvent.getValueIsAdjusting()) {
+ Verifier verifier = VerifierFactory.getVerifier(this.text);
+ String text2 = "";
+ byte value = 1;
+ byte value2 = 0;
+ int value3;
+ for (int value4 = value3 = 0;
+ value4 < this.pass3aJList.getModel().getSize();
+ value4 = ++value3) {
+ if (this.pass3aJList.isSelectedIndex(value3)) {
+ VerificationResult verificationResult;
+ if ((verificationResult = verifier.doPass3a(value3)).getStatus() == 2) {
+ value = 0;
+ value2 = 1;
+ }
+ try {
+ JavaClass javaClass = Repository.lookupClass(verifier.getClassName());
+ text2 =
+ ""
+ + text2
+ + "Method '"
+ + javaClass.getMethods()[value3]
+ + "': "
+ + verificationResult.getDetailMessage().replace('\n', ' ')
+ + "\n\n";
+ } catch (ClassNotFoundException classNotFoundException) {
+ classNotFoundException.printStackTrace();
+ }
+ }
+ }
+ this.pass3aTextPane.setText(text2);
+ this.pass3aTextPane.setBackground(
+ value != 0 ? Color.green : (value2 != 0 ? Color.red : Color.yellow));
+ }
+ }
+
+ public void whatisMenuItem_actionPerformed(ActionEvent actionEvent) {
+ JOptionPane.showMessageDialog(
+ this,
+ "The upper four boxes to the right reflect verification passes according to The Java"
+ + " Virtual Machine Specification.\n"
+ + "These are (in that order): Pass one, Pass two, Pass three (before data flow"
+ + " analysis), Pass three (data flow analysis).\n"
+ + "The bottom box to the right shows (warning) messages; warnings do not cause a class"
+ + " to be rejected.",
+ this.JUSTICE_VERSION,
+ 1);
+ }
+
+ public void jbInit() throws Exception {
+ this.jPanel = (JPanel) this.getContentPane();
+ this.jPanel.setLayout(this.cardLayout1);
+ this.setJMenuBar(this.jMenuBar1);
+ this.setSize(new Dimension(708, 451));
+ this.setTitle("JustIce");
+ this.jPanel1.setMinimumSize(new Dimension(100, 100));
+ this.jPanel1.setPreferredSize(new Dimension(100, 100));
+ this.jPanel1.setLayout(this.gridLayout1);
+ this.jSplitPane2.setOrientation(0);
+ this.jPanel2.setLayout(this.gridLayout2);
+ this.jPanel3.setMinimumSize(new Dimension(200, 100));
+ this.jPanel3.setPreferredSize(new Dimension(400, 400));
+ this.jPanel3.setLayout(this.gridLayout4);
+ this.messagesPanel.setMinimumSize(new Dimension(100, 100));
+ this.messagesPanel.setLayout(this.gridLayout3);
+ this.jPanel2.setMinimumSize(new Dimension(200, 100));
+ this.jMenu1.setText("File");
+ this.jScrollPane1.getViewport().setBackground(Color.red);
+ this.messagesScrollPane.getViewport().setBackground(Color.red);
+ this.messagesScrollPane.setPreferredSize(new Dimension(10, 10));
+ this.classNamesJList.addListSelectionListener(new VerifierSelectionListener3(this));
+ this.classNamesJList.setSelectionMode(0);
+ this.jScrollPane3.setBorder(BorderFactory.createLineBorder(Color.black));
+ this.jScrollPane3.setPreferredSize(new Dimension(100, 100));
+ this.gridLayout4.setRows(4);
+ this.gridLayout4.setColumns(1);
+ this.gridLayout4.setHgap(1);
+ this.jScrollPane4.setBorder(BorderFactory.createLineBorder(Color.black));
+ this.jScrollPane4.setPreferredSize(new Dimension(100, 100));
+ this.pass1TextPane.setBorder(BorderFactory.createRaisedBevelBorder());
+ this.pass1TextPane.setToolTipText("");
+ this.pass1TextPane.setEditable(false);
+ this.pass2TextPane.setBorder(BorderFactory.createRaisedBevelBorder());
+ this.pass2TextPane.setEditable(false);
+ this.messagesTextPane.setBorder(BorderFactory.createRaisedBevelBorder());
+ this.messagesTextPane.setEditable(false);
+ this.newFileMenuItem.setText("New...");
+ this.newFileMenuItem.setAccelerator(KeyStroke.getKeyStroke(78, 2, true));
+ this.newFileMenuItem.addActionListener(new VerifierActionListener3(this));
+ this.pass3aTextPane.setEditable(false);
+ this.pass3bTextPane.setEditable(false);
+ this.pass3aJList.addListSelectionListener(new VerifierSelectionListener2(this));
+ this.pass3bJList.addListSelectionListener(new VerifierSelectionListener(this));
+ this.jMenu2.setText("Help");
+ this.whatisMenuItem.setText("What is...");
+ this.whatisMenuItem.addActionListener(new VerifierActionListener2(this));
+ this.aboutMenuItem.setText("About");
+ this.aboutMenuItem.addActionListener(new VerifierActionListener(this));
+ this.jSplitPane2.add(this.messagesPanel, "bottom");
+ this.messagesPanel.add(this.messagesScrollPane, null);
+ this.messagesScrollPane.getViewport().add(this.messagesTextPane, null);
+ this.jSplitPane2.add(this.jPanel3, "top");
+ this.jPanel3.add(this.jScrollPane3, null);
+ this.jScrollPane3.getViewport().add(this.pass1TextPane, null);
+ this.jPanel3.add(this.jScrollPane4, null);
+ this.jPanel3.add(this.jSplitPane3, null);
+ this.jSplitPane3.add(this.jScrollPane2, "left");
+ this.jScrollPane2.getViewport().add(this.pass3aJList, null);
+ this.jSplitPane3.add(this.jScrollPane5, "right");
+ this.jScrollPane5.getViewport().add(this.pass3aTextPane, null);
+ this.jPanel3.add(this.jSplitPane4, null);
+ this.jSplitPane4.add(this.jScrollPane6, "left");
+ this.jScrollPane6.getViewport().add(this.pass3bJList, null);
+ this.jSplitPane4.add(this.jScrollPane7, "right");
+ this.jScrollPane7.getViewport().add(this.pass3bTextPane, null);
+ this.jScrollPane4.getViewport().add(this.pass2TextPane, null);
+ this.jSplitPane1.add(this.jPanel2, "top");
+ this.jPanel2.add(this.jScrollPane1, null);
+ this.jSplitPane1.add(this.jPanel1, "bottom");
+ this.jPanel1.add(this.jSplitPane2, null);
+ this.jScrollPane1.getViewport().add(this.classNamesJList, null);
+ this.jMenuBar1.add(this.jMenu1);
+ this.jMenuBar1.add(this.jMenu2);
+ this.jPanel.add(this.jSplitPane1, "jSplitPane1");
+ this.jMenu1.add(this.newFileMenuItem);
+ this.jMenu2.add(this.whatisMenuItem);
+ this.jMenu2.add(this.aboutMenuItem);
+ this.jSplitPane2.setDividerLocation(300);
+ this.jSplitPane3.setDividerLocation(150);
+ this.jSplitPane4.setDividerLocation(150);
+ }
+
+ public VerifierAppFrame() {
+ super();
+ this.jSplitPane1 = new JSplitPane();
+ this.jPanel1 = new JPanel();
+ this.jPanel2 = new JPanel();
+ this.jSplitPane2 = new JSplitPane();
+ this.jPanel3 = new JPanel();
+ this.classNamesJList = new JList();
+ this.gridLayout1 = new GridLayout();
+ this.messagesPanel = new JPanel();
+ this.gridLayout2 = new GridLayout();
+ this.jMenuBar1 = new JMenuBar();
+ this.jMenu1 = new JMenu();
+ this.jScrollPane1 = new JScrollPane();
+ this.messagesScrollPane = new JScrollPane();
+ this.jScrollPane3 = new JScrollPane();
+ this.gridLayout4 = new GridLayout();
+ this.jScrollPane4 = new JScrollPane();
+ this.cardLayout1 = new CardLayout();
+ this.JUSTICE_VERSION = "JustIce by Enver Haase";
+ this.gridLayout3 = new GridLayout();
+ this.pass1TextPane = new JTextPane();
+ this.pass2TextPane = new JTextPane();
+ this.messagesTextPane = new JTextPane();
+ this.newFileMenuItem = new JMenuItem();
+ this.jSplitPane3 = new JSplitPane();
+ this.jSplitPane4 = new JSplitPane();
+ this.jScrollPane2 = new JScrollPane();
+ this.jScrollPane5 = new JScrollPane();
+ this.jScrollPane6 = new JScrollPane();
+ this.jScrollPane7 = new JScrollPane();
+ this.pass3aJList = new JList();
+ this.pass3bJList = new JList();
+ this.pass3aTextPane = new JTextPane();
+ this.pass3bTextPane = new JTextPane();
+ this.jMenu2 = new JMenu();
+ this.whatisMenuItem = new JMenuItem();
+ this.aboutMenuItem = new JMenuItem();
+ this.enableEvents(64L);
+ try {
+ this.jbInit();
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ @Override
+ public void processWindowEvent(WindowEvent windowEvent) {
+ super.processWindowEvent(windowEvent);
+ if (windowEvent.getID() == 201) {
+ System.exit(0);
+ }
+ }
+
+ public void verify() throws ClassNotFoundException {
+ this.setTitle("PLEASE WAIT");
+ Verifier verifier;
+ Verifier verifier2 = verifier = VerifierFactory.getVerifier(this.text);
+ verifier2.flush();
+ VerificationResult verificationResult;
+ if ((verificationResult = verifier2.createVerificationResult()).getStatus() == 2) {
+ this.pass1TextPane.setText(verificationResult.getDetailMessage());
+ this.pass1TextPane.setBackground(Color.red);
+ this.pass2TextPane.setText("");
+ this.pass2TextPane.setBackground(Color.yellow);
+ this.pass3aTextPane.setText("");
+ this.pass3aJList.setListData(new Object[0]);
+ this.pass3aTextPane.setBackground(Color.yellow);
+ this.pass3bTextPane.setText("");
+ this.pass3bJList.setListData(new Object[0]);
+ verifier2 = verifier;
+ this.pass3bTextPane.setBackground(Color.yellow);
+ } else {
+ this.pass1TextPane.setBackground(Color.green);
+ this.pass1TextPane.setText(verificationResult.getDetailMessage());
+ VerificationResult verificationResult2;
+ if ((verificationResult2 = verifier.createVerificationResult2()).getStatus() == 2) {
+ this.pass2TextPane.setText(verificationResult2.getDetailMessage());
+ this.pass2TextPane.setBackground(Color.red);
+ this.pass3aTextPane.setText("");
+ this.pass3aTextPane.setBackground(Color.yellow);
+ this.pass3aJList.setListData(new Object[0]);
+ this.pass3bTextPane.setText("");
+ this.pass3bTextPane.setBackground(Color.yellow);
+ this.pass3bJList.setListData(new Object[0]);
+ verifier2 = verifier;
+ } else {
+ this.pass2TextPane.setText(verificationResult2.getDetailMessage());
+ this.pass2TextPane.setBackground(Color.green);
+ JavaClass javaClass;
+ String[] texts =
+ new String[(javaClass = Repository.lookupClass(this.text)).getMethods().length];
+ int value;
+ for (int value2 = value = 0; value2 < javaClass.getMethods().length; value2 = value) {
+ String text2 =
+ javaClass.getMethods()[value].toString().replace('\n', ' ').replace('\t', ' ');
+ int value3 = value;
+ value++;
+ texts[value3] = text2;
+ }
+ this.pass3aJList.setListData(texts);
+ this.pass3aJList.setSelectionInterval(0, javaClass.getMethods().length - 1);
+ this.pass3bJList.setListData(texts);
+ this.pass3bJList.setSelectionInterval(0, javaClass.getMethods().length - 1);
+ verifier2 = verifier;
+ }
+ }
+ String[] messages = verifier2.getMessages();
+ this.messagesTextPane.setBackground(messages.length == 0 ? Color.green : Color.yellow);
+ String text3 = "";
+ int value4;
+ for (int value5 = value4 = 0; value5 < messages.length; value5 = value4) {
+ messages[value4] = messages[value4].replace('\n', ' ');
+ StringBuilder stringBuilder = new StringBuilder().insert(0, text3).append(messages[value4]);
+ value4++;
+ text3 = stringBuilder.append((String) "\n\n").toString();
+ }
+ this.messagesTextPane.setText(text3);
+ this.setTitle(this.text + " - " + this.JUSTICE_VERSION);
+ }
+
+ public void aboutMenuItem_actionPerformed(ActionEvent actionEvent) {
+ JOptionPane.showMessageDialog(
+ this,
+ "JustIce is a Java class file verifier.\n"
+ + "It was implemented by Enver Haase in 2001, 2002.\n"
+ + "",
+ this.JUSTICE_VERSION,
+ 1);
+ }
+
+ public void newFileMenuItem_actionPerformed(ActionEvent actionEvent) {
+ String text;
+ if ((text =
+ JOptionPane.showInputDialog(
+ "Please enter the fully qualified name of a class or interface to verify:"))
+ != null
+ && !text.equals("")) {
+ VerifierFactory.getVerifier(text);
+ this.classNamesJList.setSelectedValue(text, true);
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/VerifierFactory.java b/src/main/java/com/allatori/lib/bcel/verifier/VerifierFactory.java
new file mode 100644
index 0000000..8dc7de5
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/VerifierFactory.java
@@ -0,0 +1,46 @@
+package com.allatori.lib.bcel.verifier;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+public class VerifierFactory {
+
+ public static Map hashMap = new HashMap();
+
+ public static List observers = new Vector();
+
+ public static void notify(String text) {
+ Iterator iterator2;
+ for (Iterator iterator3 = iterator2 = observers.iterator();
+ iterator3.hasNext();
+ iterator3 = iterator2) {
+ ((VerifierFactoryObserver) iterator2.next()).update(text);
+ }
+ }
+
+ public static void detach(VerifierFactoryObserver verifierFactoryObserver) {
+ observers.remove(verifierFactoryObserver);
+ }
+
+ public static Verifier getVerifier(String text) {
+ Verifier verifier;
+ if ((verifier = (Verifier) hashMap.get(text)) == null) {
+ verifier = new Verifier(text);
+ hashMap.put(text, verifier);
+ notify(text);
+ }
+ return verifier;
+ }
+
+ public static void attach(VerifierFactoryObserver verifierFactoryObserver) {
+ observers.add(verifierFactoryObserver);
+ }
+
+ public static Verifier[] getVerifiers() {
+ Verifier[] verifiers = new Verifier[hashMap.values().size()];
+ return (Verifier[]) hashMap.values().toArray(verifiers);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/VerifierFactoryListModel.java b/src/main/java/com/allatori/lib/bcel/verifier/VerifierFactoryListModel.java
new file mode 100644
index 0000000..86d4ae5
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/VerifierFactoryListModel.java
@@ -0,0 +1,63 @@
+package com.allatori.lib.bcel.verifier;
+
+import java.util.ArrayList;
+import java.util.TreeSet;
+import javax.swing.ListModel;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+
+public class VerifierFactoryListModel implements VerifierFactoryObserver, ListModel {
+
+ public TreeSet cache;
+
+ public ArrayList listeners = new ArrayList();
+
+ @Override
+ public synchronized void addListDataListener(ListDataListener listDataListener) {
+ this.listeners.add(listDataListener);
+ }
+
+ public VerifierFactoryListModel() {
+ this.cache = new TreeSet();
+ VerifierFactory.attach(this);
+ this.update(null);
+ }
+
+ @Override
+ public synchronized Object getElementAt(int value) {
+ return this.cache.toArray()[value];
+ }
+
+ @Override
+ public synchronized void removeListDataListener(ListDataListener listDataListener) {
+ this.listeners.remove(listDataListener);
+ }
+
+ @Override
+ public synchronized void update(String text) {
+ int size2 = this.listeners.size();
+ Verifier[] verifiers;
+ int value = (verifiers = VerifierFactory.getVerifiers()).length;
+ int value2 = 0;
+ this.cache.clear();
+ for (int index = 0; value2 < value; value2 = index) {
+ int value3 = index;
+ Verifier[] verifiers2 = verifiers;
+ TreeSet treeSet = this.cache;
+ index++;
+ treeSet.add(verifiers2[value3].getClassName());
+ }
+ int value4;
+ for (int value5 = value4 = 0; value5 < size2; value5 = value4) {
+ ListDataEvent listDataEvent = new ListDataEvent(this, 0, 0, value - 1);
+ ListDataListener listDataListener = (ListDataListener) this.listeners.get(value4);
+ value4++;
+ listDataListener.contentsChanged(listDataEvent);
+ }
+ }
+
+ @Override
+ public synchronized int getSize() {
+ return this.cache.size();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/VerifierFactoryObserver.java b/src/main/java/com/allatori/lib/bcel/verifier/VerifierFactoryObserver.java
new file mode 100644
index 0000000..29e9082
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/VerifierFactoryObserver.java
@@ -0,0 +1,6 @@
+package com.allatori.lib.bcel.verifier;
+
+public interface VerifierFactoryObserver {
+
+ void update(String text);
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/VerifyDialog$IvjEventHandler.java b/src/main/java/com/allatori/lib/bcel/verifier/VerifyDialog$IvjEventHandler.java
new file mode 100644
index 0000000..8c45b2a
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/VerifyDialog$IvjEventHandler.java
@@ -0,0 +1,30 @@
+package com.allatori.lib.bcel.verifier;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class VerifyDialog$IvjEventHandler implements ActionListener {
+
+ public final VerifyDialog this$0;
+
+ @Override
+ public void actionPerformed(ActionEvent actionEvent) {
+ if (actionEvent.getSource() == VerifyDialog.getJButton3(this.this$0)) {
+ VerifyDialog.processActionEvent(this.this$0, actionEvent);
+ }
+ if (actionEvent.getSource() == VerifyDialog.getJButton2(this.this$0)) {
+ VerifyDialog.processActionEvent2(this.this$0, actionEvent);
+ }
+ if (actionEvent.getSource() == VerifyDialog.getJButton(this.this$0)) {
+ VerifyDialog.processActionEvent4(this.this$0, actionEvent);
+ }
+ if (actionEvent.getSource() == VerifyDialog.getJButton4(this.this$0)) {
+ VerifyDialog.processActionEvent3(this.this$0, actionEvent);
+ }
+ }
+
+ public VerifyDialog$IvjEventHandler(VerifyDialog verifyDialog) {
+ super();
+ this.this$0 = verifyDialog;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/VerifyDialog.java b/src/main/java/com/allatori/lib/bcel/verifier/VerifyDialog.java
new file mode 100644
index 0000000..edbc68a
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/VerifyDialog.java
@@ -0,0 +1,531 @@
+package com.allatori.lib.bcel.verifier;
+
+import com.allatori.lib.bcel.Repository;
+import com.allatori.lib.bcel.verifier.ui.VerifierWindowListener;
+import java.awt.Color;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.SystemColor;
+import java.awt.event.ActionEvent;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+
+public class VerifyDialog extends JDialog {
+
+ public JPanel ivjPass3Panel;
+
+ public JButton ivjPass3Button;
+
+ public JPanel ivjJDialogContentPane = null;
+
+ public JButton ivjPass1Button;
+
+ public static int classes_to_verify;
+
+ public JPanel ivjPass1Panel = null;
+
+ public String class_name;
+
+ public JPanel ivjPass2Panel = null;
+
+ public JButton ivjFlushButton;
+
+ public JButton ivjPass2Button;
+
+ public VerifyDialog$IvjEventHandler ivjEventHandler;
+
+ public JButton getPass3Button() {
+ if (this.ivjPass3Button == null) {
+ try {
+ this.ivjPass3Button = new JButton();
+ this.ivjPass3Button.setName("Pass3Button");
+ this.ivjPass3Button.setText("Passes 3a+3b: Verify code arrays");
+ this.ivjPass3Button.setBackground(SystemColor.controlHighlight);
+ this.ivjPass3Button.setBounds(100, 160, 300, 30);
+ this.ivjPass3Button.setActionCommand("Button2");
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ return this.ivjPass3Button;
+ }
+ return this.ivjPass3Button;
+ } else {
+ return this.ivjPass3Button;
+ }
+ }
+
+ public void processActionEvent(ActionEvent actionEvent) {
+ try {
+ this.flushButton_ActionPerformed(actionEvent);
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ }
+ }
+
+ public VerifyDialog(Frame frame, String text) {
+ super(frame, text);
+ this.ivjJDialogContentPane = null;
+ this.ivjPass1Panel = null;
+ this.ivjPass2Panel = null;
+ this.ivjPass3Panel = null;
+ this.ivjPass1Button = null;
+ this.ivjPass2Button = null;
+ this.ivjPass3Button = null;
+ this.ivjEventHandler = new VerifyDialog$IvjEventHandler(this);
+ this.class_name = "java.lang.Object";
+ this.ivjFlushButton = null;
+ }
+
+ public VerifyDialog(Dialog dialog) {
+ super(dialog);
+ this.ivjJDialogContentPane = null;
+ this.ivjPass1Panel = null;
+ this.ivjPass2Panel = null;
+ this.ivjPass3Panel = null;
+ this.ivjPass1Button = null;
+ this.ivjPass2Button = null;
+ this.ivjPass3Button = null;
+ this.ivjEventHandler = new VerifyDialog$IvjEventHandler(this);
+ this.class_name = "java.lang.Object";
+ this.ivjFlushButton = null;
+ }
+
+ public VerifyDialog(String text) {
+ super();
+ String text2 = text;
+ this.ivjJDialogContentPane = null;
+ this.ivjPass1Panel = null;
+ this.ivjPass2Panel = null;
+ this.ivjPass3Panel = null;
+ this.ivjPass1Button = null;
+ this.ivjPass2Button = null;
+ this.ivjPass3Button = null;
+ this.ivjEventHandler = new VerifyDialog$IvjEventHandler(this);
+ this.class_name = "java.lang.Object";
+ this.ivjFlushButton = null;
+ int value;
+ if ((value = text2.lastIndexOf(".class")) != -1) {
+ text2 = text2.substring(0, value);
+ }
+ String text3 = text2.replace('/', '.');
+ this.class_name = text3;
+ this.initialize();
+ }
+
+ public static void processActionEvent(VerifyDialog verifyDialog, ActionEvent actionEvent) {
+ verifyDialog.processActionEvent4(actionEvent);
+ }
+
+ public static JButton getJButton(VerifyDialog verifyDialog) {
+ return verifyDialog.getPass3Button();
+ }
+
+ public void pass2Button_ActionPerformed(ActionEvent actionEvent) {
+ this.pass1Button_ActionPerformed(actionEvent);
+ VerificationResult verificationResult;
+ if ((verificationResult =
+ VerifierFactory.getVerifier(this.class_name).createVerificationResult2())
+ .getStatus()
+ == 1) {
+ this.getPass2Panel().setBackground(Color.green);
+ this.getPass2Panel().repaint();
+ }
+ if (verificationResult.getStatus() == 0) {
+ this.getPass2Panel().setBackground(Color.yellow);
+ this.getPass2Panel().repaint();
+ }
+ if (verificationResult.getStatus() == 2) {
+ this.getPass2Panel().setBackground(Color.red);
+ this.getPass2Panel().repaint();
+ }
+ }
+
+ public void processActionEvent2(ActionEvent actionEvent) {
+ try {
+ this.pass4Button_ActionPerformed(actionEvent);
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ }
+ }
+
+ public void initialize() {
+ VerifyDialog verifyDialog;
+ label12:
+ {
+ try {
+ this.setName("VerifyDialog");
+ this.setDefaultCloseOperation(2);
+ this.setSize(430, 280);
+ this.setVisible(true);
+ this.setModal(true);
+ this.setResizable(false);
+ this.setContentPane(this.getJDialogContentPane());
+ this.initConnections();
+ } catch (Throwable throwable) {
+ verifyDialog = this;
+ this.handleException(throwable);
+ break label12;
+ }
+ verifyDialog = this;
+ }
+ verifyDialog.setTitle("'" + this.class_name + "' verification - JustIce / BCEL");
+ }
+
+ public VerifyDialog(Dialog dialog, String text, boolean matches) {
+ super(dialog, text, matches);
+ this.ivjJDialogContentPane = null;
+ this.ivjPass1Panel = null;
+ this.ivjPass2Panel = null;
+ this.ivjPass3Panel = null;
+ this.ivjPass1Button = null;
+ this.ivjPass2Button = null;
+ this.ivjPass3Button = null;
+ this.ivjEventHandler = new VerifyDialog$IvjEventHandler(this);
+ this.class_name = "java.lang.Object";
+ this.ivjFlushButton = null;
+ }
+
+ public JButton getPass2Button() {
+ if (this.ivjPass2Button == null) {
+ try {
+ this.ivjPass2Button = new JButton();
+ this.ivjPass2Button.setName("Pass2Button");
+ this.ivjPass2Button.setText("Pass 2: Verify static .class file constraints");
+ this.ivjPass2Button.setBackground(SystemColor.controlHighlight);
+ this.ivjPass2Button.setBounds(100, 100, 300, 30);
+ this.ivjPass2Button.setActionCommand("Button2");
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ return this.ivjPass2Button;
+ }
+ return this.ivjPass2Button;
+ } else {
+ return this.ivjPass2Button;
+ }
+ }
+
+ public VerifyDialog(Frame frame) {
+ super(frame);
+ this.ivjJDialogContentPane = null;
+ this.ivjPass1Panel = null;
+ this.ivjPass2Panel = null;
+ this.ivjPass3Panel = null;
+ this.ivjPass1Button = null;
+ this.ivjPass2Button = null;
+ this.ivjPass3Button = null;
+ this.ivjEventHandler = new VerifyDialog$IvjEventHandler(this);
+ this.class_name = "java.lang.Object";
+ this.ivjFlushButton = null;
+ }
+
+ public void pass4Button_ActionPerformed(ActionEvent actionEvent) {
+ this.pass2Button_ActionPerformed(actionEvent);
+ Color color = Color.green;
+ Verifier verifier;
+ if ((verifier = VerifierFactory.getVerifier(this.class_name))
+ .createVerificationResult2()
+ .getStatus()
+ == 1) {
+ try {
+ int value = Repository.lookupClass(this.class_name).getMethods().length;
+ for (int index = 0; index < value; index++) {
+ if (verifier.doPass3b(index).getStatus() != 1) {
+ color = Color.red;
+ break;
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ classNotFoundException.printStackTrace();
+ }
+ } else {
+ color = Color.yellow;
+ }
+ this.getPass3Panel().setBackground(color);
+ this.getPass3Panel().repaint();
+ }
+
+ public JPanel getJDialogContentPane() {
+ if (this.ivjJDialogContentPane == null) {
+ try {
+ this.ivjJDialogContentPane = new JPanel();
+ this.ivjJDialogContentPane.setName("JDialogContentPane");
+ this.ivjJDialogContentPane.setLayout(null);
+ this.getJDialogContentPane().add(this.getPass1Panel(), this.getPass1Panel().getName());
+ this.getJDialogContentPane().add(this.getPass3Panel(), this.getPass3Panel().getName());
+ this.getJDialogContentPane().add(this.getPass2Panel(), this.getPass2Panel().getName());
+ this.getJDialogContentPane().add(this.getPass1Button(), this.getPass1Button().getName());
+ this.getJDialogContentPane().add(this.getPass2Button(), this.getPass2Button().getName());
+ this.getJDialogContentPane().add(this.getPass3Button(), this.getPass3Button().getName());
+ this.getJDialogContentPane().add(this.getFlushButton(), this.getFlushButton().getName());
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ return this.ivjJDialogContentPane;
+ }
+ return this.ivjJDialogContentPane;
+ } else {
+ return this.ivjJDialogContentPane;
+ }
+ }
+
+ public VerifyDialog(Dialog dialog, boolean matches) {
+ super(dialog, matches);
+ this.ivjJDialogContentPane = null;
+ this.ivjPass1Panel = null;
+ this.ivjPass2Panel = null;
+ this.ivjPass3Panel = null;
+ this.ivjPass1Button = null;
+ this.ivjPass2Button = null;
+ this.ivjPass3Button = null;
+ this.ivjEventHandler = new VerifyDialog$IvjEventHandler(this);
+ this.class_name = "java.lang.Object";
+ this.ivjFlushButton = null;
+ }
+
+ public static JButton getJButton2(VerifyDialog verifyDialog) {
+ return verifyDialog.getPass2Button();
+ }
+
+ public void initConnections() throws Exception {
+ this.getPass1Button().addActionListener(this.ivjEventHandler);
+ this.getPass2Button().addActionListener(this.ivjEventHandler);
+ this.getPass3Button().addActionListener(this.ivjEventHandler);
+ this.getFlushButton().addActionListener(this.ivjEventHandler);
+ }
+
+ public void processActionEvent3(ActionEvent actionEvent) {
+ try {
+ this.pass2Button_ActionPerformed(actionEvent);
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ }
+ }
+
+ public static void processActionEvent2(VerifyDialog verifyDialog, ActionEvent actionEvent) {
+ verifyDialog.processActionEvent3(actionEvent);
+ }
+
+ public VerifyDialog(Frame frame, String text, boolean matches) {
+ super(frame, text, matches);
+ this.ivjJDialogContentPane = null;
+ this.ivjPass1Panel = null;
+ this.ivjPass2Panel = null;
+ this.ivjPass3Panel = null;
+ this.ivjPass1Button = null;
+ this.ivjPass2Button = null;
+ this.ivjPass3Button = null;
+ this.ivjEventHandler = new VerifyDialog$IvjEventHandler(this);
+ this.class_name = "java.lang.Object";
+ this.ivjFlushButton = null;
+ }
+
+ public VerifyDialog(Frame frame, boolean matches) {
+ super(frame, matches);
+ this.ivjJDialogContentPane = null;
+ this.ivjPass1Panel = null;
+ this.ivjPass2Panel = null;
+ this.ivjPass3Panel = null;
+ this.ivjPass1Button = null;
+ this.ivjPass2Button = null;
+ this.ivjPass3Button = null;
+ this.ivjEventHandler = new VerifyDialog$IvjEventHandler(this);
+ this.class_name = "java.lang.Object";
+ this.ivjFlushButton = null;
+ }
+
+ public static void main(String[] texts) {
+ classes_to_verify = texts.length;
+ int value;
+ for (int value2 = value = 0; value2 < texts.length; value2 = ++value) {
+ try {
+ VerifyDialog verifyDialog = new VerifyDialog(texts[value]);
+ verifyDialog.setModal(true);
+ verifyDialog.addWindowListener(new VerifierWindowListener());
+ verifyDialog.setVisible(true);
+ } catch (Throwable throwable) {
+ System.err.println("Exception occurred in main() of javax.swing.JDialog");
+ throwable.printStackTrace(System.out);
+ }
+ }
+ }
+
+ public void handleException(Throwable throwable) {
+ System.out.println("--------- UNCAUGHT EXCEPTION ---------");
+ throwable.printStackTrace(System.out);
+ }
+
+ public VerifyDialog() {
+ this.ivjPass3Panel = null;
+ this.ivjPass1Button = null;
+ this.ivjPass2Button = null;
+ this.ivjPass3Button = null;
+ this.ivjEventHandler = new VerifyDialog$IvjEventHandler(this);
+ this.class_name = "java.lang.Object";
+ this.ivjFlushButton = null;
+ this.initialize();
+ }
+
+ public static JButton getJButton3(VerifyDialog verifyDialog) {
+ return verifyDialog.getPass1Button();
+ }
+
+ public VerifyDialog(Dialog dialog, String text) {
+ super(dialog, text);
+ this.ivjJDialogContentPane = null;
+ this.ivjPass1Panel = null;
+ this.ivjPass2Panel = null;
+ this.ivjPass3Panel = null;
+ this.ivjPass1Button = null;
+ this.ivjPass2Button = null;
+ this.ivjPass3Button = null;
+ this.ivjEventHandler = new VerifyDialog$IvjEventHandler(this);
+ this.class_name = "java.lang.Object";
+ this.ivjFlushButton = null;
+ }
+
+ public static void processActionEvent3(VerifyDialog verifyDialog, ActionEvent actionEvent) {
+ verifyDialog.processActionEvent(actionEvent);
+ }
+
+ public JButton getFlushButton() {
+ if (this.ivjFlushButton == null) {
+ try {
+ this.ivjFlushButton = new JButton();
+ this.ivjFlushButton.setName("FlushButton");
+ this.ivjFlushButton.setText("Flush: Forget old verification results");
+ this.ivjFlushButton.setBackground(SystemColor.controlHighlight);
+ this.ivjFlushButton.setBounds(60, 215, 300, 30);
+ this.ivjFlushButton.setForeground(Color.red);
+ this.ivjFlushButton.setActionCommand("FlushButton");
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ return this.ivjFlushButton;
+ }
+ return this.ivjFlushButton;
+ } else {
+ return this.ivjFlushButton;
+ }
+ }
+
+ public JPanel getPass2Panel() {
+ if (this.ivjPass2Panel == null) {
+ try {
+ this.ivjPass2Panel = new JPanel();
+ this.ivjPass2Panel.setName("Pass2Panel");
+ this.ivjPass2Panel.setLayout(null);
+ this.ivjPass2Panel.setBackground(SystemColor.controlShadow);
+ this.ivjPass2Panel.setBounds(30, 90, 50, 50);
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ return this.ivjPass2Panel;
+ }
+ return this.ivjPass2Panel;
+ } else {
+ return this.ivjPass2Panel;
+ }
+ }
+
+ public static void processActionEvent4(VerifyDialog verifyDialog, ActionEvent actionEvent) {
+ verifyDialog.processActionEvent2(actionEvent);
+ }
+
+ public void flushButton_ActionPerformed(ActionEvent actionEvent) {
+ VerifierFactory.getVerifier(this.class_name).flush();
+ Repository.removeClass(this.class_name);
+ this.getPass1Panel().setBackground(Color.gray);
+ this.getPass1Panel().repaint();
+ this.getPass2Panel().setBackground(Color.gray);
+ this.getPass2Panel().repaint();
+ this.getPass3Panel().setBackground(Color.gray);
+ this.getPass3Panel().repaint();
+ }
+
+ public JButton getPass1Button() {
+ if (this.ivjPass1Button == null) {
+ try {
+ this.ivjPass1Button = new JButton();
+ this.ivjPass1Button.setName("Pass1Button");
+ this.ivjPass1Button.setText("Pass1: Verify binary layout of .class file");
+ this.ivjPass1Button.setBackground(SystemColor.controlHighlight);
+ this.ivjPass1Button.setBounds(100, 40, 300, 30);
+ this.ivjPass1Button.setActionCommand("Button1");
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ return this.ivjPass1Button;
+ }
+ return this.ivjPass1Button;
+ } else {
+ return this.ivjPass1Button;
+ }
+ }
+
+ public static int getClasses_to_verify() {
+ return classes_to_verify;
+ }
+
+ public JPanel getPass3Panel() {
+ if (this.ivjPass3Panel == null) {
+ try {
+ this.ivjPass3Panel = new JPanel();
+ this.ivjPass3Panel.setName("Pass3Panel");
+ this.ivjPass3Panel.setLayout(null);
+ this.ivjPass3Panel.setBackground(SystemColor.controlShadow);
+ this.ivjPass3Panel.setBounds(30, 150, 50, 50);
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ return this.ivjPass3Panel;
+ }
+ return this.ivjPass3Panel;
+ } else {
+ return this.ivjPass3Panel;
+ }
+ }
+
+ public void pass1Button_ActionPerformed(ActionEvent actionEvent) {
+ VerificationResult verificationResult;
+ if ((verificationResult =
+ VerifierFactory.getVerifier(this.class_name).createVerificationResult())
+ .getStatus()
+ == 1) {
+ this.getPass1Panel().setBackground(Color.green);
+ this.getPass1Panel().repaint();
+ }
+ if (verificationResult.getStatus() == 2) {
+ this.getPass1Panel().setBackground(Color.red);
+ this.getPass1Panel().repaint();
+ }
+ }
+
+ public static JButton getJButton4(VerifyDialog verifyDialog) {
+ return verifyDialog.getFlushButton();
+ }
+
+ public JPanel getPass1Panel() {
+ if (this.ivjPass1Panel == null) {
+ try {
+ this.ivjPass1Panel = new JPanel();
+ this.ivjPass1Panel.setName("Pass1Panel");
+ this.ivjPass1Panel.setLayout(null);
+ this.ivjPass1Panel.setBackground(SystemColor.controlShadow);
+ this.ivjPass1Panel.setBounds(30, 30, 50, 50);
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ return this.ivjPass1Panel;
+ }
+ return this.ivjPass1Panel;
+ } else {
+ return this.ivjPass1Panel;
+ }
+ }
+
+ public static int calculateCount() {
+ return classes_to_verify--;
+ }
+
+ public void processActionEvent4(ActionEvent actionEvent) {
+ try {
+ this.pass1Button_ActionPerformed(actionEvent);
+ } catch (Throwable throwable) {
+ this.handleException(throwable);
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/AssertionViolatedException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/AssertionViolatedException.java
new file mode 100644
index 0000000..145a2ea
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/AssertionViolatedException.java
@@ -0,0 +1,38 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public final class AssertionViolatedException extends RuntimeException {
+
+ public String detailMessage;
+
+ public AssertionViolatedException(String text) {
+ super("INTERNAL ERROR: " + text);
+ this.detailMessage = super.getMessage();
+ }
+
+ public static void main(String[] texts) {
+ AssertionViolatedException assertionViolatedException = new AssertionViolatedException("Oops!");
+ assertionViolatedException.extendMessage("\nFOUND:\n\t", "\nExiting!!\n");
+ throw assertionViolatedException;
+ }
+
+ @Override
+ public String getMessage() {
+ return this.detailMessage;
+ }
+
+ public void extendMessage(String text, String text2) {
+ String text3 = text2;
+ if (text == null) {
+ text = "";
+ }
+ if (this.detailMessage == null) {
+ this.detailMessage = "";
+ }
+ if (text3 == null) {
+ text3 = "";
+ }
+ this.detailMessage = "" + text + this.detailMessage + text3;
+ }
+
+ public AssertionViolatedException() {}
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/ClassConstraintException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/ClassConstraintException.java
new file mode 100644
index 0000000..3363c3e
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/ClassConstraintException.java
@@ -0,0 +1,10 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public class ClassConstraintException extends LoadingException {
+
+ public ClassConstraintException(String text) {
+ super(text);
+ }
+
+ public ClassConstraintException() {}
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/CodeConstraintException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/CodeConstraintException.java
new file mode 100644
index 0000000..4943a9b
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/CodeConstraintException.java
@@ -0,0 +1,10 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public abstract class CodeConstraintException extends VerificationException {
+
+ public CodeConstraintException(String text) {
+ super(text);
+ }
+
+ public CodeConstraintException() {}
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/InvalidMethodException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/InvalidMethodException.java
new file mode 100644
index 0000000..840609f
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/InvalidMethodException.java
@@ -0,0 +1,8 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public class InvalidMethodException extends RuntimeException {
+
+ public InvalidMethodException(String text) {
+ super(text);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/LinkingConstraintException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/LinkingConstraintException.java
new file mode 100644
index 0000000..15c0440
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/LinkingConstraintException.java
@@ -0,0 +1,3 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public class LinkingConstraintException extends StructuralCodeConstraintException {}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/LoadingException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/LoadingException.java
new file mode 100644
index 0000000..eb1ff47
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/LoadingException.java
@@ -0,0 +1,10 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public class LoadingException extends VerificationException {
+
+ public LoadingException() {}
+
+ public LoadingException(String text) {
+ super(text);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/StaticCodeConstraintException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/StaticCodeConstraintException.java
new file mode 100644
index 0000000..0cf7191
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/StaticCodeConstraintException.java
@@ -0,0 +1,8 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public abstract class StaticCodeConstraintException extends CodeConstraintException {
+
+ public StaticCodeConstraintException(String text) {
+ super(text);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/StaticCodeInstructionConstraintException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/StaticCodeInstructionConstraintException.java
new file mode 100644
index 0000000..4b9cf8d
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/StaticCodeInstructionConstraintException.java
@@ -0,0 +1,8 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public class StaticCodeInstructionConstraintException extends StaticCodeConstraintException {
+
+ public StaticCodeInstructionConstraintException(String text) {
+ super(text);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/StaticCodeInstructionOperandConstraintException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/StaticCodeInstructionOperandConstraintException.java
new file mode 100644
index 0000000..7687f0b
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/StaticCodeInstructionOperandConstraintException.java
@@ -0,0 +1,8 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public class StaticCodeInstructionOperandConstraintException extends StaticCodeConstraintException {
+
+ public StaticCodeInstructionOperandConstraintException(String text) {
+ super(text);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/StructuralCodeConstraintException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/StructuralCodeConstraintException.java
new file mode 100644
index 0000000..d8c9f4f
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/StructuralCodeConstraintException.java
@@ -0,0 +1,10 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public class StructuralCodeConstraintException extends CodeConstraintException {
+
+ public StructuralCodeConstraintException(String text) {
+ super(text);
+ }
+
+ public StructuralCodeConstraintException() {}
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/Utility.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/Utility.java
new file mode 100644
index 0000000..0f80542
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/Utility.java
@@ -0,0 +1,14 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+public final class Utility {
+
+ public static String getStackTrace(Throwable throwable) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(stringWriter);
+ throwable.printStackTrace(printWriter);
+ return stringWriter.toString();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/VerificationException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/VerificationException.java
new file mode 100644
index 0000000..3b29112
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/VerificationException.java
@@ -0,0 +1,10 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public abstract class VerificationException extends VerifierConstraintViolatedException {
+
+ public VerificationException(String text) {
+ super(text);
+ }
+
+ public VerificationException() {}
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/exc/VerifierConstraintViolatedException.java b/src/main/java/com/allatori/lib/bcel/verifier/exc/VerifierConstraintViolatedException.java
new file mode 100644
index 0000000..fd19e14
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/exc/VerifierConstraintViolatedException.java
@@ -0,0 +1,32 @@
+package com.allatori.lib.bcel.verifier.exc;
+
+public abstract class VerifierConstraintViolatedException extends RuntimeException {
+
+ public String detailMessage;
+
+ public VerifierConstraintViolatedException(String detailMessage) {
+ super(detailMessage);
+ this.detailMessage = detailMessage;
+ }
+
+ @Override
+ public String getMessage() {
+ return this.detailMessage;
+ }
+
+ public VerifierConstraintViolatedException() {}
+
+ public void extendMessage(String text, String text2) {
+ String text3 = text2;
+ if (text == null) {
+ text = "";
+ }
+ if (this.detailMessage == null) {
+ this.detailMessage = "";
+ }
+ if (text3 == null) {
+ text3 = "";
+ }
+ this.detailMessage = "" + text + this.detailMessage + text3;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/IntList.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/IntList.java
new file mode 100644
index 0000000..049cc40
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/IntList.java
@@ -0,0 +1,25 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class IntList {
+
+ public List theList = new ArrayList();
+
+ public void add(int value) {
+ this.theList.add(new Integer(value));
+ }
+
+ public boolean contains(int value) {
+ Integer[] values = new Integer[this.theList.size()];
+ this.theList.toArray(values);
+ int value2 = 0;
+ for (int value3 = value2; value3 < values.length; value3 = ++value2) {
+ if (value == values[value2]) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/LocalVariableInfo.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/LocalVariableInfo.java
new file mode 100644
index 0000000..270a7ef
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/LocalVariableInfo.java
@@ -0,0 +1,62 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.lib.bcel.verifier.exc.ClassConstraintException;
+import java.util.Hashtable;
+
+public class LocalVariableInfo {
+
+ public Hashtable types = new Hashtable();
+
+ public Hashtable names = new Hashtable();
+
+ public Type getType(int value) {
+ return (Type) this.types.get(Integer.toString(value));
+ }
+
+ public void add(int value, String text, Type type) {
+ if (this.getName(value) != null && !this.getName(value).equals(text)) {
+ throw new ClassConstraintException(
+ ("At bytecode offset '"
+ + value
+ + "' a local variable has two different names: '"
+ + this.getName(value)
+ + "' and '"
+ + text
+ + "'."));
+ }
+ if (this.getType(value) != null && !this.getType(value).equals(type)) {
+ throw new ClassConstraintException(
+ ("At bytecode offset '"
+ + value
+ + "' a local variable has two different types: '"
+ + this.getType(value)
+ + "' and '"
+ + type
+ + "'."));
+ }
+ this.setName(value, text);
+ this.setType(value, type);
+ }
+
+ public void setName(int value, String text) {
+ this.names.put(Integer.toString(value), text);
+ }
+
+ public void setType(int value, Type type) {
+ this.types.put(Integer.toString(value), type);
+ }
+
+ public void add(String text, int value, int value2, Type type) {
+ int value3;
+ for (int value4 = value3 = value; value4 <= value + value2; value4 = value3) {
+ int value5 = value3;
+ value3++;
+ this.add(value5, text, type);
+ }
+ }
+
+ public String getName(int value) {
+ return (String) this.names.get(Integer.toString(value));
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/LocalVariablesInfo.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/LocalVariablesInfo.java
new file mode 100644
index 0000000..08763ff
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/LocalVariablesInfo.java
@@ -0,0 +1,47 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+
+public class LocalVariablesInfo {
+
+ public LocalVariableInfo[] localVariableInfos;
+
+ public void add(int value, String text, int value2, int value3, Type type) {
+ if (value >= 0 && value < this.localVariableInfos.length) {
+ this.localVariableInfos[value].add(text, value2, value3, type);
+ if (type == Type.LONG) {
+ this.localVariableInfos[value + 1].add(
+ text, value2, value3, UpperWordType.getUpperWordType());
+ }
+ if (type == Type.DOUBLE) {
+ this.localVariableInfos[value + 1].add(
+ text, value2, value3, UpperWordType2.getUpperWordType2());
+ }
+ } else {
+ throw new AssertionViolatedException(
+ "Slot number for local variable information out of range.");
+ }
+ }
+
+ public LocalVariablesInfo(int value) {
+ this.localVariableInfos = new LocalVariableInfo[value];
+ int value2;
+ for (int value3 = value2 = 0; value3 < value; value3 = value2) {
+ LocalVariableInfo[] localVariableInfos2 = this.localVariableInfos;
+ LocalVariableInfo localVariableInfo = new LocalVariableInfo();
+ int value4 = value2;
+ value2++;
+ localVariableInfos2[value4] = localVariableInfo;
+ }
+ }
+
+ public LocalVariableInfo getLocalVariableInfo(int value) {
+ if (value >= 0 && value < this.localVariableInfos.length) {
+ return this.localVariableInfos[value];
+ } else {
+ throw new AssertionViolatedException(
+ "Slot number for local variable information out of range.");
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass1Verifier.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass1Verifier.java
new file mode 100644
index 0000000..84efc0d
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass1Verifier.java
@@ -0,0 +1,71 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.internal.VerifierConstraintViolatedExceptionSupport;
+import com.allatori.lib.bcel.Repository;
+import com.allatori.lib.bcel.classfile.ClassFormatException;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.verifier.PassVerifier;
+import com.allatori.lib.bcel.verifier.VerificationResult;
+import com.allatori.lib.bcel.verifier.Verifier;
+import com.allatori.lib.bcel.verifier.exc.Utility;
+
+public final class Pass1Verifier extends PassVerifier {
+
+ public JavaClass jc;
+
+ public Verifier myOwner;
+
+ public JavaClass getJavaClass() {
+ if (this.jc == null) {
+ try {
+ this.jc = Repository.lookupClass(this.myOwner.getClassName());
+ } catch (ClassNotFoundException classNotFoundException) {
+ return this.jc;
+ }
+ return this.jc;
+ } else {
+ return this.jc;
+ }
+ }
+
+ @Override
+ public VerificationResult getVerificationResult() {
+ JavaClass javaClass;
+ try {
+ if ((javaClass = this.getJavaClass()) != null
+ && !this.myOwner.getClassName().equals(javaClass.getText2())) {
+ throw new VerifierConstraintViolatedExceptionSupport(
+ ("Wrong name: the internal name of the .class file '"
+ + javaClass.getText2()
+ + "' does not match the file's name '"
+ + this.myOwner.getClassName()
+ + "'."));
+ }
+ } catch (
+ VerifierConstraintViolatedExceptionSupport verifierConstraintViolatedExceptionSupport) {
+ return new VerificationResult(2, verifierConstraintViolatedExceptionSupport.getMessage());
+ } catch (ClassFormatException classFormatException) {
+ return new VerificationResult(2, classFormatException.getMessage());
+ } catch (RuntimeException runtimeException) {
+ return new VerificationResult(
+ 2,
+ "Parsing via BCEL did not succeed. "
+ + runtimeException.getClass().getName()
+ + " occured:\n"
+ + Utility.getStackTrace(runtimeException));
+ }
+ return javaClass != null
+ ? VerificationResult.VERIFICATION_RESULT2
+ : new VerificationResult(2, "Repository.lookup() failed. FILE NOT FOUND?");
+ }
+
+ public Pass1Verifier(Verifier verifier) {
+ super();
+ this.myOwner = verifier;
+ }
+
+ @Override
+ public String[] getMessages() {
+ return super.getMessages();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$1.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$1.java
new file mode 100644
index 0000000..aa727da
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$1.java
@@ -0,0 +1,3 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+public class Pass2Verifier$1 {}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$CPESSC_Visitor.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$CPESSC_Visitor.java
new file mode 100644
index 0000000..521b666
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$CPESSC_Visitor.java
@@ -0,0 +1,1223 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.lib.bcel.Repository;
+import com.allatori.lib.bcel.classfile.Attribute;
+import com.allatori.lib.bcel.classfile.ClassFormatException;
+import com.allatori.lib.bcel.classfile.Code;
+import com.allatori.lib.bcel.classfile.CodeException;
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.classfile.ConstantClass;
+import com.allatori.lib.bcel.classfile.ConstantDouble;
+import com.allatori.lib.bcel.classfile.ConstantFieldref;
+import com.allatori.lib.bcel.classfile.ConstantFloat;
+import com.allatori.lib.bcel.classfile.ConstantInteger;
+import com.allatori.lib.bcel.classfile.ConstantInterfaceMethodref;
+import com.allatori.lib.bcel.classfile.ConstantLong;
+import com.allatori.lib.bcel.classfile.ConstantMethodref;
+import com.allatori.lib.bcel.classfile.ConstantNameAndType;
+import com.allatori.lib.bcel.classfile.ConstantPool;
+import com.allatori.lib.bcel.classfile.ConstantString;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.classfile.ConstantValue;
+import com.allatori.lib.bcel.classfile.Deprecated;
+import com.allatori.lib.bcel.classfile.DescendingVisitor;
+import com.allatori.lib.bcel.classfile.EmptyVisitor;
+import com.allatori.lib.bcel.classfile.ExceptionTable;
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.classfile.InnerClass;
+import com.allatori.lib.bcel.classfile.InnerClasses;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.classfile.LineNumber;
+import com.allatori.lib.bcel.classfile.LineNumberTable;
+import com.allatori.lib.bcel.classfile.LocalVariable;
+import com.allatori.lib.bcel.classfile.LocalVariableTable;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.classfile.Node;
+import com.allatori.lib.bcel.classfile.SourceFile;
+import com.allatori.lib.bcel.classfile.Synthetic;
+import com.allatori.lib.bcel.classfile.Unknown;
+import com.allatori.lib.bcel.classfile.Visitor;
+import com.allatori.lib.bcel.generic.ArrayType;
+import com.allatori.lib.bcel.generic.ObjectType;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.lib.bcel.verifier.VerificationResult;
+import com.allatori.lib.bcel.verifier.VerifierFactory;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import com.allatori.lib.bcel.verifier.exc.ClassConstraintException;
+import com.allatori.lib.bcel.verifier.exc.LoadingException;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+
+public class Pass2Verifier$CPESSC_Visitor extends EmptyVisitor implements Visitor {
+
+ public Class CONST_Float;
+
+ public Set field_names;
+
+ public Set method_names_and_desc;
+
+ public Set field_names_and_desc;
+
+ public DescendingVisitor carrier;
+
+ public Class CONST_NameAndType;
+
+ public Class CONST_Long;
+
+ public Class CONST_Double;
+
+ public final JavaClass jc;
+
+ public final int cplen;
+
+ public Class CONST_Integer;
+
+ public Class CONST_Class;
+
+ public Class CONST_String;
+
+ public final ConstantPool cp;
+
+ public final Pass2Verifier this$0;
+
+ public Class CONST_Utf8;
+
+ @Override
+ public void visitField(Field field) {
+ if (this.jc.isEnabled17()) {
+ int value = 0;
+ if (field.isEnabled9()) {
+ value++;
+ }
+ if (field.isEnabled13()) {
+ value++;
+ }
+ if (field.isEnabled6()) {
+ value++;
+ }
+ if (value > 1) {
+ throw new LoadingException(
+ ("Field '"
+ + Pass2Verifier.getText(field)
+ + "' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC"
+ + " modifiers set."));
+ }
+ if (field.isEnabled3() && field.isEnabled()) {
+ throw new LoadingException(
+ ("Field '"
+ + Pass2Verifier.getText(field)
+ + "' must only have at most one of its ACC_FINAL, ACC_VOLATILE modifiers set."));
+ }
+ } else {
+ if (!field.isEnabled6()) {
+ throw new LoadingException(
+ ("Interface field '"
+ + Pass2Verifier.getText(field)
+ + "' must have the ACC_PUBLIC modifier set but hasn't!"));
+ }
+ if (!field.isEnabled11()) {
+ throw new LoadingException(
+ ("Interface field '"
+ + Pass2Verifier.getText(field)
+ + "' must have the ACC_STATIC modifier set but hasn't!"));
+ }
+ if (!field.isEnabled3()) {
+ throw new LoadingException(
+ ("Interface field '"
+ + Pass2Verifier.getText(field)
+ + "' must have the ACC_FINAL modifier set but hasn't!"));
+ }
+ }
+ if ((field.getAccess_flags2() & -224) > 0) {
+ this.this$0.addMessage(
+ "Field '"
+ + Pass2Verifier.getText(field)
+ + "' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED,"
+ + " ACC_STATIC, ACC_FINAL, ACC_VOLATILE, ACC_TRANSIENT set (ignored).");
+ }
+ this.checkIndex(field, field.getCount3(), this.CONST_Utf8);
+ String text;
+ if (!Pass2Verifier.matchesText(text = field.getText())) {
+ throw new LoadingException(
+ ("Field '"
+ + Pass2Verifier.getText(field)
+ + "' has illegal name '"
+ + field.getText()
+ + "'."));
+ }
+ this.checkIndex(field, field.getCount(), this.CONST_Utf8);
+ String bytes = ((ConstantUtf8) this.cp.getConstant(field.getCount())).getBytes();
+ try {
+ Type.getType(bytes);
+ } catch (ClassFormatException classFormatException) {
+ throw new LoadingException(
+ ("Illegal descriptor (==signature) '"
+ + bytes
+ + "' used by '"
+ + Pass2Verifier.getText(field)
+ + "'."));
+ }
+ String text2 = "" + text + bytes;
+ if (this.field_names_and_desc.contains(text2)) {
+ throw new LoadingException(
+ ("No two fields (like '"
+ + Pass2Verifier.getText(field)
+ + "') are allowed have same names and descriptors!"));
+ }
+ if (this.field_names.contains(text)) {
+ this.this$0.addMessage(
+ "More than one field of name '"
+ + text
+ + "' detected (but with different type descriptors). This is very unusual.");
+ }
+ this.field_names_and_desc.add(text2);
+ this.field_names.add(text);
+ Attribute[] attributes = field.getAttributes();
+ int value2 = 0;
+ for (int value3 = value2; value3 < attributes.length; value3 = ++value2) {
+ if (!(attributes[value2] instanceof ConstantValue)
+ && !(attributes[value2] instanceof Synthetic)
+ && !(attributes[value2] instanceof Deprecated)) {
+ this.this$0.addMessage(
+ "Attribute '"
+ + Pass2Verifier.getText(attributes[value2])
+ + "' as an attribute of Field '"
+ + Pass2Verifier.getText(field)
+ + "' is unknown and will therefore be ignored.");
+ }
+ if (!(attributes[value2] instanceof ConstantValue)) {
+ this.this$0.addMessage(
+ "Attribute '"
+ + Pass2Verifier.getText(attributes[value2])
+ + "' as an attribute of Field '"
+ + Pass2Verifier.getText(field)
+ + "' is not a ConstantValue and is therefore only of use for debuggers and such.");
+ }
+ }
+ }
+
+ @Override
+ public void visitLocalVariable(LocalVariable localVariable) {}
+
+ @Override
+ public void visitUnknown(Unknown unknown) {
+ this.checkIndex(unknown, unknown.getName_index(), this.CONST_Utf8);
+ this.this$0.addMessage(
+ "Unknown attribute '"
+ + Pass2Verifier.getText(unknown)
+ + "'. This attribute is not known in any context!");
+ }
+
+ @Override
+ public void visitLineNumberTable(LineNumberTable lineNumberTable) {
+ this.checkIndex(lineNumberTable, lineNumberTable.getName_index(), this.CONST_Utf8);
+ String text;
+ if (!(text = ((ConstantUtf8) this.cp.getConstant(lineNumberTable.getName_index())).getBytes())
+ .equals("LineNumberTable")) {
+ throw new LoadingException(
+ ("The LineNumberTable attribute '"
+ + Pass2Verifier.getText(lineNumberTable)
+ + "' is not correctly named 'LineNumberTable' but '"
+ + text
+ + "'."));
+ }
+ }
+
+ @Override
+ public void visitCodeException(CodeException codeException) {}
+
+ @Override
+ public void visitConstantFloat(ConstantFloat constantFloat) {
+ if (constantFloat.getTag() != 4) {
+ throw new LoadingException(
+ ("Wrong constant tag in '" + Pass2Verifier.getText(constantFloat) + "'."));
+ }
+ }
+
+ @Override
+ public void visitConstantFieldref(ConstantFieldref constantFieldref) {
+ if (constantFieldref.getTag() != 9) {
+ throw new LoadingException(
+ ("Wrong constant tag in '" + Pass2Verifier.getText(constantFieldref) + "'."));
+ }
+ this.checkIndex(constantFieldref, constantFieldref.getClass_index(), this.CONST_Class);
+ this.checkIndex(
+ constantFieldref, constantFieldref.getName_and_type_index(), this.CONST_NameAndType);
+ }
+
+ @Override
+ public void visitConstantString(ConstantString constantString) {
+ if (constantString.getTag() != 8) {
+ throw new LoadingException(
+ ("Wrong constant tag in '" + Pass2Verifier.getText(constantString) + "'."));
+ }
+ this.checkIndex(constantString, constantString.getStringIndex(), this.CONST_Utf8);
+ }
+
+ @Override
+ public void visitExceptionTable(ExceptionTable exceptionTable) {
+ JavaClass javaClass;
+ try {
+ this.checkIndex(exceptionTable, exceptionTable.getName_index(), this.CONST_Utf8);
+ String text;
+ if (!(text = ((ConstantUtf8) this.cp.getConstant(exceptionTable.getName_index())).getBytes())
+ .equals("Exceptions")) {
+ throw new LoadingException(
+ ("The Exceptions attribute '"
+ + Pass2Verifier.getText(exceptionTable)
+ + "' is not correctly named 'Exceptions' but '"
+ + text
+ + "'."));
+ }
+ int[] exceptionIndexTable = exceptionTable.getExceptionIndexTable();
+ for (int index = 0; index < exceptionIndexTable.length; index++) {
+ this.checkIndex(exceptionTable, exceptionIndexTable[index], this.CONST_Class);
+ ConstantClass constantClass;
+ ConstantClass constantClass2 =
+ constantClass = (ConstantClass) this.cp.getConstant(exceptionIndexTable[index]);
+ this.checkIndex(constantClass2, constantClass2.getNameIndex(), this.CONST_Utf8);
+ String text2;
+ VerificationResult verificationResult;
+ if ((verificationResult =
+ VerifierFactory.getVerifier(
+ text2 =
+ ((ConstantUtf8) this.cp.getConstant(constantClass.getNameIndex()))
+ .getBytes()
+ .replace('/', '.'))
+ .createVerificationResult())
+ != VerificationResult.VERIFICATION_RESULT2) {
+ throw new LoadingException(
+ ("Exceptions attribute '"
+ + Pass2Verifier.getText(exceptionTable)
+ + "' references '"
+ + text2
+ + "' as an Exception but it does not pass verification pass 1: "
+ + verificationResult));
+ }
+ JavaClass javaClass2 = Repository.lookupClass(text2);
+ JavaClass javaClass3 = Repository.lookupClass(Type.THROWABLE.getClassName());
+ JavaClass javaClass4 = Repository.lookupClass(Type.OBJECT.getClassName());
+ JavaClass javaClass5 = javaClass2;
+ while (true) {
+ if (javaClass5 == javaClass4) {
+ javaClass = javaClass2;
+ break;
+ }
+ if (javaClass2 == javaClass3) {
+ javaClass = javaClass2;
+ break;
+ }
+ VerificationResult verificationResult2;
+ if ((verificationResult2 =
+ VerifierFactory.getVerifier(javaClass2.getText5()).createVerificationResult())
+ != VerificationResult.VERIFICATION_RESULT2) {
+ throw new LoadingException(
+ ("Exceptions attribute '"
+ + Pass2Verifier.getText(exceptionTable)
+ + "' references '"
+ + text2
+ + "' as an Exception but '"
+ + javaClass2.getText5()
+ + "' in the ancestor hierachy does not pass verification pass 1: "
+ + verificationResult2));
+ }
+ javaClass5 = javaClass2 = Repository.lookupClass(javaClass2.getText5());
+ }
+ if (javaClass != javaClass3) {
+ throw new LoadingException(
+ ("Exceptions attribute '"
+ + Pass2Verifier.getText(exceptionTable)
+ + "' references '"
+ + text2
+ + "' as an Exception but it is not a subclass of '"
+ + javaClass3.getText2()
+ + "'."));
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitConstantValue(ConstantValue constantValue) {
+ this.checkIndex(constantValue, constantValue.getName_index(), this.CONST_Utf8);
+ String text;
+ if (!(text = ((ConstantUtf8) this.cp.getConstant(constantValue.getName_index())).getBytes())
+ .equals("ConstantValue")) {
+ throw new LoadingException(
+ ("The ConstantValue attribute '"
+ + Pass2Verifier.getText(constantValue)
+ + "' is not correctly named 'ConstantValue' but '"
+ + text
+ + "'."));
+ }
+ Object result;
+ if ((result = this.carrier.predecessor()) instanceof Field) {
+ Field field = (Field) result;
+ Type type = Type.getType(((ConstantUtf8) this.cp.getConstant(field.getCount())).getBytes());
+ int value;
+ if ((value = constantValue.getConstantValueIndex()) >= 0 && value < this.cplen) {
+ Constant constant = this.cp.getConstant(value);
+ if (!this.CONST_Long.isInstance(constant) || !type.equals(Type.LONG)) {
+ if (!this.CONST_Float.isInstance(constant) || !type.equals(Type.FLOAT)) {
+ if (!this.CONST_Double.isInstance(constant) || !type.equals(Type.DOUBLE)) {
+ if (!this.CONST_Integer.isInstance(constant)
+ || !type.equals(Type.INT)
+ && !type.equals(Type.SHORT)
+ && !type.equals(Type.CHAR)
+ && !type.equals(Type.BYTE)
+ && !type.equals(Type.BOOLEAN)) {
+ if (!this.CONST_String.isInstance(constant) || !type.equals(Type.STRING)) {
+ throw new LoadingException(
+ ("Illegal type of ConstantValue '"
+ + constantValue
+ + "' embedding Constant '"
+ + constant
+ + "'. It is referenced by field '"
+ + Pass2Verifier.getText(field)
+ + "' expecting a different type: '"
+ + type
+ + "'."));
+ }
+ }
+ }
+ }
+ }
+ } else {
+ throw new LoadingException(
+ ("Invalid index '"
+ + value
+ + "' used by '"
+ + Pass2Verifier.getText(constantValue)
+ + "'."));
+ }
+ }
+ }
+
+ @Override
+ public void visitInnerClass(InnerClass innerClass) {}
+
+ public Pass2Verifier$CPESSC_Visitor(Pass2Verifier pass2Verifier, JavaClass javaClass) {
+ super();
+ this.this$0 = pass2Verifier;
+ this.field_names = new HashSet();
+ this.field_names_and_desc = new HashSet();
+ this.method_names_and_desc = new HashSet();
+ this.jc = javaClass;
+ this.cp = javaClass.getConstantPool();
+ this.cplen = this.cp.getLength();
+ this.CONST_Class = ConstantClass.class;
+ this.CONST_String = ConstantString.class;
+ this.CONST_Integer = ConstantInteger.class;
+ this.CONST_Float = ConstantFloat.class;
+ this.CONST_Long = ConstantLong.class;
+ this.CONST_Double = ConstantDouble.class;
+ this.CONST_NameAndType = ConstantNameAndType.class;
+ this.CONST_Utf8 = ConstantUtf8.class;
+ this.carrier = new DescendingVisitor(javaClass, this);
+ this.carrier.visit();
+ }
+
+ public Pass2Verifier$CPESSC_Visitor(
+ Pass2Verifier pass2Verifier, JavaClass javaClass, Pass2Verifier$1 pass2Verifier$1) {
+ this(pass2Verifier, javaClass);
+ }
+
+ @Override
+ public void visitLineNumber(LineNumber lineNumber) {}
+
+ @Override
+ public void visitJavaClass(JavaClass javaClass) {
+ Attribute[] attributes = javaClass.getAttributes();
+ byte value = 0;
+ byte value2 = 0;
+ boolean matches = new Pass2Verifier$InnerClassDetector(this.jc).innerClassReferenced();
+ int value3;
+ for (int value4 = value3 = 0; value4 < attributes.length; value4 = ++value3) {
+ if (!(attributes[value3] instanceof SourceFile)
+ && !(attributes[value3] instanceof Deprecated)
+ && !(attributes[value3] instanceof InnerClasses)
+ && !(attributes[value3] instanceof Synthetic)) {
+ this.this$0.addMessage(
+ "Attribute '"
+ + Pass2Verifier.getText(attributes[value3])
+ + "' as an attribute of the ClassFile structure '"
+ + Pass2Verifier.getText(javaClass)
+ + "' is unknown and will therefore be ignored.");
+ }
+ Attribute[] attributes2;
+ if (attributes[value3] instanceof SourceFile) {
+ if (value != 0) {
+ throw new LoadingException(
+ ("A ClassFile structure (like '"
+ + Pass2Verifier.getText(javaClass)
+ + "') may have no more than one SourceFile attribute."));
+ }
+ value = 1;
+ attributes2 = attributes;
+ } else {
+ attributes2 = attributes;
+ }
+ if (attributes2[value3] instanceof InnerClasses) {
+ boolean matches2;
+ if (value2 == 0) {
+ value2 = 1;
+ matches2 = matches;
+ } else {
+ if (matches) {
+ throw new LoadingException(
+ ("A Classfile structure (like '"
+ + Pass2Verifier.getText(javaClass)
+ + "') must have exactly one InnerClasses attribute if at least one Inner Class"
+ + " is referenced (which is the case). More than one InnerClasses attribute was"
+ + " found."));
+ }
+ matches2 = matches;
+ }
+ if (!matches2) {
+ this.this$0.addMessage(
+ "No referenced Inner Class found, but InnerClasses attribute '"
+ + Pass2Verifier.getText(attributes[value3])
+ + "' found. Strongly suggest removal of that attribute.");
+ }
+ }
+ }
+ if (matches && value2 == 0) {
+ this.this$0.addMessage(
+ "A Classfile structure (like '"
+ + Pass2Verifier.getText(javaClass)
+ + "') must have exactly one InnerClasses attribute if at least one Inner Class is"
+ + " referenced (which is the case). No InnerClasses attribute was found.");
+ }
+ }
+
+ @Override
+ public void visitConstantDouble(ConstantDouble constantDouble) {
+ if (constantDouble.getTag() != 6) {
+ throw new LoadingException(
+ ("Wrong constant tag in '" + Pass2Verifier.getText(constantDouble) + "'."));
+ }
+ }
+
+ @Override
+ public void visitSynthetic(Synthetic synthetic) {
+ this.checkIndex(synthetic, synthetic.getName_index(), this.CONST_Utf8);
+ String text;
+ if (!(text = ((ConstantUtf8) this.cp.getConstant(synthetic.getName_index())).getBytes())
+ .equals("Synthetic")) {
+ throw new LoadingException(
+ ("The Synthetic attribute '"
+ + Pass2Verifier.getText(synthetic)
+ + "' is not correctly named 'Synthetic' but '"
+ + text
+ + "'."));
+ }
+ }
+
+ @Override
+ public void visitConstantUtf8(ConstantUtf8 constantUtf8) {
+ if (constantUtf8.getTag() != 1) {
+ throw new LoadingException(
+ ("Wrong constant tag in '" + Pass2Verifier.getText(constantUtf8) + "'."));
+ }
+ }
+
+ @Override
+ public void visitLocalVariableTable(LocalVariableTable localVariableTable) {}
+
+ public void checkIndex(Node node, int value, Class classValue) {
+ if (value >= 0 && value < this.cplen) {
+ Constant constant = this.cp.getConstant(value);
+ if (!classValue.isInstance(constant)) {
+ throw new ClassCastException(
+ ("Illegal constant '"
+ + Pass2Verifier.getText(constant)
+ + "' at index '"
+ + value
+ + "'. '"
+ + Pass2Verifier.getText(node)
+ + "' expects a '"
+ + classValue
+ + "'."));
+ }
+ } else {
+ throw new LoadingException(
+ ("Invalid index '" + value + "' used by '" + Pass2Verifier.getText(node) + "'."));
+ }
+ }
+
+ @Override
+ public void visitInnerClasses(InnerClasses innerClasses) {
+ this.checkIndex(innerClasses, innerClasses.getName_index(), this.CONST_Utf8);
+ String text;
+ if (!(text = ((ConstantUtf8) this.cp.getConstant(innerClasses.getName_index())).getBytes())
+ .equals("InnerClasses")) {
+ throw new LoadingException(
+ ("The InnerClasses attribute '"
+ + Pass2Verifier.getText(innerClasses)
+ + "' is not correctly named 'InnerClasses' but '"
+ + text
+ + "'."));
+ }
+ InnerClass[] innerClasses2 = innerClasses.getInnerClasses();
+ int value;
+ for (int value2 = value = 0; value2 < innerClasses2.length; value2 = ++value) {
+ this.checkIndex(innerClasses, innerClasses2[value].getInner_class_index(), this.CONST_Class);
+ int value3;
+ if ((value3 = innerClasses2[value].getOuter_class_index()) != 0) {
+ this.checkIndex(innerClasses, value3, this.CONST_Class);
+ }
+ int value4;
+ if ((value4 = innerClasses2[value].getInner_name_index()) != 0) {
+ this.checkIndex(innerClasses, value4, this.CONST_Utf8);
+ }
+ if ((innerClasses2[value].getInner_access_flags() & -1568) != 0) {
+ this.this$0.addMessage(
+ "Unknown access flag for inner class '"
+ + Pass2Verifier.getText(innerClasses2[value])
+ + "' set (InnerClasses attribute '"
+ + Pass2Verifier.getText(innerClasses)
+ + "').");
+ }
+ }
+ }
+
+ @Override
+ public void visitCode(Code code) {
+ JavaClass javaClass;
+ try {
+ this.checkIndex(code, code.getName_index(), this.CONST_Utf8);
+ String text;
+ if (!(text = ((ConstantUtf8) this.cp.getConstant(code.getName_index())).getBytes())
+ .equals("Code")) {
+ throw new LoadingException(
+ ("The Code attribute '"
+ + Pass2Verifier.getText(code)
+ + "' is not correctly named 'Code' but '"
+ + text
+ + "'."));
+ }
+ if (!(this.carrier.predecessor() instanceof Method)) {
+ this.this$0.addMessage(
+ "Code attribute '"
+ + Pass2Verifier.getText(code)
+ + "' is not declared in a method_info structure but in '"
+ + this.carrier.predecessor()
+ + "'. Ignored.");
+ } else {
+ Method method = (Method) this.carrier.predecessor();
+ if (code.getCode().length == 0) {
+ throw new LoadingException(
+ ("Code array of Code attribute '"
+ + Pass2Verifier.getText(code)
+ + "' (method '"
+ + method
+ + "') must not be empty."));
+ }
+ CodeException[] exceptionTable = code.getExceptionTable();
+ int value;
+ for (int value2 = value = 0; value2 < exceptionTable.length; value2 = ++value) {
+ int value3;
+ if ((value3 = exceptionTable[value].getCatch_type()) != 0) {
+ this.checkIndex(code, value3, this.CONST_Class);
+ ConstantClass constantClass;
+ ConstantClass constantClass2 =
+ constantClass = (ConstantClass) this.cp.getConstant(value3);
+ this.checkIndex(constantClass2, constantClass2.getNameIndex(), this.CONST_Utf8);
+ String text2;
+ VerificationResult verificationResult;
+ if ((verificationResult =
+ VerifierFactory.getVerifier(
+ text2 =
+ ((ConstantUtf8) this.cp.getConstant(constantClass.getNameIndex()))
+ .getBytes()
+ .replace('/', '.'))
+ .createVerificationResult())
+ != VerificationResult.VERIFICATION_RESULT2) {
+ throw new LoadingException(
+ ("Code attribute '"
+ + Pass2Verifier.getText(code)
+ + "' (method '"
+ + method
+ + "') has an exception_table entry '"
+ + Pass2Verifier.getText(exceptionTable[value])
+ + "' that references '"
+ + text2
+ + "' as an Exception but it does not pass verification pass 1: "
+ + verificationResult));
+ }
+ JavaClass javaClass2 = Repository.lookupClass(text2);
+ JavaClass javaClass3 = Repository.lookupClass(Type.THROWABLE.getClassName());
+ JavaClass javaClass4 = Repository.lookupClass(Type.OBJECT.getClassName());
+ JavaClass javaClass5 = javaClass2;
+ while (true) {
+ if (javaClass5 == javaClass4) {
+ javaClass = javaClass2;
+ break;
+ }
+ if (javaClass2 == javaClass3) {
+ javaClass = javaClass2;
+ break;
+ }
+ VerificationResult verificationResult2;
+ if ((verificationResult2 =
+ VerifierFactory.getVerifier(javaClass2.getText5()).createVerificationResult())
+ != VerificationResult.VERIFICATION_RESULT2) {
+ throw new LoadingException(
+ ("Code attribute '"
+ + Pass2Verifier.getText(code)
+ + "' (method '"
+ + method
+ + "') has an exception_table entry '"
+ + Pass2Verifier.getText(exceptionTable[value])
+ + "' that references '"
+ + text2
+ + "' as an Exception but '"
+ + javaClass2.getText5()
+ + "' in the ancestor hierachy does not pass verification pass 1: "
+ + verificationResult2));
+ }
+ javaClass5 = javaClass2 = Repository.lookupClass(javaClass2.getText5());
+ }
+ if (javaClass != javaClass3) {
+ throw new LoadingException(
+ ("Code attribute '"
+ + Pass2Verifier.getText(code)
+ + "' (method '"
+ + method
+ + "') has an exception_table entry '"
+ + Pass2Verifier.getText(exceptionTable[value])
+ + "' that references '"
+ + text2
+ + "' as an Exception but it is not a subclass of '"
+ + javaClass3.getText2()
+ + "'."));
+ }
+ }
+ }
+ int value4 = -1;
+ Method[] methods =
+ Repository.lookupClass(Pass2Verifier.access$400(this.this$0).getClassName())
+ .getMethods();
+ int value5;
+ int value6 = value5 = 0;
+ while (true) {
+ if (value6 >= methods.length) {
+ value6 = value4;
+ break;
+ }
+ if (method == methods[value5]) {
+ value6 = value4 = value5;
+ break;
+ }
+ value6 = ++value5;
+ }
+ if (value6 < 0) {
+ throw new AssertionViolatedException(
+ "Could not find a known BCEL Method object in the corresponding BCEL JavaClass"
+ + " object.");
+ }
+ Pass2Verifier.access$500(this.this$0)[value4] =
+ new LocalVariablesInfo(code.getMax_locals());
+ int value7 = 0;
+ Attribute[] attributes = code.getAttributes();
+ for (int index = 0; index < attributes.length; index++) {
+ Attribute[] attributes2;
+ if (!(attributes[index] instanceof LineNumberTable)
+ && !(attributes[index] instanceof LocalVariableTable)) {
+ Pass2Verifier pass2Verifier = this.this$0;
+ StringBuilder stringBuilder = new StringBuilder().insert(0, "Attribute '");
+ attributes2 = attributes;
+ pass2Verifier.addMessage(
+ stringBuilder
+ .append(Pass2Verifier.getText(attributes[index]))
+ .append("' as an attribute of Code attribute '")
+ .append(Pass2Verifier.getText(code))
+ .append("' (method '")
+ .append(method)
+ .append("') is unknown and will therefore be ignored.")
+ .toString());
+ } else {
+ this.this$0.addMessage(
+ "Attribute '"
+ + Pass2Verifier.getText(attributes[index])
+ + "' as an attribute of Code attribute '"
+ + Pass2Verifier.getText(code)
+ + "' (method '"
+ + method
+ + "') will effectively be ignored and is only useful for debuggers and such.");
+ attributes2 = attributes;
+ }
+ if (attributes2[index] instanceof LocalVariableTable) {
+ LocalVariableTable localVariableTable;
+ LocalVariableTable localVariableTable2 =
+ localVariableTable = (LocalVariableTable) attributes[index];
+ this.checkIndex(
+ localVariableTable2, localVariableTable2.getName_index(), this.CONST_Utf8);
+ String text3;
+ if (!(text3 =
+ ((ConstantUtf8) this.cp.getConstant(localVariableTable.getName_index()))
+ .getBytes())
+ .equals("LocalVariableTable")) {
+ throw new LoadingException(
+ ("The LocalVariableTable attribute '"
+ + Pass2Verifier.getText(localVariableTable)
+ + "' is not correctly named 'LocalVariableTable' but '"
+ + text3
+ + "'."));
+ }
+ LocalVariable[] localVariableTable3 = localVariableTable.getLocalVariableTable();
+ int value8;
+ for (value6 = value8 = 0; value6 < localVariableTable3.length; value6 = ++value8) {
+ this.checkIndex(
+ localVariableTable, localVariableTable3[value8].getName_index(), this.CONST_Utf8);
+ String text4;
+ if (!Pass2Verifier.matchesText4(
+ text4 =
+ ((ConstantUtf8)
+ this.cp.getConstant(localVariableTable3[value8].getName_index()))
+ .getBytes())) {
+ throw new LoadingException(
+ ("LocalVariableTable '"
+ + Pass2Verifier.getText(localVariableTable)
+ + "' references a local variable by the name '"
+ + text4
+ + "' which is not a legal Java simple name."));
+ }
+ this.checkIndex(
+ localVariableTable,
+ localVariableTable3[value8].getSignature_index(),
+ this.CONST_Utf8);
+ String bytes =
+ ((ConstantUtf8)
+ this.cp.getConstant(localVariableTable3[value8].getSignature_index()))
+ .getBytes();
+ Type type;
+ try {
+ type = Type.getType(bytes);
+ } catch (ClassFormatException classFormatException) {
+ throw new LoadingException(
+ ("Illegal descriptor (==signature) '"
+ + bytes
+ + "' used by LocalVariable '"
+ + Pass2Verifier.getText(localVariableTable3[value8])
+ + "' referenced by '"
+ + Pass2Verifier.getText(localVariableTable)
+ + "'."));
+ }
+ int index2 = localVariableTable3[value8].getIndex();
+ Code code2;
+ if (type != Type.LONG && type != Type.DOUBLE) {
+ value6 = index2;
+ code2 = code;
+ } else {
+ value6 = index2 + 1;
+ code2 = code;
+ }
+ if (value6 >= code2.getMax_locals()) {
+ throw new LoadingException(
+ ("LocalVariableTable attribute '"
+ + Pass2Verifier.getText(localVariableTable)
+ + "' references a LocalVariable '"
+ + Pass2Verifier.getText(localVariableTable3[value8])
+ + "' with an index that exceeds the surrounding Code attribute's max_locals"
+ + " value of '"
+ + code.getMax_locals()
+ + "'."));
+ }
+ try {
+ Pass2Verifier.access$500(this.this$0)[value4].add(
+ index2,
+ text4,
+ localVariableTable3[value8].getStart_pc(),
+ localVariableTable3[value8].getLength(),
+ type);
+ } catch (ClassConstraintException classConstraintException) {
+ throw new LoadingException(
+ ("Conflicting information in LocalVariableTable '"
+ + Pass2Verifier.getText(localVariableTable)
+ + "' found in Code attribute '"
+ + Pass2Verifier.getText(code)
+ + "' (method '"
+ + Pass2Verifier.getText(method)
+ + "'). "
+ + classConstraintException.getMessage()));
+ }
+ }
+ if (++value7 > code.getMax_locals()) {
+ throw new LoadingException(
+ ("Number of LocalVariableTable attributes of Code attribute '"
+ + Pass2Verifier.getText(code)
+ + "' (method '"
+ + Pass2Verifier.getText(method)
+ + "') exceeds number of local variable slots '"
+ + code.getMax_locals()
+ + "' ('There may be no more than one LocalVariableTable attribute per local"
+ + " variable in the Code attribute.')."));
+ }
+ }
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitConstantInterfaceMethodref(
+ ConstantInterfaceMethodref constantInterfaceMethodref) {
+ if (constantInterfaceMethodref.getTag() != 11) {
+ throw new LoadingException(
+ ("Wrong constant tag in '" + Pass2Verifier.getText(constantInterfaceMethodref) + "'."));
+ }
+ this.checkIndex(
+ constantInterfaceMethodref, constantInterfaceMethodref.getClass_index(), this.CONST_Class);
+ this.checkIndex(
+ constantInterfaceMethodref,
+ constantInterfaceMethodref.getName_and_type_index(),
+ this.CONST_NameAndType);
+ }
+
+ @Override
+ public void visitConstantMethodref(ConstantMethodref constantMethodref) {
+ if (constantMethodref.getTag() != 10) {
+ throw new LoadingException(
+ ("Wrong constant tag in '" + Pass2Verifier.getText(constantMethodref) + "'."));
+ }
+ this.checkIndex(constantMethodref, constantMethodref.getClass_index(), this.CONST_Class);
+ this.checkIndex(
+ constantMethodref, constantMethodref.getName_and_type_index(), this.CONST_NameAndType);
+ }
+
+ @Override
+ public void visitConstantClass(ConstantClass constantClass) {
+ if (constantClass.getTag() != 7) {
+ throw new LoadingException(
+ ("Wrong constant tag in '" + Pass2Verifier.getText(constantClass) + "'."));
+ }
+ this.checkIndex(constantClass, constantClass.getNameIndex(), this.CONST_Utf8);
+ }
+
+ @Override
+ public void visitConstantInteger(ConstantInteger constantInteger) {
+ if (constantInteger.getTag() != 3) {
+ throw new LoadingException(
+ ("Wrong constant tag in '" + Pass2Verifier.getText(constantInteger) + "'."));
+ }
+ }
+
+ @Override
+ public void visitConstantNameAndType(ConstantNameAndType constantNameAndType) {
+ if (constantNameAndType.getTag() != 12) {
+ throw new LoadingException(
+ ("Wrong constant tag in '" + Pass2Verifier.getText(constantNameAndType) + "'."));
+ }
+ this.checkIndex(constantNameAndType, constantNameAndType.getName_index(), this.CONST_Utf8);
+ this.checkIndex(constantNameAndType, constantNameAndType.getSignature_index(), this.CONST_Utf8);
+ }
+
+ @Override
+ public void visitDeprecated(Deprecated deprecated) {
+ this.checkIndex(deprecated, deprecated.getName_index(), this.CONST_Utf8);
+ String text;
+ if (!(text = ((ConstantUtf8) this.cp.getConstant(deprecated.getName_index())).getBytes())
+ .equals("Deprecated")) {
+ throw new LoadingException(
+ ("The Deprecated attribute '"
+ + Pass2Verifier.getText(deprecated)
+ + "' is not correctly named 'Deprecated' but '"
+ + text
+ + "'."));
+ }
+ }
+
+ @Override
+ public void visitConstantLong(ConstantLong constantLong) {
+ if (constantLong.getTag() != 5) {
+ throw new LoadingException(
+ ("Wrong constant tag in '" + Pass2Verifier.getText(constantLong) + "'."));
+ }
+ }
+
+ @Override
+ public void visitConstantPool(ConstantPool constantPool) {}
+
+ @Override
+ public void visitMethod(Method method) {
+ this.checkIndex(method, method.getCount3(), this.CONST_Utf8);
+ String text;
+ if (!Pass2Verifier.matchesEnabled2(text = method.getText(), true)) {
+ throw new LoadingException(
+ ("Method '" + Pass2Verifier.getText(method) + "' has illegal name '" + text + "'."));
+ }
+ this.checkIndex(method, method.getCount(), this.CONST_Utf8);
+ String bytes = ((ConstantUtf8) this.cp.getConstant(method.getCount())).getBytes();
+ Type[] types;
+ Type type;
+ try {
+ type = Type.getReturnType(bytes);
+ types = Type.getArgumentTypes(bytes);
+ } catch (ClassFormatException classFormatException) {
+ throw new LoadingException(
+ ("Illegal descriptor (==signature) '"
+ + bytes
+ + "' used by Method '"
+ + Pass2Verifier.getText(method)
+ + "'."));
+ }
+ Type type2 = type;
+ if (type2 instanceof ArrayType) {
+ type2 = ((ArrayType) type2).getBasicType();
+ }
+ VerificationResult verificationResult;
+ if (type2 instanceof ObjectType
+ && (verificationResult =
+ VerifierFactory.getVerifier(((ObjectType) type2).getClassName())
+ .createVerificationResult())
+ != VerificationResult.VERIFICATION_RESULT2) {
+ throw new LoadingException(
+ ("Method '"
+ + Pass2Verifier.getText(method)
+ + "' has a return type that does not pass verification pass 1: '"
+ + verificationResult
+ + "'."));
+ }
+ int value;
+ for (int value2 = value = 0; value2 < types.length; value2 = ++value) {
+ Type type3;
+ if ((type3 = types[value]) instanceof ArrayType) {
+ type3 = ((ArrayType) type3).getBasicType();
+ }
+ VerificationResult verificationResult2;
+ if (type3 instanceof ObjectType
+ && (verificationResult2 =
+ VerifierFactory.getVerifier(((ObjectType) type3).getClassName())
+ .createVerificationResult())
+ != VerificationResult.VERIFICATION_RESULT2) {
+ throw new LoadingException(
+ ("Method '"
+ + Pass2Verifier.getText(method)
+ + "' has an argument type that does not pass verification pass 1: '"
+ + verificationResult2
+ + "'."));
+ }
+ }
+ if (text.equals("") && types.length != 0) {
+ throw new LoadingException(
+ ("Method '"
+ + Pass2Verifier.getText(method)
+ + "' has illegal name '"
+ + text
+ + "'. It's name resembles the class or interface initialization method which it isn't"
+ + " because of its arguments (==descriptor)."));
+ }
+ if (this.jc.isEnabled17()) {
+ int value3 = 0;
+ if (method.isEnabled9()) {
+ value3++;
+ }
+ if (method.isEnabled13()) {
+ value3++;
+ }
+ if (method.isEnabled6()) {
+ value3++;
+ }
+ if (value3 > 1) {
+ throw new LoadingException(
+ ("Method '"
+ + Pass2Verifier.getText(method)
+ + "' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC"
+ + " modifiers set."));
+ }
+ if (method.isEnabled15()) {
+ if (method.isEnabled3()) {
+ throw new LoadingException(
+ ("Abstract method '"
+ + Pass2Verifier.getText(method)
+ + "' must not have the ACC_FINAL modifier set."));
+ }
+ if (method.isEnabled14()) {
+ throw new LoadingException(
+ ("Abstract method '"
+ + Pass2Verifier.getText(method)
+ + "' must not have the ACC_NATIVE modifier set."));
+ }
+ if (method.isEnabled9()) {
+ throw new LoadingException(
+ ("Abstract method '"
+ + Pass2Verifier.getText(method)
+ + "' must not have the ACC_PRIVATE modifier set."));
+ }
+ if (method.isEnabled11()) {
+ throw new LoadingException(
+ ("Abstract method '"
+ + Pass2Verifier.getText(method)
+ + "' must not have the ACC_STATIC modifier set."));
+ }
+ if (method.isEnabled7()) {
+ throw new LoadingException(
+ ("Abstract method '"
+ + Pass2Verifier.getText(method)
+ + "' must not have the ACC_STRICT modifier set."));
+ }
+ if (method.isEnabled12()) {
+ throw new LoadingException(
+ ("Abstract method '"
+ + Pass2Verifier.getText(method)
+ + "' must not have the ACC_SYNCHRONIZED modifier set."));
+ }
+ }
+ } else if (!text.equals("")) {
+ if (!method.isEnabled6()) {
+ throw new LoadingException(
+ ("Interface method '"
+ + Pass2Verifier.getText(method)
+ + "' must have the ACC_PUBLIC modifier set but hasn't!"));
+ }
+ if (!method.isEnabled15()) {
+ throw new LoadingException(
+ ("Interface method '"
+ + Pass2Verifier.getText(method)
+ + "' must have the ACC_STATIC modifier set but hasn't!"));
+ }
+ if (method.isEnabled9()
+ || method.isEnabled13()
+ || method.isEnabled11()
+ || method.isEnabled3()
+ || method.isEnabled12()
+ || method.isEnabled14()
+ || method.isEnabled7()) {
+ throw new LoadingException(
+ ("Interface method '"
+ + Pass2Verifier.getText(method)
+ + "' must not have any of the ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,"
+ + " ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT modifiers set."));
+ }
+ }
+ if (!text.equals("")
+ || !method.isEnabled11()
+ && !method.isEnabled3()
+ && !method.isEnabled12()
+ && !method.isEnabled14()
+ && !method.isEnabled15()) {
+ if (text.equals("")) {
+ if ((method.getAccess_flags2() & -2049) > 0) {
+ this.this$0.addMessage(
+ "Class or interface initialization method '"
+ + Pass2Verifier.getText(method)
+ + "' has superfluous access modifier(s) set: everything but ACC_STRICT is"
+ + " ignored.");
+ }
+ if (method.isEnabled15()) {
+ throw new LoadingException(
+ ("Class or interface initialization method '"
+ + Pass2Verifier.getText(method)
+ + "' must not be abstract. This contradicts the Java Language Specification,"
+ + " Second Edition (which omits this constraint) but is common practice of"
+ + " existing verifiers."));
+ }
+ }
+ if ((method.getAccess_flags2() & -3392) > 0) {
+ this.this$0.addMessage(
+ "Method '"
+ + Pass2Verifier.getText(method)
+ + "' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED,"
+ + " ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT"
+ + " set (ignored).");
+ }
+ String text2 = "" + text + bytes;
+ if (this.method_names_and_desc.contains(text2)) {
+ throw new LoadingException(
+ ("No two methods (like '"
+ + Pass2Verifier.getText(method)
+ + "') are allowed have same names and desciptors!"));
+ }
+ this.method_names_and_desc.add(text2);
+ Attribute[] attributes = method.getAttributes();
+ int value4 = 0;
+ int value5 = 0;
+ for (int value6 = value5; value6 < attributes.length; value6 = ++value5) {
+ if (!(attributes[value5] instanceof Code)
+ && !(attributes[value5] instanceof ExceptionTable)
+ && !(attributes[value5] instanceof Synthetic)
+ && !(attributes[value5] instanceof Deprecated)) {
+ this.this$0.addMessage(
+ "Attribute '"
+ + Pass2Verifier.getText(attributes[value5])
+ + "' as an attribute of Method '"
+ + Pass2Verifier.getText(method)
+ + "' is unknown and will therefore be ignored.");
+ }
+ if (!(attributes[value5] instanceof Code)
+ && !(attributes[value5] instanceof ExceptionTable)) {
+ this.this$0.addMessage(
+ "Attribute '"
+ + Pass2Verifier.getText(attributes[value5])
+ + "' as an attribute of Method '"
+ + Pass2Verifier.getText(method)
+ + "' is neither Code nor Exceptions and is therefore only of use for debuggers"
+ + " and such.");
+ }
+ if (attributes[value5] instanceof Code && (method.isEnabled14() || method.isEnabled15())) {
+ throw new LoadingException(
+ ("Native or abstract methods like '"
+ + Pass2Verifier.getText(method)
+ + "' must not have a Code attribute like '"
+ + Pass2Verifier.getText(attributes[value5])
+ + "'."));
+ }
+ if (attributes[value5] instanceof Code) {
+ value4++;
+ }
+ }
+ if (!method.isEnabled14() && !method.isEnabled15() && value4 != 1) {
+ throw new LoadingException(
+ ("Non-native, non-abstract methods like '"
+ + Pass2Verifier.getText(method)
+ + "' must have exactly one Code attribute (found: "
+ + value4
+ + ")."));
+ }
+ } else {
+ throw new LoadingException(
+ ("Instance initialization method '"
+ + Pass2Verifier.getText(method)
+ + "' must not have any of the ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE,"
+ + " ACC_ABSTRACT modifiers set."));
+ }
+ }
+
+ @Override
+ public void visitSourceFile(SourceFile sourceFile) {
+ this.checkIndex(sourceFile, sourceFile.getName_index(), this.CONST_Utf8);
+ String text;
+ if (!(text = ((ConstantUtf8) this.cp.getConstant(sourceFile.getName_index())).getBytes())
+ .equals("SourceFile")) {
+ throw new LoadingException(
+ ("The SourceFile attribute '"
+ + Pass2Verifier.getText(sourceFile)
+ + "' is not correctly named 'SourceFile' but '"
+ + text
+ + "'."));
+ }
+ this.checkIndex(sourceFile, sourceFile.getSourceFileIndex(), this.CONST_Utf8);
+ String text2;
+ String text3 =
+ text2 = ((ConstantUtf8) this.cp.getConstant(sourceFile.getSourceFileIndex())).getBytes();
+ String text4 = text3.toLowerCase(Locale.ENGLISH);
+ if (text3.indexOf(47) != -1
+ || text2.indexOf(92) != -1
+ || text2.indexOf(58) != -1
+ || text4.lastIndexOf(".java") == -1) {
+ this.this$0.addMessage(
+ "SourceFile attribute '"
+ + Pass2Verifier.getText(sourceFile)
+ + "' has a funny name: remember not to confuse certain parsers working on javap's"
+ + " output. Also, this name ('"
+ + text2
+ + "') is considered an unqualified (simple) file name only.");
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$FAMRAV_Visitor.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$FAMRAV_Visitor.java
new file mode 100644
index 0000000..ae520af
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$FAMRAV_Visitor.java
@@ -0,0 +1,185 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.lib.bcel.classfile.ClassFormatException;
+import com.allatori.lib.bcel.classfile.ConstantClass;
+import com.allatori.lib.bcel.classfile.ConstantFieldref;
+import com.allatori.lib.bcel.classfile.ConstantInterfaceMethodref;
+import com.allatori.lib.bcel.classfile.ConstantMethodref;
+import com.allatori.lib.bcel.classfile.ConstantNameAndType;
+import com.allatori.lib.bcel.classfile.ConstantPool;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.classfile.EmptyVisitor;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.classfile.Visitor;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.lib.bcel.verifier.exc.LoadingException;
+
+public class Pass2Verifier$FAMRAV_Visitor extends EmptyVisitor implements Visitor {
+
+ public final ConstantPool cp;
+
+ public final Pass2Verifier this$0;
+
+ public Pass2Verifier$FAMRAV_Visitor(
+ Pass2Verifier pass2Verifier, JavaClass javaClass, Pass2Verifier$1 pass2Verifier$1) {
+ this(pass2Verifier, javaClass);
+ }
+
+ @Override
+ public void visitConstantFieldref(ConstantFieldref constantFieldref) {
+ if (constantFieldref.getTag() != 9) {
+ throw new LoadingException(
+ ("ConstantFieldref '" + Pass2Verifier.getText(constantFieldref) + "' has wrong tag!"));
+ }
+ int name_and_type_index = constantFieldref.getName_and_type_index();
+ ConstantNameAndType constantNameAndType =
+ (ConstantNameAndType) this.cp.getConstant(name_and_type_index);
+ String text;
+ if (!Pass2Verifier.matchesText(
+ text =
+ ((ConstantUtf8) this.cp.getConstant(constantNameAndType.getName_index())).getBytes())) {
+ throw new LoadingException(
+ ("Invalid field name '"
+ + text
+ + "' referenced by '"
+ + Pass2Verifier.getText(constantFieldref)
+ + "'."));
+ }
+ int class_index = constantFieldref.getClass_index();
+ ConstantClass constantClass = (ConstantClass) this.cp.getConstant(class_index);
+ String text2;
+ if (!Pass2Verifier.matchesText2(
+ text2 = ((ConstantUtf8) this.cp.getConstant(constantClass.getNameIndex())).getBytes())) {
+ throw new LoadingException(
+ ("Illegal class name '"
+ + text2
+ + "' used by '"
+ + Pass2Verifier.getText(constantFieldref)
+ + "'."));
+ }
+ String bytes =
+ ((ConstantUtf8) this.cp.getConstant(constantNameAndType.getSignature_index())).getBytes();
+ try {
+ Type.getType(bytes);
+ } catch (ClassFormatException classFormatException) {
+ throw new LoadingException(
+ ("Illegal descriptor (==signature) '"
+ + bytes
+ + "' used by '"
+ + Pass2Verifier.getText(constantFieldref)
+ + "'."));
+ }
+ }
+
+ @Override
+ public void visitConstantMethodref(ConstantMethodref constantMethodref) {
+ if (constantMethodref.getTag() != 10) {
+ throw new LoadingException(
+ ("ConstantMethodref '" + Pass2Verifier.getText(constantMethodref) + "' has wrong tag!"));
+ }
+ int name_and_type_index = constantMethodref.getName_and_type_index();
+ ConstantNameAndType constantNameAndType =
+ (ConstantNameAndType) this.cp.getConstant(name_and_type_index);
+ String text;
+ if (!Pass2Verifier.matchesText3(
+ text =
+ ((ConstantUtf8) this.cp.getConstant(constantNameAndType.getName_index())).getBytes())) {
+ throw new LoadingException(
+ ("Invalid (non-interface) method name '"
+ + text
+ + "' referenced by '"
+ + Pass2Verifier.getText(constantMethodref)
+ + "'."));
+ }
+ int class_index = constantMethodref.getClass_index();
+ ConstantClass constantClass = (ConstantClass) this.cp.getConstant(class_index);
+ String text2;
+ if (!Pass2Verifier.matchesText2(
+ text2 = ((ConstantUtf8) this.cp.getConstant(constantClass.getNameIndex())).getBytes())) {
+ throw new LoadingException(
+ ("Illegal class name '"
+ + text2
+ + "' used by '"
+ + Pass2Verifier.getText(constantMethodref)
+ + "'."));
+ }
+ String bytes =
+ ((ConstantUtf8) this.cp.getConstant(constantNameAndType.getSignature_index())).getBytes();
+ try {
+ Type returnType = Type.getReturnType(bytes);
+ if (text.equals("") && returnType != Type.VOID) {
+ throw new LoadingException("Instance initialization method must have VOID return type.");
+ }
+ } catch (ClassFormatException classFormatException) {
+ throw new LoadingException(
+ ("Illegal descriptor (==signature) '"
+ + bytes
+ + "' used by '"
+ + Pass2Verifier.getText(constantMethodref)
+ + "'."));
+ }
+ }
+
+ @Override
+ public void visitConstantInterfaceMethodref(
+ ConstantInterfaceMethodref constantInterfaceMethodref) {
+ if (constantInterfaceMethodref.getTag() != 11) {
+ throw new LoadingException(
+ ("ConstantInterfaceMethodref '"
+ + Pass2Verifier.getText(constantInterfaceMethodref)
+ + "' has wrong tag!"));
+ }
+ int name_and_type_index = constantInterfaceMethodref.getName_and_type_index();
+ ConstantNameAndType constantNameAndType =
+ (ConstantNameAndType) this.cp.getConstant(name_and_type_index);
+ String text;
+ if (!Pass2Verifier.matchesText10(
+ text =
+ ((ConstantUtf8) this.cp.getConstant(constantNameAndType.getName_index())).getBytes())) {
+ throw new LoadingException(
+ ("Invalid (interface) method name '"
+ + text
+ + "' referenced by '"
+ + Pass2Verifier.getText(constantInterfaceMethodref)
+ + "'."));
+ }
+ int class_index = constantInterfaceMethodref.getClass_index();
+ ConstantClass constantClass = (ConstantClass) this.cp.getConstant(class_index);
+ String text2;
+ if (!Pass2Verifier.matchesText2(
+ text2 = ((ConstantUtf8) this.cp.getConstant(constantClass.getNameIndex())).getBytes())) {
+ throw new LoadingException(
+ ("Illegal class name '"
+ + text2
+ + "' used by '"
+ + Pass2Verifier.getText(constantInterfaceMethodref)
+ + "'."));
+ }
+ String bytes =
+ ((ConstantUtf8) this.cp.getConstant(constantNameAndType.getSignature_index())).getBytes();
+ try {
+ Type returnType = Type.getReturnType(bytes);
+ if (text.equals("") && returnType != Type.VOID) {
+ this.this$0.addMessage(
+ "Class or interface initialization method '' usually has VOID return type"
+ + " instead of '"
+ + returnType
+ + "'. Note this is really not a requirement of The Java Virtual Machine"
+ + " Specification, Second Edition.");
+ }
+ } catch (ClassFormatException classFormatException) {
+ throw new LoadingException(
+ ("Illegal descriptor (==signature) '"
+ + bytes
+ + "' used by '"
+ + Pass2Verifier.getText(constantInterfaceMethodref)
+ + "'."));
+ }
+ }
+
+ public Pass2Verifier$FAMRAV_Visitor(Pass2Verifier pass2Verifier, JavaClass javaClass) {
+ super();
+ this.this$0 = pass2Verifier;
+ this.cp = javaClass.getConstantPool();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$InnerClassDetector.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$InnerClassDetector.java
new file mode 100644
index 0000000..bf5f266
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier$InnerClassDetector.java
@@ -0,0 +1,41 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.classfile.ConstantClass;
+import com.allatori.lib.bcel.classfile.ConstantPool;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.classfile.DescendingVisitor;
+import com.allatori.lib.bcel.classfile.EmptyVisitor;
+import com.allatori.lib.bcel.classfile.JavaClass;
+
+public class Pass2Verifier$InnerClassDetector extends EmptyVisitor {
+
+ public ConstantPool cp;
+
+ public boolean hasInnerClass;
+
+ public JavaClass jc;
+
+ public boolean innerClassReferenced() {
+ return this.hasInnerClass;
+ }
+
+ @Override
+ public void visitConstantClass(ConstantClass constantClass) {
+ Constant constant;
+ if ((constant = this.cp.getConstant(constantClass.getNameIndex())) instanceof ConstantUtf8) {
+ String bytes = ((ConstantUtf8) constant).getBytes();
+ if (bytes.startsWith(this.jc.getText2().replace('.', '/') + "$")) {
+ this.hasInnerClass = true;
+ }
+ }
+ }
+
+ public Pass2Verifier$InnerClassDetector(JavaClass javaClass) {
+ super();
+ this.hasInnerClass = false;
+ this.jc = javaClass;
+ this.cp = this.jc.getConstantPool();
+ new DescendingVisitor(this.jc, this).visit();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier.java
new file mode 100644
index 0000000..d48ab94
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass2Verifier.java
@@ -0,0 +1,258 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.lib.bcel.Constants;
+import com.allatori.lib.bcel.Repository;
+import com.allatori.lib.bcel.classfile.DescendingVisitor;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.classfile.Node;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.lib.bcel.verifier.PassVerifier;
+import com.allatori.lib.bcel.verifier.VerificationResult;
+import com.allatori.lib.bcel.verifier.Verifier;
+import com.allatori.lib.bcel.verifier.VerifierFactory;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import com.allatori.lib.bcel.verifier.exc.LoadingException;
+import java.util.HashMap;
+import java.util.HashSet;
+
+public final class Pass2Verifier extends PassVerifier implements Constants {
+
+ public Verifier myOwner;
+
+ public LocalVariablesInfo[] localVariablesInfos;
+
+ public static Verifier access$400(Pass2Verifier pass2Verifier) {
+ return pass2Verifier.myOwner;
+ }
+
+ public Pass2Verifier(Verifier verifier) {
+ super();
+ this.myOwner = verifier;
+ }
+
+ public static boolean matchesText(String text) {
+ return matchesText9(text);
+ }
+
+ public static boolean matchesText2(String text) {
+ return matchesText8(text);
+ }
+
+ public void final_methods_are_not_overridden() {
+ try {
+ HashMap entries = new HashMap();
+ JavaClass javaClass = Repository.lookupClass(this.myOwner.getClassName());
+ for (int value = -1; value != 0; javaClass = Repository.lookupClass(javaClass.getText5())) {
+ value = javaClass.getCount2();
+ Method[] methods = javaClass.getMethods();
+ int value2;
+ for (int value3 = value2 = 0; value3 < methods.length; value3 = ++value2) {
+ String text = "" + methods[value2].getText() + methods[value2].getText2();
+ if (entries.containsKey(text)) {
+ if (methods[value2].isEnabled3()) {
+ if (!methods[value2].isEnabled9()) {
+ throw new LoadingException(
+ ("Method '"
+ + text
+ + "' in class '"
+ + entries.get(text)
+ + "' overrides the final (not-overridable) definition in class '"
+ + javaClass.getText2()
+ + "'."));
+ }
+ this.addMessage(
+ "Method '"
+ + text
+ + "' in class '"
+ + entries.get(text)
+ + "' overrides the final (not-overridable) definition in class '"
+ + javaClass.getText2()
+ + "'. This is okay, as the original definition was private; however this"
+ + " constraint leverage was introduced by JLS 8.4.6 (not vmspec2) and the"
+ + " behaviour of the Sun verifiers.");
+ } else if (!methods[value2].isEnabled11()) {
+ entries.put(text, javaClass.getText2());
+ }
+ } else if (!methods[value2].isEnabled11()) {
+ entries.put(text, javaClass.getText2());
+ }
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ public static String getText(Node node) {
+ return createText(node);
+ }
+
+ public static boolean matchesText3(String text) {
+ return matchesText5(text);
+ }
+
+ public void every_class_has_an_accessible_superclass() {
+ try {
+ HashSet values = new HashSet();
+ JavaClass javaClass = Repository.lookupClass(this.myOwner.getClassName());
+ int value = -1;
+ while (value != 0) {
+ if ((value = javaClass.getCount2()) == 0) {
+ if (javaClass != Repository.lookupClass(Type.OBJECT.getClassName())) {
+ throw new LoadingException(
+ ("Superclass of '"
+ + javaClass.getText2()
+ + "' missing but not "
+ + Type.OBJECT.getClassName()
+ + " itself!"));
+ }
+ } else {
+ String text5 = javaClass.getText5();
+ if (!values.add(text5)) {
+ throw new LoadingException("Circular superclass hierarchy detected.");
+ }
+ if (VerifierFactory.getVerifier(text5).createVerificationResult()
+ != VerificationResult.VERIFICATION_RESULT2) {
+ throw new LoadingException(("Could not load in ancestor class '" + text5 + "'."));
+ }
+ if ((javaClass = Repository.lookupClass(text5)).isEnabled3()) {
+ throw new LoadingException(
+ ("Ancestor class '"
+ + text5
+ + "' has the FINAL access modifier and must therefore not be subclassed."));
+ }
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ public static String createText(Node node) {
+ return new StringRepresentation(node).toString();
+ }
+
+ public static boolean matchesText4(String text) {
+ return matchesText6(text);
+ }
+
+ public static LocalVariablesInfo[] access$500(Pass2Verifier pass2Verifier) {
+ return pass2Verifier.localVariablesInfos;
+ }
+
+ public static boolean matchesText5(String text) {
+ return matchesEnabled(text, false);
+ }
+
+ public static boolean matchesText6(String text) {
+ if (text.length() == 0) {
+ return false;
+ }
+ if (!Character.isJavaIdentifierStart(text.charAt(0))) {
+ return false;
+ }
+ int value;
+ for (int value2 = value = 1; value2 < text.length(); value2 = ++value) {
+ if (!Character.isJavaIdentifierPart(text.charAt(value))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void constant_pool_entries_satisfy_static_constraints() {
+ try {
+ JavaClass javaClass = Repository.lookupClass(this.myOwner.getClassName());
+ new Pass2Verifier$CPESSC_Visitor(this, javaClass, null);
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public VerificationResult getVerificationResult() {
+ try {
+ if (this.myOwner.createVerificationResult().equals(VerificationResult.VERIFICATION_RESULT2)) {
+ this.localVariablesInfos =
+ new LocalVariablesInfo
+ [Repository.lookupClass(this.myOwner.getClassName()).getMethods().length];
+ VerificationResult verificationResult = VerificationResult.VERIFICATION_RESULT2;
+ try {
+ this.constant_pool_entries_satisfy_static_constraints();
+ this.field_and_method_refs_are_valid();
+ this.every_class_has_an_accessible_superclass();
+ this.final_methods_are_not_overridden();
+ return verificationResult;
+ } catch (LoadingException loadingException) {
+ return new VerificationResult(2, loadingException.getMessage());
+ }
+ } else {
+ return VerificationResult.VERIFICATION_RESULT;
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ public static boolean matchesEnabled(String text, boolean matches) {
+ if (matchesText7(text)) {
+ return true;
+ } else {
+ return matches ? text.equals("") || text.equals("") : text.equals("");
+ }
+ }
+
+ public static boolean matchesText7(String text) {
+ if (!Character.isJavaIdentifierStart(text.charAt(0))) {
+ return false;
+ }
+ int value;
+ for (int value2 = value = 1; value2 < text.length(); value2 = ++value) {
+ if (!Character.isJavaIdentifierPart(text.charAt(value))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void field_and_method_refs_are_valid() {
+ try {
+ JavaClass javaClass = Repository.lookupClass(this.myOwner.getClassName());
+ new DescendingVisitor(javaClass, new Pass2Verifier$FAMRAV_Visitor(this, javaClass, null))
+ .visit();
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ public static final boolean matchesText8(String text) {
+ return true;
+ }
+
+ public LocalVariablesInfo getLocalVariablesInfo(int value) {
+ if (this.getVerificationResult2() != VerificationResult.VERIFICATION_RESULT2) {
+ return null;
+ } else if (value >= 0 && value < this.localVariablesInfos.length) {
+ return this.localVariablesInfos[value];
+ } else {
+ throw new AssertionViolatedException("Method number out of range.");
+ }
+ }
+
+ public static boolean matchesEnabled2(String text, boolean matches) {
+ return matchesEnabled(text, matches);
+ }
+
+ public static boolean matchesText9(String text) {
+ return matchesText6(text);
+ }
+
+ public static boolean matchesText10(String text) {
+ return matchesText11(text);
+ }
+
+ public static boolean matchesText11(String text) {
+ return text.startsWith("<") ? false : matchesText7(text);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass3aVerifier$InstOperandConstraintVisitor.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass3aVerifier$InstOperandConstraintVisitor.java
new file mode 100644
index 0000000..2785714
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass3aVerifier$InstOperandConstraintVisitor.java
@@ -0,0 +1,1016 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.lib.bcel.Repository;
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.classfile.ConstantClass;
+import com.allatori.lib.bcel.classfile.ConstantDouble;
+import com.allatori.lib.bcel.classfile.ConstantFieldref;
+import com.allatori.lib.bcel.classfile.ConstantFloat;
+import com.allatori.lib.bcel.classfile.ConstantInteger;
+import com.allatori.lib.bcel.classfile.ConstantInterfaceMethodref;
+import com.allatori.lib.bcel.classfile.ConstantLong;
+import com.allatori.lib.bcel.classfile.ConstantMethodref;
+import com.allatori.lib.bcel.classfile.ConstantNameAndType;
+import com.allatori.lib.bcel.classfile.ConstantString;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ALOAD;
+import com.allatori.lib.bcel.generic.ANEWARRAY;
+import com.allatori.lib.bcel.generic.ASTORE;
+import com.allatori.lib.bcel.generic.ArrayType;
+import com.allatori.lib.bcel.generic.CHECKCAST;
+import com.allatori.lib.bcel.generic.ConstantPoolGen;
+import com.allatori.lib.bcel.generic.DLOAD;
+import com.allatori.lib.bcel.generic.DSTORE;
+import com.allatori.lib.bcel.generic.EmptyVisitor;
+import com.allatori.lib.bcel.generic.FLOAD;
+import com.allatori.lib.bcel.generic.FSTORE;
+import com.allatori.lib.bcel.generic.FieldInstruction;
+import com.allatori.lib.bcel.generic.GETSTATIC;
+import com.allatori.lib.bcel.generic.IINC;
+import com.allatori.lib.bcel.generic.ILOAD;
+import com.allatori.lib.bcel.generic.INSTANCEOF;
+import com.allatori.lib.bcel.generic.INVOKEINTERFACE;
+import com.allatori.lib.bcel.generic.INVOKESPECIAL;
+import com.allatori.lib.bcel.generic.INVOKESTATIC;
+import com.allatori.lib.bcel.generic.INVOKEVIRTUAL;
+import com.allatori.lib.bcel.generic.ISTORE;
+import com.allatori.lib.bcel.generic.Instruction;
+import com.allatori.lib.bcel.generic.InvokeInstruction;
+import com.allatori.lib.bcel.generic.LDC;
+import com.allatori.lib.bcel.generic.LDC2_W;
+import com.allatori.lib.bcel.generic.LLOAD;
+import com.allatori.lib.bcel.generic.LOOKUPSWITCH;
+import com.allatori.lib.bcel.generic.LSTORE;
+import com.allatori.lib.bcel.generic.LoadClass;
+import com.allatori.lib.bcel.generic.MULTIANEWARRAY;
+import com.allatori.lib.bcel.generic.NEW;
+import com.allatori.lib.bcel.generic.NEWARRAY;
+import com.allatori.lib.bcel.generic.ObjectType;
+import com.allatori.lib.bcel.generic.PUTSTATIC;
+import com.allatori.lib.bcel.generic.RET;
+import com.allatori.lib.bcel.generic.TABLESWITCH;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.lib.bcel.verifier.VerificationResult;
+import com.allatori.lib.bcel.verifier.VerifierFactory;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import com.allatori.lib.bcel.verifier.exc.StaticCodeInstructionConstraintException;
+
+public class Pass3aVerifier$InstOperandConstraintVisitor extends EmptyVisitor {
+
+ public ConstantPoolGen constantPoolGen;
+
+ public final Pass3aVerifier this$0;
+
+ public Pass3aVerifier$InstOperandConstraintVisitor(
+ Pass3aVerifier pass3aVerifier, ConstantPoolGen constantPoolGen2) {
+ super();
+ this.this$0 = pass3aVerifier;
+ this.constantPoolGen = constantPoolGen2;
+ }
+
+ @Override
+ public void visitASTORE(ASTORE aSTORE) {
+ int value;
+ if ((value = aSTORE.getIndex()) < 0) {
+ this.constraintViolated(aSTORE, "Index '" + value + "' must be non-negative.");
+ } else {
+ int value2 = this.maxLocals() - 1;
+ if (value > value2) {
+ this.constraintViolated(
+ aSTORE,
+ "Index '" + value + "' must not be greater than max_locals-1 '" + value2 + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitLDC(LDC lDC) {
+ this.indexValid(lDC, lDC.getIndex());
+ Constant constant;
+ if ((constant = this.constantPoolGen.getConstant(lDC.getIndex())) instanceof ConstantClass) {
+ this.this$0.addMessage(
+ "Operand of LDC or LDC_W is CONSTANT_Class '"
+ + constant
+ + "' - this is only supported in JDK 1.5 and higher.");
+ } else {
+ if (!(constant instanceof ConstantInteger)
+ && !(constant instanceof ConstantFloat)
+ && !(constant instanceof ConstantString)) {
+ this.constraintViolated(
+ lDC,
+ "Operand of LDC or LDC_W must be one of CONSTANT_Integer, CONSTANT_Float or"
+ + " CONSTANT_String, but is '"
+ + constant
+ + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitPUTSTATIC(PUTSTATIC pUTSTATIC) {
+ Field field;
+ try {
+ String fieldName = pUTSTATIC.getFieldName(this.constantPoolGen);
+ JavaClass javaClass;
+ Field[] fields =
+ (javaClass =
+ Repository.lookupClass(
+ pUTSTATIC.createObjectType(this.constantPoolGen).getClassName()))
+ .getFields();
+ Field field2 = null;
+ int value;
+ int value2 = value = 0;
+ while (true) {
+ if (value2 >= fields.length) {
+ field = field2;
+ break;
+ }
+ if (fields[value].getText().equals(fieldName)) {
+ field = field2 = fields[value];
+ break;
+ }
+ value2 = ++value;
+ }
+ if (field == null) {
+ throw new AssertionViolatedException("Field not found?!?");
+ }
+ if (field2.isEnabled3()
+ && !Pass3aVerifier.access$000(this.this$0)
+ .getClassName()
+ .equals(pUTSTATIC.createObjectType(this.constantPoolGen).getClassName())) {
+ this.constraintViolated(
+ pUTSTATIC,
+ "Referenced field '"
+ + field2
+ + "' is final and must therefore be declared in the current class '"
+ + Pass3aVerifier.access$000(this.this$0).getClassName()
+ + "' which is not the case: it is declared in '"
+ + pUTSTATIC.createObjectType(this.constantPoolGen).getClassName()
+ + "'.");
+ }
+ if (!field2.isEnabled11()) {
+ this.constraintViolated(
+ pUTSTATIC, "Referenced field '" + field2 + "' is not static which it should be.");
+ }
+ String text =
+ Repository.lookupClass(Pass3aVerifier.access$000(this.this$0).getClassName())
+ .getMethods()[Pass3aVerifier.access$100(this.this$0)]
+ .getText();
+ if (!javaClass.isEnabled17() && !text.equals("")) {
+ this.constraintViolated(
+ pUTSTATIC,
+ "Interface field '" + field2 + "' must be set in a '" + "" + "' method.");
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitTABLESWITCH(TABLESWITCH tABLESWITCH) {}
+
+ @Override
+ public void visitDLOAD(DLOAD dLOAD) {
+ int value;
+ if ((value = dLOAD.getIndex()) < 0) {
+ this.constraintViolated(
+ dLOAD,
+ "Index '"
+ + value
+ + "' must be non-negative. [Constraint by JustIce as an analogon to the single-slot"
+ + " xLOAD/xSTORE instructions; may not happen anyway.]");
+ } else {
+ int value2 = this.maxLocals() - 2;
+ if (value > value2) {
+ this.constraintViolated(
+ dLOAD, "Index '" + value + "' must not be greater than max_locals-2 '" + value2 + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitMULTIANEWARRAY(MULTIANEWARRAY mULTIANEWARRAY) {
+ this.indexValid(mULTIANEWARRAY, mULTIANEWARRAY.getIndex());
+ Constant constant;
+ if (!((constant = this.constantPoolGen.getConstant(mULTIANEWARRAY.getIndex()))
+ instanceof ConstantClass)) {
+ this.constraintViolated(
+ mULTIANEWARRAY, "Expecting a CONSTANT_Class operand, but found a '" + constant + "'.");
+ }
+ short value;
+ if ((value = mULTIANEWARRAY.getDimensions()) < 1) {
+ this.constraintViolated(
+ mULTIANEWARRAY, "Number of dimensions to create must be greater than zero.");
+ }
+ Type type;
+ if ((type = mULTIANEWARRAY.getType(this.constantPoolGen)) instanceof ArrayType) {
+ if (((ArrayType) type).getDimensions() < value) {
+ this.constraintViolated(
+ mULTIANEWARRAY,
+ "Not allowed to create array with more dimensions ('+dimensions2create+') than the one"
+ + " referenced by the CONSTANT_Class '"
+ + type
+ + "'.");
+ return;
+ }
+ } else {
+ this.constraintViolated(
+ mULTIANEWARRAY,
+ "Expecting a CONSTANT_Class referencing an array type. [Constraint not found in The Java"
+ + " Virtual Machine Specification, Second Edition, 4.8.1]");
+ }
+ }
+
+ @Override
+ public void visitInvokeInstruction(InvokeInstruction invokeInstruction) {
+ this.indexValid(invokeInstruction, invokeInstruction.getIndex());
+ if (!(invokeInstruction instanceof INVOKEVIRTUAL)
+ && !(invokeInstruction instanceof INVOKESPECIAL)
+ && !(invokeInstruction instanceof INVOKESTATIC)) {
+ Constant constant;
+ if (!((constant = this.constantPoolGen.getConstant(invokeInstruction.getIndex()))
+ instanceof ConstantInterfaceMethodref)) {
+ this.constraintViolated(
+ invokeInstruction,
+ "Indexing a constant that's not a CONSTANT_InterfaceMethodref but a '"
+ + constant
+ + "'.");
+ }
+ ConstantNameAndType constantNameAndType =
+ (ConstantNameAndType)
+ this.constantPoolGen.getConstant(
+ ((ConstantInterfaceMethodref) constant).getName_and_type_index());
+ String text;
+ if ((text =
+ ((ConstantUtf8) this.constantPoolGen.getConstant(constantNameAndType.getName_index()))
+ .getBytes())
+ .equals("")) {
+ this.constraintViolated(invokeInstruction, "Method to invoke must not be ''.");
+ }
+ if (text.equals("")) {
+ this.constraintViolated(invokeInstruction, "Method to invoke must not be ''.");
+ }
+ } else {
+ Constant constant2;
+ if (!((constant2 = this.constantPoolGen.getConstant(invokeInstruction.getIndex()))
+ instanceof ConstantMethodref)) {
+ this.constraintViolated(
+ invokeInstruction,
+ "Indexing a constant that's not a CONSTANT_Methodref but a '" + constant2 + "'.");
+ } else {
+ ConstantNameAndType constantNameAndType2 =
+ (ConstantNameAndType)
+ this.constantPoolGen.getConstant(
+ ((ConstantMethodref) constant2).getName_and_type_index());
+ ConstantUtf8 constantUtf8;
+ if ((constantUtf8 =
+ (ConstantUtf8)
+ this.constantPoolGen.getConstant(constantNameAndType2.getName_index()))
+ .getBytes()
+ .equals("")
+ && !(invokeInstruction instanceof INVOKESPECIAL)) {
+ this.constraintViolated(
+ invokeInstruction,
+ "Only INVOKESPECIAL is allowed to invoke instance initialization methods.");
+ }
+ if (!constantUtf8.getBytes().equals("") && constantUtf8.getBytes().startsWith("<")) {
+ this.constraintViolated(
+ invokeInstruction,
+ "No method with a name beginning with '<' other than the instance initialization"
+ + " methods may be called by the method invocation instructions.");
+ }
+ }
+ }
+ Type type;
+ if ((type = invokeInstruction.getType2(this.constantPoolGen)) instanceof ArrayType) {
+ type = ((ArrayType) type).getBasicType();
+ }
+ VerificationResult verificationResult;
+ if (type instanceof ObjectType
+ && (verificationResult =
+ VerifierFactory.getVerifier(((ObjectType) type).getClassName())
+ .createVerificationResult2())
+ .getStatus()
+ != 1) {
+ this.constraintViolated(
+ invokeInstruction,
+ "Return type class/interface could not be verified successfully: '"
+ + verificationResult.getDetailMessage()
+ + "'.");
+ }
+ Type[] argumentTypes = invokeInstruction.getArgumentTypes(this.constantPoolGen);
+ int value;
+ for (int value2 = value = 0; value2 < argumentTypes.length; value2 = ++value) {
+ Type type2;
+ if ((type2 = argumentTypes[value]) instanceof ArrayType) {
+ type2 = ((ArrayType) type2).getBasicType();
+ }
+ VerificationResult verificationResult2;
+ if (type2 instanceof ObjectType
+ && (verificationResult2 =
+ VerifierFactory.getVerifier(((ObjectType) type2).getClassName())
+ .createVerificationResult2())
+ .getStatus()
+ != 1) {
+ this.constraintViolated(
+ invokeInstruction,
+ "Argument type class/interface could not be verified successfully: '"
+ + verificationResult2.getDetailMessage()
+ + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitFSTORE(FSTORE fSTORE) {
+ int value;
+ if ((value = fSTORE.getIndex()) < 0) {
+ this.constraintViolated(fSTORE, "Index '" + value + "' must be non-negative.");
+ } else {
+ int value2 = this.maxLocals() - 1;
+ if (value > value2) {
+ this.constraintViolated(
+ fSTORE,
+ "Index '" + value + "' must not be greater than max_locals-1 '" + value2 + "'.");
+ }
+ }
+ }
+
+ public void constraintViolated(Instruction instruction, String text) {
+ throw new StaticCodeInstructionConstraintException(
+ ("Instruction " + instruction + " constraint violated: " + text));
+ }
+
+ @Override
+ public void visitINSTANCEOF(INSTANCEOF nSTANCEOF) {
+ this.indexValid(nSTANCEOF, nSTANCEOF.getIndex());
+ Constant constant;
+ if (!((constant = this.constantPoolGen.getConstant(nSTANCEOF.getIndex()))
+ instanceof ConstantClass)) {
+ this.constraintViolated(
+ nSTANCEOF, "Expecting a CONSTANT_Class operand, but found a '" + constant + "'.");
+ }
+ }
+
+ @Override
+ public void visitFieldInstruction(FieldInstruction fieldInstruction) {
+ Field field;
+ Field field2;
+ try {
+ this.indexValid(fieldInstruction, fieldInstruction.getIndex());
+ Constant constant;
+ if (!((constant = this.constantPoolGen.getConstant(fieldInstruction.getIndex()))
+ instanceof ConstantFieldref)) {
+ this.constraintViolated(
+ fieldInstruction,
+ "Indexing a constant that's not a CONSTANT_Fieldref but a '" + constant + "'.");
+ }
+ String fieldName = fieldInstruction.getFieldName(this.constantPoolGen);
+ JavaClass javaClass;
+ Field[] fields =
+ (javaClass =
+ Repository.lookupClass(
+ fieldInstruction.createObjectType(this.constantPoolGen).getClassName()))
+ .getFields();
+ Field field3 = null;
+ int value;
+ int value2 = value = 0;
+ while (true) {
+ if (value2 >= fields.length) {
+ field2 = field3;
+ break;
+ }
+ if (fields[value].getText().equals(fieldName)) {
+ Type type = Type.getType(fields[value].getText2());
+ Type type2 = fieldInstruction.getType(this.constantPoolGen);
+ if (type.equals(type2)) {
+ field2 = field3 = fields[value];
+ break;
+ }
+ }
+ value2 = ++value;
+ }
+ if (field2 != null) {
+ Type.getType(field3.getText2());
+ fieldInstruction.getType(this.constantPoolGen);
+ } else {
+ JavaClass[] javaClasss = javaClass.createJavaClasss();
+ int value3;
+ value2 = value3 = 0;
+ label52:
+ while (true) {
+ if (value2 < javaClasss.length) {
+ Field[] fields2 = javaClasss[value3].getFields();
+ int value4;
+ value2 = value4 = 0;
+ while (true) {
+ if (value2 >= fields2.length) {
+ value2 = ++value3;
+ continue label52;
+ }
+ if (fields2[value4].getText().equals(fieldName)) {
+ Type type3 = Type.getType(fields2[value4].getText2());
+ Type type4 = fieldInstruction.getType(this.constantPoolGen);
+ if (type3.equals(type4)) {
+ if (((field3 = fields2[value4]).getAccess_flags2() & 5) == 0) {
+ field = null;
+ break label52;
+ }
+ break;
+ }
+ }
+ value2 = ++value4;
+ }
+ }
+ field = field3;
+ break;
+ }
+ if (field == null) {
+ this.constraintViolated(
+ fieldInstruction,
+ "Referenced field '"
+ + fieldName
+ + "' does not exist in class '"
+ + javaClass.getText2()
+ + "'.");
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitILOAD(ILOAD lOAD) {
+ int value;
+ if ((value = lOAD.getIndex()) < 0) {
+ this.constraintViolated(lOAD, "Index '" + value + "' must be non-negative.");
+ } else {
+ int value2 = this.maxLocals() - 1;
+ if (value > value2) {
+ this.constraintViolated(
+ lOAD, "Index '" + value + "' must not be greater than max_locals-1 '" + value2 + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitLoadClass(LoadClass loadClass) {
+ ObjectType objectType;
+ VerificationResult verificationResult;
+ if ((objectType = loadClass.getLoadClassType(this.constantPoolGen)) != null
+ && (verificationResult =
+ VerifierFactory.getVerifier(objectType.getClassName())
+ .createVerificationResult())
+ .getStatus()
+ != 1) {
+ this.constraintViolated(
+ (Instruction) loadClass,
+ "Class '"
+ + loadClass.getLoadClassType(this.constantPoolGen).getClassName()
+ + "' is referenced, but cannot be loaded: '"
+ + verificationResult
+ + "'.");
+ }
+ }
+
+ public boolean matchesValues(Object[] results, Object[] results2) {
+ if (results.length != results2.length) {
+ return false;
+ }
+ int value;
+ for (int value2 = value = 0; value2 < results.length; value2 = ++value) {
+ if (!results[value].equals(results2[value])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void visitNEWARRAY(NEWARRAY nEWARRAY) {
+ byte value;
+ if ((value = nEWARRAY.getTypecode()) != 4
+ && value != 5
+ && value != 6
+ && value != 7
+ && value != 8
+ && value != 9
+ && value != 10
+ && value != 11) {
+ this.constraintViolated(nEWARRAY, "Illegal type code '+t+' for 'atype' operand.");
+ }
+ }
+
+ @Override
+ public void visitLDC2_W(LDC2_W lDC2_W) {
+ this.indexValid(lDC2_W, lDC2_W.getIndex());
+ Constant constant;
+ if (!((constant = this.constantPoolGen.getConstant(lDC2_W.getIndex())) instanceof ConstantLong)
+ && !(constant instanceof ConstantDouble)) {
+ this.constraintViolated(
+ lDC2_W,
+ "Operand of LDC2_W must be CONSTANT_Long or CONSTANT_Double, but is '" + constant + "'.");
+ }
+ try {
+ this.indexValid(lDC2_W, lDC2_W.getIndex() + 1);
+ } catch (StaticCodeInstructionConstraintException staticCodeInstructionConstraintException) {
+ throw new AssertionViolatedException(
+ "OOPS: Does not BCEL handle that? LDC2_W operand has a problem.");
+ }
+ }
+
+ @Override
+ public void visitRET(RET rET) {
+ int value;
+ if ((value = rET.getIndex()) < 0) {
+ this.constraintViolated(rET, "Index '" + value + "' must be non-negative.");
+ } else {
+ int value2 = this.maxLocals() - 1;
+ if (value > value2) {
+ this.constraintViolated(
+ rET, "Index '" + value + "' must not be greater than max_locals-1 '" + value2 + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitLLOAD(LLOAD lLOAD) {
+ int value;
+ if ((value = lLOAD.getIndex()) < 0) {
+ this.constraintViolated(
+ lLOAD,
+ "Index '"
+ + value
+ + "' must be non-negative. [Constraint by JustIce as an analogon to the single-slot"
+ + " xLOAD/xSTORE instructions; may not happen anyway.]");
+ } else {
+ int value2 = this.maxLocals() - 2;
+ if (value > value2) {
+ this.constraintViolated(
+ lLOAD, "Index '" + value + "' must not be greater than max_locals-2 '" + value2 + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitINVOKEVIRTUAL(INVOKEVIRTUAL nVOKEVIRTUAL) {
+ Method method;
+ try {
+ JavaClass javaClass;
+ Method[] methods =
+ (javaClass = Repository.lookupClass(nVOKEVIRTUAL.getText2(this.constantPoolGen)))
+ .getMethods();
+ int value;
+ int value2 = value = 0;
+ while (true) {
+ if (value2 >= methods.length) {
+ method = (Method) (Object) null;
+ break;
+ }
+ if (methods[value].getText().equals(nVOKEVIRTUAL.getText4(this.constantPoolGen))
+ && Type.getReturnType(methods[value].getText2())
+ .equals(nVOKEVIRTUAL.getType2(this.constantPoolGen))
+ && this.matchesValues(
+ Type.getArgumentTypes(methods[value].getText2()),
+ nVOKEVIRTUAL.getArgumentTypes(this.constantPoolGen))) {
+ method = methods[value];
+ break;
+ }
+ value2 = ++value;
+ }
+ if (method == null) {
+ this.constraintViolated(
+ nVOKEVIRTUAL,
+ "Referenced method '"
+ + nVOKEVIRTUAL.getText4(this.constantPoolGen)
+ + "' with expected signature '"
+ + nVOKEVIRTUAL.getText3(this.constantPoolGen)
+ + "' not found in class '"
+ + javaClass.getText2()
+ + "'. The native verifier does allow the method to be declared in some superclass"
+ + " or implemented interface, which the Java Virtual Machine Specification, Second"
+ + " Edition does not.");
+ }
+ if (!javaClass.isEnabled17()) {
+ this.constraintViolated(
+ nVOKEVIRTUAL,
+ "Referenced class '"
+ + javaClass.getText2()
+ + "' is an interface, but not a class as expected.");
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitLSTORE(LSTORE lSTORE) {
+ int value;
+ if ((value = lSTORE.getIndex()) < 0) {
+ this.constraintViolated(
+ lSTORE,
+ "Index '"
+ + value
+ + "' must be non-negative. [Constraint by JustIce as an analogon to the single-slot"
+ + " xLOAD/xSTORE instructions; may not happen anyway.]");
+ } else {
+ int value2 = this.maxLocals() - 2;
+ if (value > value2) {
+ this.constraintViolated(
+ lSTORE,
+ "Index '" + value + "' must not be greater than max_locals-2 '" + value2 + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitIINC(IINC iNC) {
+ int value;
+ if ((value = iNC.getIndex()) < 0) {
+ this.constraintViolated(iNC, "Index '" + value + "' must be non-negative.");
+ } else {
+ int value2 = this.maxLocals() - 1;
+ if (value > value2) {
+ this.constraintViolated(
+ iNC, "Index '" + value + "' must not be greater than max_locals-1 '" + value2 + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitANEWARRAY(ANEWARRAY aNEWARRAY) {
+ this.indexValid(aNEWARRAY, aNEWARRAY.getIndex());
+ Constant constant;
+ if (!((constant = this.constantPoolGen.getConstant(aNEWARRAY.getIndex()))
+ instanceof ConstantClass)) {
+ this.constraintViolated(
+ aNEWARRAY, "Expecting a CONSTANT_Class operand, but found a '" + constant + "'.");
+ }
+ Type type;
+ if ((type = aNEWARRAY.getType(this.constantPoolGen)) instanceof ArrayType
+ && ((ArrayType) type).getDimensions() >= 255) {
+ this.constraintViolated(
+ aNEWARRAY, "Not allowed to create an array with more than 255 dimensions.");
+ }
+ }
+
+ @Override
+ public void visitNEW(NEW nEW) {
+ this.indexValid(nEW, nEW.getIndex());
+ Constant constant;
+ if (!((constant = this.constantPoolGen.getConstant(nEW.getIndex())) instanceof ConstantClass)) {
+ this.constraintViolated(
+ nEW, "Expecting a CONSTANT_Class operand, but found a '" + constant + "'.");
+ } else {
+ ConstantUtf8 constantUtf8 =
+ (ConstantUtf8)
+ this.constantPoolGen.getConstant(((ConstantClass) constant).getNameIndex());
+ if (Type.getType("L" + constantUtf8.getBytes() + ";") instanceof ArrayType) {
+ this.constraintViolated(nEW, "NEW must not be used to create an array.");
+ }
+ }
+ }
+
+ @Override
+ public void visitDSTORE(DSTORE dSTORE) {
+ int value;
+ if ((value = dSTORE.getIndex()) < 0) {
+ this.constraintViolated(
+ dSTORE,
+ "Index '"
+ + value
+ + "' must be non-negative. [Constraint by JustIce as an analogon to the single-slot"
+ + " xLOAD/xSTORE instructions; may not happen anyway.]");
+ } else {
+ int value2 = this.maxLocals() - 2;
+ if (value > value2) {
+ this.constraintViolated(
+ dSTORE,
+ "Index '" + value + "' must not be greater than max_locals-2 '" + value2 + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitLOOKUPSWITCH(LOOKUPSWITCH lOOKUPSWITCH) {
+ int[] match = lOOKUPSWITCH.getMatch();
+ int value = Integer.MIN_VALUE;
+ int value2;
+ for (int value3 = value2 = 0; value3 < match.length; value3 = ++value2) {
+ if (match[value2] == value && value2 != 0) {
+ this.constraintViolated(
+ lOOKUPSWITCH, "Match '" + match[value2] + "' occurs more than once.");
+ }
+ if (match[value2] < value) {
+ this.constraintViolated(lOOKUPSWITCH, "Lookup table must be sorted but isn't.");
+ } else {
+ value = match[value2];
+ }
+ }
+ }
+
+ @Override
+ public void visitCHECKCAST(CHECKCAST cHECKCAST) {
+ this.indexValid(cHECKCAST, cHECKCAST.getIndex());
+ Constant constant;
+ if (!((constant = this.constantPoolGen.getConstant(cHECKCAST.getIndex()))
+ instanceof ConstantClass)) {
+ this.constraintViolated(
+ cHECKCAST, "Expecting a CONSTANT_Class operand, but found a '" + constant + "'.");
+ }
+ }
+
+ public void indexValid(Instruction instruction, int value) {
+ if (value < 0 || value >= this.constantPoolGen.getSize()) {
+ this.constraintViolated(instruction, "Illegal constant pool index '" + value + "'.");
+ }
+ }
+
+ @Override
+ public void visitINVOKESPECIAL(INVOKESPECIAL nVOKESPECIAL) {
+ Method method;
+ Method method2;
+ Method method3;
+ try {
+ JavaClass javaClass;
+ Method[] methods =
+ (javaClass = Repository.lookupClass(nVOKESPECIAL.getText2(this.constantPoolGen)))
+ .getMethods();
+ int value;
+ int value2 = value = 0;
+ while (true) {
+ if (value2 >= methods.length) {
+ method3 = (Method) (Object) null;
+ break;
+ }
+ if (methods[value].getText().equals(nVOKESPECIAL.getText4(this.constantPoolGen))
+ && Type.getReturnType(methods[value].getText2())
+ .equals(nVOKESPECIAL.getType2(this.constantPoolGen))
+ && this.matchesValues(
+ Type.getArgumentTypes(methods[value].getText2()),
+ nVOKESPECIAL.getArgumentTypes(this.constantPoolGen))) {
+ method3 = methods[value];
+ break;
+ }
+ value2 = ++value;
+ }
+ if (method3 == null) {
+ this.constraintViolated(
+ nVOKESPECIAL,
+ "Referenced method '"
+ + nVOKESPECIAL.getText4(this.constantPoolGen)
+ + "' with expected signature '"
+ + nVOKESPECIAL.getText3(this.constantPoolGen)
+ + "' not found in class '"
+ + javaClass.getText2()
+ + "'. The native verifier does allow the method to be declared in some superclass"
+ + " or implemented interface, which the Java Virtual Machine Specification, Second"
+ + " Edition does not.");
+ }
+ JavaClass javaClass2;
+ if ((javaClass2 =
+ Repository.lookupClass(Pass3aVerifier.access$000(this.this$0).getClassName()))
+ .isEnabled16()
+ && Repository.matchesJavaClass(javaClass2, javaClass)
+ && !javaClass2.equals(javaClass)
+ && !nVOKESPECIAL.getText4(this.constantPoolGen).equals("")) {
+ int value3 = -1;
+ Method method4 = null;
+ while (true) {
+ if (value3 == 0) {
+ method2 = method4;
+ break;
+ }
+ value3 = javaClass2.getCount2();
+ Method[] methods2 =
+ (javaClass2 = Repository.lookupClass(javaClass2.getText5())).getMethods();
+ int value4;
+ value2 = value4 = 0;
+ while (true) {
+ if (value2 >= methods2.length) {
+ method = method4;
+ break;
+ }
+ if (methods2[value4].getText().equals(nVOKESPECIAL.getText4(this.constantPoolGen))
+ && Type.getReturnType(methods2[value4].getText2())
+ .equals(nVOKESPECIAL.getType2(this.constantPoolGen))
+ && this.matchesValues(
+ Type.getArgumentTypes(methods2[value4].getText2()),
+ nVOKESPECIAL.getArgumentTypes(this.constantPoolGen))) {
+ method = method4 = methods2[value4];
+ break;
+ }
+ value2 = ++value4;
+ }
+ if (method != null) {
+ method2 = method4;
+ break;
+ }
+ }
+ if (method2 == null) {
+ this.constraintViolated(
+ nVOKESPECIAL,
+ "ACC_SUPER special lookup procedure not successful: method '"
+ + nVOKESPECIAL.getText4(this.constantPoolGen)
+ + "' with proper signature not declared in superclass hierarchy.");
+ return;
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitFLOAD(FLOAD fLOAD) {
+ int value;
+ if ((value = fLOAD.getIndex()) < 0) {
+ this.constraintViolated(fLOAD, "Index '" + value + "' must be non-negative.");
+ } else {
+ int value2 = this.maxLocals() - 1;
+ if (value > value2) {
+ this.constraintViolated(
+ fLOAD, "Index '" + value + "' must not be greater than max_locals-1 '" + value2 + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitISTORE(ISTORE sTORE) {
+ int value;
+ if ((value = sTORE.getIndex()) < 0) {
+ this.constraintViolated(sTORE, "Index '" + value + "' must be non-negative.");
+ } else {
+ int value2 = this.maxLocals() - 1;
+ if (value > value2) {
+ this.constraintViolated(
+ sTORE, "Index '" + value + "' must not be greater than max_locals-1 '" + value2 + "'.");
+ }
+ }
+ }
+
+ public int maxLocals() {
+ try {
+ return Repository.lookupClass(Pass3aVerifier.access$000(this.this$0).getClassName())
+ .getMethods()[Pass3aVerifier.access$100(this.this$0)]
+ .getCode()
+ .getMax_locals();
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitGETSTATIC(GETSTATIC gETSTATIC) {
+ Field field;
+ try {
+ String fieldName = gETSTATIC.getFieldName(this.constantPoolGen);
+ Field[] fields =
+ Repository.lookupClass(gETSTATIC.createObjectType(this.constantPoolGen).getClassName())
+ .getFields();
+ Field field2 = null;
+ int value;
+ int value2 = value = 0;
+ while (true) {
+ if (value2 >= fields.length) {
+ field = field2;
+ break;
+ }
+ if (fields[value].getText().equals(fieldName)) {
+ field = field2 = fields[value];
+ break;
+ }
+ value2 = ++value;
+ }
+ if (field == null) {
+ throw new AssertionViolatedException("Field not found?!?");
+ }
+ if (!field2.isEnabled11()) {
+ this.constraintViolated(
+ gETSTATIC, "Referenced field '" + field2 + "' is not static which it should be.");
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitALOAD(ALOAD aLOAD) {
+ int value;
+ if ((value = aLOAD.getIndex()) < 0) {
+ this.constraintViolated(aLOAD, "Index '" + value + "' must be non-negative.");
+ } else {
+ int value2 = this.maxLocals() - 1;
+ if (value > value2) {
+ this.constraintViolated(
+ aLOAD, "Index '" + value + "' must not be greater than max_locals-1 '" + value2 + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitINVOKEINTERFACE(INVOKEINTERFACE nVOKEINTERFACE) {
+ Method method;
+ try {
+ JavaClass javaClass;
+ Method[] methods =
+ (javaClass = Repository.lookupClass(nVOKEINTERFACE.getText2(this.constantPoolGen)))
+ .getMethods();
+ int value;
+ int value2 = value = 0;
+ while (true) {
+ if (value2 >= methods.length) {
+ method = (Method) (Object) null;
+ break;
+ }
+ if (methods[value].getText().equals(nVOKEINTERFACE.getText4(this.constantPoolGen))
+ && Type.getReturnType(methods[value].getText2())
+ .equals(nVOKEINTERFACE.getType2(this.constantPoolGen))
+ && this.matchesValues(
+ Type.getArgumentTypes(methods[value].getText2()),
+ nVOKEINTERFACE.getArgumentTypes(this.constantPoolGen))) {
+ method = methods[value];
+ break;
+ }
+ value2 = ++value;
+ }
+ if (method == null) {
+ this.constraintViolated(
+ nVOKEINTERFACE,
+ "Referenced method '"
+ + nVOKEINTERFACE.getText4(this.constantPoolGen)
+ + "' with expected signature '"
+ + nVOKEINTERFACE.getText3(this.constantPoolGen)
+ + "' not found in class '"
+ + javaClass.getText2()
+ + "'. The native verifier does allow the method to be declared in some"
+ + " superinterface, which the Java Virtual Machine Specification, Second Edition"
+ + " does not.");
+ }
+ if (javaClass.isEnabled17()) {
+ this.constraintViolated(
+ nVOKEINTERFACE,
+ "Referenced class '"
+ + javaClass.getText2()
+ + "' is a class, but not an interface as expected.");
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitINVOKESTATIC(INVOKESTATIC nVOKESTATIC) {
+ Method method;
+ try {
+ JavaClass javaClass;
+ Method[] methods =
+ (javaClass = Repository.lookupClass(nVOKESTATIC.getText2(this.constantPoolGen)))
+ .getMethods();
+ Method method2 = null;
+ int value;
+ int value2 = value = 0;
+ while (true) {
+ if (value2 >= methods.length) {
+ method = method2;
+ break;
+ }
+ if (methods[value].getText().equals(nVOKESTATIC.getText4(this.constantPoolGen))
+ && Type.getReturnType(methods[value].getText2())
+ .equals(nVOKESTATIC.getType2(this.constantPoolGen))
+ && this.matchesValues(
+ Type.getArgumentTypes(methods[value].getText2()),
+ nVOKESTATIC.getArgumentTypes(this.constantPoolGen))) {
+ method = method2 = methods[value];
+ break;
+ }
+ value2 = ++value;
+ }
+ if (method == null) {
+ this.constraintViolated(
+ nVOKESTATIC,
+ "Referenced method '"
+ + nVOKESTATIC.getText4(this.constantPoolGen)
+ + "' with expected signature '"
+ + nVOKESTATIC.getText3(this.constantPoolGen)
+ + "' not found in class '"
+ + javaClass.getText2()
+ + "'. The native verifier possibly allows the method to be declared in some"
+ + " superclass or implemented interface, which the Java Virtual Machine"
+ + " Specification, Second Edition does not.");
+ } else if (!method2.isEnabled11()) {
+ this.constraintViolated(
+ nVOKESTATIC,
+ "Referenced method '"
+ + nVOKESTATIC.getText4(this.constantPoolGen)
+ + "' has ACC_STATIC unset.");
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass3aVerifier.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass3aVerifier.java
new file mode 100644
index 0000000..dd1108d
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/Pass3aVerifier.java
@@ -0,0 +1,317 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.lib.bcel.Repository;
+import com.allatori.lib.bcel.classfile.Attribute;
+import com.allatori.lib.bcel.classfile.Code;
+import com.allatori.lib.bcel.classfile.CodeException;
+import com.allatori.lib.bcel.classfile.LineNumber;
+import com.allatori.lib.bcel.classfile.LineNumberTable;
+import com.allatori.lib.bcel.classfile.LocalVariable;
+import com.allatori.lib.bcel.classfile.LocalVariableTable;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ASTORE;
+import com.allatori.lib.bcel.generic.ATHROW;
+import com.allatori.lib.bcel.generic.BREAKPOINT;
+import com.allatori.lib.bcel.generic.ConstantPoolGen;
+import com.allatori.lib.bcel.generic.GotoInstruction;
+import com.allatori.lib.bcel.generic.IMPDEP1;
+import com.allatori.lib.bcel.generic.IMPDEP2;
+import com.allatori.lib.bcel.generic.Instruction;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.InstructionList;
+import com.allatori.lib.bcel.generic.JsrInstruction;
+import com.allatori.lib.bcel.generic.RET;
+import com.allatori.lib.bcel.generic.ReturnInstruction;
+import com.allatori.lib.bcel.verifier.PassVerifier;
+import com.allatori.lib.bcel.verifier.VerificationResult;
+import com.allatori.lib.bcel.verifier.Verifier;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import com.allatori.lib.bcel.verifier.exc.InvalidMethodException;
+import com.allatori.lib.bcel.verifier.exc.LoadingException;
+import com.allatori.lib.bcel.verifier.exc.StaticCodeInstructionConstraintException;
+import com.allatori.lib.bcel.verifier.exc.StaticCodeInstructionOperandConstraintException;
+
+public final class Pass3aVerifier extends PassVerifier {
+
+ public int method_no;
+
+ public InstructionList instructionList;
+
+ public Verifier myOwner;
+
+ public Code code;
+
+ public void pass3StaticInstructionChecks() {
+ if (this.code.getCode().length >= 65536) {
+ throw new StaticCodeInstructionOperandConstraintException(
+ ("Code array in code attribute '"
+ + this.code
+ + "' too big: must be smaller than 65536 bytes."));
+ }
+ InstructionHandle instructionHandle;
+ for (InstructionHandle instructionHandle2 = instructionHandle = this.instructionList.getStart();
+ instructionHandle2 != null;
+ instructionHandle2 = instructionHandle = instructionHandle.getInstructionHandle2()) {
+ Instruction instruction;
+ if ((instruction = instructionHandle.getInstruction()) instanceof IMPDEP1) {
+ throw new StaticCodeInstructionOperandConstraintException(
+ "IMPDEP1 must not be in the code, it is an illegal instruction for _internal_ JVM"
+ + " use!");
+ }
+ if (instruction instanceof IMPDEP2) {
+ throw new StaticCodeInstructionOperandConstraintException(
+ "IMPDEP2 must not be in the code, it is an illegal instruction for _internal_ JVM"
+ + " use!");
+ }
+ if (instruction instanceof BREAKPOINT) {
+ throw new StaticCodeInstructionOperandConstraintException(
+ "BREAKPOINT must not be in the code, it is an illegal instruction for _internal_ JVM"
+ + " use!");
+ }
+ }
+ Instruction instruction2;
+ if (!((instruction2 = this.instructionList.getEnd().getInstruction())
+ instanceof ReturnInstruction)
+ && !(instruction2 instanceof RET)
+ && !(instruction2 instanceof GotoInstruction)
+ && !(instruction2 instanceof ATHROW)) {
+ throw new StaticCodeInstructionOperandConstraintException(
+ "Execution must not fall off the bottom of the code array. This constraint is enforced"
+ + " statically as some existing verifiers do - so it may be a false alarm if the last"
+ + " instruction is not reachable.");
+ }
+ }
+
+ @Override
+ public VerificationResult getVerificationResult() {
+ Pass3aVerifier pass3aVerifier;
+ try {
+ if (!this.myOwner
+ .createVerificationResult2()
+ .equals(VerificationResult.VERIFICATION_RESULT2)) {
+ return VerificationResult.VERIFICATION_RESULT;
+ }
+ Method[] methods = Repository.lookupClass(this.myOwner.getClassName()).getMethods();
+ if (this.method_no >= methods.length) {
+ throw new InvalidMethodException("METHOD DOES NOT EXIST!");
+ }
+ Method method = methods[this.method_no];
+ this.code = method.getCode();
+ if (method.isEnabled15() || method.isEnabled14()) {
+ return VerificationResult.VERIFICATION_RESULT2;
+ }
+ try {
+ this.instructionList = new InstructionList(method.getCode().getCode());
+ } catch (RuntimeException runtimeException) {
+ return new VerificationResult(
+ 2, "Bad bytecode in the code array of the Code attribute of method '" + method + "'.");
+ }
+ pass3aVerifier = this;
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ pass3aVerifier.instructionList.setPositions(true);
+ VerificationResult verificationResult = VerificationResult.VERIFICATION_RESULT2;
+ try {
+ this.delayedPass2Checks();
+ } catch (LoadingException loadingException) {
+ return new VerificationResult(2, loadingException.getMessage());
+ }
+ this.pass3StaticInstructionChecks();
+ this.pass3StaticInstructionOperandsChecks();
+ return verificationResult;
+ }
+
+ public int getMethodNo() {
+ return this.method_no;
+ }
+
+ public void pass3StaticInstructionOperandsChecks() {
+ try {
+ ConstantPoolGen constantPoolGen =
+ new ConstantPoolGen(
+ Repository.lookupClass(this.myOwner.getClassName()).getConstantPool());
+ Pass3aVerifier$InstOperandConstraintVisitor pass3aVerifier$InstOperandConstraintVisitor =
+ new Pass3aVerifier$InstOperandConstraintVisitor(this, constantPoolGen);
+ for (InstructionHandle start = this.instructionList.getStart();
+ start != null;
+ start = start.getInstructionHandle2()) {
+ Instruction instruction;
+ if ((instruction = start.getInstruction()) instanceof JsrInstruction) {
+ InstructionHandle instructionHandle;
+ if ((instructionHandle = ((JsrInstruction) instruction).getTarget())
+ == this.instructionList.getStart()) {
+ throw new StaticCodeInstructionConstraintException(
+ ("Due to JustIce's clear definition of subroutines, no JSR or JSR_W may have a"
+ + " top-level instruction (such as the very first instruction, which is"
+ + " targeted by instruction '"
+ + start
+ + "' as its target."));
+ }
+ if (!(instructionHandle.getInstruction() instanceof ASTORE)) {
+ throw new StaticCodeInstructionConstraintException(
+ ("Due to JustIce's clear definition of subroutines, no JSR or JSR_W may target"
+ + " anything else than an ASTORE instruction. Instruction '"
+ + start
+ + "' targets '"
+ + instructionHandle
+ + "'."));
+ }
+ }
+ start.accept(pass3aVerifier$InstOperandConstraintVisitor);
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ public static boolean contains(int[] values, int value) {
+ int value2;
+ for (int value3 = value2 = 0; value3 < values.length; value3 = ++value2) {
+ if (values[value2] == value) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Pass3aVerifier(Verifier verifier, int method_no) {
+ super();
+ this.myOwner = verifier;
+ this.method_no = method_no;
+ }
+
+ public static Verifier access$000(Pass3aVerifier pass3aVerifier) {
+ return pass3aVerifier.myOwner;
+ }
+
+ public void delayedPass2Checks() {
+ int[] instructionPositions = this.instructionList.getInstructionPositions();
+ int value = this.code.getCode().length;
+ LineNumberTable lineNumberTable;
+ if ((lineNumberTable = this.code.getLineNumberTable()) != null) {
+ LineNumber[] lineNumberTable2 = lineNumberTable.getLineNumberTable();
+ IntList intList = new IntList();
+ int value2;
+ label87:
+ for (int value3 = value2 = 0; value3 < lineNumberTable2.length; value3 = ++value2) {
+ int value4;
+ for (int value5 = value4 = 0; value5 < instructionPositions.length; value5 = ++value4) {
+ int start_pc = lineNumberTable2[value2].getStart_pc();
+ if (instructionPositions[value4] == start_pc) {
+ if (intList.contains(start_pc)) {
+ this.addMessage(
+ "LineNumberTable attribute '"
+ + this.code.getLineNumberTable()
+ + "' refers to the same code offset ('"
+ + start_pc
+ + "') more than once which is violating the semantics [but is sometimes"
+ + " produced by IBM's 'jikes' compiler].");
+ } else {
+ intList.add(start_pc);
+ }
+ continue label87;
+ }
+ }
+ throw new LoadingException(
+ ("Code attribute '"
+ + this.code
+ + "' has a LineNumberTable attribute '"
+ + this.code.getLineNumberTable()
+ + "' referring to a code offset ('"
+ + lineNumberTable2[value2].getStart_pc()
+ + "') that does not exist."));
+ }
+ }
+ Attribute[] attributes = this.code.getAttributes();
+ int value6;
+ for (int value7 = value6 = 0; value7 < attributes.length; value7 = ++value6) {
+ LocalVariableTable localVariableTable;
+ if (attributes[value6] instanceof LocalVariableTable
+ && (localVariableTable = (LocalVariableTable) attributes[value6]) != null) {
+ LocalVariable[] localVariableTable2 = localVariableTable.getLocalVariableTable();
+ int value8;
+ for (int value9 = value8 = 0; value9 < localVariableTable2.length; value9 = ++value8) {
+ int start_pc2 = localVariableTable2[value8].getStart_pc();
+ int length2 = localVariableTable2[value8].getLength();
+ if (!contains(instructionPositions, start_pc2)) {
+ throw new LoadingException(
+ ("Code attribute '"
+ + this.code
+ + "' has a LocalVariableTable attribute '"
+ + this.code.getLocalVariableTable()
+ + "' referring to a code offset ('"
+ + start_pc2
+ + "') that does not exist."));
+ }
+ if (!contains(instructionPositions, start_pc2 + length2)
+ && start_pc2 + length2 != value) {
+ throw new LoadingException(
+ ("Code attribute '"
+ + this.code
+ + "' has a LocalVariableTable attribute '"
+ + this.code.getLocalVariableTable()
+ + "' referring to a code offset start_pc+length ('"
+ + (start_pc2 + length2)
+ + "') that does not exist."));
+ }
+ }
+ }
+ }
+ CodeException[] exceptionTable = this.code.getExceptionTable();
+ int value10;
+ for (int value11 = value10 = 0; value11 < exceptionTable.length; value11 = ++value10) {
+ int start_pc3 = exceptionTable[value10].getStart_pc();
+ int end_pc = exceptionTable[value10].getEnd_pc();
+ int handler_pc = exceptionTable[value10].getHandler_pc();
+ if (start_pc3 >= end_pc) {
+ throw new LoadingException(
+ ("Code attribute '"
+ + this.code
+ + "' has an exception_table entry '"
+ + exceptionTable[value10]
+ + "' that has its start_pc ('"
+ + start_pc3
+ + "') not smaller than its end_pc ('"
+ + end_pc
+ + "')."));
+ }
+ if (!contains(instructionPositions, start_pc3)) {
+ throw new LoadingException(
+ ("Code attribute '"
+ + this.code
+ + "' has an exception_table entry '"
+ + exceptionTable[value10]
+ + "' that has a non-existant bytecode offset as its start_pc ('"
+ + start_pc3
+ + "')."));
+ }
+ if (!contains(instructionPositions, end_pc) && end_pc != value) {
+ throw new LoadingException(
+ ("Code attribute '"
+ + this.code
+ + "' has an exception_table entry '"
+ + exceptionTable[value10]
+ + "' that has a non-existant bytecode offset as its end_pc ('"
+ + start_pc3
+ + "') [that is also not equal to code_length ('"
+ + value
+ + "')]."));
+ }
+ if (!contains(instructionPositions, handler_pc)) {
+ throw new LoadingException(
+ ("Code attribute '"
+ + this.code
+ + "' has an exception_table entry '"
+ + exceptionTable[value10]
+ + "' that has a non-existant bytecode offset as its handler_pc ('"
+ + handler_pc
+ + "')."));
+ }
+ }
+ }
+
+ public static int access$100(Pass3aVerifier pass3aVerifier) {
+ return pass3aVerifier.method_no;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/StringRepresentation.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/StringRepresentation.java
new file mode 100644
index 0000000..4bf440b
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/StringRepresentation.java
@@ -0,0 +1,215 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.lib.bcel.classfile.Code;
+import com.allatori.lib.bcel.classfile.CodeException;
+import com.allatori.lib.bcel.classfile.ConstantClass;
+import com.allatori.lib.bcel.classfile.ConstantDouble;
+import com.allatori.lib.bcel.classfile.ConstantFieldref;
+import com.allatori.lib.bcel.classfile.ConstantFloat;
+import com.allatori.lib.bcel.classfile.ConstantInteger;
+import com.allatori.lib.bcel.classfile.ConstantInterfaceMethodref;
+import com.allatori.lib.bcel.classfile.ConstantLong;
+import com.allatori.lib.bcel.classfile.ConstantMethodref;
+import com.allatori.lib.bcel.classfile.ConstantNameAndType;
+import com.allatori.lib.bcel.classfile.ConstantPool;
+import com.allatori.lib.bcel.classfile.ConstantString;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.classfile.ConstantValue;
+import com.allatori.lib.bcel.classfile.Deprecated;
+import com.allatori.lib.bcel.classfile.EmptyVisitor;
+import com.allatori.lib.bcel.classfile.ExceptionTable;
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.classfile.InnerClass;
+import com.allatori.lib.bcel.classfile.InnerClasses;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.classfile.LineNumber;
+import com.allatori.lib.bcel.classfile.LineNumberTable;
+import com.allatori.lib.bcel.classfile.LocalVariable;
+import com.allatori.lib.bcel.classfile.LocalVariableTable;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.classfile.Node;
+import com.allatori.lib.bcel.classfile.Signature;
+import com.allatori.lib.bcel.classfile.SourceFile;
+import com.allatori.lib.bcel.classfile.StackMap;
+import com.allatori.lib.bcel.classfile.Synthetic;
+import com.allatori.lib.bcel.classfile.Unknown;
+import com.allatori.lib.bcel.classfile.Visitor;
+
+public class StringRepresentation extends EmptyVisitor implements Visitor {
+
+ public Node n;
+
+ public String tostring;
+
+ @Override
+ public void visitJavaClass(JavaClass javaClass) {
+ this.tostring = this.toString(javaClass);
+ }
+
+ @Override
+ public void visitCode(Code code) {
+ this.tostring = "";
+ }
+
+ @Override
+ public void visitLineNumber(LineNumber lineNumber) {
+ this.tostring = this.toString(lineNumber);
+ }
+
+ @Override
+ public void visitConstantValue(ConstantValue constantValue) {
+ this.tostring = this.toString(constantValue);
+ }
+
+ @Override
+ public void visitLocalVariableTable(LocalVariableTable localVariableTable) {
+ this.tostring = "";
+ }
+
+ @Override
+ public void visitConstantLong(ConstantLong constantLong) {
+ this.tostring = this.toString(constantLong);
+ }
+
+ @Override
+ public void visitField(Field field) {
+ this.tostring = this.toString(field);
+ }
+
+ @Override
+ public void visitSourceFile(SourceFile sourceFile) {
+ this.tostring = this.toString(sourceFile);
+ }
+
+ @Override
+ public void visitConstantFieldref(ConstantFieldref constantFieldref) {
+ this.tostring = this.toString(constantFieldref);
+ }
+
+ @Override
+ public void visitConstantClass(ConstantClass constantClass) {
+ this.tostring = this.toString(constantClass);
+ }
+
+ @Override
+ public void visitConstantPool(ConstantPool constantPool) {
+ this.tostring = this.toString(constantPool);
+ }
+
+ @Override
+ public void visitConstantInteger(ConstantInteger constantInteger) {
+ this.tostring = this.toString(constantInteger);
+ }
+
+ @Override
+ public void visitStackMap(StackMap stackMap) {
+ this.tostring = this.toString(stackMap);
+ }
+
+ @Override
+ public void visitMethod(Method method) {
+ this.tostring = this.toString(method);
+ }
+
+ @Override
+ public void visitInnerClass(InnerClass innerClass) {
+ this.tostring = this.toString(innerClass);
+ }
+
+ @Override
+ public void visitConstantNameAndType(ConstantNameAndType constantNameAndType) {
+ this.tostring = this.toString(constantNameAndType);
+ }
+
+ @Override
+ public void visitConstantMethodref(ConstantMethodref constantMethodref) {
+ this.tostring = this.toString(constantMethodref);
+ }
+
+ public String toString(Node node) {
+ try {
+ return node.toString();
+ } catch (RuntimeException runtimeException) {
+ String name = node.getClass().getName();
+ String text = name.substring(name.lastIndexOf(".") + 1);
+ return "<<" + text + ">>";
+ }
+ }
+
+ @Override
+ public void visitLocalVariable(LocalVariable localVariable) {
+ this.tostring = this.toString(localVariable);
+ }
+
+ @Override
+ public void visitConstantFloat(ConstantFloat constantFloat) {
+ this.tostring = this.toString(constantFloat);
+ }
+
+ @Override
+ public void visitConstantUtf8(ConstantUtf8 constantUtf8) {
+ this.tostring = this.toString(constantUtf8);
+ }
+
+ @Override
+ public void visitUnknown(Unknown unknown) {
+ this.tostring = this.toString(unknown);
+ }
+
+ @Override
+ public void visitExceptionTable(ExceptionTable exceptionTable) {
+ this.tostring = this.toString(exceptionTable);
+ }
+
+ @Override
+ public void visitConstantString(ConstantString constantString) {
+ this.tostring = this.toString(constantString);
+ }
+
+ @Override
+ public void visitDeprecated(Deprecated deprecated) {
+ this.tostring = this.toString(deprecated);
+ }
+
+ public StringRepresentation(Node node) {
+ super();
+ this.n = node;
+ node.accept(this);
+ }
+
+ @Override
+ public void visitInnerClasses(InnerClasses innerClasses) {
+ this.tostring = this.toString(innerClasses);
+ }
+
+ @Override
+ public void visitCodeException(CodeException codeException) {
+ this.tostring = this.toString(codeException);
+ }
+
+ @Override
+ public void visitConstantDouble(ConstantDouble constantDouble) {
+ this.tostring = this.toString(constantDouble);
+ }
+
+ @Override
+ public void visitLineNumberTable(LineNumberTable lineNumberTable) {
+ this.tostring = "";
+ }
+
+ @Override
+ public void visitSignature(Signature signature) {
+ this.tostring = this.toString(signature);
+ }
+
+ @Override
+ public void visitConstantInterfaceMethodref(
+ ConstantInterfaceMethodref constantInterfaceMethodref) {
+ this.tostring = this.toString(constantInterfaceMethodref);
+ }
+
+ @Override
+ public void visitSynthetic(Synthetic synthetic) {
+ this.tostring = this.toString(synthetic);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/UpperWordType.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/UpperWordType.java
new file mode 100644
index 0000000..83e3845
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/UpperWordType.java
@@ -0,0 +1,16 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.lib.bcel.generic.Type;
+
+public final class UpperWordType extends Type {
+
+ public static UpperWordType upperWordType = new UpperWordType();
+
+ public UpperWordType() {
+ super((byte) 15, "Long_Upper");
+ }
+
+ public static UpperWordType getUpperWordType() {
+ return upperWordType;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/statics/UpperWordType2.java b/src/main/java/com/allatori/lib/bcel/verifier/statics/UpperWordType2.java
new file mode 100644
index 0000000..93da10b
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/statics/UpperWordType2.java
@@ -0,0 +1,16 @@
+package com.allatori.lib.bcel.verifier.statics;
+
+import com.allatori.lib.bcel.generic.Type;
+
+public final class UpperWordType2 extends Type {
+
+ public static UpperWordType2 upperWordType2 = new UpperWordType2();
+
+ public static UpperWordType2 getUpperWordType2() {
+ return upperWordType2;
+ }
+
+ public UpperWordType2() {
+ super((byte) 15, "Long_Upper");
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/ControlFlowGraph$InstructionContextImpl.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/ControlFlowGraph$InstructionContextImpl.java
new file mode 100644
index 0000000..07d98d6
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/ControlFlowGraph$InstructionContextImpl.java
@@ -0,0 +1,272 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.generic.ATHROW;
+import com.allatori.lib.bcel.generic.BranchInstruction;
+import com.allatori.lib.bcel.generic.GotoInstruction;
+import com.allatori.lib.bcel.generic.Instruction;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.JsrInstruction;
+import com.allatori.lib.bcel.generic.RET;
+import com.allatori.lib.bcel.generic.ReturnInstruction;
+import com.allatori.lib.bcel.generic.Select;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import com.allatori.lib.bcel.verifier.exc.StructuralCodeConstraintException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ControlFlowGraph$InstructionContextImpl implements InstructionContext {
+
+ public final ControlFlowGraph this$0;
+
+ public ArrayList arrayList;
+
+ public Map entries;
+
+ public int TAG;
+
+ public InstructionHandle instruction;
+
+ public Map entries2;
+
+ public String createText() {
+ String text = this.toString();
+ int value;
+ for (int value2 = value = this.arrayList.size() - 1; value2 >= 0; value2 = value) {
+ StringBuilder stringBuilder =
+ new StringBuilder().append(this.arrayList.get(value)).append("\n");
+ String text2 = text;
+ value--;
+ text = stringBuilder.append(text2).toString();
+ }
+ return text;
+ }
+
+ public boolean mergeInFrames(Frame frame) {
+ Frame frame2;
+ Frame frame3 = frame2 = (Frame) this.entries2.get(this.lastExecutionJSR());
+ OperandStack clone = frame3.getStack().getClone();
+ LocalVariables clone2 = frame3.getLocals().getClone();
+ try {
+ frame2.getStack().merge(frame.getStack());
+ frame2.getLocals().merge(frame.getLocals());
+ } catch (StructuralCodeConstraintException structuralCodeConstraintException) {
+ this.extendMessageWithFlow(structuralCodeConstraintException);
+ throw structuralCodeConstraintException;
+ }
+ return !clone.equals(frame2.getStack()) || !clone2.equals(frame2.getLocals());
+ }
+
+ @Override
+ public void setTag(int TAG) {
+ this.TAG = TAG;
+ }
+
+ public void extendMessageWithFlow(
+ StructuralCodeConstraintException structuralCodeConstraintException) {
+ structuralCodeConstraintException.extendMessage(
+ "", "" + ((String) "Execution flow:\n") + this.createText());
+ }
+
+ public InstructionHandle[] _getSuccessors() {
+ InstructionHandle[] instructionHandles = new InstructionHandle[0];
+ InstructionHandle[] instructionHandles2 = new InstructionHandle[1];
+ InstructionHandle[] instructionHandles3 = new InstructionHandle[2];
+ Instruction instruction;
+ if (!((instruction = this.getInstruction().getInstruction()) instanceof RET)) {
+ if (instruction instanceof ReturnInstruction) {
+ return instructionHandles;
+ }
+ if (instruction instanceof ATHROW) {
+ return instructionHandles;
+ }
+ if (instruction instanceof JsrInstruction) {
+ instructionHandles2[0] = ((JsrInstruction) instruction).getTarget();
+ return instructionHandles2;
+ }
+ if (instruction instanceof GotoInstruction) {
+ instructionHandles2[0] = ((GotoInstruction) instruction).getTarget();
+ return instructionHandles2;
+ }
+ if (instruction instanceof BranchInstruction) {
+ if (instruction instanceof Select) {
+ InstructionHandle[] instructionHandles4;
+ InstructionHandle[] instructionHandles5;
+ (instructionHandles5 =
+ new InstructionHandle
+ [(instructionHandles4 = ((Select) instruction).getTargets()).length + 1])
+ [0] =
+ ((Select) instruction).getTarget();
+ System.arraycopy(
+ instructionHandles4, 0, instructionHandles5, 1, instructionHandles4.length);
+ return instructionHandles5;
+ } else {
+ instructionHandles3[0] = this.getInstruction().getInstructionHandle2();
+ instructionHandles3[1] = ((BranchInstruction) instruction).getTarget();
+ return instructionHandles3;
+ }
+ } else {
+ instructionHandles2[0] = this.getInstruction().getInstructionHandle2();
+ return instructionHandles2;
+ }
+ } else {
+ Subroutine subroutine;
+ if ((subroutine =
+ ControlFlowGraph.access$100(this.this$0).subroutineOf(this.getInstruction()))
+ == null) {
+ throw new AssertionViolatedException("Asking for successors of a RET in dead code?!");
+ }
+ InstructionHandle[] instructionHandles6;
+ InstructionHandle[] instructionHandles7 =
+ new InstructionHandle[(instructionHandles6 = subroutine.getInstructionHandles()).length];
+ int value;
+ for (int value2 = value = 0; value2 < instructionHandles6.length; value2 = value) {
+ InstructionHandle instructionHandle2 = instructionHandles6[value].getInstructionHandle2();
+ int value3 = value;
+ value++;
+ instructionHandles7[value3] = instructionHandle2;
+ }
+ return instructionHandles7;
+ }
+ }
+
+ @Override
+ public InstructionHandle getInstruction() {
+ return this.instruction;
+ }
+
+ @Override
+ public int getTag() {
+ return this.TAG;
+ }
+
+ public ControlFlowGraph$InstructionContextImpl lastExecutionJSR() {
+ int size2 = this.arrayList.size();
+ int value = 0;
+ int value2;
+ for (int value3 = value2 = size2 - 1; value3 >= 0; value3 = --value2) {
+ Instruction instruction;
+ ControlFlowGraph$InstructionContextImpl controlFlowGraph$InstructionContextImpl;
+ if ((instruction =
+ (controlFlowGraph$InstructionContextImpl =
+ (ControlFlowGraph$InstructionContextImpl) this.arrayList.get(value2))
+ .getInstruction()
+ .getInstruction())
+ instanceof RET) {
+ value++;
+ }
+ if (instruction instanceof JsrInstruction) {
+ if (--value == -1) {
+ return controlFlowGraph$InstructionContextImpl;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public InstructionContext[] getSuccessors() {
+ return this.this$0.contextsOf(this._getSuccessors());
+ }
+
+ @Override
+ public ExceptionHandler[] getExceptionHandlers() {
+ return ControlFlowGraph.access$000(this.this$0).getExceptionHandlers(this.getInstruction());
+ }
+
+ @Override
+ public Frame getOutFrame(ArrayList arrayList) {
+ this.arrayList = arrayList;
+ ControlFlowGraph$InstructionContextImpl controlFlowGraph$InstructionContextImpl =
+ this.lastExecutionJSR();
+ Frame frame;
+ if ((frame = (Frame) this.entries.get(controlFlowGraph$InstructionContextImpl)) == null) {
+ throw new AssertionViolatedException(
+ ("outFrame not set! This:\n"
+ + this
+ + "\nExecutionChain: "
+ + this.createText()
+ + "\nOutFrames: '"
+ + this.entries
+ + "'."));
+ } else {
+ return frame.getClone();
+ }
+ }
+
+ @Override
+ public Frame getInFrame() {
+ ControlFlowGraph$InstructionContextImpl controlFlowGraph$InstructionContextImpl =
+ this.lastExecutionJSR();
+ Frame frame;
+ if ((frame = (Frame) this.entries2.get(controlFlowGraph$InstructionContextImpl)) == null) {
+ throw new AssertionViolatedException(
+ ("inFrame not set! This:\n" + this + "\nInFrames: '" + this.entries2 + "'."));
+ } else {
+ return frame.getClone();
+ }
+ }
+
+ @Override
+ public boolean execute(
+ Frame frame,
+ ArrayList values,
+ InstConstraintVisitor instConstraintVisitor,
+ ExecutionVisitor executionVisitor) {
+ this.arrayList = (ArrayList) values.clone();
+ if (this.lastExecutionJSR() == null
+ && ControlFlowGraph.access$100(this.this$0).subroutineOf(this.getInstruction())
+ != ControlFlowGraph.access$100(this.this$0).getTopLevel()) {
+ throw new AssertionViolatedException(
+ ("Huh?! Am I '" + this + "' part of a subroutine or not?"));
+ }
+ if (this.lastExecutionJSR() != null
+ && ControlFlowGraph.access$100(this.this$0).subroutineOf(this.getInstruction())
+ == ControlFlowGraph.access$100(this.this$0).getTopLevel()) {
+ throw new AssertionViolatedException(
+ ("Huh?! Am I '" + this + "' part of a subroutine or not?"));
+ }
+ Frame frame2;
+ Frame frame3;
+ if ((frame2 = (Frame) this.entries2.get(this.lastExecutionJSR())) == null) {
+ this.entries2.put(this.lastExecutionJSR(), frame);
+ frame3 = frame;
+ } else {
+ if (frame2.equals(frame)) {
+ return false;
+ }
+ if (!this.mergeInFrames(frame)) {
+ return false;
+ }
+ frame3 = frame2;
+ }
+ Frame clone2 = frame3.getClone();
+ try {
+ instConstraintVisitor.setFrame(clone2);
+ this.getInstruction().accept(instConstraintVisitor);
+ } catch (StructuralCodeConstraintException structuralCodeConstraintException) {
+ structuralCodeConstraintException.extendMessage(
+ "", "\nInstructionHandle: " + this.getInstruction() + "\n");
+ structuralCodeConstraintException.extendMessage("", "\nExecution Frame:\n" + clone2);
+ this.extendMessageWithFlow(structuralCodeConstraintException);
+ throw structuralCodeConstraintException;
+ }
+ executionVisitor.setFrame(clone2);
+ this.getInstruction().accept(executionVisitor);
+ this.entries.put(this.lastExecutionJSR(), clone2);
+ return true;
+ }
+
+ public ControlFlowGraph$InstructionContextImpl(
+ ControlFlowGraph controlFlowGraph, InstructionHandle instructionHandle) {
+ super();
+ this.this$0 = controlFlowGraph;
+ this.arrayList = null;
+ if (instructionHandle == null) {
+ throw new AssertionViolatedException("Cannot instantiate InstructionContextImpl from NULL.");
+ }
+ this.instruction = instructionHandle;
+ this.entries2 = new HashMap();
+ this.entries = new HashMap();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/ControlFlowGraph.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/ControlFlowGraph.java
new file mode 100644
index 0000000..e3506d6
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/ControlFlowGraph.java
@@ -0,0 +1,69 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ControlFlowGraph {
+
+ public final Subroutines subroutines;
+
+ public Map entries;
+
+ public final ExceptionHandlers exceptionhandlers;
+
+ public ControlFlowGraph(MethodGen methodGen) {
+ super();
+ this.entries = new HashMap();
+ this.subroutines = new Subroutines(methodGen);
+ this.exceptionhandlers = new ExceptionHandlers(methodGen);
+ InstructionHandle[] instructionHandles = methodGen.getInstructionList().getInstructionHandles();
+ int value;
+ for (int value2 = value = 0; value2 < instructionHandles.length; value2 = value) {
+ this.entries.put(
+ instructionHandles[value],
+ new ControlFlowGraph$InstructionContextImpl(this, instructionHandles[value++]));
+ }
+ }
+
+ public boolean isDead(InstructionHandle instructionHandle) {
+ return this.subroutines.subroutineOf(instructionHandle) == null;
+ }
+
+ public InstructionContext[] getInstructionContexts() {
+ InstructionContext[] instructionContexts = new InstructionContext[this.entries.values().size()];
+ return (InstructionContext[]) this.entries.values().toArray(instructionContexts);
+ }
+
+ public InstructionContext contextOf(InstructionHandle instructionHandle) {
+ InstructionContext instructionContext;
+ if ((instructionContext = (InstructionContext) this.entries.get(instructionHandle)) == null) {
+ throw new AssertionViolatedException(
+ "InstructionContext requested for an InstructionHandle that's not known!");
+ } else {
+ return instructionContext;
+ }
+ }
+
+ public static Subroutines access$100(ControlFlowGraph controlFlowGraph) {
+ return controlFlowGraph.subroutines;
+ }
+
+ public static ExceptionHandlers access$000(ControlFlowGraph controlFlowGraph) {
+ return controlFlowGraph.exceptionhandlers;
+ }
+
+ public InstructionContext[] contextsOf(InstructionHandle[] instructionHandles) {
+ InstructionContext[] instructionContexts = new InstructionContext[instructionHandles.length];
+ int value;
+ for (int value2 = value = 0; value2 < instructionHandles.length; value2 = value) {
+ InstructionContext instructionContext = this.contextOf(instructionHandles[value]);
+ int value3 = value;
+ value++;
+ instructionContexts[value3] = instructionContext;
+ }
+ return instructionContexts;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/ExceptionHandler.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/ExceptionHandler.java
new file mode 100644
index 0000000..5e33274
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/ExceptionHandler.java
@@ -0,0 +1,25 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.ObjectType;
+
+public class ExceptionHandler {
+
+ public InstructionHandle handlerpc;
+
+ public ObjectType catchtype;
+
+ public InstructionHandle getHandlerStart() {
+ return this.handlerpc;
+ }
+
+ public ObjectType getExceptionType() {
+ return this.catchtype;
+ }
+
+ public ExceptionHandler(ObjectType objectType, InstructionHandle instructionHandle) {
+ super();
+ this.catchtype = objectType;
+ this.handlerpc = instructionHandle;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/ExceptionHandlers.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/ExceptionHandlers.java
new file mode 100644
index 0000000..0a3c56b
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/ExceptionHandlers.java
@@ -0,0 +1,50 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.generic.CodeExceptionGen;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.MethodGen;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class ExceptionHandlers {
+
+ public Map exceptionhandlers;
+
+ public ExceptionHandlers(MethodGen methodGen) {
+ super();
+ this.exceptionhandlers = new HashMap();
+ CodeExceptionGen[] exceptionHandlers = methodGen.getExceptionHandlers();
+ int value;
+ for (int value2 = value = 0; value2 < exceptionHandlers.length; value2 = ++value) {
+ ExceptionHandler exceptionHandler =
+ new ExceptionHandler(
+ exceptionHandlers[value].getCatchType(),
+ exceptionHandlers[value].getInstructionHandle3());
+ InstructionHandle instructionHandle;
+ for (InstructionHandle instructionHandle2 =
+ instructionHandle = exceptionHandlers[value].getInstructionHandle2();
+ instructionHandle2
+ != exceptionHandlers[value].getInstructionHandle().getInstructionHandle2();
+ instructionHandle2 = instructionHandle) {
+ Set values;
+ if ((values = (Set) this.exceptionhandlers.get(instructionHandle)) == null) {
+ values = new HashSet();
+ this.exceptionhandlers.put(instructionHandle, values);
+ }
+ values.add(exceptionHandler);
+ instructionHandle = instructionHandle.getInstructionHandle2();
+ }
+ }
+ }
+
+ public ExceptionHandler[] getExceptionHandlers(InstructionHandle instructionHandle) {
+ Set values;
+ if ((values = (Set) this.exceptionhandlers.get(instructionHandle)) == null) {
+ return new ExceptionHandler[0];
+ }
+ ExceptionHandler[] exceptionHandlers = new ExceptionHandler[values.size()];
+ return (ExceptionHandler[]) values.toArray(exceptionHandlers);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/ExecutionVisitor.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/ExecutionVisitor.java
new file mode 100644
index 0000000..5c345fa
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/ExecutionVisitor.java
@@ -0,0 +1,1278 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.classfile.ConstantDouble;
+import com.allatori.lib.bcel.classfile.ConstantFloat;
+import com.allatori.lib.bcel.classfile.ConstantInteger;
+import com.allatori.lib.bcel.classfile.ConstantLong;
+import com.allatori.lib.bcel.classfile.ConstantString;
+import com.allatori.lib.bcel.generic.AALOAD;
+import com.allatori.lib.bcel.generic.AASTORE;
+import com.allatori.lib.bcel.generic.ACONST_NULL;
+import com.allatori.lib.bcel.generic.ALOAD;
+import com.allatori.lib.bcel.generic.ANEWARRAY;
+import com.allatori.lib.bcel.generic.ARETURN;
+import com.allatori.lib.bcel.generic.ARRAYLENGTH;
+import com.allatori.lib.bcel.generic.ASTORE;
+import com.allatori.lib.bcel.generic.ATHROW;
+import com.allatori.lib.bcel.generic.ArrayType;
+import com.allatori.lib.bcel.generic.BALOAD;
+import com.allatori.lib.bcel.generic.BASTORE;
+import com.allatori.lib.bcel.generic.BIPUSH;
+import com.allatori.lib.bcel.generic.CALOAD;
+import com.allatori.lib.bcel.generic.CASTORE;
+import com.allatori.lib.bcel.generic.CHECKCAST;
+import com.allatori.lib.bcel.generic.ConstantPoolGen;
+import com.allatori.lib.bcel.generic.D2F;
+import com.allatori.lib.bcel.generic.D2I;
+import com.allatori.lib.bcel.generic.D2L;
+import com.allatori.lib.bcel.generic.DADD;
+import com.allatori.lib.bcel.generic.DALOAD;
+import com.allatori.lib.bcel.generic.DASTORE;
+import com.allatori.lib.bcel.generic.DCMPG;
+import com.allatori.lib.bcel.generic.DCMPL;
+import com.allatori.lib.bcel.generic.DCONST;
+import com.allatori.lib.bcel.generic.DDIV;
+import com.allatori.lib.bcel.generic.DLOAD;
+import com.allatori.lib.bcel.generic.DMUL;
+import com.allatori.lib.bcel.generic.DNEG;
+import com.allatori.lib.bcel.generic.DREM;
+import com.allatori.lib.bcel.generic.DRETURN;
+import com.allatori.lib.bcel.generic.DSTORE;
+import com.allatori.lib.bcel.generic.DSUB;
+import com.allatori.lib.bcel.generic.DUP;
+import com.allatori.lib.bcel.generic.DUP2;
+import com.allatori.lib.bcel.generic.DUP2_X1;
+import com.allatori.lib.bcel.generic.DUP2_X2;
+import com.allatori.lib.bcel.generic.DUP_X1;
+import com.allatori.lib.bcel.generic.DUP_X2;
+import com.allatori.lib.bcel.generic.EmptyVisitor;
+import com.allatori.lib.bcel.generic.F2D;
+import com.allatori.lib.bcel.generic.F2I;
+import com.allatori.lib.bcel.generic.F2L;
+import com.allatori.lib.bcel.generic.FADD;
+import com.allatori.lib.bcel.generic.FALOAD;
+import com.allatori.lib.bcel.generic.FASTORE;
+import com.allatori.lib.bcel.generic.FCMPG;
+import com.allatori.lib.bcel.generic.FCMPL;
+import com.allatori.lib.bcel.generic.FCONST;
+import com.allatori.lib.bcel.generic.FDIV;
+import com.allatori.lib.bcel.generic.FLOAD;
+import com.allatori.lib.bcel.generic.FMUL;
+import com.allatori.lib.bcel.generic.FNEG;
+import com.allatori.lib.bcel.generic.FREM;
+import com.allatori.lib.bcel.generic.FRETURN;
+import com.allatori.lib.bcel.generic.FSTORE;
+import com.allatori.lib.bcel.generic.FSUB;
+import com.allatori.lib.bcel.generic.GETFIELD;
+import com.allatori.lib.bcel.generic.GETSTATIC;
+import com.allatori.lib.bcel.generic.GOTO;
+import com.allatori.lib.bcel.generic.GOTO_W;
+import com.allatori.lib.bcel.generic.I2B;
+import com.allatori.lib.bcel.generic.I2C;
+import com.allatori.lib.bcel.generic.I2D;
+import com.allatori.lib.bcel.generic.I2F;
+import com.allatori.lib.bcel.generic.I2L;
+import com.allatori.lib.bcel.generic.I2S;
+import com.allatori.lib.bcel.generic.IADD;
+import com.allatori.lib.bcel.generic.IALOAD;
+import com.allatori.lib.bcel.generic.IAND;
+import com.allatori.lib.bcel.generic.IASTORE;
+import com.allatori.lib.bcel.generic.ICONST;
+import com.allatori.lib.bcel.generic.IDIV;
+import com.allatori.lib.bcel.generic.IFEQ;
+import com.allatori.lib.bcel.generic.IFGE;
+import com.allatori.lib.bcel.generic.IFGT;
+import com.allatori.lib.bcel.generic.IFLE;
+import com.allatori.lib.bcel.generic.IFLT;
+import com.allatori.lib.bcel.generic.IFNE;
+import com.allatori.lib.bcel.generic.IFNONNULL;
+import com.allatori.lib.bcel.generic.IFNULL;
+import com.allatori.lib.bcel.generic.IF_ACMPEQ;
+import com.allatori.lib.bcel.generic.IF_ACMPNE;
+import com.allatori.lib.bcel.generic.IF_ICMPEQ;
+import com.allatori.lib.bcel.generic.IF_ICMPGE;
+import com.allatori.lib.bcel.generic.IF_ICMPGT;
+import com.allatori.lib.bcel.generic.IF_ICMPLE;
+import com.allatori.lib.bcel.generic.IF_ICMPLT;
+import com.allatori.lib.bcel.generic.IF_ICMPNE;
+import com.allatori.lib.bcel.generic.IINC;
+import com.allatori.lib.bcel.generic.ILOAD;
+import com.allatori.lib.bcel.generic.IMUL;
+import com.allatori.lib.bcel.generic.INEG;
+import com.allatori.lib.bcel.generic.INSTANCEOF;
+import com.allatori.lib.bcel.generic.INVOKEINTERFACE;
+import com.allatori.lib.bcel.generic.INVOKESPECIAL;
+import com.allatori.lib.bcel.generic.INVOKESTATIC;
+import com.allatori.lib.bcel.generic.INVOKEVIRTUAL;
+import com.allatori.lib.bcel.generic.IOR;
+import com.allatori.lib.bcel.generic.IREM;
+import com.allatori.lib.bcel.generic.IRETURN;
+import com.allatori.lib.bcel.generic.ISHL;
+import com.allatori.lib.bcel.generic.ISHR;
+import com.allatori.lib.bcel.generic.ISTORE;
+import com.allatori.lib.bcel.generic.ISUB;
+import com.allatori.lib.bcel.generic.IUSHR;
+import com.allatori.lib.bcel.generic.IXOR;
+import com.allatori.lib.bcel.generic.JSR;
+import com.allatori.lib.bcel.generic.JSR_W;
+import com.allatori.lib.bcel.generic.L2D;
+import com.allatori.lib.bcel.generic.L2F;
+import com.allatori.lib.bcel.generic.L2I;
+import com.allatori.lib.bcel.generic.LADD;
+import com.allatori.lib.bcel.generic.LALOAD;
+import com.allatori.lib.bcel.generic.LAND;
+import com.allatori.lib.bcel.generic.LASTORE;
+import com.allatori.lib.bcel.generic.LCMP;
+import com.allatori.lib.bcel.generic.LCONST;
+import com.allatori.lib.bcel.generic.LDC;
+import com.allatori.lib.bcel.generic.LDC2_W;
+import com.allatori.lib.bcel.generic.LDC_W;
+import com.allatori.lib.bcel.generic.LDIV;
+import com.allatori.lib.bcel.generic.LLOAD;
+import com.allatori.lib.bcel.generic.LMUL;
+import com.allatori.lib.bcel.generic.LNEG;
+import com.allatori.lib.bcel.generic.LOOKUPSWITCH;
+import com.allatori.lib.bcel.generic.LOR;
+import com.allatori.lib.bcel.generic.LREM;
+import com.allatori.lib.bcel.generic.LRETURN;
+import com.allatori.lib.bcel.generic.LSHL;
+import com.allatori.lib.bcel.generic.LSHR;
+import com.allatori.lib.bcel.generic.LSTORE;
+import com.allatori.lib.bcel.generic.LSUB;
+import com.allatori.lib.bcel.generic.LUSHR;
+import com.allatori.lib.bcel.generic.LXOR;
+import com.allatori.lib.bcel.generic.MONITORENTER;
+import com.allatori.lib.bcel.generic.MONITOREXIT;
+import com.allatori.lib.bcel.generic.MULTIANEWARRAY;
+import com.allatori.lib.bcel.generic.NEW;
+import com.allatori.lib.bcel.generic.NEWARRAY;
+import com.allatori.lib.bcel.generic.NOP;
+import com.allatori.lib.bcel.generic.ObjectType;
+import com.allatori.lib.bcel.generic.POP;
+import com.allatori.lib.bcel.generic.POP2;
+import com.allatori.lib.bcel.generic.PUTFIELD;
+import com.allatori.lib.bcel.generic.PUTSTATIC;
+import com.allatori.lib.bcel.generic.RET;
+import com.allatori.lib.bcel.generic.RETURN;
+import com.allatori.lib.bcel.generic.ReturnaddressType;
+import com.allatori.lib.bcel.generic.SALOAD;
+import com.allatori.lib.bcel.generic.SASTORE;
+import com.allatori.lib.bcel.generic.SIPUSH;
+import com.allatori.lib.bcel.generic.SWAP;
+import com.allatori.lib.bcel.generic.TABLESWITCH;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.lib.bcel.generic.Visitor;
+
+public class ExecutionVisitor extends EmptyVisitor implements Visitor {
+
+ public Frame frame = null;
+
+ public ConstantPoolGen cpg = null;
+
+ @Override
+ public void visitLSTORE(LSTORE lSTORE) {
+ this.locals().set(lSTORE.getIndex(), this.stack().pop());
+ this.locals().set(lSTORE.getIndex() + 1, Type.UNKNOWN);
+ }
+
+ @Override
+ public void visitLASTORE(LASTORE lASTORE) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitIF_ICMPGE(IF_ICMPGE f_ICMPGE) {
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitBASTORE(BASTORE bASTORE) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitANEWARRAY(ANEWARRAY aNEWARRAY) {
+ this.stack().pop();
+ this.stack().push(new ArrayType(aNEWARRAY.getType(this.cpg), 1));
+ }
+
+ @Override
+ public void visitINVOKEINTERFACE(INVOKEINTERFACE nVOKEINTERFACE) {
+ this.stack().pop();
+ int value = 0;
+ for (int value2 = value;
+ value2 < nVOKEINTERFACE.getArgumentTypes(this.cpg).length;
+ value2 = value) {
+ value++;
+ this.stack().pop();
+ }
+ if (nVOKEINTERFACE.getType2(this.cpg) != Type.VOID) {
+ Type type;
+ if ((type = nVOKEINTERFACE.getType2(this.cpg)).equals(Type.BOOLEAN)
+ || type.equals(Type.CHAR)
+ || type.equals(Type.BYTE)
+ || type.equals(Type.SHORT)) {
+ type = Type.INT;
+ }
+ this.stack().push(type);
+ }
+ }
+
+ @Override
+ public void visitNEWARRAY(NEWARRAY nEWARRAY) {
+ this.stack().pop();
+ this.stack().push(nEWARRAY.getType());
+ }
+
+ @Override
+ public void visitIRETURN(IRETURN rETURN) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitFSTORE(FSTORE fSTORE) {
+ this.locals().set(fSTORE.getIndex(), this.stack().pop());
+ }
+
+ @Override
+ public void visitI2B(I2B i2B) {
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitFCMPL(FCMPL fCMPL) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitINSTANCEOF(INSTANCEOF nSTANCEOF) {
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitIFLE(IFLE fLE) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitMONITORENTER(MONITORENTER mONITORENTER) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitI2C(I2C i2C) {
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitIF_ICMPNE(IF_ICMPNE f_ICMPNE) {
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitISTORE(ISTORE sTORE) {
+ this.locals().set(sTORE.getIndex(), this.stack().pop());
+ }
+
+ @Override
+ public void visitIDIV(IDIV dIV) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitI2F(I2F i2F) {
+ this.stack().pop();
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitLADD(LADD lADD) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitLALOAD(LALOAD lALOAD) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitDLOAD(DLOAD dLOAD) {
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitIMUL(IMUL mUL) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitFDIV(FDIV fDIV) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitBIPUSH(BIPUSH bIPUSH) {
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitSALOAD(SALOAD sALOAD) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitLUSHR(LUSHR lUSHR) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitDSUB(DSUB dSUB) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitL2I(L2I l2I) {
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitPOP(POP pOP) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitSWAP(SWAP sWAP) {
+ Type type = this.stack().pop();
+ Type type2 = this.stack().pop();
+ this.stack().push(type);
+ this.stack().push(type2);
+ }
+
+ @Override
+ public void visitBALOAD(BALOAD bALOAD) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitDREM(DREM dREM) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitLMUL(LMUL lMUL) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitJSR_W(JSR_W jSR_W) {
+ this.stack().push(new ReturnaddressType(jSR_W.physicalSuccessor()));
+ }
+
+ @Override
+ public void visitLDC2_W(LDC2_W lDC2_W) {
+ Constant constant;
+ if ((constant = this.cpg.getConstant(lDC2_W.getIndex())) instanceof ConstantLong) {
+ this.stack().push(Type.LONG);
+ }
+ if (constant instanceof ConstantDouble) {
+ this.stack().push(Type.DOUBLE);
+ }
+ }
+
+ @Override
+ public void visitAASTORE(AASTORE aASTORE) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ public void setConstantPoolGen(ConstantPoolGen constantPoolGen) {
+ this.cpg = constantPoolGen;
+ }
+
+ public void visitLDC_W(LDC_W lDC_W) {
+ Constant constant;
+ if ((constant = this.cpg.getConstant(lDC_W.getIndex())) instanceof ConstantInteger) {
+ this.stack().push(Type.INT);
+ }
+ if (constant instanceof ConstantFloat) {
+ this.stack().push(Type.FLOAT);
+ }
+ if (constant instanceof ConstantString) {
+ this.stack().push(Type.STRING);
+ }
+ }
+
+ @Override
+ public void visitRETURN(RETURN rETURN) {}
+
+ @Override
+ public void visitI2D(I2D i2D) {
+ this.stack().pop();
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitIAND(IAND aND) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitGOTO(GOTO gOTO) {}
+
+ @Override
+ public void visitLSHL(LSHL lSHL) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitIASTORE(IASTORE aSTORE) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitIFGT(IFGT fGT) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitISUB(ISUB sUB) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitIOR(IOR oR) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitFMUL(FMUL fMUL) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitRET(RET rET) {}
+
+ @Override
+ public void visitDCONST(DCONST dCONST) {
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitLRETURN(LRETURN lRETURN) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitIF_ICMPEQ(IF_ICMPEQ f_ICMPEQ) {
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitINVOKESTATIC(INVOKESTATIC nVOKESTATIC) {
+ int value;
+ for (int value2 = value = 0;
+ value2 < nVOKESTATIC.getArgumentTypes(this.cpg).length;
+ value2 = value) {
+ value++;
+ this.stack().pop();
+ }
+ if (nVOKESTATIC.getType2(this.cpg) != Type.VOID) {
+ Type type;
+ if ((type = nVOKESTATIC.getType2(this.cpg)).equals(Type.BOOLEAN)
+ || type.equals(Type.CHAR)
+ || type.equals(Type.BYTE)
+ || type.equals(Type.SHORT)) {
+ type = Type.INT;
+ }
+ this.stack().push(type);
+ }
+ }
+
+ @Override
+ public void visitFNEG(FNEG fNEG) {
+ this.stack().pop();
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitFADD(FADD fADD) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitIADD(IADD aDD) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitDUP_X2(DUP_X2 dUP_X2) {
+ Type type = this.stack().pop();
+ Type type2;
+ if ((type2 = this.stack().pop()).getSize() == 2) {
+ this.stack().push(type);
+ this.stack().push(type2);
+ this.stack().push(type);
+ } else {
+ Type type3 = this.stack().pop();
+ this.stack().push(type);
+ this.stack().push(type3);
+ this.stack().push(type2);
+ this.stack().push(type);
+ }
+ }
+
+ @Override
+ public void visitLNEG(LNEG lNEG) {
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitDUP2(DUP2 dUP2) {
+ Type type;
+ if ((type = this.stack().pop()).getSize() == 2) {
+ this.stack().push(type);
+ this.stack().push(type);
+ } else {
+ Type type2 = this.stack().pop();
+ this.stack().push(type2);
+ this.stack().push(type);
+ this.stack().push(type2);
+ this.stack().push(type);
+ }
+ }
+
+ @Override
+ public void visitI2L(I2L i2L) {
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitIALOAD(IALOAD aLOAD) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitNOP(NOP nOP) {}
+
+ @Override
+ public void visitLOR(LOR lOR) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitIF_ACMPNE(IF_ACMPNE f_ACMPNE) {
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitICONST(ICONST cONST) {
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitGOTO_W(GOTO_W gOTO_W) {}
+
+ @Override
+ public void visitAALOAD(AALOAD aALOAD) {
+ this.stack().pop();
+ Type type = this.stack().pop();
+ if (type == Type.NULL) {
+ this.stack().push(Type.NULL);
+ } else {
+ ArrayType arrayType = (ArrayType) type;
+ this.stack().push(arrayType.getElementType());
+ }
+ }
+
+ @Override
+ public void visitSIPUSH(SIPUSH sIPUSH) {
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitACONST_NULL(ACONST_NULL aCONST_NULL) {
+ this.stack().push(Type.NULL);
+ }
+
+ @Override
+ public void visitLLOAD(LLOAD lLOAD) {
+ this.stack().push(this.locals().get(lLOAD.getIndex()));
+ }
+
+ @Override
+ public void visitDMUL(DMUL dMUL) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitIFNONNULL(IFNONNULL fNONNULL) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitFALOAD(FALOAD fALOAD) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitDUP(DUP dUP) {
+ Type type = this.stack().pop();
+ this.stack().push(type);
+ this.stack().push(type);
+ }
+
+ @Override
+ public void visitIUSHR(IUSHR uSHR) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitDRETURN(DRETURN dRETURN) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitF2I(F2I f2I) {
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitDALOAD(DALOAD dALOAD) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitLAND(LAND lAND) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitIF_ICMPGT(IF_ICMPGT f_ICMPGT) {
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitL2F(L2F l2F) {
+ this.stack().pop();
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitISHL(ISHL sHL) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ public void setFrame(Frame frame2) {
+ this.frame = frame2;
+ }
+
+ @Override
+ public void visitDUP2_X1(DUP2_X1 dUP2_X1) {
+ Type type;
+ if ((type = this.stack().pop()).getSize() == 2) {
+ Type type2 = this.stack().pop();
+ this.stack().push(type);
+ this.stack().push(type2);
+ this.stack().push(type);
+ } else {
+ Type type3 = this.stack().pop();
+ Type type4 = this.stack().pop();
+ this.stack().push(type3);
+ this.stack().push(type);
+ this.stack().push(type4);
+ this.stack().push(type3);
+ this.stack().push(type);
+ }
+ }
+
+ @Override
+ public void visitIF_ICMPLT(IF_ICMPLT f_ICMPLT) {
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitALOAD(ALOAD aLOAD) {
+ this.stack().push(this.locals().get(aLOAD.getIndex()));
+ }
+
+ @Override
+ public void visitLREM(LREM lREM) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitMONITOREXIT(MONITOREXIT mONITOREXIT) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitDCMPG(DCMPG dCMPG) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ public OperandStack stack() {
+ return this.frame.getStack();
+ }
+
+ @Override
+ public void visitLOOKUPSWITCH(LOOKUPSWITCH lOOKUPSWITCH) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitCALOAD(CALOAD cALOAD) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitFLOAD(FLOAD fLOAD) {
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitFRETURN(FRETURN fRETURN) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitIF_ICMPLE(IF_ICMPLE f_ICMPLE) {
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitDCMPL(DCMPL dCMPL) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitD2L(D2L d2L) {
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitDSTORE(DSTORE dSTORE) {
+ this.locals().set(dSTORE.getIndex(), this.stack().pop());
+ this.locals().set(dSTORE.getIndex() + 1, Type.UNKNOWN);
+ }
+
+ @Override
+ public void visitL2D(L2D l2D) {
+ this.stack().pop();
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitINVOKEVIRTUAL(INVOKEVIRTUAL nVOKEVIRTUAL) {
+ this.stack().pop();
+ int value = 0;
+ for (int value2 = value;
+ value2 < nVOKEVIRTUAL.getArgumentTypes(this.cpg).length;
+ value2 = value) {
+ value++;
+ this.stack().pop();
+ }
+ if (nVOKEVIRTUAL.getType2(this.cpg) != Type.VOID) {
+ Type type;
+ if ((type = nVOKEVIRTUAL.getType2(this.cpg)).equals(Type.BOOLEAN)
+ || type.equals(Type.CHAR)
+ || type.equals(Type.BYTE)
+ || type.equals(Type.SHORT)) {
+ type = Type.INT;
+ }
+ this.stack().push(type);
+ }
+ }
+
+ @Override
+ public void visitIFLT(IFLT fLT) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitIINC(IINC iNC) {}
+
+ @Override
+ public void visitDUP2_X2(DUP2_X2 dUP2_X2) {
+ Type type;
+ if ((type = this.stack().pop()).getSize() == 2) {
+ Type type2;
+ if ((type2 = this.stack().pop()).getSize() == 2) {
+ this.stack().push(type);
+ this.stack().push(type2);
+ this.stack().push(type);
+ } else {
+ Type type3 = this.stack().pop();
+ this.stack().push(type);
+ this.stack().push(type3);
+ this.stack().push(type2);
+ this.stack().push(type);
+ }
+ } else {
+ Type type4 = this.stack().pop();
+ Type type5;
+ if ((type5 = this.stack().pop()).getSize() == 2) {
+ this.stack().push(type4);
+ this.stack().push(type);
+ this.stack().push(type5);
+ this.stack().push(type4);
+ this.stack().push(type);
+ } else {
+ Type type6 = this.stack().pop();
+ this.stack().push(type4);
+ this.stack().push(type);
+ this.stack().push(type6);
+ this.stack().push(type5);
+ this.stack().push(type4);
+ this.stack().push(type);
+ }
+ }
+ }
+
+ @Override
+ public void visitDUP_X1(DUP_X1 dUP_X1) {
+ Type type = this.stack().pop();
+ Type type2 = this.stack().pop();
+ this.stack().push(type);
+ this.stack().push(type2);
+ this.stack().push(type);
+ }
+
+ @Override
+ public void visitFCONST(FCONST fCONST) {
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitMULTIANEWARRAY(MULTIANEWARRAY mULTIANEWARRAY) {
+ int value;
+ for (int value2 = value = 0; value2 < mULTIANEWARRAY.getDimensions(); value2 = value) {
+ value++;
+ this.stack().pop();
+ }
+ this.stack().push(mULTIANEWARRAY.getType(this.cpg));
+ }
+
+ @Override
+ public void visitDNEG(DNEG dNEG) {
+ this.stack().pop();
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitPUTSTATIC(PUTSTATIC pUTSTATIC) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitIREM(IREM rEM) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitDASTORE(DASTORE dASTORE) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitLDC(LDC lDC) {
+ Constant constant;
+ if ((constant = this.cpg.getConstant(lDC.getIndex())) instanceof ConstantInteger) {
+ this.stack().push(Type.INT);
+ }
+ if (constant instanceof ConstantFloat) {
+ this.stack().push(Type.FLOAT);
+ }
+ if (constant instanceof ConstantString) {
+ this.stack().push(Type.STRING);
+ }
+ }
+
+ @Override
+ public void visitF2D(F2D f2D) {
+ this.stack().pop();
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitFSUB(FSUB fSUB) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitI2S(I2S i2S) {
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitFCMPG(FCMPG fCMPG) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitLDIV(LDIV lDIV) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitDADD(DADD dADD) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitD2I(D2I d2I) {
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitJSR(JSR jSR) {
+ this.stack().push(new ReturnaddressType(jSR.physicalSuccessor()));
+ }
+
+ @Override
+ public void visitARRAYLENGTH(ARRAYLENGTH aRRAYLENGTH) {
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitARETURN(ARETURN aRETURN) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitIFNULL(IFNULL fNULL) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitGETFIELD(GETFIELD gETFIELD) {
+ this.stack().pop();
+ Type type2 = gETFIELD.getType2(this.cpg);
+ if (type2.equals(Type.BOOLEAN)
+ || type2.equals(Type.CHAR)
+ || type2.equals(Type.BYTE)
+ || type2.equals(Type.SHORT)) {
+ type2 = Type.INT;
+ }
+ this.stack().push(type2);
+ }
+
+ @Override
+ public void visitGETSTATIC(GETSTATIC gETSTATIC) {
+ Type type;
+ if ((type = gETSTATIC.getType2(this.cpg)).equals(Type.BOOLEAN)
+ || type.equals(Type.CHAR)
+ || type.equals(Type.BYTE)
+ || type.equals(Type.SHORT)) {
+ type = Type.INT;
+ }
+ this.stack().push(type);
+ }
+
+ @Override
+ public void visitCASTORE(CASTORE cASTORE) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitLSHR(LSHR lSHR) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitSASTORE(SASTORE sASTORE) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitISHR(ISHR sHR) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitPOP2(POP2 pOP2) {
+ if (this.stack().pop().getSize() == 1) {
+ this.stack().pop();
+ }
+ }
+
+ @Override
+ public void visitLXOR(LXOR lXOR) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitNEW(NEW nEW) {
+ this.stack().push(new UninitializedObjectType((ObjectType) nEW.getType(this.cpg)));
+ }
+
+ @Override
+ public void visitLCONST(LCONST lCONST) {
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitFREM(FREM fREM) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitIFGE(IFGE fGE) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitILOAD(ILOAD lOAD) {
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitIFNE(IFNE fNE) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitDDIV(DDIV dDIV) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.DOUBLE);
+ }
+
+ @Override
+ public void visitIFEQ(IFEQ fEQ) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitPUTFIELD(PUTFIELD pUTFIELD) {
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitF2L(F2L f2L) {
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitD2F(D2F d2F) {
+ this.stack().pop();
+ this.stack().push(Type.FLOAT);
+ }
+
+ @Override
+ public void visitLSUB(LSUB lSUB) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.LONG);
+ }
+
+ @Override
+ public void visitLCMP(LCMP lCMP) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitTABLESWITCH(TABLESWITCH tABLESWITCH) {
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitCHECKCAST(CHECKCAST cHECKCAST) {
+ this.stack().pop();
+ this.stack().push(cHECKCAST.getType(this.cpg));
+ }
+
+ @Override
+ public void visitATHROW(ATHROW aTHROW) {
+ Type type = this.stack().pop();
+ this.stack().clear();
+ if (type.equals(Type.NULL)) {
+ this.stack().push(Type.getType("Ljava/lang/NullPointerException;"));
+ } else {
+ this.stack().push(type);
+ }
+ }
+
+ @Override
+ public void visitFASTORE(FASTORE fASTORE) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ public LocalVariables locals() {
+ return this.frame.getLocals();
+ }
+
+ @Override
+ public void visitIXOR(IXOR xOR) {
+ this.stack().pop();
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitIF_ACMPEQ(IF_ACMPEQ f_ACMPEQ) {
+ this.stack().pop();
+ this.stack().pop();
+ }
+
+ @Override
+ public void visitINEG(INEG nEG) {
+ this.stack().pop();
+ this.stack().push(Type.INT);
+ }
+
+ @Override
+ public void visitASTORE(ASTORE aSTORE) {
+ this.locals().set(aSTORE.getIndex(), this.stack().pop());
+ }
+
+ @Override
+ public void visitINVOKESPECIAL(INVOKESPECIAL nVOKESPECIAL) {
+ if (nVOKESPECIAL.getText4(this.cpg).equals("")) {
+ UninitializedObjectType uninitializedObjectType;
+ if ((uninitializedObjectType =
+ (UninitializedObjectType)
+ this.stack().peek(nVOKESPECIAL.getArgumentTypes(this.cpg).length))
+ == Frame._this) {
+ Frame._this = null;
+ }
+ this.stack().initializeObject(uninitializedObjectType);
+ this.locals().initializeObject(uninitializedObjectType);
+ }
+ this.stack().pop();
+ int value = 0;
+ for (int value2 = value;
+ value2 < nVOKESPECIAL.getArgumentTypes(this.cpg).length;
+ value2 = value) {
+ value++;
+ this.stack().pop();
+ }
+ if (nVOKESPECIAL.getType2(this.cpg) != Type.VOID) {
+ Type type;
+ if ((type = nVOKESPECIAL.getType2(this.cpg)).equals(Type.BOOLEAN)
+ || type.equals(Type.CHAR)
+ || type.equals(Type.BYTE)
+ || type.equals(Type.SHORT)) {
+ type = Type.INT;
+ }
+ this.stack().push(type);
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/Frame.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Frame.java
new file mode 100644
index 0000000..d482ab4
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Frame.java
@@ -0,0 +1,53 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+public class Frame {
+
+ public static UninitializedObjectType _this;
+
+ public LocalVariables locals;
+
+ public OperandStack stack;
+
+ public OperandStack getStack() {
+ return this.stack;
+ }
+
+ public LocalVariables getLocals() {
+ return this.locals;
+ }
+
+ @Override
+ public boolean equals(Object result) {
+ if (!(result instanceof Frame)) {
+ return false;
+ }
+ Frame frame = (Frame) result;
+ return this.stack.equals(frame.stack) && this.locals.equals(frame.locals);
+ }
+
+ @Override
+ public int hashCode() {
+ return this.stack.hashCode() ^ this.locals.hashCode();
+ }
+
+ public Frame(LocalVariables localVariables, OperandStack operandStack) {
+ super();
+ this.locals = localVariables;
+ this.stack = operandStack;
+ }
+
+ @Override
+ public Object clone() {
+ return new Frame(this.locals.getClone(), this.stack.getClone());
+ }
+
+ public Frame getClone() {
+ return (Frame) this.clone();
+ }
+
+ public Frame(int value, int value2) {
+ super();
+ this.locals = new LocalVariables(value);
+ this.stack = new OperandStack(value2);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/GenericArray.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/GenericArray.java
new file mode 100644
index 0000000..af1ad71
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/GenericArray.java
@@ -0,0 +1,11 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import java.io.Serializable;
+
+public class GenericArray implements Cloneable, Serializable {
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/InstConstraintVisitor.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/InstConstraintVisitor.java
new file mode 100644
index 0000000..d4c0cc1
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/InstConstraintVisitor.java
@@ -0,0 +1,3162 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.Repository;
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.classfile.ConstantClass;
+import com.allatori.lib.bcel.classfile.ConstantDouble;
+import com.allatori.lib.bcel.classfile.ConstantFieldref;
+import com.allatori.lib.bcel.classfile.ConstantFloat;
+import com.allatori.lib.bcel.classfile.ConstantInteger;
+import com.allatori.lib.bcel.classfile.ConstantLong;
+import com.allatori.lib.bcel.classfile.ConstantString;
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.generic.AALOAD;
+import com.allatori.lib.bcel.generic.AASTORE;
+import com.allatori.lib.bcel.generic.ACONST_NULL;
+import com.allatori.lib.bcel.generic.ALOAD;
+import com.allatori.lib.bcel.generic.ANEWARRAY;
+import com.allatori.lib.bcel.generic.ARETURN;
+import com.allatori.lib.bcel.generic.ARRAYLENGTH;
+import com.allatori.lib.bcel.generic.ASTORE;
+import com.allatori.lib.bcel.generic.ATHROW;
+import com.allatori.lib.bcel.generic.ArrayType;
+import com.allatori.lib.bcel.generic.BALOAD;
+import com.allatori.lib.bcel.generic.BASTORE;
+import com.allatori.lib.bcel.generic.BIPUSH;
+import com.allatori.lib.bcel.generic.BREAKPOINT;
+import com.allatori.lib.bcel.generic.CALOAD;
+import com.allatori.lib.bcel.generic.CASTORE;
+import com.allatori.lib.bcel.generic.CHECKCAST;
+import com.allatori.lib.bcel.generic.CPInstruction;
+import com.allatori.lib.bcel.generic.ConstantPoolGen;
+import com.allatori.lib.bcel.generic.D2F;
+import com.allatori.lib.bcel.generic.D2I;
+import com.allatori.lib.bcel.generic.D2L;
+import com.allatori.lib.bcel.generic.DADD;
+import com.allatori.lib.bcel.generic.DALOAD;
+import com.allatori.lib.bcel.generic.DASTORE;
+import com.allatori.lib.bcel.generic.DCMPG;
+import com.allatori.lib.bcel.generic.DCMPL;
+import com.allatori.lib.bcel.generic.DCONST;
+import com.allatori.lib.bcel.generic.DDIV;
+import com.allatori.lib.bcel.generic.DLOAD;
+import com.allatori.lib.bcel.generic.DMUL;
+import com.allatori.lib.bcel.generic.DNEG;
+import com.allatori.lib.bcel.generic.DREM;
+import com.allatori.lib.bcel.generic.DRETURN;
+import com.allatori.lib.bcel.generic.DSTORE;
+import com.allatori.lib.bcel.generic.DSUB;
+import com.allatori.lib.bcel.generic.DUP;
+import com.allatori.lib.bcel.generic.DUP2;
+import com.allatori.lib.bcel.generic.DUP2_X1;
+import com.allatori.lib.bcel.generic.DUP2_X2;
+import com.allatori.lib.bcel.generic.DUP_X1;
+import com.allatori.lib.bcel.generic.DUP_X2;
+import com.allatori.lib.bcel.generic.EmptyVisitor;
+import com.allatori.lib.bcel.generic.F2D;
+import com.allatori.lib.bcel.generic.F2I;
+import com.allatori.lib.bcel.generic.F2L;
+import com.allatori.lib.bcel.generic.FADD;
+import com.allatori.lib.bcel.generic.FALOAD;
+import com.allatori.lib.bcel.generic.FASTORE;
+import com.allatori.lib.bcel.generic.FCMPG;
+import com.allatori.lib.bcel.generic.FCMPL;
+import com.allatori.lib.bcel.generic.FCONST;
+import com.allatori.lib.bcel.generic.FDIV;
+import com.allatori.lib.bcel.generic.FLOAD;
+import com.allatori.lib.bcel.generic.FMUL;
+import com.allatori.lib.bcel.generic.FNEG;
+import com.allatori.lib.bcel.generic.FREM;
+import com.allatori.lib.bcel.generic.FRETURN;
+import com.allatori.lib.bcel.generic.FSTORE;
+import com.allatori.lib.bcel.generic.FSUB;
+import com.allatori.lib.bcel.generic.FieldInstruction;
+import com.allatori.lib.bcel.generic.GETFIELD;
+import com.allatori.lib.bcel.generic.GETSTATIC;
+import com.allatori.lib.bcel.generic.GOTO;
+import com.allatori.lib.bcel.generic.GOTO_W;
+import com.allatori.lib.bcel.generic.I2B;
+import com.allatori.lib.bcel.generic.I2C;
+import com.allatori.lib.bcel.generic.I2D;
+import com.allatori.lib.bcel.generic.I2F;
+import com.allatori.lib.bcel.generic.I2L;
+import com.allatori.lib.bcel.generic.I2S;
+import com.allatori.lib.bcel.generic.IADD;
+import com.allatori.lib.bcel.generic.IALOAD;
+import com.allatori.lib.bcel.generic.IAND;
+import com.allatori.lib.bcel.generic.IASTORE;
+import com.allatori.lib.bcel.generic.ICONST;
+import com.allatori.lib.bcel.generic.IDIV;
+import com.allatori.lib.bcel.generic.IFEQ;
+import com.allatori.lib.bcel.generic.IFGE;
+import com.allatori.lib.bcel.generic.IFGT;
+import com.allatori.lib.bcel.generic.IFLE;
+import com.allatori.lib.bcel.generic.IFLT;
+import com.allatori.lib.bcel.generic.IFNE;
+import com.allatori.lib.bcel.generic.IFNONNULL;
+import com.allatori.lib.bcel.generic.IFNULL;
+import com.allatori.lib.bcel.generic.IF_ACMPEQ;
+import com.allatori.lib.bcel.generic.IF_ACMPNE;
+import com.allatori.lib.bcel.generic.IF_ICMPEQ;
+import com.allatori.lib.bcel.generic.IF_ICMPGE;
+import com.allatori.lib.bcel.generic.IF_ICMPGT;
+import com.allatori.lib.bcel.generic.IF_ICMPLE;
+import com.allatori.lib.bcel.generic.IF_ICMPLT;
+import com.allatori.lib.bcel.generic.IF_ICMPNE;
+import com.allatori.lib.bcel.generic.IINC;
+import com.allatori.lib.bcel.generic.ILOAD;
+import com.allatori.lib.bcel.generic.IMPDEP1;
+import com.allatori.lib.bcel.generic.IMPDEP2;
+import com.allatori.lib.bcel.generic.IMUL;
+import com.allatori.lib.bcel.generic.INEG;
+import com.allatori.lib.bcel.generic.INSTANCEOF;
+import com.allatori.lib.bcel.generic.INVOKEINTERFACE;
+import com.allatori.lib.bcel.generic.INVOKESPECIAL;
+import com.allatori.lib.bcel.generic.INVOKESTATIC;
+import com.allatori.lib.bcel.generic.INVOKEVIRTUAL;
+import com.allatori.lib.bcel.generic.IOR;
+import com.allatori.lib.bcel.generic.IREM;
+import com.allatori.lib.bcel.generic.IRETURN;
+import com.allatori.lib.bcel.generic.ISHL;
+import com.allatori.lib.bcel.generic.ISHR;
+import com.allatori.lib.bcel.generic.ISTORE;
+import com.allatori.lib.bcel.generic.ISUB;
+import com.allatori.lib.bcel.generic.IUSHR;
+import com.allatori.lib.bcel.generic.IXOR;
+import com.allatori.lib.bcel.generic.Instruction;
+import com.allatori.lib.bcel.generic.InvokeInstruction;
+import com.allatori.lib.bcel.generic.JSR;
+import com.allatori.lib.bcel.generic.JSR_W;
+import com.allatori.lib.bcel.generic.L2D;
+import com.allatori.lib.bcel.generic.L2F;
+import com.allatori.lib.bcel.generic.L2I;
+import com.allatori.lib.bcel.generic.LADD;
+import com.allatori.lib.bcel.generic.LALOAD;
+import com.allatori.lib.bcel.generic.LAND;
+import com.allatori.lib.bcel.generic.LASTORE;
+import com.allatori.lib.bcel.generic.LCMP;
+import com.allatori.lib.bcel.generic.LCONST;
+import com.allatori.lib.bcel.generic.LDC;
+import com.allatori.lib.bcel.generic.LDC2_W;
+import com.allatori.lib.bcel.generic.LDC_W;
+import com.allatori.lib.bcel.generic.LDIV;
+import com.allatori.lib.bcel.generic.LLOAD;
+import com.allatori.lib.bcel.generic.LMUL;
+import com.allatori.lib.bcel.generic.LNEG;
+import com.allatori.lib.bcel.generic.LOOKUPSWITCH;
+import com.allatori.lib.bcel.generic.LOR;
+import com.allatori.lib.bcel.generic.LREM;
+import com.allatori.lib.bcel.generic.LRETURN;
+import com.allatori.lib.bcel.generic.LSHL;
+import com.allatori.lib.bcel.generic.LSHR;
+import com.allatori.lib.bcel.generic.LSTORE;
+import com.allatori.lib.bcel.generic.LSUB;
+import com.allatori.lib.bcel.generic.LUSHR;
+import com.allatori.lib.bcel.generic.LXOR;
+import com.allatori.lib.bcel.generic.LoadClass;
+import com.allatori.lib.bcel.generic.LoadInstruction;
+import com.allatori.lib.bcel.generic.LocalVariableInstruction;
+import com.allatori.lib.bcel.generic.MONITORENTER;
+import com.allatori.lib.bcel.generic.MONITOREXIT;
+import com.allatori.lib.bcel.generic.MULTIANEWARRAY;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.generic.NEW;
+import com.allatori.lib.bcel.generic.NEWARRAY;
+import com.allatori.lib.bcel.generic.NOP;
+import com.allatori.lib.bcel.generic.ObjectType;
+import com.allatori.lib.bcel.generic.POP;
+import com.allatori.lib.bcel.generic.POP2;
+import com.allatori.lib.bcel.generic.PUTFIELD;
+import com.allatori.lib.bcel.generic.PUTSTATIC;
+import com.allatori.lib.bcel.generic.RET;
+import com.allatori.lib.bcel.generic.RETURN;
+import com.allatori.lib.bcel.generic.ReferenceType;
+import com.allatori.lib.bcel.generic.ReturnInstruction;
+import com.allatori.lib.bcel.generic.ReturnaddressType;
+import com.allatori.lib.bcel.generic.SALOAD;
+import com.allatori.lib.bcel.generic.SASTORE;
+import com.allatori.lib.bcel.generic.SIPUSH;
+import com.allatori.lib.bcel.generic.SWAP;
+import com.allatori.lib.bcel.generic.StackConsumer;
+import com.allatori.lib.bcel.generic.StackInstruction;
+import com.allatori.lib.bcel.generic.StackProducer;
+import com.allatori.lib.bcel.generic.StoreInstruction;
+import com.allatori.lib.bcel.generic.TABLESWITCH;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.lib.bcel.generic.Visitor;
+import com.allatori.lib.bcel.verifier.VerificationResult;
+import com.allatori.lib.bcel.verifier.VerifierFactory;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import com.allatori.lib.bcel.verifier.exc.StructuralCodeConstraintException;
+
+public class InstConstraintVisitor extends EmptyVisitor implements Visitor {
+
+ public MethodGen mg;
+
+ public ConstantPoolGen cpg;
+
+ public static ObjectType GENERIC_ARRAY =
+ new ObjectType("com.allatori.lib.bcel.verifier.structurals.GenericArray");
+
+ public Frame frame = null;
+
+ @Override
+ public void visitIFGE(IFGE fGE) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ fGE,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitINSTANCEOF(INSTANCEOF nSTANCEOF) {
+ Type type;
+ if (!((type = this.stack().peek(0)) instanceof ReferenceType)) {
+ this.constraintViolated(
+ nSTANCEOF, "The 'objectref' is not of a ReferenceType but of type " + type + ".");
+ }
+ Constant constant;
+ if (!((constant = this.cpg.getConstant(nSTANCEOF.getIndex())) instanceof ConstantClass)) {
+ this.constraintViolated(
+ nSTANCEOF, "The Constant at 'index' is not a ConstantClass, but '" + constant + "'.");
+ }
+ }
+
+ @Override
+ public void visitLCMP(LCMP lCMP) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lCMP,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lCMP,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitFNEG(FNEG fNEG) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ fNEG,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitGETSTATIC(GETSTATIC gETSTATIC) {}
+
+ @Override
+ public void visitLASTORE(LASTORE lASTORE) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lASTORE,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ this.processType2(lASTORE, this.stack().peek(1));
+ if (this.stack().peek(2) != Type.NULL) {
+ if (!(this.stack().peek(2) instanceof ArrayType)) {
+ this.constraintViolated(
+ lASTORE,
+ "Stack next-to-next-to-top must be of type long[] but is '"
+ + this.stack().peek(2)
+ + "'.");
+ }
+ if (((ArrayType) this.stack().peek(2)).getBasicType() != Type.LONG) {
+ this.constraintViolated(
+ lASTORE,
+ "Stack next-to-next-to-top must be of type long[] but is '"
+ + this.stack().peek(2)
+ + "'.");
+ }
+ }
+ }
+
+ public void setFrame(Frame frame2) {
+ this.frame = frame2;
+ }
+
+ @Override
+ public void visitDUP2_X1(DUP2_X1 dUP2_X1) {
+ if (this.stack().peek().getSize() == 2) {
+ if (this.stack().peek(1).getSize() != 1) {
+ this.constraintViolated(
+ dUP2_X1,
+ "If stack top's size is 2, then stack next-to-top's size must be 1. But it is '"
+ + this.stack().peek(1)
+ + "' of size '"
+ + this.stack().peek(1).getSize()
+ + "'.");
+ }
+ } else {
+ if (this.stack().peek(1).getSize() != 1) {
+ this.constraintViolated(
+ dUP2_X1,
+ "If stack top's size is 1, then stack next-to-top's size must also be 1. But it is '"
+ + this.stack().peek(1)
+ + "' of size '"
+ + this.stack().peek(1).getSize()
+ + "'.");
+ }
+ if (this.stack().peek(2).getSize() != 1) {
+ this.constraintViolated(
+ dUP2_X1,
+ "If stack top's size is 1, then stack next-to-next-to-top's size must also be 1. But it"
+ + " is '"
+ + this.stack().peek(2)
+ + "' of size '"
+ + this.stack().peek(2).getSize()
+ + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitDREM(DREM dREM) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ dREM,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.DOUBLE) {
+ this.constraintViolated(
+ dREM,
+ "The value at the stack next-to-top is not of type 'double', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ public void referenceTypeIsInitialized(Instruction instruction, ReferenceType referenceType) {
+ if (referenceType instanceof UninitializedObjectType) {
+ this.constraintViolated(
+ instruction, "Working on an uninitialized object '" + referenceType + "'.");
+ }
+ }
+
+ @Override
+ public void visitLoadInstruction(LoadInstruction loadInstruction) {
+ if (this.locals().get(loadInstruction.getIndex()) == Type.UNKNOWN) {
+ this.constraintViolated(
+ loadInstruction,
+ "Read-Access on local variable " + loadInstruction.getIndex() + " with unknown content.");
+ }
+ if (loadInstruction.getType(this.cpg).getSize() == 2
+ && this.locals().get(loadInstruction.getIndex() + 1) != Type.UNKNOWN) {
+ this.constraintViolated(
+ loadInstruction,
+ "Reading a two-locals value from local variables "
+ + loadInstruction.getIndex()
+ + " and "
+ + (loadInstruction.getIndex() + 1)
+ + " where the latter one is destroyed.");
+ }
+ InstConstraintVisitor instConstraintVisitor;
+ label26:
+ {
+ if (!(loadInstruction instanceof ALOAD)) {
+ if (this.locals().get(loadInstruction.getIndex()) != loadInstruction.getType(this.cpg)) {
+ StringBuilder stringBuilder =
+ new StringBuilder()
+ .insert(
+ 0,
+ "Local Variable type and LOADing Instruction type mismatch: Local Variable:"
+ + " '");
+ instConstraintVisitor = this;
+ this.constraintViolated(
+ loadInstruction,
+ stringBuilder
+ .append(this.locals().get(loadInstruction.getIndex()))
+ .append("'; Instruction type: '")
+ .append(loadInstruction.getType(this.cpg))
+ .append("'.")
+ .toString());
+ break label26;
+ }
+ } else if (!(this.locals().get(loadInstruction.getIndex()) instanceof ReferenceType)) {
+ this.constraintViolated(
+ loadInstruction,
+ "Local Variable type and LOADing Instruction type mismatch: Local Variable: '"
+ + this.locals().get(loadInstruction.getIndex())
+ + "'; Instruction expects a ReferenceType.");
+ }
+ instConstraintVisitor = this;
+ }
+ if (instConstraintVisitor.stack().maxStack() - this.stack().slotsUsed()
+ < loadInstruction.getType(this.cpg).getSize()) {
+ this.constraintViolated(
+ loadInstruction,
+ "Not enough free stack slots to load a '"
+ + loadInstruction.getType(this.cpg)
+ + "' onto the OperandStack.");
+ }
+ }
+
+ @Override
+ public void visitDNEG(DNEG dNEG) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ dNEG,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitStackProducer(StackProducer stackProducer) {
+ this._visitStackAccessor((Instruction) stackProducer);
+ }
+
+ @Override
+ public void visitI2B(I2B i2B) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ i2B,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitL2I(L2I l2I) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ l2I,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIALOAD(IALOAD aLOAD) {
+ this.processType2(aLOAD, this.stack().peek());
+ if (this.stack().peek(1) != Type.NULL) {
+ if (!(this.stack().peek(1) instanceof ArrayType)) {
+ this.constraintViolated(
+ aLOAD,
+ "Stack next-to-top must be of type int[] but is '" + this.stack().peek(1) + "'.");
+ }
+ if (((ArrayType) this.stack().peek(1)).getBasicType() != Type.INT) {
+ this.constraintViolated(
+ aLOAD,
+ "Stack next-to-top must be of type int[] but is '" + this.stack().peek(1) + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitFMUL(FMUL fMUL) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ fMUL,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.FLOAT) {
+ this.constraintViolated(
+ fMUL,
+ "The value at the stack next-to-top is not of type 'float', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitLLOAD(LLOAD lLOAD) {}
+
+ @Override
+ public void visitDUP_X1(DUP_X1 dUP_X1) {
+ if (this.stack().peek().getSize() != 1) {
+ this.constraintViolated(
+ dUP_X1,
+ "Type on stack top '"
+ + this.stack().peek()
+ + "' should occupy exactly one slot, not '"
+ + this.stack().peek().getSize()
+ + "'.");
+ }
+ if (this.stack().peek(1).getSize() != 1) {
+ this.constraintViolated(
+ dUP_X1,
+ "Type on stack next-to-top '"
+ + this.stack().peek(1)
+ + "' should occupy exactly one slot, not '"
+ + this.stack().peek(1).getSize()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitPOP2(POP2 pOP2) {
+ if (this.stack().peek().getSize() != 2) {
+ this.constraintViolated(
+ pOP2,
+ "Stack top size should be 2 but stack top is '"
+ + this.stack().peek()
+ + "' of size '"
+ + this.stack().peek().getSize()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitFCONST(FCONST fCONST) {}
+
+ @Override
+ public void visitLDC2_W(LDC2_W lDC2_W) {
+ Constant constant;
+ if (!((constant = this.cpg.getConstant(lDC2_W.getIndex())) instanceof ConstantLong)
+ && !(constant instanceof ConstantDouble)) {
+ this.constraintViolated(
+ lDC2_W,
+ "Referenced constant should be a CONSTANT_Integer, a CONSTANT_Float or a CONSTANT_String,"
+ + " but is '"
+ + constant
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitPUTSTATIC(PUTSTATIC pUTSTATIC) {
+ Field field;
+ try {
+ String fieldName = pUTSTATIC.getFieldName(this.cpg);
+ Field[] fields =
+ Repository.lookupClass(pUTSTATIC.createObjectType(this.cpg).getClassName()).getFields();
+ Field field2 = null;
+ int value;
+ int value2 = value = 0;
+ while (true) {
+ if (value2 >= fields.length) {
+ field = field2;
+ break;
+ }
+ if (fields[value].getText().equals(fieldName)) {
+ Type type = Type.getType(fields[value].getText2());
+ Type type2 = pUTSTATIC.getType(this.cpg);
+ if (type.equals(type2)) {
+ field = field2 = fields[value];
+ break;
+ }
+ }
+ value2 = ++value;
+ }
+ if (field == null) {
+ throw new AssertionViolatedException("Field not found?!?");
+ }
+ Type type3 = this.stack().peek();
+ Type type4;
+ Type type5 = type4 = Type.getType(field2.getText2());
+ if (type5 == Type.BOOLEAN
+ || type5 == Type.BYTE
+ || type5 == Type.CHAR
+ || type5 == Type.SHORT) {
+ type5 = Type.INT;
+ }
+ if (type4 instanceof ReferenceType) {
+ ReferenceType referenceType;
+ if (type3 instanceof ReferenceType) {
+ ReferenceType referenceType2 = (ReferenceType) type3;
+ referenceType = referenceType2;
+ this.referenceTypeIsInitialized(pUTSTATIC, referenceType2);
+ } else {
+ this.constraintViolated(
+ pUTSTATIC,
+ "The stack top type '" + type3 + "' is not of a reference type as expected.");
+ referenceType = (ReferenceType) (Object) null;
+ }
+ if (!referenceType.matchesType2(type5)) {
+ this.constraintViolated(
+ pUTSTATIC,
+ "The stack top type '"
+ + type3
+ + "' is not assignment compatible with '"
+ + type5
+ + "'.");
+ return;
+ }
+ } else if (type5 != type3) {
+ this.constraintViolated(
+ pUTSTATIC,
+ "The stack top type '" + type3 + "' is not of type '" + type5 + "' as expected.");
+ return;
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ public void constraintViolated(Instruction instruction, String text) {
+ String name = instruction.getClass().getName();
+ throw new StructuralCodeConstraintException(
+ ("Instruction "
+ + name.substring(name.lastIndexOf(46) + 1)
+ + " constraint violated: "
+ + text));
+ }
+
+ @Override
+ public void visitBASTORE(BASTORE bASTORE) {
+ Type type = this.stack().peek(2);
+ Type type2 = this.stack().peek(1);
+ Type type3 = this.stack().peek(0);
+ this.processType2(bASTORE, type2);
+ this.processType(bASTORE, type3);
+ if (this.arrayrefOfArrayType(bASTORE, type)
+ && !((ArrayType) type).getElementType().equals(Type.BOOLEAN)
+ && !((ArrayType) type).getElementType().equals(Type.BYTE)) {
+ this.constraintViolated(
+ bASTORE,
+ "The 'arrayref' does not refer to an array with elements of a Type.BYTE or Type.BOOLEAN"
+ + " but to an array of '"
+ + ((ArrayType) type).getElementType()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitAALOAD(AALOAD aALOAD) {
+ Type type = this.stack().peek(1);
+ Type type2 = this.stack().peek(0);
+ this.processType2(aALOAD, type2);
+ if (this.arrayrefOfArrayType(aALOAD, type)
+ && !(((ArrayType) type).getElementType() instanceof ReferenceType)) {
+ this.constraintViolated(
+ aALOAD,
+ "The 'arrayref' does not refer to an array with elements of a ReferenceType but to an"
+ + " array of "
+ + ((ArrayType) type).getElementType()
+ + ".");
+ }
+ }
+
+ @Override
+ public void visitARRAYLENGTH(ARRAYLENGTH aRRAYLENGTH) {
+ Type type = this.stack().peek(0);
+ this.arrayrefOfArrayType(aRRAYLENGTH, type);
+ }
+
+ @Override
+ public void visitDSTORE(DSTORE dSTORE) {}
+
+ @Override
+ public void visitATHROW(ATHROW aTHROW) {
+ try {
+ if (!(this.stack().peek() instanceof ObjectType) && !this.stack().peek().equals(Type.NULL)) {
+ this.constraintViolated(
+ aTHROW,
+ "The 'objectref' is not of an (initialized) ObjectType but of type "
+ + this.stack().peek()
+ + ".");
+ }
+ if (!this.stack().peek().equals(Type.NULL)) {
+ ObjectType objectType = (ObjectType) this.stack().peek();
+ ObjectType objectType2 = (ObjectType) Type.getType("Ljava/lang/Throwable;");
+ if (!objectType.matchesObjectType(objectType2) && !objectType.equals(objectType2)) {
+ this.constraintViolated(
+ aTHROW,
+ "The 'objectref' is not of class Throwable or of a subclass of Throwable, but of '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitI2S(I2S i2S) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ i2S,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitINVOKESTATIC(INVOKESTATIC nVOKESTATIC) {
+ try {
+ VerificationResult verificationResult;
+ String text;
+ Type type;
+ if ((type = nVOKESTATIC.getType(this.cpg)) instanceof ObjectType
+ && (verificationResult =
+ VerifierFactory.getVerifier(text = ((ObjectType) type).getClassName())
+ .createVerificationResult2())
+ .getStatus()
+ != 1) {
+ this.constraintViolated(
+ nVOKESTATIC,
+ "Class '"
+ + text
+ + "' is referenced, but cannot be loaded and resolved: '"
+ + verificationResult
+ + "'.");
+ }
+ int value;
+ Type[] types;
+ for (int value2 = (value = (types = nVOKESTATIC.getArgumentTypes(this.cpg)).length) - 1;
+ value2 >= 0;
+ value2--) {
+ Type type2 = this.stack().peek(value - 1 - value2);
+ Type type3;
+ if ((type3 = types[value2]) == Type.BOOLEAN
+ || type3 == Type.BYTE
+ || type3 == Type.CHAR
+ || type3 == Type.SHORT) {
+ type3 = Type.INT;
+ }
+ if (!type2.equals(type3)) {
+ if (type2 instanceof ReferenceType && type3 instanceof ReferenceType) {
+ ReferenceType referenceType = (ReferenceType) type2;
+ ReferenceType referenceType2 = (ReferenceType) type3;
+ if (!referenceType.matchesType2(referenceType2)) {
+ this.constraintViolated(
+ nVOKESTATIC,
+ "Expecting a '"
+ + type3
+ + "' but found a '"
+ + type2
+ + "' on the stack (which is not assignment compatible).");
+ }
+ this.referenceTypeIsInitialized(nVOKESTATIC, referenceType);
+ } else {
+ this.constraintViolated(
+ nVOKESTATIC,
+ "Expecting a '" + type3 + "' but found a '" + type2 + "' on the stack.");
+ }
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitIF_ICMPNE(IF_ICMPNE f_ICMPNE) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ f_ICMPNE,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ f_ICMPNE,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitFSUB(FSUB fSUB) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ fSUB,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.FLOAT) {
+ this.constraintViolated(
+ fSUB,
+ "The value at the stack next-to-top is not of type 'float', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitDCONST(DCONST dCONST) {}
+
+ @Override
+ public void visitLocalVariableInstruction(LocalVariableInstruction localVariableInstruction) {
+ if (this.locals().getLocals()
+ <= (localVariableInstruction.getType(this.cpg).getSize() == 1
+ ? localVariableInstruction.getIndex()
+ : localVariableInstruction.getIndex() + 1)) {
+ this.constraintViolated(
+ localVariableInstruction,
+ "The 'index' is not a valid index into the local variable array.");
+ }
+ }
+
+ @Override
+ public void visitINVOKEVIRTUAL(INVOKEVIRTUAL nVOKEVIRTUAL) {
+ try {
+ String text;
+ VerificationResult verificationResult;
+ Type type;
+ if ((type = nVOKEVIRTUAL.getType(this.cpg)) instanceof ObjectType
+ && (verificationResult =
+ VerifierFactory.getVerifier(text = ((ObjectType) type).getClassName())
+ .createVerificationResult2())
+ .getStatus()
+ != 1) {
+ this.constraintViolated(
+ nVOKEVIRTUAL,
+ "Class '"
+ + text
+ + "' is referenced, but cannot be loaded and resolved: '"
+ + verificationResult
+ + "'.");
+ }
+ Type[] types;
+ int value;
+ int value2;
+ for (int value3 =
+ value = (value2 = (types = nVOKEVIRTUAL.getArgumentTypes(this.cpg)).length) - 1;
+ value3 >= 0;
+ value3 = --value) {
+ Type type2 = this.stack().peek(value2 - 1 - value);
+ Type type3;
+ if ((type3 = types[value]) == Type.BOOLEAN
+ || type3 == Type.BYTE
+ || type3 == Type.CHAR
+ || type3 == Type.SHORT) {
+ type3 = Type.INT;
+ }
+ if (!type2.equals(type3)) {
+ if (type2 instanceof ReferenceType && type3 instanceof ReferenceType) {
+ ReferenceType referenceType = (ReferenceType) type2;
+ ReferenceType referenceType2 = (ReferenceType) type3;
+ if (!referenceType.matchesType2(referenceType2)) {
+ this.constraintViolated(
+ nVOKEVIRTUAL,
+ "Expecting a '"
+ + type3
+ + "' but found a '"
+ + type2
+ + "' on the stack (which is not assignment compatible).");
+ }
+ this.referenceTypeIsInitialized(nVOKEVIRTUAL, referenceType);
+ } else {
+ this.constraintViolated(
+ nVOKEVIRTUAL,
+ "Expecting a '" + type3 + "' but found a '" + type2 + "' on the stack.");
+ }
+ }
+ }
+ Type type4;
+ if ((type4 = this.stack().peek(value2)) != Type.NULL) {
+ if (!(type4 instanceof ReferenceType)) {
+ this.constraintViolated(
+ nVOKEVIRTUAL,
+ "Expecting a reference type as 'objectref' on the stack, not a '" + type4 + "'.");
+ }
+ Type type5;
+ label51:
+ {
+ this.referenceTypeIsInitialized(nVOKEVIRTUAL, (ReferenceType) type4);
+ if (!(type4 instanceof ObjectType)) {
+ if (!(type4 instanceof ArrayType)) {
+ type5 = type4;
+ this.constraintViolated(
+ nVOKEVIRTUAL,
+ "Expecting an ObjectType as 'objectref' on the stack, not a '" + type4 + "'.");
+ break label51;
+ }
+ type4 = GENERIC_ARRAY;
+ }
+ type5 = type4;
+ }
+ String className = ((ObjectType) type5).getClassName();
+ String text2 = nVOKEVIRTUAL.getText2(this.cpg);
+ if (!Repository.matchesText(className, text2)) {
+ this.constraintViolated(
+ nVOKEVIRTUAL,
+ "The 'objref' item '" + type4 + "' does not implement '" + text2 + "' as expected.");
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitD2I(D2I d2I) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ d2I,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitNOP(NOP nOP) {}
+
+ public void visitLDC_W(LDC_W lDC_W) {
+ Constant constant;
+ if (!((constant = this.cpg.getConstant(lDC_W.getIndex())) instanceof ConstantInteger)
+ && !(constant instanceof ConstantFloat)
+ && !(constant instanceof ConstantString)) {
+ this.constraintViolated(
+ lDC_W,
+ "Referenced constant should be a CONSTANT_Integer, a CONSTANT_Float or a CONSTANT_String,"
+ + " but is '"
+ + constant
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitLXOR(LXOR lXOR) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lXOR,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lXOR,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitLCONST(LCONST lCONST) {}
+
+ @Override
+ public void visitIF_ACMPEQ(IF_ACMPEQ f_ACMPEQ) {
+ if (!(this.stack().peek() instanceof ReferenceType)) {
+ this.constraintViolated(
+ f_ACMPEQ,
+ "The value at the stack top is not of a ReferenceType, but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (!(this.stack().peek(1) instanceof ReferenceType)) {
+ this.constraintViolated(
+ f_ACMPEQ,
+ "The value at the stack next-to-top is not of a ReferenceType, but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitI2L(I2L i2L) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ i2L,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitReturnInstruction(ReturnInstruction returnInstruction) {
+ Type type;
+ if ((type = this.mg.getType()) == Type.BOOLEAN
+ || type == Type.BYTE
+ || type == Type.SHORT
+ || type == Type.CHAR) {
+ type = Type.INT;
+ }
+ ReturnInstruction returnInstruction2;
+ if (returnInstruction instanceof RETURN) {
+ if (type == Type.VOID) {
+ return;
+ }
+ returnInstruction2 = returnInstruction;
+ this.constraintViolated(returnInstruction, "RETURN instruction in non-void method.");
+ } else {
+ returnInstruction2 = returnInstruction;
+ }
+ if (returnInstruction2 instanceof ARETURN) {
+ if (this.stack().peek() != Type.NULL) {
+ if (!(this.stack().peek() instanceof ReferenceType)) {
+ this.constraintViolated(
+ returnInstruction,
+ "Reference type expected on top of stack, but is: '" + this.stack().peek() + "'.");
+ }
+ this.referenceTypeIsInitialized(returnInstruction, (ReferenceType) this.stack().peek());
+ }
+ } else {
+ if (!type.equals(this.stack().peek())) {
+ this.constraintViolated(
+ returnInstruction,
+ "Current method has return type of '"
+ + this.mg.getType()
+ + "' expecting a '"
+ + type
+ + "' on top of the stack. But stack top is a '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitIFNE(IFNE fNE) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ fNE,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitDRETURN(DRETURN dRETURN) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ dRETURN,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitD2L(D2L d2L) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ d2L,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIREM(IREM rEM) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ rEM,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ rEM,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitJSR(JSR jSR) {}
+
+ @Override
+ public void visitIMPDEP2(IMPDEP2 mPDEP2) {
+ throw new AssertionViolatedException(
+ "In this JustIce verification pass there should not occur an illegal instruction such as"
+ + " IMPDEP2.");
+ }
+
+ @Override
+ public void visitSASTORE(SASTORE sASTORE) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ sASTORE,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ this.processType2(sASTORE, this.stack().peek(1));
+ if (this.stack().peek(2) != Type.NULL) {
+ if (!(this.stack().peek(2) instanceof ArrayType)) {
+ this.constraintViolated(
+ sASTORE,
+ "Stack next-to-next-to-top must be of type short[] but is '"
+ + this.stack().peek(2)
+ + "'.");
+ }
+ if (((ArrayType) this.stack().peek(2)).getBasicType() != Type.SHORT) {
+ this.constraintViolated(
+ sASTORE,
+ "Stack next-to-next-to-top must be of type short[] but is '"
+ + this.stack().peek(2)
+ + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitCALOAD(CALOAD cALOAD) {
+ Type type = this.stack().peek(1);
+ Type type2 = this.stack().peek(0);
+ this.processType2(cALOAD, type2);
+ this.arrayrefOfArrayType(cALOAD, type);
+ }
+
+ @Override
+ public void visitGOTO_W(GOTO_W gOTO_W) {}
+
+ @Override
+ public void visitGOTO(GOTO gOTO) {}
+
+ public OperandStack stack() {
+ return this.frame.getStack();
+ }
+
+ @Override
+ public void visitIASTORE(IASTORE aSTORE) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ aSTORE,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ this.processType2(aSTORE, this.stack().peek(1));
+ if (this.stack().peek(2) != Type.NULL) {
+ if (!(this.stack().peek(2) instanceof ArrayType)) {
+ this.constraintViolated(
+ aSTORE,
+ "Stack next-to-next-to-top must be of type int[] but is '"
+ + this.stack().peek(2)
+ + "'.");
+ }
+ if (((ArrayType) this.stack().peek(2)).getBasicType() != Type.INT) {
+ this.constraintViolated(
+ aSTORE,
+ "Stack next-to-next-to-top must be of type int[] but is '"
+ + this.stack().peek(2)
+ + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitSALOAD(SALOAD sALOAD) {
+ this.processType2(sALOAD, this.stack().peek());
+ if (this.stack().peek(1) != Type.NULL) {
+ if (!(this.stack().peek(1) instanceof ArrayType)) {
+ this.constraintViolated(
+ sALOAD,
+ "Stack next-to-top must be of type short[] but is '" + this.stack().peek(1) + "'.");
+ }
+ if (((ArrayType) this.stack().peek(1)).getBasicType() != Type.SHORT) {
+ this.constraintViolated(
+ sALOAD,
+ "Stack next-to-top must be of type short[] but is '" + this.stack().peek(1) + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitIF_ICMPGT(IF_ICMPGT f_ICMPGT) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ f_ICMPGT,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ f_ICMPGT,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitDALOAD(DALOAD dALOAD) {
+ this.processType2(dALOAD, this.stack().peek());
+ if (this.stack().peek(1) != Type.NULL) {
+ if (!(this.stack().peek(1) instanceof ArrayType)) {
+ this.constraintViolated(
+ dALOAD,
+ "Stack next-to-top must be of type double[] but is '" + this.stack().peek(1) + "'.");
+ }
+ if (((ArrayType) this.stack().peek(1)).getBasicType() != Type.DOUBLE) {
+ this.constraintViolated(
+ dALOAD,
+ "Stack next-to-top must be of type double[] but is '" + this.stack().peek(1) + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitL2F(L2F l2F) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ l2F,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitDDIV(DDIV dDIV) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ dDIV,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.DOUBLE) {
+ this.constraintViolated(
+ dDIV,
+ "The value at the stack next-to-top is not of type 'double', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitPOP(POP pOP) {
+ if (this.stack().peek().getSize() != 1) {
+ this.constraintViolated(
+ pOP,
+ "Stack top size should be 1 but stack top is '"
+ + this.stack().peek()
+ + "' of size '"
+ + this.stack().peek().getSize()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitLSTORE(LSTORE lSTORE) {}
+
+ @Override
+ public void visitF2D(F2D f2D) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ f2D,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitNEWARRAY(NEWARRAY nEWARRAY) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ nEWARRAY,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitLAND(LAND lAND) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lAND,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lAND,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitDLOAD(DLOAD dLOAD) {}
+
+ @Override
+ public void visitStoreInstruction(StoreInstruction storeInstruction) {
+ if (this.stack().isEmpty()) {
+ this.constraintViolated(storeInstruction, "Cannot STORE: Stack to read from is empty.");
+ }
+ if (!(storeInstruction instanceof ASTORE)) {
+ if (this.stack().peek() != storeInstruction.getType(this.cpg)) {
+ this.constraintViolated(
+ storeInstruction,
+ "Stack top type and STOREing Instruction type mismatch: Stack top: '"
+ + this.stack().peek()
+ + "'; Instruction type: '"
+ + storeInstruction.getType(this.cpg)
+ + "'.");
+ return;
+ }
+ } else {
+ Type type;
+ if (!((type = this.stack().peek()) instanceof ReferenceType)
+ && !(type instanceof ReturnaddressType)) {
+ this.constraintViolated(
+ storeInstruction,
+ "Stack top type and STOREing Instruction type mismatch: Stack top: '"
+ + this.stack().peek()
+ + "'; Instruction expects a ReferenceType or a ReturnadressType.");
+ }
+ }
+ }
+
+ @Override
+ public void visitARETURN(ARETURN aRETURN) {
+ if (!(this.stack().peek() instanceof ReferenceType)) {
+ this.constraintViolated(
+ aRETURN,
+ "The 'objectref' at the stack top is not of a ReferenceType but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ ReferenceType referenceType = (ReferenceType) this.stack().peek();
+ this.referenceTypeIsInitialized(aRETURN, referenceType);
+ }
+
+ @Override
+ public void visitLSHR(LSHR lSHR) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ lSHR,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lSHR,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitDASTORE(DASTORE dASTORE) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ dASTORE,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ this.processType2(dASTORE, this.stack().peek(1));
+ if (this.stack().peek(2) != Type.NULL) {
+ if (!(this.stack().peek(2) instanceof ArrayType)) {
+ this.constraintViolated(
+ dASTORE,
+ "Stack next-to-next-to-top must be of type double[] but is '"
+ + this.stack().peek(2)
+ + "'.");
+ }
+ if (((ArrayType) this.stack().peek(2)).getBasicType() != Type.DOUBLE) {
+ this.constraintViolated(
+ dASTORE,
+ "Stack next-to-next-to-top must be of type double[] but is '"
+ + this.stack().peek(2)
+ + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitFALOAD(FALOAD fALOAD) {
+ this.processType2(fALOAD, this.stack().peek());
+ if (this.stack().peek(1) != Type.NULL) {
+ if (!(this.stack().peek(1) instanceof ArrayType)) {
+ this.constraintViolated(
+ fALOAD,
+ "Stack next-to-top must be of type float[] but is '" + this.stack().peek(1) + "'.");
+ }
+ if (((ArrayType) this.stack().peek(1)).getBasicType() != Type.FLOAT) {
+ this.constraintViolated(
+ fALOAD,
+ "Stack next-to-top must be of type float[] but is '" + this.stack().peek(1) + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitIFLT(IFLT fLT) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ fLT,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitLADD(LADD lADD) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lADD,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lADD,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitI2C(I2C i2C) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ i2C,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitFCMPG(FCMPG fCMPG) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ fCMPG,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.FLOAT) {
+ this.constraintViolated(
+ fCMPG,
+ "The value at the stack next-to-top is not of type 'float', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitLoadClass(LoadClass loadClass) {
+ ObjectType objectType;
+ VerificationResult verificationResult;
+ if ((objectType = loadClass.getLoadClassType(this.cpg)) != null
+ && (verificationResult =
+ VerifierFactory.getVerifier(objectType.getClassName())
+ .createVerificationResult2())
+ .getStatus()
+ != 1) {
+ this.constraintViolated(
+ (Instruction) loadClass,
+ "Class '"
+ + loadClass.getLoadClassType(this.cpg).getClassName()
+ + "' is referenced, but cannot be loaded and resolved: '"
+ + verificationResult
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitFCMPL(FCMPL fCMPL) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ fCMPL,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.FLOAT) {
+ this.constraintViolated(
+ fCMPL,
+ "The value at the stack next-to-top is not of type 'float', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitTABLESWITCH(TABLESWITCH tABLESWITCH) {
+ this.processType2(tABLESWITCH, this.stack().peek());
+ }
+
+ @Override
+ public void visitDUP2(DUP2 dUP2) {
+ if (this.stack().peek().getSize() != 2) {
+ if (this.stack().peek(1).getSize() != 1) {
+ this.constraintViolated(
+ dUP2,
+ "If stack top's size is 1, then stack next-to-top's size must also be 1. But it is '"
+ + this.stack().peek(1)
+ + "' of size '"
+ + this.stack().peek(1).getSize()
+ + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitInvokeInstruction(InvokeInstruction invokeInstruction) {}
+
+ @Override
+ public void visitI2D(I2D i2D) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ i2D,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitMONITORENTER(MONITORENTER mONITORENTER) {
+ if (!(this.stack().peek() instanceof ReferenceType)) {
+ this.constraintViolated(
+ mONITORENTER,
+ "The stack top should be of a ReferenceType, but is '" + this.stack().peek() + "'.");
+ }
+ }
+
+ @Override
+ public void visitIUSHR(IUSHR uSHR) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ uSHR,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ uSHR,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIRETURN(IRETURN rETURN) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ rETURN,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIXOR(IXOR xOR) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ xOR,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ xOR,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitLNEG(LNEG lNEG) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lNEG,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitFSTORE(FSTORE fSTORE) {}
+
+ @Override
+ public void visitILOAD(ILOAD lOAD) {}
+
+ @Override
+ public void visitFieldInstruction(FieldInstruction fieldInstruction) {
+ Constant constant;
+ if (!((constant = this.cpg.getConstant(fieldInstruction.getIndex()))
+ instanceof ConstantFieldref)) {
+ this.constraintViolated(
+ fieldInstruction,
+ "Index '"
+ + fieldInstruction.getIndex()
+ + "' should refer to a CONSTANT_Fieldref_info structure, but refers to '"
+ + constant
+ + "'.");
+ }
+ String text;
+ Type type;
+ VerificationResult verificationResult;
+ if ((type = fieldInstruction.getType(this.cpg)) instanceof ObjectType
+ && (verificationResult =
+ VerifierFactory.getVerifier(text = ((ObjectType) type).getClassName())
+ .createVerificationResult2())
+ .getStatus()
+ != 1) {
+ this.constraintViolated(
+ fieldInstruction,
+ "Class '"
+ + text
+ + "' is referenced, but cannot be loaded and resolved: '"
+ + verificationResult
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitANEWARRAY(ANEWARRAY aNEWARRAY) {
+ if (!this.stack().peek().equals(Type.INT)) {
+ this.constraintViolated(
+ aNEWARRAY,
+ "The 'count' at the stack top is not of type '"
+ + Type.INT
+ + "' but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitCHECKCAST(CHECKCAST cHECKCAST) {
+ Type type;
+ if (!((type = this.stack().peek(0)) instanceof ReferenceType)) {
+ this.constraintViolated(
+ cHECKCAST, "The 'objectref' is not of a ReferenceType but of type " + type + ".");
+ }
+ Constant constant;
+ if (!((constant = this.cpg.getConstant(cHECKCAST.getIndex())) instanceof ConstantClass)) {
+ this.constraintViolated(
+ cHECKCAST, "The Constant at 'index' is not a ConstantClass, but '" + constant + "'.");
+ }
+ }
+
+ @Override
+ public void visitLALOAD(LALOAD lALOAD) {
+ this.processType2(lALOAD, this.stack().peek());
+ if (this.stack().peek(1) != Type.NULL) {
+ if (!(this.stack().peek(1) instanceof ArrayType)) {
+ this.constraintViolated(
+ lALOAD,
+ "Stack next-to-top must be of type long[] but is '" + this.stack().peek(1) + "'.");
+ }
+ if (((ArrayType) this.stack().peek(1)).getBasicType() != Type.LONG) {
+ this.constraintViolated(
+ lALOAD,
+ "Stack next-to-top must be of type long[] but is '" + this.stack().peek(1) + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitISUB(ISUB sUB) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ sUB,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ sUB,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitFREM(FREM fREM) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ fREM,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.FLOAT) {
+ this.constraintViolated(
+ fREM,
+ "The value at the stack next-to-top is not of type 'float', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitSIPUSH(SIPUSH sIPUSH) {}
+
+ public boolean arrayrefOfArrayType(Instruction instruction, Type type) {
+ if (!(type instanceof ArrayType) && !type.equals(Type.NULL)) {
+ this.constraintViolated(
+ instruction, "The 'arrayref' does not refer to an array but is of type " + type + ".");
+ }
+ return type instanceof ArrayType;
+ }
+
+ @Override
+ public void visitDCMPL(DCMPL dCMPL) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ dCMPL,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.DOUBLE) {
+ this.constraintViolated(
+ dCMPL,
+ "The value at the stack next-to-top is not of type 'double', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitBIPUSH(BIPUSH bIPUSH) {}
+
+ @Override
+ public void visitIADD(IADD aDD) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ aDD,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ aDD,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitACONST_NULL(ACONST_NULL aCONST_NULL) {}
+
+ @Override
+ public void visitLDIV(LDIV lDIV) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lDIV,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lDIV,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitFRETURN(FRETURN fRETURN) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ fRETURN,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ public void setConstantPoolGen(ConstantPoolGen constantPoolGen) {
+ this.cpg = constantPoolGen;
+ }
+
+ @Override
+ public void visitIINC(IINC iNC) {
+ if (this.locals().getLocals()
+ <= (iNC.getType(this.cpg).getSize() == 1 ? iNC.getIndex() : iNC.getIndex() + 1)) {
+ this.constraintViolated(
+ iNC, "The 'index' is not a valid index into the local variable array.");
+ }
+ this.processType2(iNC, this.locals().get(iNC.getIndex()));
+ }
+
+ @Override
+ public void visitStackConsumer(StackConsumer stackConsumer) {
+ this._visitStackAccessor((Instruction) stackConsumer);
+ }
+
+ public InstConstraintVisitor() {
+ this.cpg = null;
+ this.mg = null;
+ }
+
+ @Override
+ public void visitIAND(IAND aND) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ aND,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ aND,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitALOAD(ALOAD aLOAD) {}
+
+ public void _visitStackAccessor(Instruction instruction) {
+ int value;
+ if ((value = instruction.consumeStack(this.cpg)) > this.stack().slotsUsed()) {
+ this.constraintViolated(
+ instruction,
+ "Cannot consume "
+ + value
+ + " stack slots: only "
+ + this.stack().slotsUsed()
+ + " slot(s) left on stack!\nStack:\n"
+ + this.stack());
+ }
+ int value2;
+ if ((value2 = instruction.produceStack(this.cpg) - instruction.consumeStack(this.cpg))
+ + this.stack().slotsUsed()
+ > this.stack().maxStack()) {
+ this.constraintViolated(
+ instruction,
+ "Cannot produce "
+ + value2
+ + " stack slots: only "
+ + (this.stack().maxStack() - this.stack().slotsUsed())
+ + " free stack slot(s) left.\nStack:\n"
+ + this.stack());
+ }
+ }
+
+ @Override
+ public void visitMULTIANEWARRAY(MULTIANEWARRAY mULTIANEWARRAY) {
+ short dimensions = mULTIANEWARRAY.getDimensions();
+ int value;
+ for (int value2 = value = 0; value2 < dimensions; value2 = ++value) {
+ if (this.stack().peek(value) != Type.INT) {
+ this.constraintViolated(
+ mULTIANEWARRAY,
+ "The '" + dimensions + "' upper stack types should be 'int' but aren't.");
+ }
+ }
+ }
+
+ @Override
+ public void visitLSHL(LSHL lSHL) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ lSHL,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lSHL,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitISTORE(ISTORE sTORE) {}
+
+ @Override
+ public void visitLDC(LDC lDC) {
+ Constant constant;
+ if (!((constant = this.cpg.getConstant(lDC.getIndex())) instanceof ConstantInteger)
+ && !(constant instanceof ConstantFloat)
+ && !(constant instanceof ConstantString)) {
+ this.constraintViolated(
+ lDC,
+ "Referenced constant should be a CONSTANT_Integer, a CONSTANT_Float or a CONSTANT_String,"
+ + " but is '"
+ + constant
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitBALOAD(BALOAD bALOAD) {
+ Type type = this.stack().peek(1);
+ Type type2 = this.stack().peek(0);
+ this.processType2(bALOAD, type2);
+ if (this.arrayrefOfArrayType(bALOAD, type)
+ && !((ArrayType) type).getElementType().equals(Type.BOOLEAN)
+ && !((ArrayType) type).getElementType().equals(Type.BYTE)) {
+ this.constraintViolated(
+ bALOAD,
+ "The 'arrayref' does not refer to an array with elements of a Type.BYTE or Type.BOOLEAN"
+ + " but to an array of '"
+ + ((ArrayType) type).getElementType()
+ + "'.");
+ }
+ }
+
+ public void processType(Instruction instruction, Type type) {
+ if (!type.equals(Type.INT)) {
+ this.constraintViolated(
+ instruction, "The 'value' is not of type int but of type " + type + ".");
+ }
+ }
+
+ @Override
+ public void visitSWAP(SWAP sWAP) {
+ if (this.stack().peek().getSize() != 1) {
+ this.constraintViolated(
+ sWAP,
+ "The value at the stack top is not of size '1', but of size '"
+ + this.stack().peek().getSize()
+ + "'.");
+ }
+ if (this.stack().peek(1).getSize() != 1) {
+ this.constraintViolated(
+ sWAP,
+ "The value at the stack next-to-top is not of size '1', but of size '"
+ + this.stack().peek(1).getSize()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitICONST(ICONST cONST) {}
+
+ @Override
+ public void visitGETFIELD(GETFIELD gETFIELD) {
+ Field field;
+ Field field2;
+ try {
+ Type type;
+ if (!((type = this.stack().peek()) instanceof ObjectType) && type != Type.NULL) {
+ this.constraintViolated(
+ gETFIELD,
+ "Stack top should be an object reference that's not an array reference, but is '"
+ + type
+ + "'.");
+ }
+ String fieldName = gETFIELD.getFieldName(this.cpg);
+ JavaClass javaClass;
+ Field[] fields =
+ (javaClass = Repository.lookupClass(gETFIELD.createObjectType(this.cpg).getClassName()))
+ .getFields();
+ Field field3 = null;
+ int value;
+ int value2 = value = 0;
+ while (true) {
+ if (value2 >= fields.length) {
+ field2 = field3;
+ break;
+ }
+ if (fields[value].getText().equals(fieldName)) {
+ Type type2 = Type.getType(fields[value].getText2());
+ Type type3 = gETFIELD.getType(this.cpg);
+ if (type2.equals(type3)) {
+ field2 = field3 = fields[value];
+ break;
+ }
+ }
+ value2 = ++value;
+ }
+ if (field2 == null) {
+ JavaClass[] javaClasss = javaClass.createJavaClasss();
+ label76:
+ {
+ int value3;
+ label75:
+ for (int value4 = value3 = 0; value4 < javaClasss.length; value4 = ++value3) {
+ Field[] fields2 = javaClasss[value3].getFields();
+ int value5;
+ for (int value6 = value5 = 0; value6 < fields2.length; value6 = ++value5) {
+ if (fields2[value5].getText().equals(fieldName)) {
+ Type type4 = Type.getType(fields2[value5].getText2());
+ Type type5 = gETFIELD.getType(this.cpg);
+ if (type4.equals(type5)) {
+ if (((field3 = fields2[value5]).getAccess_flags2() & 5) == 0) {
+ field = field3 = null;
+ break label76;
+ }
+ break label75;
+ }
+ }
+ }
+ }
+ field = field3;
+ }
+ if (field == null) {
+ throw new AssertionViolatedException(("Field '" + fieldName + "' not found?!?"));
+ }
+ }
+ if (field3.isEnabled13()) {
+ ObjectType objectType = gETFIELD.createObjectType(this.cpg);
+ ObjectType objectType2 = new ObjectType(this.mg.getClass_name());
+ if (objectType.equals(objectType2) || objectType2.matchesObjectType(objectType)) {
+ Type type6;
+ if ((type6 = this.stack().peek()) == Type.NULL) {
+ return;
+ }
+ if (!(type6 instanceof ObjectType)) {
+ this.constraintViolated(
+ gETFIELD,
+ "The 'objectref' must refer to an object that's not an array. Found instead: '"
+ + type6
+ + "'.");
+ }
+ ObjectType objectType3;
+ if (!(objectType3 = (ObjectType) type6).equals(objectType2)
+ && !objectType3.matchesObjectType(objectType2)) {}
+ }
+ }
+ if (field3.isEnabled11()) {
+ this.constraintViolated(
+ gETFIELD, "Referenced field '" + field3 + "' is static which it shouldn't be.");
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitIFLE(IFLE fLE) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ fLE,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitL2D(L2D l2D) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ l2D,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitLOOKUPSWITCH(LOOKUPSWITCH lOOKUPSWITCH) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ lOOKUPSWITCH,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitMONITOREXIT(MONITOREXIT mONITOREXIT) {
+ if (!(this.stack().peek() instanceof ReferenceType)) {
+ this.constraintViolated(
+ mONITOREXIT,
+ "The stack top should be of a ReferenceType, but is '" + this.stack().peek() + "'.");
+ }
+ }
+
+ @Override
+ public void visitIF_ICMPEQ(IF_ICMPEQ f_ICMPEQ) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ f_ICMPEQ,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ f_ICMPEQ,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIMUL(IMUL mUL) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ mUL,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ mUL,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ public LocalVariables locals() {
+ return this.frame.getLocals();
+ }
+
+ @Override
+ public void visitDUP_X2(DUP_X2 dUP_X2) {
+ if (this.stack().peek().getSize() != 1) {
+ this.constraintViolated(
+ dUP_X2,
+ "Stack top type must be of size 1, but is '"
+ + this.stack().peek()
+ + "' of size '"
+ + this.stack().peek().getSize()
+ + "'.");
+ }
+ if (this.stack().peek(1).getSize() != 2) {
+ if (this.stack().peek(2).getSize() != 1) {
+ this.constraintViolated(
+ dUP_X2,
+ "If stack top's size is 1 and stack next-to-top's size is 1, stack"
+ + " next-to-next-to-top's size must also be 1, but is: '"
+ + this.stack().peek(2)
+ + "' of size '"
+ + this.stack().peek(2).getSize()
+ + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitIF_ICMPGE(IF_ICMPGE f_ICMPGE) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ f_ICMPGE,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ f_ICMPGE,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIMPDEP1(IMPDEP1 mPDEP1) {
+ throw new AssertionViolatedException(
+ "In this JustIce verification pass there should not occur an illegal instruction such as"
+ + " IMPDEP1.");
+ }
+
+ @Override
+ public void visitBREAKPOINT(BREAKPOINT bREAKPOINT) {
+ throw new AssertionViolatedException(
+ "In this JustIce verification pass there should not occur an illegal instruction such as"
+ + " BREAKPOINT.");
+ }
+
+ @Override
+ public void visitAASTORE(AASTORE aASTORE) {
+ try {
+ Type type = this.stack().peek(2);
+ Type type2 = this.stack().peek(1);
+ Type type3 = this.stack().peek(0);
+ this.processType2(aASTORE, type2);
+ if (!(type3 instanceof ReferenceType)) {
+ this.constraintViolated(
+ aASTORE, "The 'value' is not of a ReferenceType but of type " + type3 + ".");
+ }
+ if (this.arrayrefOfArrayType(aASTORE, type)) {
+ if (!(((ArrayType) type).getElementType() instanceof ReferenceType)) {
+ this.constraintViolated(
+ aASTORE,
+ "The 'arrayref' does not refer to an array with elements of a ReferenceType but to an"
+ + " array of "
+ + ((ArrayType) type).getElementType()
+ + ".");
+ }
+ if (!((ReferenceType) type3)
+ .matchesType2((ReferenceType) ((ArrayType) type).getElementType())) {
+ this.constraintViolated(
+ aASTORE,
+ "The type of 'value' ('"
+ + type3
+ + "') is not assignment compatible to the components of the array 'arrayref'"
+ + " refers to. ('"
+ + ((ArrayType) type).getElementType()
+ + "')");
+ return;
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitINVOKEINTERFACE(INVOKEINTERFACE nVOKEINTERFACE) {
+ int value;
+ if ((value = nVOKEINTERFACE.getCount()) == 0) {
+ this.constraintViolated(nVOKEINTERFACE, "The 'count' argument must not be 0.");
+ }
+ Type type;
+ VerificationResult verificationResult;
+ String text;
+ if ((type = nVOKEINTERFACE.getType(this.cpg)) instanceof ObjectType
+ && (verificationResult =
+ VerifierFactory.getVerifier(text = ((ObjectType) type).getClassName())
+ .createVerificationResult2())
+ .getStatus()
+ != 1) {
+ this.constraintViolated(
+ nVOKEINTERFACE,
+ "Class '"
+ + text
+ + "' is referenced, but cannot be loaded and resolved: '"
+ + verificationResult
+ + "'.");
+ }
+ int value2;
+ int value3;
+ Type[] types;
+ for (int value4 =
+ value2 = (value3 = (types = nVOKEINTERFACE.getArgumentTypes(this.cpg)).length) - 1;
+ value4 >= 0;
+ value4 = --value2) {
+ Type type2 = this.stack().peek(value3 - 1 - value2);
+ Type type3;
+ if ((type3 = types[value2]) == Type.BOOLEAN
+ || type3 == Type.BYTE
+ || type3 == Type.CHAR
+ || type3 == Type.SHORT) {
+ type3 = Type.INT;
+ }
+ if (!type2.equals(type3)) {
+ if (type2 instanceof ReferenceType && type3 instanceof ReferenceType) {
+ ReferenceType referenceType = (ReferenceType) type2;
+ this.referenceTypeIsInitialized(nVOKEINTERFACE, referenceType);
+ } else {
+ this.constraintViolated(
+ nVOKEINTERFACE,
+ "Expecting a '" + type3 + "' but found a '" + type2 + "' on the stack.");
+ }
+ }
+ }
+ Type type4;
+ if ((type4 = this.stack().peek(value3)) != Type.NULL) {
+ if (!(type4 instanceof ReferenceType)) {
+ this.constraintViolated(
+ nVOKEINTERFACE,
+ "Expecting a reference type as 'objectref' on the stack, not a '" + type4 + "'.");
+ }
+ this.referenceTypeIsInitialized(nVOKEINTERFACE, (ReferenceType) type4);
+ if (!(type4 instanceof ObjectType)) {
+ if (!(type4 instanceof ArrayType)) {
+ this.constraintViolated(
+ nVOKEINTERFACE,
+ "Expecting an ObjectType as 'objectref' on the stack, not a '" + type4 + "'.");
+ }
+ }
+ int value5 = 1;
+ int value6;
+ for (int value7 = value6 = 0; value7 < value3; value7 = value6) {
+ Type type5 = types[value6];
+ int value8 = value5;
+ value6++;
+ value5 = value8 + type5.getSize();
+ }
+ if (value != value5) {
+ this.constraintViolated(
+ nVOKEINTERFACE,
+ "The 'count' argument should probably read '" + value5 + "' but is '" + value + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitLMUL(LMUL lMUL) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lMUL,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lMUL,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitDSUB(DSUB dSUB) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ dSUB,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.DOUBLE) {
+ this.constraintViolated(
+ dSUB,
+ "The value at the stack next-to-top is not of type 'double', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitINVOKESPECIAL(INVOKESPECIAL nVOKESPECIAL) {
+ Type type;
+ try {
+ if (nVOKESPECIAL.getText4(this.cpg).equals("")
+ && !(this.stack().peek(nVOKESPECIAL.getArgumentTypes(this.cpg).length)
+ instanceof UninitializedObjectType)) {
+ this.constraintViolated(
+ nVOKESPECIAL,
+ "Possibly initializing object twice. A valid instruction sequence must not have an"
+ + " uninitialized object on the operand stack or in a local variable during a"
+ + " backwards branch, or in a local variable in code protected by an exception"
+ + " handler. Please see The Java Virtual Machine Specification, Second Edition,"
+ + " 4.9.4 (pages 147 and 148) for details.");
+ }
+ String text;
+ VerificationResult verificationResult;
+ Type type2;
+ if ((type2 = nVOKESPECIAL.getType(this.cpg)) instanceof ObjectType
+ && (verificationResult =
+ VerifierFactory.getVerifier(text = ((ObjectType) type2).getClassName())
+ .createVerificationResult2())
+ .getStatus()
+ != 1) {
+ this.constraintViolated(
+ nVOKESPECIAL,
+ "Class '"
+ + text
+ + "' is referenced, but cannot be loaded and resolved: '"
+ + verificationResult
+ + "'.");
+ }
+ int value;
+ int value2;
+ Type[] types;
+ for (int value3 =
+ value2 = (value = (types = nVOKESPECIAL.getArgumentTypes(this.cpg)).length) - 1;
+ value3 >= 0;
+ value3 = --value2) {
+ Type type3 = this.stack().peek(value - 1 - value2);
+ Type type4;
+ if ((type4 = types[value2]) == Type.BOOLEAN
+ || type4 == Type.BYTE
+ || type4 == Type.CHAR
+ || type4 == Type.SHORT) {
+ type4 = Type.INT;
+ }
+ if (!type3.equals(type4)) {
+ if (type3 instanceof ReferenceType && type4 instanceof ReferenceType) {
+ ReferenceType referenceType = (ReferenceType) type3;
+ ReferenceType referenceType2 = (ReferenceType) type4;
+ if (!referenceType.matchesType2(referenceType2)) {
+ this.constraintViolated(
+ nVOKESPECIAL,
+ "Expecting a '"
+ + type4
+ + "' but found a '"
+ + type3
+ + "' on the stack (which is not assignment compatible).");
+ }
+ this.referenceTypeIsInitialized(nVOKESPECIAL, referenceType);
+ } else {
+ this.constraintViolated(
+ nVOKESPECIAL,
+ "Expecting a '" + type4 + "' but found a '" + type3 + "' on the stack.");
+ }
+ }
+ }
+ Type type5;
+ if ((type5 = this.stack().peek(value)) != Type.NULL) {
+ if (!(type5 instanceof ReferenceType)) {
+ this.constraintViolated(
+ nVOKESPECIAL,
+ "Expecting a reference type as 'objectref' on the stack, not a '" + type5 + "'.");
+ }
+ String text2;
+ INVOKESPECIAL nVOKESPECIAL2;
+ if (!nVOKESPECIAL.getText4(this.cpg).equals("")) {
+ label64:
+ {
+ this.referenceTypeIsInitialized(nVOKESPECIAL, (ReferenceType) type5);
+ if (!(type5 instanceof ObjectType)) {
+ if (!(type5 instanceof ArrayType)) {
+ type = type5;
+ this.constraintViolated(
+ nVOKESPECIAL,
+ "Expecting an ObjectType as 'objectref' on the stack, not a '" + type5 + "'.");
+ break label64;
+ }
+ type5 = GENERIC_ARRAY;
+ }
+ type = type5;
+ }
+ text2 = ((ObjectType) type).getClassName();
+ nVOKESPECIAL2 = nVOKESPECIAL;
+ } else {
+ if (!(type5 instanceof UninitializedObjectType)) {
+ this.constraintViolated(
+ nVOKESPECIAL,
+ "Expecting an UninitializedObjectType as 'objectref' on the stack, not a '"
+ + type5
+ + "'. Otherwise, you couldn't invoke a method since an array has no methods"
+ + " (not to speak of a return address).");
+ }
+ text2 = ((UninitializedObjectType) type5).getInitialized().getClassName();
+ nVOKESPECIAL2 = nVOKESPECIAL;
+ }
+ String text22 = nVOKESPECIAL2.getText2(this.cpg);
+ if (!Repository.matchesText(text2, text22)) {
+ this.constraintViolated(
+ nVOKESPECIAL,
+ "The 'objref' item '" + type5 + "' does not implement '" + text22 + "' as expected.");
+ }
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitFLOAD(FLOAD fLOAD) {}
+
+ @Override
+ public void visitPUTFIELD(PUTFIELD pUTFIELD) {
+ Field field;
+ try {
+ Type type;
+ if (!((type = this.stack().peek(1)) instanceof ObjectType) && type != Type.NULL) {
+ this.constraintViolated(
+ pUTFIELD,
+ "Stack next-to-top should be an object reference that's not an array reference, but is"
+ + " '"
+ + type
+ + "'.");
+ }
+ String fieldName = pUTFIELD.getFieldName(this.cpg);
+ Field[] fields =
+ Repository.lookupClass(pUTFIELD.createObjectType(this.cpg).getClassName()).getFields();
+ Field field2 = null;
+ int value;
+ int value2 = value = 0;
+ while (true) {
+ if (value2 >= fields.length) {
+ field = field2;
+ break;
+ }
+ if (fields[value].getText().equals(fieldName)) {
+ Type type2 = Type.getType(fields[value].getText2());
+ Type type3 = pUTFIELD.getType(this.cpg);
+ if (type2.equals(type3)) {
+ field = field2 = fields[value];
+ break;
+ }
+ }
+ value2 = ++value;
+ }
+ if (field == null) {
+ throw new AssertionViolatedException("Field not found?!?");
+ }
+ Type type4 = this.stack().peek();
+ Type type5;
+ Type type6 = type5 = Type.getType(field2.getText2());
+ if (type6 == Type.BOOLEAN
+ || type6 == Type.BYTE
+ || type6 == Type.CHAR
+ || type6 == Type.SHORT) {
+ type6 = Type.INT;
+ }
+ if (type5 instanceof ReferenceType) {
+ ReferenceType referenceType;
+ if (type4 instanceof ReferenceType) {
+ ReferenceType referenceType2 = (ReferenceType) type4;
+ referenceType = referenceType2;
+ this.referenceTypeIsInitialized(pUTFIELD, referenceType2);
+ } else {
+ this.constraintViolated(
+ pUTFIELD,
+ "The stack top type '" + type4 + "' is not of a reference type as expected.");
+ referenceType = (ReferenceType) (Object) null;
+ }
+ if (!referenceType.matchesType2(type6)) {
+ this.constraintViolated(
+ pUTFIELD,
+ "The stack top type '"
+ + type4
+ + "' is not assignment compatible with '"
+ + type6
+ + "'.");
+ }
+ } else if (type6 != type4) {
+ this.constraintViolated(
+ pUTFIELD,
+ "The stack top type '" + type4 + "' is not of type '" + type6 + "' as expected.");
+ }
+ if (field2.isEnabled13()) {
+ ObjectType objectType = pUTFIELD.createObjectType(this.cpg);
+ ObjectType objectType2 = new ObjectType(this.mg.getClass_name());
+ if (objectType.equals(objectType2) || objectType2.matchesObjectType(objectType)) {
+ Type type7;
+ if ((type7 = this.stack().peek(1)) == Type.NULL) {
+ return;
+ }
+ if (!(type7 instanceof ObjectType)) {
+ this.constraintViolated(
+ pUTFIELD,
+ "The 'objectref' must refer to an object that's not an array. Found instead: '"
+ + type7
+ + "'.");
+ }
+ ObjectType objectType3;
+ if (!(objectType3 = (ObjectType) type7).equals(objectType2)
+ && !objectType3.matchesObjectType(objectType2)) {
+ this.constraintViolated(
+ pUTFIELD,
+ "The referenced field has the ACC_PROTECTED modifier, and it's a member of the"
+ + " current class or a superclass of the current class. However, the referenced"
+ + " object type '"
+ + this.stack().peek()
+ + "' is not the current class or a subclass of the current class.");
+ }
+ }
+ }
+ if (field2.isEnabled11()) {
+ this.constraintViolated(
+ pUTFIELD, "Referenced field '" + field2 + "' is static which it shouldn't be.");
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public void visitCASTORE(CASTORE cASTORE) {
+ Type type = this.stack().peek(2);
+ Type type2 = this.stack().peek(1);
+ Type type3 = this.stack().peek(0);
+ this.processType2(cASTORE, type2);
+ this.processType(cASTORE, type3);
+ if (this.arrayrefOfArrayType(cASTORE, type)
+ && !((ArrayType) type).getElementType().equals(Type.CHAR)) {
+ this.constraintViolated(
+ cASTORE,
+ "The 'arrayref' does not refer to an array with elements of type char but to an array of"
+ + " type "
+ + ((ArrayType) type).getElementType()
+ + ".");
+ }
+ }
+
+ @Override
+ public void visitLUSHR(LUSHR lUSHR) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ lUSHR,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lUSHR,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitF2L(F2L f2L) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ f2L,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitD2F(D2F d2F) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ d2F,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIF_ACMPNE(IF_ACMPNE f_ACMPNE) {
+ if (!(this.stack().peek() instanceof ReferenceType)) {
+ this.constraintViolated(
+ f_ACMPNE,
+ "The value at the stack top is not of a ReferenceType, but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (!(this.stack().peek(1) instanceof ReferenceType)) {
+ this.constraintViolated(
+ f_ACMPNE,
+ "The value at the stack next-to-top is not of a ReferenceType, but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitF2I(F2I f2I) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ f2I,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitDADD(DADD dADD) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ dADD,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.DOUBLE) {
+ this.constraintViolated(
+ dADD,
+ "The value at the stack next-to-top is not of type 'double', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIFNULL(IFNULL fNULL) {
+ if (!(this.stack().peek() instanceof ReferenceType)) {
+ this.constraintViolated(
+ fNULL,
+ "The value at the stack top is not of a ReferenceType, but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ this.referenceTypeIsInitialized(fNULL, (ReferenceType) this.stack().peek());
+ }
+
+ @Override
+ public void visitIFNONNULL(IFNONNULL fNONNULL) {
+ if (!(this.stack().peek() instanceof ReferenceType)) {
+ this.constraintViolated(
+ fNONNULL,
+ "The value at the stack top is not of a ReferenceType, but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ this.referenceTypeIsInitialized(fNONNULL, (ReferenceType) this.stack().peek());
+ }
+
+ @Override
+ public void visitNEW(NEW nEW) {
+ Type type;
+ if (!((type = nEW.getType(this.cpg)) instanceof ReferenceType)) {
+ throw new AssertionViolatedException("NEW.getType() returning a non-reference type?!");
+ }
+ if (!(type instanceof ObjectType)) {
+ this.constraintViolated(
+ nEW, "Expecting a class type (ObjectType) to work on. Found: '" + type + "'.");
+ }
+ ObjectType objectType;
+ if (!(objectType = (ObjectType) type).isClass_name2()) {
+ this.constraintViolated(
+ nEW, "Expecting a class type (ObjectType) to work on. Found: '" + objectType + "'.");
+ }
+ }
+
+ @Override
+ public void visitFADD(FADD fADD) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ fADD,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.FLOAT) {
+ this.constraintViolated(
+ fADD,
+ "The value at the stack next-to-top is not of type 'float', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIF_ICMPLE(IF_ICMPLE f_ICMPLE) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ f_ICMPLE,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ f_ICMPLE,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitJSR_W(JSR_W jSR_W) {}
+
+ @Override
+ public void visitCPInstruction(CPInstruction cPInstruction) {
+ int value;
+ if ((value = cPInstruction.getIndex()) < 0 || value >= this.cpg.getSize()) {
+ throw new AssertionViolatedException(
+ ("Huh?! Constant pool index of instruction '"
+ + cPInstruction
+ + "' illegal? Pass 3a should have checked this!"));
+ }
+ }
+
+ @Override
+ public void visitLOR(LOR lOR) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lOR,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lOR,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitLSUB(LSUB lSUB) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lSUB,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lSUB,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitFDIV(FDIV fDIV) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ fDIV,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.FLOAT) {
+ this.constraintViolated(
+ fDIV,
+ "The value at the stack next-to-top is not of type 'float', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitDUP2_X2(DUP2_X2 dUP2_X2) {
+ InstConstraintVisitor instConstraintVisitor;
+ if (this.stack().peek(0).getSize() == 2) {
+ if (this.stack().peek(1).getSize() == 2) {
+ return;
+ }
+ if (this.stack().peek(2).getSize() == 1) {
+ return;
+ }
+ StringBuilder stringBuilder =
+ new StringBuilder()
+ .append(
+ "If stack top's size is 2 and stack-next-to-top's size is 1, then stack"
+ + " next-to-next-to-top's size must also be 1. But it is '");
+ instConstraintVisitor = this;
+ this.constraintViolated(
+ dUP2_X2,
+ stringBuilder
+ .append(this.stack().peek(2))
+ .append("' of size '")
+ .append(this.stack().peek(2).getSize())
+ .append("'.")
+ .toString());
+ } else {
+ if (this.stack().peek(1).getSize() == 1) {
+ if (this.stack().peek(2).getSize() == 2) {
+ return;
+ }
+ if (this.stack().peek(3).getSize() == 1) {
+ return;
+ }
+ }
+ instConstraintVisitor = this;
+ }
+ instConstraintVisitor.constraintViolated(
+ dUP2_X2,
+ "The operand sizes on the stack do not match any of the four forms of usage of this"
+ + " instruction.");
+ }
+
+ @Override
+ public void visitLRETURN(LRETURN lRETURN) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lRETURN,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitFASTORE(FASTORE fASTORE) {
+ if (this.stack().peek() != Type.FLOAT) {
+ this.constraintViolated(
+ fASTORE,
+ "The value at the stack top is not of type 'float', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ this.processType2(fASTORE, this.stack().peek(1));
+ if (this.stack().peek(2) != Type.NULL) {
+ if (!(this.stack().peek(2) instanceof ArrayType)) {
+ this.constraintViolated(
+ fASTORE,
+ "Stack next-to-next-to-top must be of type float[] but is '"
+ + this.stack().peek(2)
+ + "'.");
+ }
+ if (((ArrayType) this.stack().peek(2)).getBasicType() != Type.FLOAT) {
+ this.constraintViolated(
+ fASTORE,
+ "Stack next-to-next-to-top must be of type float[] but is '"
+ + this.stack().peek(2)
+ + "'.");
+ }
+ }
+ }
+
+ @Override
+ public void visitStackInstruction(StackInstruction stackInstruction) {
+ this._visitStackAccessor(stackInstruction);
+ }
+
+ @Override
+ public void visitIDIV(IDIV dIV) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ dIV,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ dIV,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitDMUL(DMUL dMUL) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ dMUL,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.DOUBLE) {
+ this.constraintViolated(
+ dMUL,
+ "The value at the stack next-to-top is not of type 'double', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitLREM(LREM lREM) {
+ if (this.stack().peek() != Type.LONG) {
+ this.constraintViolated(
+ lREM,
+ "The value at the stack top is not of type 'long', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.LONG) {
+ this.constraintViolated(
+ lREM,
+ "The value at the stack next-to-top is not of type 'long', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIOR(IOR oR) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ oR,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ oR,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitISHR(ISHR sHR) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ sHR,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ sHR,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ public void processType2(Instruction instruction, Type type) {
+ if (!type.equals(Type.INT)) {
+ this.constraintViolated(
+ instruction, "The 'index' is not of type int but of type " + type + ".");
+ }
+ }
+
+ @Override
+ public void visitDCMPG(DCMPG dCMPG) {
+ if (this.stack().peek() != Type.DOUBLE) {
+ this.constraintViolated(
+ dCMPG,
+ "The value at the stack top is not of type 'double', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.DOUBLE) {
+ this.constraintViolated(
+ dCMPG,
+ "The value at the stack next-to-top is not of type 'double', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ public void setMethodGen(MethodGen methodGen) {
+ this.mg = methodGen;
+ }
+
+ @Override
+ public void visitISHL(ISHL sHL) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ sHL,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ sHL,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitDUP(DUP dUP) {
+ if (this.stack().peek().getSize() != 1) {
+ this.constraintViolated(
+ dUP,
+ "Won't DUP type on stack top '"
+ + this.stack().peek()
+ + "' because it must occupy exactly one slot, not '"
+ + this.stack().peek().getSize()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitASTORE(ASTORE aSTORE) {
+ if (!(this.stack().peek() instanceof ReferenceType)
+ && !(this.stack().peek() instanceof ReturnaddressType)) {
+ this.constraintViolated(
+ aSTORE,
+ "The 'objectref' is not of a ReferenceType or of ReturnaddressType but of "
+ + this.stack().peek()
+ + ".");
+ }
+ }
+
+ @Override
+ public void visitRETURN(RETURN rETURN) {
+ if (this.mg.getName().equals("")
+ && Frame._this != null
+ && !this.mg.getClass_name().equals(Type.OBJECT.getClassName())) {
+ this.constraintViolated(
+ rETURN, "Leaving a constructor that itself did not call a constructor.");
+ }
+ }
+
+ @Override
+ public void visitINEG(INEG nEG) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ nEG,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIFEQ(IFEQ fEQ) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ fEQ,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIFGT(IFGT fGT) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ fGT,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitRET(RET rET) {
+ if (!(this.locals().get(rET.getIndex()) instanceof ReturnaddressType)) {
+ this.constraintViolated(
+ rET, "Expecting a ReturnaddressType in local variable " + rET.getIndex() + ".");
+ }
+ if (this.locals().get(rET.getIndex()) == ReturnaddressType.NO_TARGET) {
+ throw new AssertionViolatedException("Oops: RET expecting a target!");
+ }
+ }
+
+ @Override
+ public void visitI2F(I2F i2F) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ i2F,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ }
+
+ @Override
+ public void visitIF_ICMPLT(IF_ICMPLT f_ICMPLT) {
+ if (this.stack().peek() != Type.INT) {
+ this.constraintViolated(
+ f_ICMPLT,
+ "The value at the stack top is not of type 'int', but of type '"
+ + this.stack().peek()
+ + "'.");
+ }
+ if (this.stack().peek(1) != Type.INT) {
+ this.constraintViolated(
+ f_ICMPLT,
+ "The value at the stack next-to-top is not of type 'int', but of type '"
+ + this.stack().peek(1)
+ + "'.");
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/InstructionContext.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/InstructionContext.java
new file mode 100644
index 0000000..bab1b8c
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/InstructionContext.java
@@ -0,0 +1,27 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import java.util.ArrayList;
+
+public interface InstructionContext {
+
+ Frame getOutFrame(ArrayList values);
+
+ InstructionContext[] getSuccessors();
+
+ InstructionHandle getInstruction();
+
+ int getTag();
+
+ ExceptionHandler[] getExceptionHandlers();
+
+ boolean execute(
+ Frame frame,
+ ArrayList values,
+ InstConstraintVisitor instConstraintVisitor,
+ ExecutionVisitor executionVisitor);
+
+ void setTag(int value);
+
+ Frame getInFrame();
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/LocalVariables.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/LocalVariables.java
new file mode 100644
index 0000000..c8830d2
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/LocalVariables.java
@@ -0,0 +1,147 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.generic.ReferenceType;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import com.allatori.lib.bcel.verifier.exc.StructuralCodeConstraintException;
+
+public class LocalVariables {
+
+ public Type[] locals;
+
+ public LocalVariables getClone() {
+ return (LocalVariables) this.clone();
+ }
+
+ public LocalVariables(int value) {
+ this.locals = new Type[value];
+ int value2;
+ for (int value3 = value2 = 0; value3 < value; value3 = value2) {
+ Type type = Type.UNKNOWN;
+ int value4 = value2;
+ Type[] types = this.locals;
+ value2++;
+ types[value4] = type;
+ }
+ }
+
+ @Override
+ public Object clone() {
+ LocalVariables localVariables = new LocalVariables(this.locals.length);
+ int value;
+ for (int value2 = value = 0; value2 < this.locals.length; value2 = value) {
+ Type type = this.locals[value];
+ int value3 = value;
+ Type[] types = localVariables.locals;
+ value++;
+ types[value3] = type;
+ }
+ return localVariables;
+ }
+
+ public Type get(int value) {
+ return this.locals[value];
+ }
+
+ @Override
+ public int hashCode() {
+ return this.locals.length;
+ }
+
+ public void merge(LocalVariables localVariables) {
+ if (this.locals.length != localVariables.locals.length) {
+ throw new AssertionViolatedException(
+ "Merging LocalVariables of different size?!? From different methods or what?!?");
+ }
+ int value;
+ for (int value2 = value = 0; value2 < this.locals.length; value2 = value) {
+ int value3 = value;
+ value++;
+ this.merge(localVariables, value3);
+ }
+ }
+
+ public void merge(LocalVariables localVariables, int value) {
+ try {
+ if (!(this.locals[value] instanceof UninitializedObjectType)
+ && localVariables.locals[value] instanceof UninitializedObjectType) {
+ throw new StructuralCodeConstraintException(
+ "Backwards branch with an uninitialized object in the local variables detected.");
+ }
+ if (!this.locals[value].equals(localVariables.locals[value])
+ && this.locals[value] instanceof UninitializedObjectType
+ && localVariables.locals[value] instanceof UninitializedObjectType) {
+ throw new StructuralCodeConstraintException(
+ "Backwards branch with an uninitialized object in the local variables detected.");
+ }
+ if (this.locals[value] instanceof UninitializedObjectType
+ && !(localVariables.locals[value] instanceof UninitializedObjectType)) {
+ this.locals[value] = ((UninitializedObjectType) this.locals[value]).getInitialized();
+ }
+ if (this.locals[value] instanceof ReferenceType
+ && localVariables.locals[value] instanceof ReferenceType) {
+ if (!this.locals[value].equals(localVariables.locals[value])) {
+ ReferenceType referenceType;
+ if ((referenceType =
+ ((ReferenceType) this.locals[value])
+ .createReferenceType((ReferenceType) localVariables.locals[value]))
+ != null) {
+ this.locals[value] = referenceType;
+ return;
+ }
+ throw new AssertionViolatedException(
+ ("Could not load all the super classes of '"
+ + this.locals[value]
+ + "' and '"
+ + localVariables.locals[value]
+ + "'."));
+ }
+ } else if (!this.locals[value].equals(localVariables.locals[value])) {
+ this.locals[value] = Type.UNKNOWN;
+ return;
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ public void set(int value, Type type) {
+ if (type != Type.BYTE && type != Type.SHORT && type != Type.BOOLEAN && type != Type.CHAR) {
+ this.locals[value] = type;
+ } else {
+ throw new AssertionViolatedException(
+ ("LocalVariables do not know about '" + type + "'. Use Type.INT instead."));
+ }
+ }
+
+ public int getLocals() {
+ return this.locals.length;
+ }
+
+ @Override
+ public boolean equals(Object result) {
+ if (!(result instanceof LocalVariables)) {
+ return false;
+ }
+ LocalVariables localVariables = (LocalVariables) result;
+ if (this.locals.length != localVariables.locals.length) {
+ return false;
+ }
+ int value;
+ for (int value2 = value = 0; value2 < this.locals.length; value2 = ++value) {
+ if (!this.locals[value].equals(localVariables.locals[value])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void initializeObject(UninitializedObjectType uninitializedObjectType) {
+ int value;
+ for (int value2 = value = 0; value2 < this.locals.length; value2 = ++value) {
+ if (this.locals[value] == uninitializedObjectType) {
+ this.locals[value] = uninitializedObjectType.getInitialized();
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/OperandStack.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/OperandStack.java
new file mode 100644
index 0000000..cab8b14
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/OperandStack.java
@@ -0,0 +1,175 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.generic.ObjectType;
+import com.allatori.lib.bcel.generic.ReferenceType;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import com.allatori.lib.bcel.verifier.exc.StructuralCodeConstraintException;
+import java.util.ArrayList;
+
+public class OperandStack {
+
+ public int maxStack;
+
+ public ArrayList stack;
+
+ public boolean isEmpty() {
+ return this.stack.isEmpty();
+ }
+
+ public int slotsUsed() {
+ int value = 0;
+ int value2;
+ for (int value3 = value2 = 0; value3 < this.stack.size(); value3 = value2) {
+ Type type = this.peek(value2);
+ int value4 = value;
+ value2++;
+ value = value4 + type.getSize();
+ }
+ return value;
+ }
+
+ public int size() {
+ return this.stack.size();
+ }
+
+ public void clear() {
+ this.stack = new ArrayList();
+ }
+
+ @Override
+ public int hashCode() {
+ return this.stack.hashCode();
+ }
+
+ public OperandStack getClone() {
+ return (OperandStack) this.clone();
+ }
+
+ public void merge(OperandStack operandStack) {
+ try {
+ if (this.slotsUsed() == operandStack.slotsUsed() && this.size() == operandStack.size()) {
+ for (int index = 0; index < this.size(); index++) {
+ if (!(this.stack.get(index) instanceof UninitializedObjectType)
+ && operandStack.stack.get(index) instanceof UninitializedObjectType) {
+ throw new StructuralCodeConstraintException(
+ "Backwards branch with an uninitialized object on the stack detected.");
+ }
+ if (!this.stack.get(index).equals(operandStack.stack.get(index))
+ && this.stack.get(index) instanceof UninitializedObjectType
+ && !(operandStack.stack.get(index) instanceof UninitializedObjectType)) {
+ throw new StructuralCodeConstraintException(
+ "Backwards branch with an uninitialized object on the stack detected.");
+ }
+ if (this.stack.get(index) instanceof UninitializedObjectType
+ && !(operandStack.stack.get(index) instanceof UninitializedObjectType)) {
+ this.stack.set(
+ index, ((UninitializedObjectType) this.stack.get(index)).getInitialized());
+ }
+ if (!this.stack.get(index).equals(operandStack.stack.get(index))) {
+ if (!(this.stack.get(index) instanceof ReferenceType)
+ || !(operandStack.stack.get(index) instanceof ReferenceType)) {
+ throw new StructuralCodeConstraintException(
+ ("Cannot merge stacks of different types:\nStack A:\n"
+ + this
+ + "\nStack B:\n"
+ + operandStack));
+ }
+ this.stack.set(
+ index,
+ ((ReferenceType) this.stack.get(index))
+ .createReferenceType((ReferenceType) operandStack.stack.get(index)));
+ }
+ }
+ } else {
+ throw new StructuralCodeConstraintException(
+ ("Cannot merge stacks of different size:\nOperandStack A:\n"
+ + this
+ + "\nOperandStack B:\n"
+ + operandStack));
+ }
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ }
+
+ @Override
+ public Object clone() {
+ OperandStack operandStack;
+ (operandStack = new OperandStack(this.maxStack)).stack = (ArrayList) this.stack.clone();
+ return operandStack;
+ }
+
+ public void push(Type type) {
+ if (type == null) {
+ throw new AssertionViolatedException("Cannot push NULL onto OperandStack.");
+ }
+ if (type != Type.BOOLEAN && type != Type.CHAR && type != Type.BYTE && type != Type.SHORT) {
+ if (this.slotsUsed() >= this.maxStack) {
+ throw new AssertionViolatedException(
+ ("OperandStack too small, should have thrown proper Exception elsewhere. Stack: "
+ + this));
+ }
+ this.stack.add(type);
+ } else {
+ throw new AssertionViolatedException(
+ ("The OperandStack does not know about '" + type + "'; use Type.INT instead."));
+ }
+ }
+
+ public Type peek(int value) {
+ return (Type) this.stack.get(this.size() - value - 1);
+ }
+
+ public void initializeObject(UninitializedObjectType uninitializedObjectType) {
+ int value;
+ for (int value2 = value = 0; value2 < this.stack.size(); value2 = ++value) {
+ if (this.stack.get(value) == uninitializedObjectType) {
+ this.stack.set(value, uninitializedObjectType.getInitialized());
+ }
+ }
+ }
+
+ public OperandStack(int maxStack, ObjectType objectType) {
+ super();
+ this.stack = new ArrayList();
+ this.maxStack = maxStack;
+ this.push(objectType);
+ }
+
+ public OperandStack(int maxStack) {
+ super();
+ this.stack = new ArrayList();
+ this.maxStack = maxStack;
+ }
+
+ @Override
+ public boolean equals(Object result) {
+ if (!(result instanceof OperandStack)) {
+ return false;
+ }
+ OperandStack operandStack = (OperandStack) result;
+ return this.stack.equals(operandStack.stack);
+ }
+
+ public Type pop() {
+ return (Type) this.stack.remove(this.size() - 1);
+ }
+
+ public int maxStack() {
+ return this.maxStack;
+ }
+
+ public Type pop(int value) {
+ int value2;
+ for (int value3 = value2 = 0; value3 < value; value3 = value2) {
+ value2++;
+ this.pop();
+ }
+ return null;
+ }
+
+ public Type peek() {
+ return this.peek(0);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/Pass3bVerifier$1.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Pass3bVerifier$1.java
new file mode 100644
index 0000000..e7b6a57
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Pass3bVerifier$1.java
@@ -0,0 +1,3 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+public class Pass3bVerifier$1 {}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/Pass3bVerifier$InstructionContextQueue.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Pass3bVerifier$InstructionContextQueue.java
new file mode 100644
index 0000000..4d835d9
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Pass3bVerifier$InstructionContextQueue.java
@@ -0,0 +1,50 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+public final class Pass3bVerifier$InstructionContextQueue {
+
+ public List ecs;
+
+ public List ics = new Vector();
+
+ public Pass3bVerifier$InstructionContextQueue(Pass3bVerifier$1 pass3bVerifier$1) {
+ this();
+ }
+
+ public ArrayList getEC(int value) {
+ return (ArrayList) this.ecs.get(value);
+ }
+
+ public int size() {
+ return this.ics.size();
+ }
+
+ public InstructionContext getIC(int value) {
+ return (InstructionContext) this.ics.get(value);
+ }
+
+ public Pass3bVerifier$InstructionContextQueue() {
+ this.ecs = new Vector();
+ }
+
+ public boolean isEmpty() {
+ return this.ics.isEmpty();
+ }
+
+ public void add(InstructionContext instructionContext, ArrayList values) {
+ this.ics.add(instructionContext);
+ this.ecs.add(values);
+ }
+
+ public void remove(int value) {
+ this.ics.remove(value);
+ this.ecs.remove(value);
+ }
+
+ public void remove() {
+ this.remove(0);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/Pass3bVerifier.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Pass3bVerifier.java
new file mode 100644
index 0000000..ed18fc5
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Pass3bVerifier.java
@@ -0,0 +1,273 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.Repository;
+import com.allatori.lib.bcel.classfile.JavaClass;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ConstantPoolGen;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.JsrInstruction;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.generic.ObjectType;
+import com.allatori.lib.bcel.generic.RET;
+import com.allatori.lib.bcel.generic.ReturnInstruction;
+import com.allatori.lib.bcel.generic.ReturnaddressType;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.lib.bcel.verifier.PassVerifier;
+import com.allatori.lib.bcel.verifier.VerificationResult;
+import com.allatori.lib.bcel.verifier.Verifier;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import com.allatori.lib.bcel.verifier.exc.VerifierConstraintViolatedException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Random;
+
+public final class Pass3bVerifier extends PassVerifier {
+
+ public Verifier myOwner;
+
+ public static final boolean DEBUG = true;
+
+ public int method_no;
+
+ @Override
+ public VerificationResult getVerificationResult() {
+ if (!this.myOwner.doPass3a(this.method_no).equals(VerificationResult.VERIFICATION_RESULT2)) {
+ return VerificationResult.VERIFICATION_RESULT;
+ }
+ JavaClass javaClass;
+ try {
+ javaClass = Repository.lookupClass(this.myOwner.getClassName());
+ } catch (ClassNotFoundException classNotFoundException) {
+ throw new AssertionViolatedException(("Missing class: " + classNotFoundException.toString()));
+ }
+ ConstantPoolGen constantPoolGen = new ConstantPoolGen(javaClass.getConstantPool());
+ InstConstraintVisitor instConstraintVisitor;
+ (instConstraintVisitor = new InstConstraintVisitor()).setConstantPoolGen(constantPoolGen);
+ ExecutionVisitor executionVisitor = new ExecutionVisitor();
+ executionVisitor.setConstantPoolGen(constantPoolGen);
+ Method[] methods = javaClass.getMethods();
+ try {
+ MethodGen methodGen =
+ new MethodGen(methods[this.method_no], this.myOwner.getClassName(), constantPoolGen);
+ instConstraintVisitor.setMethodGen(methodGen);
+ if (!methodGen.isEnabled15() && !methodGen.isEnabled14()) {
+ ControlFlowGraph controlFlowGraph;
+ Frame frame;
+ MethodGen methodGen2;
+ label68:
+ {
+ controlFlowGraph = new ControlFlowGraph(methodGen);
+ frame = new Frame(methodGen.getCount(), methodGen.getCount2());
+ if (!methodGen.isEnabled11()) {
+ if (methodGen.getName().equals("")) {
+ Frame._this = new UninitializedObjectType(new ObjectType(javaClass.getText2()));
+ methodGen2 = methodGen;
+ frame.getLocals().set(0, Frame._this);
+ break label68;
+ }
+ Frame._this = null;
+ LocalVariables locals = frame.getLocals();
+ locals.set(0, new ObjectType(javaClass.getText2()));
+ }
+ methodGen2 = methodGen;
+ }
+ Type[] argumentTypes = methodGen2.getArgumentTypes();
+ int value = 0;
+ int value2;
+ for (int value3 = value2 = 0; value3 < argumentTypes.length; value3 = ++value2) {
+ if (argumentTypes[value2] == Type.SHORT
+ || argumentTypes[value2] == Type.BYTE
+ || argumentTypes[value2] == Type.CHAR
+ || argumentTypes[value2] == Type.BOOLEAN) {
+ argumentTypes[value2] = Type.INT;
+ }
+ frame
+ .getLocals()
+ .set(value + value2 + (methodGen.isEnabled11() ? 0 : 1), argumentTypes[value2]);
+ if (argumentTypes[value2].getSize() == 2) {
+ LocalVariables locals2 = frame.getLocals();
+ locals2.set(++value + value2 + (methodGen.isEnabled11() ? 0 : 1), Type.UNKNOWN);
+ }
+ }
+ this.circulationPump(
+ controlFlowGraph,
+ controlFlowGraph.contextOf(methodGen.getInstructionList().getStart()),
+ frame,
+ instConstraintVisitor,
+ executionVisitor);
+ }
+ } catch (VerifierConstraintViolatedException verifierConstraintViolatedException) {
+ verifierConstraintViolatedException.extendMessage(
+ "Constraint violated in method '" + methods[this.method_no] + "':\n", "");
+ return new VerificationResult(2, verifierConstraintViolatedException.getMessage());
+ } catch (RuntimeException runtimeException) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(stringWriter);
+ runtimeException.printStackTrace(printWriter);
+ throw new AssertionViolatedException(
+ ("Some RuntimeException occured while verify()ing class '"
+ + javaClass.getText2()
+ + "', method '"
+ + methods[this.method_no]
+ + "'. Original RuntimeException's stack trace:\n---\n"
+ + stringWriter
+ + "---\n"));
+ }
+ return VerificationResult.VERIFICATION_RESULT2;
+ }
+
+ public Pass3bVerifier(Verifier verifier, int method_no) {
+ super();
+ this.myOwner = verifier;
+ this.method_no = method_no;
+ }
+
+ public int getMethodNo() {
+ return this.method_no;
+ }
+
+ public void circulationPump(
+ ControlFlowGraph controlFlowGraph,
+ InstructionContext instructionContext,
+ Frame frame,
+ InstConstraintVisitor instConstraintVisitor,
+ ExecutionVisitor executionVisitor) {
+ InstructionContext instructionContext2;
+ new Random();
+ Pass3bVerifier$InstructionContextQueue pass3bVerifier$InstructionContextQueue =
+ new Pass3bVerifier$InstructionContextQueue(null);
+ instructionContext.execute(frame, new ArrayList(), instConstraintVisitor, executionVisitor);
+ pass3bVerifier$InstructionContextQueue.add(instructionContext, new ArrayList());
+ while (!pass3bVerifier$InstructionContextQueue.isEmpty()) {
+ InstructionContext iC = pass3bVerifier$InstructionContextQueue.getIC(0);
+ ArrayList eC = pass3bVerifier$InstructionContextQueue.getEC(0);
+ pass3bVerifier$InstructionContextQueue.remove(0);
+ ArrayList values = (ArrayList) eC.clone();
+ ArrayList values2;
+ (values2 = (ArrayList) eC.clone()).add(iC);
+ if (!(iC.getInstruction().getInstruction() instanceof RET)) {
+ InstructionContext[] successors = iC.getSuccessors();
+ int value;
+ for (int value2 = value = 0; value2 < successors.length; value2 = ++value) {
+ InstructionContext instructionContext3;
+ if ((instructionContext3 = successors[value])
+ .execute(iC.getOutFrame(values), values2, instConstraintVisitor, executionVisitor)) {
+ pass3bVerifier$InstructionContextQueue.add(
+ instructionContext3, (ArrayList) values2.clone());
+ }
+ }
+ } else {
+ RET rET = (RET) iC.getInstruction().getInstruction();
+ ReturnaddressType returnaddressType =
+ (ReturnaddressType) iC.getOutFrame(values).getLocals().get(rET.getIndex());
+ InstructionContext instructionContext4 =
+ controlFlowGraph.contextOf(returnaddressType.getTarget());
+ InstructionContext instructionContext5 = null;
+ int value3 = 0;
+ int value4;
+ int value5 = value4 = values.size() - 1;
+ while (true) {
+ if (value5 < 0) {
+ instructionContext2 = instructionContext5;
+ break;
+ }
+ if (value3 < 0) {
+ throw new AssertionViolatedException("More RET than JSR in execution chain?!");
+ }
+ if (((InstructionContext) values.get(value4)).getInstruction().getInstruction()
+ instanceof JsrInstruction) {
+ if (value3 == 0) {
+ instructionContext2 = instructionContext5 = (InstructionContext) values.get(value4);
+ break;
+ }
+ value3--;
+ }
+ if (((InstructionContext) values.get(value4)).getInstruction().getInstruction()
+ instanceof RET) {
+ value3++;
+ }
+ value5 = --value4;
+ }
+ if (instructionContext2 == null) {
+ throw new AssertionViolatedException(
+ ("RET without a JSR before in ExecutionChain?! EC: '" + values + "'."));
+ }
+ JsrInstruction jsrInstruction =
+ (JsrInstruction) instructionContext5.getInstruction().getInstruction();
+ if (instructionContext4 != controlFlowGraph.contextOf(jsrInstruction.physicalSuccessor())) {
+ throw new AssertionViolatedException(
+ ("RET '"
+ + iC.getInstruction()
+ + "' info inconsistent: jump back to '"
+ + instructionContext4
+ + "' or '"
+ + controlFlowGraph.contextOf(jsrInstruction.physicalSuccessor())
+ + "'?"));
+ }
+ if (instructionContext4.execute(
+ iC.getOutFrame(values), values2, instConstraintVisitor, executionVisitor)) {
+ pass3bVerifier$InstructionContextQueue.add(
+ instructionContext4, (ArrayList) values2.clone());
+ }
+ }
+ ExceptionHandler[] exceptionHandlers = iC.getExceptionHandlers();
+ int value6;
+ for (int value7 = value6 = 0; value7 < exceptionHandlers.length; value7 = ++value6) {
+ InstructionContext instructionContext6;
+ if ((instructionContext6 =
+ controlFlowGraph.contextOf(exceptionHandlers[value6].getHandlerStart()))
+ .execute(
+ new Frame(
+ iC.getOutFrame(values).getLocals(),
+ new OperandStack(
+ iC.getOutFrame(values).getStack().maxStack(),
+ exceptionHandlers[value6].getExceptionType() == null
+ ? Type.THROWABLE
+ : exceptionHandlers[value6].getExceptionType())),
+ new ArrayList(),
+ instConstraintVisitor,
+ executionVisitor)) {
+ pass3bVerifier$InstructionContextQueue.add(instructionContext6, new ArrayList());
+ }
+ }
+ }
+ InstructionHandle instruction = instructionContext.getInstruction();
+ do {
+ if (instruction.getInstruction() instanceof ReturnInstruction
+ && !controlFlowGraph.isDead(instruction)) {
+ Frame frame2;
+ InstructionContext instructionContext7;
+ LocalVariables locals =
+ (frame2 =
+ (instructionContext7 = controlFlowGraph.contextOf(instruction))
+ .getOutFrame(new ArrayList()))
+ .getLocals();
+ int value8;
+ for (int value9 = value8 = 0; value9 < locals.getLocals(); value9 = ++value8) {
+ if (locals.get(value8) instanceof UninitializedObjectType) {
+ this.addMessage(
+ "Warning: ReturnInstruction '"
+ + instructionContext7
+ + "' may leave method with an uninitialized object in the local variables array"
+ + " '"
+ + locals
+ + "'.");
+ }
+ }
+ OperandStack stack = frame2.getStack();
+ int value10;
+ for (int value11 = value10 = 0; value11 < stack.size(); value11 = ++value10) {
+ if (stack.peek(value10) instanceof UninitializedObjectType) {
+ this.addMessage(
+ "Warning: ReturnInstruction '"
+ + instructionContext7
+ + "' may leave method with an uninitialized object on the operand stack '"
+ + stack
+ + "'.");
+ }
+ }
+ }
+ } while ((instruction = instruction.getInstructionHandle2()) != null);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/Subroutine.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Subroutine.java
new file mode 100644
index 0000000..50d6290
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Subroutine.java
@@ -0,0 +1,20 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.generic.InstructionHandle;
+
+public interface Subroutine {
+
+ int[] getCounts();
+
+ boolean contains(InstructionHandle instructionHandle);
+
+ InstructionHandle getLeavingRET();
+
+ Subroutine[] subSubs();
+
+ int[] getCounts2();
+
+ InstructionHandle[] getInstructionHandles();
+
+ InstructionHandle[] getInstructionHandles2();
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/Subroutines$SubroutineImpl.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Subroutines$SubroutineImpl.java
new file mode 100644
index 0000000..35f7ec4
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Subroutines$SubroutineImpl.java
@@ -0,0 +1,236 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.generic.ASTORE;
+import com.allatori.lib.bcel.generic.IndexedInstruction;
+import com.allatori.lib.bcel.generic.Instruction;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.JsrInstruction;
+import com.allatori.lib.bcel.generic.LocalVariableInstruction;
+import com.allatori.lib.bcel.generic.RET;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import com.allatori.lib.bcel.verifier.exc.StructuralCodeConstraintException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class Subroutines$SubroutineImpl implements Subroutine {
+
+ public int localVariable;
+
+ public Set theJSRs;
+
+ public final Subroutines this$0;
+
+ public Set instructions;
+
+ public static final int UNSET = -1;
+
+ public InstructionHandle theRET;
+
+ public void setLeavingRET() {
+ if (this.localVariable == -1) {
+ throw new AssertionViolatedException(
+ "setLeavingRET() called for top-level 'subroutine' or forgot to set local variable"
+ + " first.");
+ }
+ Iterator iterator2 = this.instructions.iterator();
+ InstructionHandle instructionHandle = null;
+ while (iterator2.hasNext()) {
+ InstructionHandle instructionHandle2;
+ if ((instructionHandle2 = (InstructionHandle) iterator2.next()).getInstruction()
+ instanceof RET) {
+ if (instructionHandle != null) {
+ throw new StructuralCodeConstraintException(
+ ("Subroutine with more then one RET detected: '"
+ + instructionHandle
+ + "' and '"
+ + instructionHandle2
+ + "'."));
+ }
+ instructionHandle = instructionHandle2;
+ }
+ }
+ if (instructionHandle == null) {
+ throw new StructuralCodeConstraintException("Subroutine without a RET detected.");
+ }
+ if (((RET) instructionHandle.getInstruction()).getIndex() != this.localVariable) {
+ throw new StructuralCodeConstraintException(
+ ("Subroutine uses '"
+ + instructionHandle
+ + "' which does not match the correct local variable '"
+ + this.localVariable
+ + "'."));
+ }
+ this.theRET = instructionHandle;
+ }
+
+ @Override
+ public InstructionHandle[] getInstructionHandles() {
+ if (this == this.this$0.TOPLEVEL) {
+ throw new AssertionViolatedException(
+ "getLeavingRET() called on top level pseudo-subroutine.");
+ }
+ InstructionHandle[] instructionHandles = new InstructionHandle[this.theJSRs.size()];
+ return (InstructionHandle[]) this.theJSRs.toArray(instructionHandles);
+ }
+
+ @Override
+ public InstructionHandle[] getInstructionHandles2() {
+ InstructionHandle[] instructionHandles = new InstructionHandle[this.instructions.size()];
+ return (InstructionHandle[]) this.instructions.toArray(instructionHandles);
+ }
+
+ public void setLocalVariable(int localVariable) {
+ if (this.localVariable != -1) {
+ throw new AssertionViolatedException("localVariable set twice.");
+ }
+ this.localVariable = localVariable;
+ }
+
+ public void _getRecursivelyAccessedLocalsIndicesHelper(Set values, Subroutine[] subroutines) {
+ int value;
+ for (int value2 = value = 0; value2 < subroutines.length; value2 = ++value) {
+ int[] counts2 = subroutines[value].getCounts2();
+ int value3;
+ for (int value4 = value3 = 0; value4 < counts2.length; value4 = value3) {
+ values.add(new Integer(counts2[value3++]));
+ }
+ if (subroutines[value].subSubs().length != 0) {
+ this._getRecursivelyAccessedLocalsIndicesHelper(values, subroutines[value].subSubs());
+ }
+ }
+ }
+
+ public static Set access$100(Subroutines$SubroutineImpl subroutines$SubroutineImpl) {
+ return subroutines$SubroutineImpl.theJSRs;
+ }
+
+ @Override
+ public boolean contains(InstructionHandle instructionHandle) {
+ return this.instructions.contains(instructionHandle);
+ }
+
+ @Override
+ public int[] getCounts() {
+ HashSet values = new HashSet();
+ int[] counts2 = this.getCounts2();
+ int value;
+ for (int value2 = value = 0; value2 < counts2.length; value2 = value) {
+ values.add(new Integer(counts2[value++]));
+ }
+ this._getRecursivelyAccessedLocalsIndicesHelper(values, this.subSubs());
+ int[] values2 = new int[values.size()];
+ Iterator iterator2 = values.iterator();
+ int value3 = -1;
+ for (Iterator iterator3 = iterator2; iterator3.hasNext(); iterator3 = iterator2) {
+ values2[++value3] = (Integer) iterator2.next();
+ }
+ return values2;
+ }
+
+ public static InstructionHandle access$200(
+ Subroutines$SubroutineImpl subroutines$SubroutineImpl) {
+ return subroutines$SubroutineImpl.theRET;
+ }
+
+ public static int access$000(Subroutines$SubroutineImpl subroutines$SubroutineImpl) {
+ return subroutines$SubroutineImpl.localVariable;
+ }
+
+ public Subroutines$SubroutineImpl(Subroutines subroutines) {
+ super();
+ this.this$0 = subroutines;
+ this.localVariable = -1;
+ this.instructions = new HashSet();
+ this.theJSRs = new HashSet();
+ }
+
+ public void addInstruction(InstructionHandle instructionHandle) {
+ if (this.theRET != null) {
+ throw new AssertionViolatedException(
+ "All instructions must have been added before invoking setLeavingRET().");
+ }
+ this.instructions.add(instructionHandle);
+ }
+
+ @Override
+ public Subroutine[] subSubs() {
+ HashSet values = new HashSet();
+ Iterator iterator2 = this.instructions.iterator();
+ while (iterator2.hasNext()) {
+ Instruction instruction;
+ if ((instruction = ((InstructionHandle) iterator2.next()).getInstruction())
+ instanceof JsrInstruction) {
+ InstructionHandle target = ((JsrInstruction) instruction).getTarget();
+ values.add(this.this$0.getSubroutine(target));
+ }
+ }
+ Subroutine[] subroutines = new Subroutine[values.size()];
+ return (Subroutine[]) values.toArray(subroutines);
+ }
+
+ public void addEnteringJsrInstruction(InstructionHandle instructionHandle) {
+ if (instructionHandle == null
+ || !(instructionHandle.getInstruction() instanceof JsrInstruction)) {
+ throw new AssertionViolatedException("Expecting JsrInstruction InstructionHandle.");
+ }
+ if (this.localVariable == -1) {
+ throw new AssertionViolatedException("Set the localVariable first!");
+ }
+ if (this.localVariable
+ != ((ASTORE)
+ ((JsrInstruction) instructionHandle.getInstruction()).getTarget().getInstruction())
+ .getIndex()) {
+ throw new AssertionViolatedException("Setting a wrong JsrInstruction.");
+ }
+ this.theJSRs.add(instructionHandle);
+ }
+
+ @Override
+ public int[] getCounts2() {
+ HashSet values = new HashSet();
+ if (this.theRET == null && this != this.this$0.TOPLEVEL) {
+ throw new AssertionViolatedException(
+ "This subroutine object must be built up completely before calculating accessed locals.");
+ }
+ Iterator iterator2 = this.instructions.iterator();
+ while (iterator2.hasNext()) {
+ InstructionHandle instructionHandle;
+ if ((instructionHandle = (InstructionHandle) iterator2.next()).getInstruction()
+ instanceof LocalVariableInstruction
+ || instructionHandle.getInstruction() instanceof RET) {
+ int index = ((IndexedInstruction) instructionHandle.getInstruction()).getIndex();
+ values.add(new Integer(index));
+ try {
+ if (instructionHandle.getInstruction() instanceof LocalVariableInstruction
+ && ((LocalVariableInstruction) instructionHandle.getInstruction())
+ .getType(null)
+ .getSize()
+ == 2) {
+ values.add(new Integer(index + 1));
+ }
+ } catch (RuntimeException runtimeException) {
+ throw new AssertionViolatedException(
+ "Oops. BCEL did not like NULL as a ConstantPoolGen object.");
+ }
+ }
+ }
+ int[] values2 = new int[values.size()];
+ Iterator iterator3 = values.iterator();
+ int value = -1;
+ for (Iterator iterator4 = iterator3; iterator4.hasNext(); iterator4 = iterator3) {
+ values2[++value] = (Integer) iterator3.next();
+ }
+ return values2;
+ }
+
+ @Override
+ public InstructionHandle getLeavingRET() {
+ if (this == this.this$0.TOPLEVEL) {
+ throw new AssertionViolatedException(
+ "getLeavingRET() called on top level pseudo-subroutine.");
+ } else {
+ return this.theRET;
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/Subroutines.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Subroutines.java
new file mode 100644
index 0000000..da5f983
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/Subroutines.java
@@ -0,0 +1,255 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.generic.ASTORE;
+import com.allatori.lib.bcel.generic.ATHROW;
+import com.allatori.lib.bcel.generic.BranchInstruction;
+import com.allatori.lib.bcel.generic.CodeExceptionGen;
+import com.allatori.lib.bcel.generic.GotoInstruction;
+import com.allatori.lib.bcel.generic.Instruction;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.JsrInstruction;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.generic.RET;
+import com.allatori.lib.bcel.generic.ReturnInstruction;
+import com.allatori.lib.bcel.generic.Select;
+import com.allatori.lib.bcel.verifier.exc.AssertionViolatedException;
+import com.allatori.lib.bcel.verifier.exc.StructuralCodeConstraintException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+public class Subroutines {
+
+ public Map entries;
+
+ public final Subroutine TOPLEVEL;
+
+ public static final Integer INTEGER3 = new Integer(0);
+
+ public static final Integer INTEGER2 = new Integer(1);
+
+ public static final Integer INTEGER = new Integer(2);
+
+ public Subroutine subroutineOf(InstructionHandle instructionHandle) {
+ Iterator iterator2 = this.entries.values().iterator();
+ while (iterator2.hasNext()) {
+ Subroutine subroutine;
+ if ((subroutine = (Subroutine) iterator2.next()).contains(instructionHandle)) {
+ return subroutine;
+ }
+ }
+ System.err.println("DEBUG: Please verify '" + instructionHandle + "' lies in dead code.");
+ return null;
+ }
+
+ public static InstructionHandle[] getSuccessors(InstructionHandle instructionHandle) {
+ InstructionHandle[] instructionHandles = new InstructionHandle[0];
+ InstructionHandle[] instructionHandles2 = new InstructionHandle[1];
+ InstructionHandle[] instructionHandles3 = new InstructionHandle[2];
+ Instruction instruction;
+ if ((instruction = instructionHandle.getInstruction()) instanceof RET) {
+ return instructionHandles;
+ }
+ if (instruction instanceof ReturnInstruction) {
+ return instructionHandles;
+ }
+ if (instruction instanceof ATHROW) {
+ return instructionHandles;
+ }
+ if (instruction instanceof JsrInstruction) {
+ instructionHandles2[0] = instructionHandle.getInstructionHandle2();
+ return instructionHandles2;
+ }
+ if (instruction instanceof GotoInstruction) {
+ instructionHandles2[0] = ((GotoInstruction) instruction).getTarget();
+ return instructionHandles2;
+ }
+ if (instruction instanceof BranchInstruction) {
+ if (instruction instanceof Select) {
+ InstructionHandle[] instructionHandles4;
+ InstructionHandle[] instructionHandles5;
+ (instructionHandles5 =
+ new InstructionHandle
+ [(instructionHandles4 = ((Select) instruction).getTargets()).length + 1])
+ [0] =
+ ((Select) instruction).getTarget();
+ System.arraycopy(
+ instructionHandles4, 0, instructionHandles5, 1, instructionHandles4.length);
+ return instructionHandles5;
+ } else {
+ instructionHandles3[0] = instructionHandle.getInstructionHandle2();
+ instructionHandles3[1] = ((BranchInstruction) instruction).getTarget();
+ return instructionHandles3;
+ }
+ } else {
+ instructionHandles2[0] = instructionHandle.getInstructionHandle2();
+ return instructionHandles2;
+ }
+ }
+
+ public Subroutines(MethodGen methodGen) {
+ super();
+ this.entries = new HashMap();
+ InstructionHandle[] instructionHandles = methodGen.getInstructionList().getInstructionHandles();
+ CodeExceptionGen[] exceptionHandlers = methodGen.getExceptionHandlers();
+ this.TOPLEVEL = new Subroutines$SubroutineImpl(this);
+ HashSet values2 = new HashSet();
+ int value;
+ for (int value2 = value = 0; value2 < instructionHandles.length; value2 = ++value) {
+ Instruction instruction;
+ if ((instruction = instructionHandles[value].getInstruction()) instanceof JsrInstruction) {
+ values2.add(((JsrInstruction) instruction).getTarget());
+ }
+ }
+ Iterator iterator2;
+ Iterator iterator3 = iterator2 = values2.iterator();
+ while (iterator3.hasNext()) {
+ Subroutines$SubroutineImpl subroutines$SubroutineImpl = new Subroutines$SubroutineImpl(this);
+ InstructionHandle instructionHandle = (InstructionHandle) iterator2.next();
+ subroutines$SubroutineImpl.setLocalVariable(
+ ((ASTORE) instructionHandle.getInstruction()).getIndex());
+ iterator3 = iterator2;
+ this.entries.put(instructionHandle, subroutines$SubroutineImpl);
+ }
+ this.entries.put(instructionHandles[0], this.TOPLEVEL);
+ values2.add(instructionHandles[0]);
+ int value3 = 0;
+ for (int value4 = value3; value4 < instructionHandles.length; value4 = ++value3) {
+ Instruction instruction2;
+ if ((instruction2 = instructionHandles[value3].getInstruction()) instanceof JsrInstruction) {
+ InstructionHandle target = ((JsrInstruction) instruction2).getTarget();
+ ((Subroutines$SubroutineImpl) this.getSubroutine(target))
+ .addEnteringJsrInstruction(instructionHandles[value3]);
+ }
+ }
+ HashSet values3 = new HashSet();
+ HashMap entries2 = new HashMap();
+ for (InstructionHandle instructionHandle2 :
+ ((Iterable) ((Iterable>) values2))) {
+ int value5;
+ for (int value6 = value5 = 0; value6 < instructionHandles.length; value6 = value5) {
+ int value7 = value5;
+ value5++;
+ entries2.put(instructionHandles[value7], INTEGER3);
+ }
+ entries2.put(instructionHandle2, INTEGER2);
+ ArrayList values4;
+ (values4 = new ArrayList()).add(instructionHandle2);
+ int value8;
+ if (instructionHandle2 == instructionHandles[0]) {
+ for (int value9 = value8 = 0; value9 < exceptionHandlers.length; value9 = value8) {
+ entries2.put(exceptionHandlers[value8].getInstructionHandle3(), INTEGER2);
+ int value10 = value8;
+ ArrayList values5 = values4;
+ value8++;
+ values5.add(exceptionHandlers[value10].getInstructionHandle3());
+ }
+ }
+ for (ArrayList values6 = values4; values6.size() != 0; values6 = values4) {
+ InstructionHandle instructionHandle3;
+ InstructionHandle[] successors =
+ getSuccessors(instructionHandle3 = (InstructionHandle) values4.remove(0));
+ int value11;
+ for (int value12 = value11 = 0; value12 < successors.length; value12 = ++value11) {
+ if ((Integer) entries2.get(successors[value11]) == INTEGER3) {
+ entries2.put(successors[value11], INTEGER2);
+ values4.add(successors[value11]);
+ }
+ }
+ entries2.put(instructionHandle3, INTEGER);
+ }
+ int value13;
+ for (int value14 = value13 = 0; value14 < instructionHandles.length; value14 = ++value13) {
+ if (entries2.get(instructionHandles[value13]) == INTEGER) {
+ ((Subroutines$SubroutineImpl)
+ (instructionHandle2 == instructionHandles[0]
+ ? this.getTopLevel()
+ : this.getSubroutine(instructionHandle2)))
+ .addInstruction(instructionHandles[value13]);
+ if (values3.contains(instructionHandles[value13])) {
+ throw new StructuralCodeConstraintException(
+ ("Instruction '"
+ + instructionHandles[value13]
+ + "' is part of more than one subroutine (or of the top level and a"
+ + " subroutine)."));
+ }
+ values3.add(instructionHandles[value13]);
+ }
+ }
+ if (instructionHandle2 != instructionHandles[0]) {
+ ((Subroutines$SubroutineImpl) this.getSubroutine(instructionHandle2)).setLeavingRET();
+ }
+ }
+ InstructionHandle instructionHandle4;
+ int value15;
+ for (int value16 = value15 = 0; value16 < exceptionHandlers.length; value16 = ++value15) {
+ for (InstructionHandle instructionHandle5 =
+ instructionHandle4 = exceptionHandlers[value15].getInstructionHandle2();
+ instructionHandle5
+ != exceptionHandlers[value15].getInstructionHandle().getInstructionHandle2();
+ instructionHandle5 = instructionHandle4 = instructionHandle4.getInstructionHandle2()) {
+ Iterator iterator4 = this.entries.values().iterator();
+ while (iterator4.hasNext()) {
+ Subroutine subroutine;
+ if ((subroutine = (Subroutine) iterator4.next())
+ != this.entries.get(instructionHandles[0])
+ && subroutine.contains(instructionHandle4)) {
+ throw new StructuralCodeConstraintException(
+ ("Subroutine instruction '"
+ + instructionHandle4
+ + "' is protected by an exception handler, '"
+ + exceptionHandlers[value15]
+ + "'. This is forbidden by the JustIce verifier due to its clear definition of"
+ + " subroutines."));
+ }
+ }
+ }
+ }
+ this.noRecursiveCalls(this.getTopLevel(), new HashSet());
+ }
+
+ public Subroutine getSubroutine(InstructionHandle instructionHandle) {
+ Subroutine subroutine;
+ if ((subroutine = (Subroutine) this.entries.get(instructionHandle)) == null) {
+ throw new AssertionViolatedException(
+ "Subroutine requested for an InstructionHandle that is not a leader of a subroutine.");
+ } else if (subroutine == this.TOPLEVEL) {
+ throw new AssertionViolatedException(
+ "TOPLEVEL special subroutine requested; use getTopLevel().");
+ } else {
+ return subroutine;
+ }
+ }
+
+ public void noRecursiveCalls(Subroutine subroutine, Set values) {
+ Subroutine[] subroutines = subroutine.subSubs();
+ int value;
+ for (int value2 = value = 0; value2 < subroutines.length; value2 = value) {
+ int index = ((RET) subroutines[value].getLeavingRET().getInstruction()).getIndex();
+ if (!values.add(new Integer(index))) {
+ Subroutines$SubroutineImpl subroutines$SubroutineImpl =
+ (Subroutines$SubroutineImpl) subroutines[value];
+ throw new StructuralCodeConstraintException(
+ ("Subroutine with local variable '"
+ + Subroutines$SubroutineImpl.access$000(subroutines$SubroutineImpl)
+ + "', JSRs '"
+ + Subroutines$SubroutineImpl.access$100(subroutines$SubroutineImpl)
+ + "', RET '"
+ + Subroutines$SubroutineImpl.access$200(subroutines$SubroutineImpl)
+ + "' is called by a subroutine which uses the same local variable index as itself;"
+ + " maybe even a recursive call? JustIce's clean definition of a subroutine forbids"
+ + " both."));
+ }
+ this.noRecursiveCalls(subroutines[value], values);
+ value++;
+ values.remove(new Integer(index));
+ }
+ }
+
+ public Subroutine getTopLevel() {
+ return this.TOPLEVEL;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/structurals/UninitializedObjectType.java b/src/main/java/com/allatori/lib/bcel/verifier/structurals/UninitializedObjectType.java
new file mode 100644
index 0000000..22446ba
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/structurals/UninitializedObjectType.java
@@ -0,0 +1,31 @@
+package com.allatori.lib.bcel.verifier.structurals;
+
+import com.allatori.lib.bcel.Constants;
+import com.allatori.lib.bcel.generic.ObjectType;
+import com.allatori.lib.bcel.generic.ReferenceType;
+
+public class UninitializedObjectType extends ReferenceType implements Constants {
+
+ public ObjectType initialized;
+
+ @Override
+ public int hashCode() {
+ return this.initialized.hashCode();
+ }
+
+ public ObjectType getInitialized() {
+ return this.initialized;
+ }
+
+ @Override
+ public boolean equals(Object result) {
+ return !(result instanceof UninitializedObjectType)
+ ? false
+ : this.initialized.equals(((UninitializedObjectType) result).initialized);
+ }
+
+ public UninitializedObjectType(ObjectType objectType) {
+ super((byte) 15, (""));
+ this.initialized = objectType;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierActionListener.java b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierActionListener.java
new file mode 100644
index 0000000..facded8
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierActionListener.java
@@ -0,0 +1,20 @@
+package com.allatori.lib.bcel.verifier.ui;
+
+import com.allatori.lib.bcel.verifier.VerifierAppFrame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class VerifierActionListener implements ActionListener {
+
+ public final VerifierAppFrame verifierAppFrame;
+
+ @Override
+ public void actionPerformed(ActionEvent actionEvent) {
+ this.verifierAppFrame.aboutMenuItem_actionPerformed(actionEvent);
+ }
+
+ public VerifierActionListener(VerifierAppFrame verifierAppFrame2) {
+ super();
+ this.verifierAppFrame = verifierAppFrame2;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierActionListener2.java b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierActionListener2.java
new file mode 100644
index 0000000..c703613
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierActionListener2.java
@@ -0,0 +1,20 @@
+package com.allatori.lib.bcel.verifier.ui;
+
+import com.allatori.lib.bcel.verifier.VerifierAppFrame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class VerifierActionListener2 implements ActionListener {
+
+ public final VerifierAppFrame verifierAppFrame;
+
+ @Override
+ public void actionPerformed(ActionEvent actionEvent) {
+ this.verifierAppFrame.whatisMenuItem_actionPerformed(actionEvent);
+ }
+
+ public VerifierActionListener2(VerifierAppFrame verifierAppFrame2) {
+ super();
+ this.verifierAppFrame = verifierAppFrame2;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierActionListener3.java b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierActionListener3.java
new file mode 100644
index 0000000..e65583f
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierActionListener3.java
@@ -0,0 +1,20 @@
+package com.allatori.lib.bcel.verifier.ui;
+
+import com.allatori.lib.bcel.verifier.VerifierAppFrame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class VerifierActionListener3 implements ActionListener {
+
+ public final VerifierAppFrame verifierAppFrame;
+
+ @Override
+ public void actionPerformed(ActionEvent actionEvent) {
+ this.verifierAppFrame.newFileMenuItem_actionPerformed(actionEvent);
+ }
+
+ public VerifierActionListener3(VerifierAppFrame verifierAppFrame2) {
+ super();
+ this.verifierAppFrame = verifierAppFrame2;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierSelectionListener.java b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierSelectionListener.java
new file mode 100644
index 0000000..50eb52f
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierSelectionListener.java
@@ -0,0 +1,20 @@
+package com.allatori.lib.bcel.verifier.ui;
+
+import com.allatori.lib.bcel.verifier.VerifierAppFrame;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+public class VerifierSelectionListener implements ListSelectionListener {
+
+ public final VerifierAppFrame verifierAppFrame;
+
+ public VerifierSelectionListener(VerifierAppFrame verifierAppFrame2) {
+ super();
+ this.verifierAppFrame = verifierAppFrame2;
+ }
+
+ @Override
+ public void valueChanged(ListSelectionEvent listSelectionEvent) {
+ this.verifierAppFrame.pass3bJList_valueChanged(listSelectionEvent);
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierSelectionListener2.java b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierSelectionListener2.java
new file mode 100644
index 0000000..2e50e41
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierSelectionListener2.java
@@ -0,0 +1,20 @@
+package com.allatori.lib.bcel.verifier.ui;
+
+import com.allatori.lib.bcel.verifier.VerifierAppFrame;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+public class VerifierSelectionListener2 implements ListSelectionListener {
+
+ public final VerifierAppFrame verifierAppFrame;
+
+ @Override
+ public void valueChanged(ListSelectionEvent listSelectionEvent) {
+ this.verifierAppFrame.pass3aJList_valueChanged(listSelectionEvent);
+ }
+
+ public VerifierSelectionListener2(VerifierAppFrame verifierAppFrame2) {
+ super();
+ this.verifierAppFrame = verifierAppFrame2;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierSelectionListener3.java b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierSelectionListener3.java
new file mode 100644
index 0000000..89e7c86
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierSelectionListener3.java
@@ -0,0 +1,20 @@
+package com.allatori.lib.bcel.verifier.ui;
+
+import com.allatori.lib.bcel.verifier.VerifierAppFrame;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+public class VerifierSelectionListener3 implements ListSelectionListener {
+
+ public final VerifierAppFrame verifierAppFrame;
+
+ @Override
+ public void valueChanged(ListSelectionEvent listSelectionEvent) {
+ this.verifierAppFrame.classNamesJList_valueChanged(listSelectionEvent);
+ }
+
+ public VerifierSelectionListener3(VerifierAppFrame verifierAppFrame2) {
+ super();
+ this.verifierAppFrame = verifierAppFrame2;
+ }
+}
diff --git a/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierWindowListener.java b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierWindowListener.java
new file mode 100644
index 0000000..4cb0661
--- /dev/null
+++ b/src/main/java/com/allatori/lib/bcel/verifier/ui/VerifierWindowListener.java
@@ -0,0 +1,16 @@
+package com.allatori.lib.bcel.verifier.ui;
+
+import com.allatori.lib.bcel.verifier.VerifyDialog;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+public class VerifierWindowListener extends WindowAdapter {
+
+ @Override
+ public void windowClosing(WindowEvent windowEvent) {
+ VerifyDialog.calculateCount();
+ if (VerifyDialog.getClasses_to_verify() == 0) {
+ System.exit(0);
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/model/ClassStorage.java b/src/main/java/com/allatori/model/ClassStorage.java
new file mode 100644
index 0000000..5c6ce9e
--- /dev/null
+++ b/src/main/java/com/allatori/model/ClassStorage.java
@@ -0,0 +1,99 @@
+package com.allatori.model;
+
+import com.allatori.io.ClassStorageClassLoader;
+import com.allatori.lib.bcel.generic.ClassGen;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Vector;
+
+public class ClassStorage {
+
+ public Hashtable classesByName;
+
+ public Hashtable classEntryNames;
+
+ public Vector inputClasses;
+
+ public ClassLoader classLoader;
+
+ public Hashtable entryPrefixes;
+
+ public HashSet duplicateClasses;
+
+ public Hashtable sourceFiles;
+
+ public void processText(ClassGen classGen, String text, String text2) {
+ this.processText(classGen, text);
+ this.classEntryNames.put("" + text + '#' + text2, classGen.getClassName());
+ String text3 = "" + classGen.getClassName().replace('.', '/') + ".class";
+ if (text2.endsWith(text3)) {
+ String text4 = text2.substring(0, text2.length() - text3.length());
+ this.entryPrefixes.put("" + text + '#' + classGen.getClassName(), text4);
+ }
+ }
+
+ public void processClassGen(ClassGen classGen) {
+ this.classesByName.put(classGen.getClassName(), classGen);
+ this.inputClasses.add(classGen);
+ }
+
+ public String getText(ClassGen classGen) {
+ return (String) this.sourceFiles.get(classGen.getClassName());
+ }
+
+ public void processText(ClassGen classGen, String text) {
+ if (!"java.lang.Object".equals(classGen.getClassName())) {
+ if (this.classesByName.containsKey(classGen.getClassName())) {
+ this.duplicateClasses.add(classGen);
+ } else {
+ this.classesByName.put(classGen.getClassName(), classGen);
+ this.sourceFiles.put(classGen.getClassName(), text);
+ }
+ }
+ }
+
+ public Vector getInputClasses() {
+ return this.inputClasses;
+ }
+
+ public boolean matchesClassGen(ClassGen classGen) {
+ return this.duplicateClasses.contains(classGen);
+ }
+
+ public int getClassesByName() {
+ return this.classesByName.size();
+ }
+
+ public ClassGen getClassGen(String text) {
+ return (ClassGen) this.classesByName.get(text);
+ }
+
+ public ClassLoader getClassLoader() {
+ return this.classLoader;
+ }
+
+ public Iterator getClassesByName2() {
+ return this.classesByName.values().iterator();
+ }
+
+ public String getText(String text) {
+ return (String) this.classEntryNames.get(text);
+ }
+
+ public ClassStorage(ClassStorageClassLoader classStorageClassLoader) {
+ super();
+ this.classesByName = new Hashtable();
+ this.sourceFiles = new Hashtable();
+ this.duplicateClasses = new HashSet();
+ this.inputClasses = new Vector();
+ this.classEntryNames = new Hashtable();
+ this.entryPrefixes = new Hashtable();
+ this.classLoader = classStorageClassLoader;
+ classStorageClassLoader.setClassStorage(this);
+ }
+
+ public String getText2(String text) {
+ return (String) this.entryPrefixes.get(text);
+ }
+}
diff --git a/src/main/java/com/allatori/model/MethodContext.java b/src/main/java/com/allatori/model/MethodContext.java
new file mode 100644
index 0000000..cc7e998
--- /dev/null
+++ b/src/main/java/com/allatori/model/MethodContext.java
@@ -0,0 +1,39 @@
+package com.allatori.model;
+
+import com.allatori.bytecode.MethodFactory;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.MethodGen;
+
+public class MethodContext {
+
+ public MethodGen methodGen;
+
+ public Method method;
+
+ public ClassGen classGen;
+
+ public static ClassGen getClassGen(MethodContext methodContext) {
+ return methodContext.classGen;
+ }
+
+ public MethodContext(ClassGen classGen2, Method method2) {
+ super();
+ this.classGen = classGen2;
+ this.method = method2;
+ this.methodGen =
+ MethodFactory.createMethodGen(
+ method2,
+ classGen2.getClassName(),
+ classGen2.getConstantPool(),
+ classGen2.getConstantPool().getConstantPool());
+ }
+
+ public static Method getMethod(MethodContext methodContext) {
+ return methodContext.method;
+ }
+
+ public static MethodGen getMethodGen(MethodContext methodContext) {
+ return methodContext.methodGen;
+ }
+}
diff --git a/src/main/java/com/allatori/model/NameMapping.java b/src/main/java/com/allatori/model/NameMapping.java
new file mode 100644
index 0000000..771ebd2
--- /dev/null
+++ b/src/main/java/com/allatori/model/NameMapping.java
@@ -0,0 +1,14 @@
+package com.allatori.model;
+
+public class NameMapping {
+
+ public String text;
+
+ public String text2;
+
+ public NameMapping(String text, String text2) {
+ super();
+ this.text = text;
+ this.text2 = text2;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/ClassNameTable.java b/src/main/java/com/allatori/naming/ClassNameTable.java
new file mode 100644
index 0000000..4983c09
--- /dev/null
+++ b/src/main/java/com/allatori/naming/ClassNameTable.java
@@ -0,0 +1,42 @@
+package com.allatori.naming;
+
+import com.allatori.config.Configuration;
+import com.allatori.naming.generator.NameGenerator;
+import com.allatori.util.LookupTable;
+
+public class ClassNameTable {
+
+ public NameGenerator nameGenerator;
+
+ public LookupTable lookupTable;
+
+ public final NamingContext namingContext;
+
+ public LookupTable lookupTable2;
+
+ public static NameGenerator getNameGenerator(ClassNameTable classNameTable) {
+ return classNameTable.nameGenerator;
+ }
+
+ public ClassNameTable(NamingContext namingContext2) {
+ super();
+ this.namingContext = namingContext2;
+ this.nameGenerator =
+ Configuration.getRenamingOptions().getNameGenerationOptions().createNameGenerator4();
+ this.lookupTable = new LookupTable();
+ this.lookupTable2 = new LookupTable();
+ }
+
+ public static LookupTable getLookupTable(ClassNameTable classNameTable) {
+ return classNameTable.lookupTable2;
+ }
+
+ public static LookupTable getLookupTable2(ClassNameTable classNameTable) {
+ return classNameTable.lookupTable;
+ }
+
+ public ClassNameTable(
+ NamingContext namingContext, NamingConstructorToken namingConstructorToken) {
+ this(namingContext);
+ }
+}
diff --git a/src/main/java/com/allatori/naming/FieldNameTable.java b/src/main/java/com/allatori/naming/FieldNameTable.java
new file mode 100644
index 0000000..defd250
--- /dev/null
+++ b/src/main/java/com/allatori/naming/FieldNameTable.java
@@ -0,0 +1,49 @@
+package com.allatori.naming;
+
+import com.allatori.config.Configuration;
+import com.allatori.naming.generator.NameGenerator;
+import com.allatori.util.LookupTable;
+
+public class FieldNameTable {
+
+ public final NamingContext namingContext;
+
+ public LookupTable lookupTable;
+
+ public NameGenerator nameGenerator;
+
+ public LookupTable lookupTable2;
+
+ public LookupTable lookupTable3;
+
+ public static LookupTable getLookupTable(FieldNameTable fieldNameTable) {
+ return fieldNameTable.lookupTable2;
+ }
+
+ public static LookupTable getLookupTable2(FieldNameTable fieldNameTable) {
+ return fieldNameTable.lookupTable3;
+ }
+
+ public static NameGenerator getNameGenerator(FieldNameTable fieldNameTable) {
+ return fieldNameTable.nameGenerator;
+ }
+
+ public FieldNameTable(NamingContext namingContext2) {
+ super();
+ this.namingContext = namingContext2;
+ this.nameGenerator =
+ Configuration.getRenamingOptions().getNameGenerationOptions().createNameGenerator5();
+ this.lookupTable2 = new LookupTable();
+ this.lookupTable = new LookupTable();
+ this.lookupTable3 = new LookupTable();
+ }
+
+ public FieldNameTable(
+ NamingContext namingContext, NamingConstructorToken namingConstructorToken) {
+ this(namingContext);
+ }
+
+ public static LookupTable getLookupTable3(FieldNameTable fieldNameTable) {
+ return fieldNameTable.lookupTable;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/MappingImportHandler.java b/src/main/java/com/allatori/naming/MappingImportHandler.java
new file mode 100644
index 0000000..8b703ab
--- /dev/null
+++ b/src/main/java/com/allatori/naming/MappingImportHandler.java
@@ -0,0 +1,353 @@
+package com.allatori.naming;
+
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.util.LookupTable;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Vector;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class MappingImportHandler extends DefaultHandler {
+
+ public LookupTable lookupTable;
+
+ public String text;
+
+ public String text2;
+
+ public String text3;
+
+ public String text4;
+
+ public String text5;
+
+ public final NameRenamer nameRenamer;
+
+ public String text6;
+
+ public String text7;
+
+ public String text8;
+
+ public String text9;
+
+ public String text10;
+
+ public String text11;
+
+ public String text12;
+
+ public String text13;
+
+ public String text14;
+
+ public String text15;
+
+ @Override
+ public void startElement(String text16, String text17, String text18, Attributes attributes) {
+ if (this.text15.equals(text18)) {
+ this.text11 = attributes.getValue(this.text8);
+ this.text14 = attributes.getValue(this.text);
+ if (NameRenamer.isEnabled()) {
+ String text22 = NameUtils.getText2(this.text14);
+ if (NameRenamer.getLookupTable().matchesText(text22)) {
+ this.text14 =
+ NameRenamer.getLookupTable().getText(text22) + this.text14.substring(text22.length());
+ }
+ }
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText(this.text11, this.text14);
+ ParameterNameTable.getLookupTable3(
+ NamingContext.getParameterNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText(this.text14, this.text11);
+ this.update3();
+ } else {
+ if (this.text7.equals(text18)) {
+ String value = attributes.getValue(this.text8);
+ String value2 = attributes.getValue(this.text);
+ String text19 = value.substring(0, value.indexOf("("));
+ String text20 = value.substring(value.indexOf("("));
+ MethodNameTable.getLookupTable2(
+ NamingContext.getMethodNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText("" + this.text11 + "&" + text19 + "&" + text20, value2);
+ String text21 = "" + this.text11 + "&" + value2 + "&" + NameUtils.getText(text20);
+ if (MethodNameTable.getLookupTable3(
+ NamingContext.getMethodNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .matchesText(text21)) {
+ this.lookupTable.processText(text21, this.text11);
+ }
+ MethodNameTable.getLookupTable3(
+ NamingContext.getMethodNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText(text21, "&");
+ if (Configuration.getRenamingOptions().isEnabled8() && !value2.equals(text19)) {
+ MethodNameTable.getLookupTable4(
+ NamingContext.getMethodNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText("" + text19 + "&" + NameUtils.getText(text20), value2);
+ return;
+ }
+ } else {
+ if (this.text3.equals(text18)) {
+ String value3 = attributes.getValue(this.text8);
+ String value4 = attributes.getValue(this.text);
+ String text23 = value3.substring(0, value3.indexOf(this.text12));
+ String text24 = value3.substring(value3.indexOf(this.text12) + 1);
+ FieldNameTable.getLookupTable(
+ NamingContext.getFieldNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText("" + this.text11 + "&" + text23 + "&" + text24, value4);
+ FieldNameTable.getLookupTable3(
+ NamingContext.getFieldNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText("" + this.text11 + "&" + value4 + "&" + text24, "&");
+ return;
+ }
+ if (this.text2.equals(text18)) {
+ String value5 = attributes.getValue(this.text8);
+ String value6 = attributes.getValue(this.text);
+ NameRenamer.getNameMappingEntry(this.nameRenamer).processText(value5, value6);
+ return;
+ }
+ if (this.text4.equals(text18)) {
+ Integer value7 = Integer.valueOf(attributes.getValue(this.text10));
+ NameRenamer.getNameMappingEntry(this.nameRenamer).getValues().add(value7);
+ return;
+ }
+ if (this.text13.equals(text18)) {
+ String value8 = attributes.getValue(this.text6);
+ String value9 = attributes.getValue(this.text9);
+ String value10 = attributes.getValue(this.text5);
+ MethodNameTable.getLookupTable5(
+ NamingContext.getMethodNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText("" + value8 + "&" + value9, value10);
+ }
+ }
+ }
+ }
+
+ public void update() {
+ try {
+ Vector vector = new Vector(this.lookupTable.getEntries2());
+ int value;
+ for (int value2 = value = 0; value2 < vector.size(); value2 = ++value) {
+ String text = (String) vector.get(value);
+ String text2 = this.lookupTable.getText(text);
+ ClassGen classGen;
+ if ((classGen = NameRenamer.getClassStorage(this.nameRenamer).getClassGen(text2)) != null) {
+ String[] interfaceNames = classGen.getInterfaceNames();
+ int value3;
+ for (int value4 = value3 = 0; value4 < interfaceNames.length; value4 = value3) {
+ String text3 = interfaceNames[value3];
+ LookupTable lookupTable2 = this.lookupTable;
+ StringBuilder stringBuilder =
+ new StringBuilder().insert(0, text3).append(text.substring(text.indexOf("&")));
+ value3++;
+ lookupTable2.processText(stringBuilder.toString(), text3);
+ }
+ }
+ }
+ Set entries2 = this.lookupTable.getEntries2();
+ Vector vector2 =
+ new Vector(
+ MethodNameTable.getLookupTable2(
+ NamingContext.getMethodNameTable(
+ NameRenamer.getNamingContext(this.nameRenamer)))
+ .getEntries2());
+ for (String text4 : ((Iterable) ((Iterable>) entries2))) {
+ String text5 = this.lookupTable.getText(text4);
+ Iterator iterator2 = vector2.iterator();
+ while (iterator2.hasNext()) {
+ String text6;
+ if ((text6 = (String) iterator2.next()).startsWith(text5)) {
+ String text7 =
+ MethodNameTable.getLookupTable2(
+ NamingContext.getMethodNameTable(
+ NameRenamer.getNamingContext(this.nameRenamer)))
+ .getText(text6);
+ if (text4.substring(text4.indexOf("&") + 1, text4.lastIndexOf("&")).equals(text7)) {
+ String text8 = text4.substring(text4.lastIndexOf("&") + 1);
+ String text9 = text6.substring(text6.lastIndexOf("&") + 1);
+ if (text8.equals(NameUtils.getText(text9))) {
+ MethodNameTable.getLookupTable2(
+ NamingContext.getMethodNameTable(
+ NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText(text6);
+ MethodNameTable.getLookupTable3(
+ NamingContext.getMethodNameTable(
+ NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText(text4);
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception exception) {
+ }
+ }
+
+ public String createText(String text, LookupTable lookupTable) {
+ String text2 = "";
+ while (text.length() > 0) {
+ int value = text.indexOf(76);
+ int value2 = text.indexOf(59);
+ if (value != -1 && value2 != -1 && value < value2) {
+ String text3 = text.substring(value + 1, value2).replace('/', '.');
+ if (lookupTable.getText(text3) != null) {
+ text3 = lookupTable.getText(text3);
+ }
+ String text4 = text3.replace('.', '/');
+ text2 = "" + text2 + text.substring(0, value + 1) + text4 + ";";
+ text = text.substring(value2 + 1);
+ } else {
+ text2 = "" + text2 + text;
+ text = "";
+ }
+ }
+ return text2;
+ }
+
+ public static void processMappingImportHandler(MappingImportHandler mappingImportHandler)
+ throws ParserConfigurationException,
+ SAXException,
+ FileNotFoundException,
+ UnsupportedEncodingException,
+ IOException {
+ mappingImportHandler.update4();
+ }
+
+ public void update2() {
+ for (String text :
+ ((Iterable)
+ ((Iterable>)
+ FieldNameTable.getLookupTable(
+ NamingContext.getFieldNameTable(
+ NameRenamer.getNamingContext(this.nameRenamer)))
+ .getEntries2()))) {
+ String text2;
+ String text3 =
+ this.createText(
+ text2 = text.substring(text.lastIndexOf("&") + 1),
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(
+ NameRenamer.getNamingContext(this.nameRenamer))));
+ if (!text2.equals(text3)) {
+ FieldNameTable.getLookupTable2(
+ NamingContext.getFieldNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText(text2, text3);
+ }
+ }
+ for (String text4 :
+ ((Iterable)
+ ((Iterable>)
+ MethodNameTable.getLookupTable2(
+ NamingContext.getMethodNameTable(
+ NameRenamer.getNamingContext(this.nameRenamer)))
+ .getEntries2()))) {
+ String text5;
+ String text6 =
+ this.createText(
+ text5 = text4.substring(text4.lastIndexOf("&") + 1),
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(
+ NameRenamer.getNamingContext(this.nameRenamer))));
+ if (!text5.equals(text6)) {
+ MethodNameTable.getLookupTable(
+ NamingContext.getMethodNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText(text5, text6);
+ }
+ }
+ }
+
+ public MappingImportHandler(NameRenamer nameRenamer2) {
+ super();
+ this.nameRenamer = nameRenamer2;
+ this.lookupTable = new LookupTable();
+ this.text8 = "old";
+ this.text = "new";
+ this.text15 = "class";
+ this.text7 = "method";
+ this.text3 = "field";
+ this.text2 = "source";
+ this.text4 = "line";
+ this.text10 = "l";
+ this.text13 = "annotation";
+ this.text6 = "oldClassName";
+ this.text9 = "oldMethodName";
+ this.text5 = "newMethodName";
+ this.text12 = " ";
+ }
+
+ public void update3() {
+ String text2 = NameUtils.getText2(this.text11);
+ String text22 = NameUtils.getText2(this.text14);
+ if (!Configuration.getRenamingOptions().isText()
+ || !Configuration.getRenamingOptions().getDefaultPackage().equals(text22)) {
+ int value = 0;
+ int value2;
+ for (int value3 = value2 = text2.length() - 1; value3 > 0; value3 = --value2) {
+ if (text2.charAt(value2) == '.') {
+ value++;
+ }
+ }
+ int value4;
+ for (int value5 = value4 = text22.length() - 1; value5 > 0; value5 = --value4) {
+ if (text22.charAt(value4) == '.') {
+ value--;
+ }
+ }
+ if (value == 0) {
+ ClassNameTable.getLookupTable2(
+ NamingContext.getClassNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText(text2, text22);
+ ClassNameTable.getLookupTable(
+ NamingContext.getClassNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText(text22, "&");
+ String text = text2;
+ while (text.lastIndexOf(46) > 0) {
+ text2 = text2.substring(0, text2.lastIndexOf(46));
+ text22 = text22.substring(0, text22.lastIndexOf(46));
+ LookupTable lookupTable2 =
+ ClassNameTable.getLookupTable2(
+ NamingContext.getClassNameTable(NameRenamer.getNamingContext(this.nameRenamer)));
+ text = text2;
+ lookupTable2.processText(text2, text22);
+ ClassNameTable.getLookupTable(
+ NamingContext.getClassNameTable(NameRenamer.getNamingContext(this.nameRenamer)))
+ .processText(text22, "&");
+ }
+ }
+ }
+ }
+
+ public MappingImportHandler(
+ NameRenamer nameRenamer, NamingConstructorToken namingConstructorToken) {
+ this(nameRenamer);
+ }
+
+ public void update4()
+ throws ParserConfigurationException,
+ SAXException,
+ FileNotFoundException,
+ UnsupportedEncodingException,
+ IOException {
+ XMLReader xMLReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
+ xMLReader.setContentHandler(this);
+ xMLReader.parse(
+ new InputSource(
+ new InputStreamReader(
+ new FileInputStream(Configuration.getRenamingOptions().getIncrementalObfuscation()),
+ "UTF-8")));
+ this.update2();
+ this.update();
+ }
+}
diff --git a/src/main/java/com/allatori/naming/MappingXmlWriter.java b/src/main/java/com/allatori/naming/MappingXmlWriter.java
new file mode 100644
index 0000000..7b1d898
--- /dev/null
+++ b/src/main/java/com/allatori/naming/MappingXmlWriter.java
@@ -0,0 +1,285 @@
+package com.allatori.naming;
+
+import com.allatori.VersionInfo;
+import com.allatori.config.Configuration;
+import com.allatori.model.NameMapping;
+import com.allatori.optimizer.OptimizationStatistics;
+import com.allatori.util.Log;
+import java.io.BufferedWriter;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Vector;
+
+public class MappingXmlWriter {
+
+ public static StringBuilder stringBuilder = new StringBuilder(4096);
+
+ public static void processPrintWriter(PrintWriter printWriter) {
+ printWriter.println("\n");
+ printWriter.println(
+ "\n");
+ if (stringBuilder.length() > 0) {
+ printWriter.println(
+ new StringBuilder().insert(0, "\n").toString());
+ }
+ printWriter.println(
+ "\n");
+ printWriter.println("");
+ }
+
+ public static int calculateCount(Vector vector, String text) {
+ int value = 0;
+ int value2 = vector.size() - 1;
+ while (value <= value2) {
+ int value3 = value + value2 >> 1;
+ int value4;
+ if ((value4 = ((Comparable) vector.get(value3)).compareTo(text)) < 0) {
+ value = value3 + 1;
+ } else {
+ if (value4 <= 0) {
+ return value3;
+ }
+ value2 = value3 - 1;
+ }
+ }
+ return value;
+ }
+
+ public static void processRenamingLog(PrintWriter printWriter, RenamingLog renamingLog) {
+ printWriter.println(" ");
+ Vector vector = new Vector(renamingLog.lookupTable4.getEntries2());
+ Vector vector2 = new Vector(renamingLog.lookupTable5.getEntries2());
+ Vector vector3 = new Vector(renamingLog.lookupTable2.getEntries2());
+ Collections.sort(vector2);
+ Collections.sort(vector3);
+ String text3 = "\" new=\"";
+ String text4 = "\"/>";
+ String text5 = "";
+ String text6 = "";
+ String text7 = " = 0; value2 = value) {
+ String text8 = (String) vector.get(value);
+ printWriter.println(
+ (String) " ");
+ String text9 = "" + text8 + "&";
+ int value3;
+ value2 = value3 = calculateCount(vector2, text9);
+ String text10;
+ while (value2 < vector2.size() && (text10 = (String) vector2.get(value3)).startsWith(text9)) {
+ String text11 = text10.substring(text10.indexOf("&") + 1, text10.lastIndexOf("&"));
+ if (!text5.equals(text11) && !text6.equals(text11)) {
+ String text12 = text10.substring(text10.lastIndexOf("&") + 1);
+ Vector vector4;
+ if (renamingLog.lookupTable3.matchesText(text10)) {
+ vector4 = vector2;
+ printWriter.println(
+ ""
+ + text7
+ + text11
+ + text12
+ + text3
+ + renamingLog.lookupTable5.getText(text10)
+ + renamingLog.lookupTable3.getText(text10)
+ + text4);
+ renamingLog.lookupTable3.processText(text10);
+ } else {
+ printWriter.println(
+ ""
+ + text7
+ + text11
+ + text12
+ + text3
+ + renamingLog.lookupTable5.getText(text10)
+ + text4);
+ vector4 = vector2;
+ }
+ vector4.remove(value3);
+ value2 = value3;
+ } else {
+ vector2.remove(value3);
+ value2 = value3;
+ }
+ }
+ int value4;
+ value2 = value4 = calculateCount(vector3, text9);
+ String text13;
+ while (value2 < vector3.size() && (text13 = (String) vector3.get(value4)).startsWith(text9)) {
+ String text14 = text13.substring(text13.indexOf("&") + 1, text13.lastIndexOf("&"));
+ String text15 = text13.substring(text13.lastIndexOf("&") + 1);
+ value2 = value4;
+ printWriter.println(
+ ""
+ + ((String) " ");
+ }
+ Vector vector5;
+ if ((vector5 = new Vector(renamingLog.lookupTable.getEntries2())).size() > 0) {
+ printWriter.println((String) " ");
+ int value5;
+ for (int value6 = value5 = vector5.size() - 1; value6 >= 0; value6 = --value5) {
+ String text16 = (String) vector5.get(value5);
+ String text17 = renamingLog.lookupTable.getText(text16);
+ String text18 = text16.substring(text16.indexOf("&") + 1);
+ String text19 = text16.substring(0, text16.indexOf("&"));
+ if (!text5.equals(text18) && !text6.equals(text18)) {
+ printWriter.println(
+ ""
+ + ((String) " ");
+ }
+ printWriter.println(" ");
+ int value7;
+ for (int value8 = value7 = renamingLog.values2.size() - 1; value8 >= 0; value8 = value7) {
+ NameMapping nameMapping = (NameMapping) renamingLog.values2.get(value7);
+ StringBuilder stringBuilder =
+ new StringBuilder()
+ .insert(0, (String) " ");
+ printWriter.println(" ");
+ int value9;
+ for (int value10 = value9 = 0; value10 < renamingLog.values.size(); value10 = value9) {
+ StringBuilder stringBuilder2 =
+ new StringBuilder()
+ .insert(0, (String) " ");
+ printWriter.println(" ");
+ }
+
+ public static void update() {
+ String text;
+ if ((text = Configuration.getOutputOptions().getLogFile()) == null) {
+ Log.warn("Log file is not set.");
+ stringBuilder.delete(0, stringBuilder.length());
+ } else {
+ PrintWriter printWriter = null;
+ label90:
+ {
+ label91:
+ {
+ try {
+ try {
+ FileOutputStream fileOutputStream = new FileOutputStream(text);
+ PrintWriter printWriter2 =
+ printWriter =
+ new PrintWriter(
+ new BufferedWriter(
+ new OutputStreamWriter(fileOutputStream, "UTF-8"), 524288));
+ processPrintWriter(printWriter2);
+ processRenamingLog(printWriter2, Configuration.getMappingOptions().renamingLog);
+ processPrintWriter2(printWriter2);
+ printWriter2.flush();
+ break label90;
+ } catch (FileNotFoundException fileNotFoundException) {
+ Log.error("Cannot write log to '" + text + "' file.");
+ } catch (Exception exception) {
+ Log.error("Writing log file failed with exception: " + exception.getMessage());
+ break label91;
+ }
+ } catch (Throwable throwable) {
+ stringBuilder.delete(0, stringBuilder.length());
+ try {
+ printWriter.close();
+ } catch (Exception exception2) {
+ throw throwable;
+ }
+ throw throwable;
+ }
+ stringBuilder.delete(0, stringBuilder.length());
+ try {
+ printWriter.close();
+ return;
+ } catch (Exception exception3) {
+ return;
+ }
+ }
+ stringBuilder.delete(0, stringBuilder.length());
+ try {
+ printWriter.close();
+ return;
+ } catch (Exception exception4) {
+ return;
+ }
+ }
+ stringBuilder.delete(0, stringBuilder.length());
+ try {
+ printWriter.close();
+ } catch (Exception exception5) {
+ }
+ }
+ }
+
+ public static void processPrintWriter2(PrintWriter printWriter) {
+ printWriter.println("");
+ }
+}
diff --git a/src/main/java/com/allatori/naming/MethodNameTable.java b/src/main/java/com/allatori/naming/MethodNameTable.java
new file mode 100644
index 0000000..79c5f67
--- /dev/null
+++ b/src/main/java/com/allatori/naming/MethodNameTable.java
@@ -0,0 +1,63 @@
+package com.allatori.naming;
+
+import com.allatori.config.Configuration;
+import com.allatori.naming.generator.NameGenerator;
+import com.allatori.util.LookupTable;
+
+public class MethodNameTable {
+
+ public LookupTable lookupTable;
+
+ public LookupTable lookupTable2;
+
+ public NameGenerator nameGenerator;
+
+ public LookupTable lookupTable3;
+
+ public final NamingContext namingContext;
+
+ public LookupTable lookupTable4;
+
+ public LookupTable lookupTable5;
+
+ public static LookupTable getLookupTable(MethodNameTable methodNameTable) {
+ return methodNameTable.lookupTable;
+ }
+
+ public static LookupTable getLookupTable2(MethodNameTable methodNameTable) {
+ return methodNameTable.lookupTable3;
+ }
+
+ public MethodNameTable(NamingContext namingContext2) {
+ super();
+ this.namingContext = namingContext2;
+ this.nameGenerator =
+ Configuration.getRenamingOptions().getNameGenerationOptions().createNameGenerator2();
+ this.lookupTable3 = new LookupTable();
+ this.lookupTable4 = new LookupTable();
+ this.lookupTable5 = new LookupTable();
+ this.lookupTable = new LookupTable();
+ this.lookupTable2 = new LookupTable();
+ }
+
+ public static LookupTable getLookupTable3(MethodNameTable methodNameTable) {
+ return methodNameTable.lookupTable5;
+ }
+
+ public static NameGenerator getNameGenerator(MethodNameTable methodNameTable) {
+ return methodNameTable.nameGenerator;
+ }
+
+ public static LookupTable getLookupTable4(MethodNameTable methodNameTable) {
+ return methodNameTable.lookupTable2;
+ }
+
+ public MethodNameTable(
+ NamingContext namingContext, NamingConstructorToken namingConstructorToken) {
+ this(namingContext);
+ }
+
+ public static LookupTable getLookupTable5(MethodNameTable methodNameTable) {
+ return methodNameTable.lookupTable4;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/NameComparator.java b/src/main/java/com/allatori/naming/NameComparator.java
new file mode 100644
index 0000000..5b49835
--- /dev/null
+++ b/src/main/java/com/allatori/naming/NameComparator.java
@@ -0,0 +1,13 @@
+package com.allatori.naming;
+
+import java.util.Comparator;
+
+public class NameComparator implements Comparator {
+
+ @Override
+ public int compare(Object result, Object result2) {
+ String text = (String) result;
+ String text2 = (String) result2;
+ return text.length() - text2.length();
+ }
+}
diff --git a/src/main/java/com/allatori/naming/NameLengthComparator.java b/src/main/java/com/allatori/naming/NameLengthComparator.java
new file mode 100644
index 0000000..c5b2e83
--- /dev/null
+++ b/src/main/java/com/allatori/naming/NameLengthComparator.java
@@ -0,0 +1,13 @@
+package com.allatori.naming;
+
+import java.util.Comparator;
+
+public class NameLengthComparator implements Comparator {
+
+ @Override
+ public int compare(Object result, Object result2) {
+ String text = (String) result;
+ String text2 = (String) result2;
+ return text.length() - text2.length();
+ }
+}
diff --git a/src/main/java/com/allatori/naming/NameMappingEntry.java b/src/main/java/com/allatori/naming/NameMappingEntry.java
new file mode 100644
index 0000000..b47d63e
--- /dev/null
+++ b/src/main/java/com/allatori/naming/NameMappingEntry.java
@@ -0,0 +1,170 @@
+package com.allatori.naming;
+
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.Attribute;
+import com.allatori.lib.bcel.classfile.SourceFile;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.LineNumberGen;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.model.NameMapping;
+import com.allatori.naming.generator.NameGenerator;
+import com.allatori.util.LookupTable;
+import com.allatori.util.random.RandomUtils;
+import java.util.HashSet;
+import java.util.Vector;
+
+public class NameMappingEntry {
+
+ public Vector values;
+
+ public NameGenerator nameGenerator;
+
+ public String text;
+
+ public LookupTable lookupTable;
+
+ public Vector values2;
+
+ public LookupTable lookupTable2;
+
+ public String text2;
+
+ public HashSet values3;
+
+ public Vector getValues2() {
+ return this.values2;
+ }
+
+ public void processClassGen(ClassGen classGen) {
+ int lineNumbersMode =
+ Configuration.getRenamingOptions().getLineNumberOptions().getLineNumbersMode();
+ Configuration.getRenamingOptions().getLineNumberOptions();
+ if (lineNumbersMode != 2) {
+ lineNumbersMode =
+ Configuration.getRenamingOptions().getLineNumberOptions().getLineNumbersMode();
+ Configuration.getRenamingOptions().getLineNumberOptions();
+ int value;
+ if (lineNumbersMode == 3) {
+ Attribute[] attributes;
+ for (int value2 = value = (attributes = classGen.getAttributes()).length - 1;
+ value2 >= 0;
+ value2 = --value) {
+ Attribute attribute;
+ if ((attribute = attributes[value]) instanceof SourceFile) {
+ classGen.processAttribute2(attribute);
+ return;
+ }
+ }
+ } else {
+ lineNumbersMode =
+ Configuration.getRenamingOptions().getLineNumberOptions().getLineNumbersMode();
+ Configuration.getRenamingOptions().getLineNumberOptions();
+ int value3;
+ if (lineNumbersMode == 1) {
+ Attribute[] attributes2;
+ for (int value4 = value3 = (attributes2 = classGen.getAttributes()).length - 1;
+ value4 >= 0;
+ value4 = --value3) {
+ Attribute attribute2;
+ if ((attribute2 = attributes2[value3]) instanceof SourceFile) {
+ SourceFile sourceFile;
+ String text = (sourceFile = (SourceFile) attribute2).getText();
+ String text2;
+ if ((text2 = this.lookupTable.getText(text)) == null) {
+ do {
+ text2 = this.nameGenerator.nextName();
+ } while (this.values3.contains(text2));
+ this.values2.add(new NameMapping(text, text2));
+ this.lookupTable.processText(text, text2);
+ this.values3.add(text2);
+ }
+ sourceFile.setSourceFileIndex(classGen.getConstantPool().addUtf8(text2));
+ return;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public Vector getValues() {
+ return this.values;
+ }
+
+ public NameMappingEntry() {
+ super();
+ this.nameGenerator =
+ Configuration.getRenamingOptions().getNameGenerationOptions().createNameGenerator();
+ this.values2 = new Vector();
+ this.lookupTable = new LookupTable();
+ this.values3 = new HashSet();
+ this.values = new Vector();
+ this.lookupTable2 = new LookupTable();
+ this.text2 = "\" s=\"";
+ this.text = "\" e=\"";
+ }
+
+ public LookupTable getLookupTable2() {
+ return this.lookupTable2;
+ }
+
+ public void processMethodGen(String text3, MethodGen methodGen) {
+ int lineNumbersMode =
+ Configuration.getRenamingOptions().getLineNumberOptions().getLineNumbersMode();
+ Configuration.getRenamingOptions().getLineNumberOptions();
+ if (lineNumbersMode != 2) {
+ lineNumbersMode =
+ Configuration.getRenamingOptions().getLineNumberOptions().getLineNumbersMode();
+ Configuration.getRenamingOptions().getLineNumberOptions();
+ if (lineNumbersMode == 3) {
+ methodGen.removeLineNumbers();
+ } else {
+ lineNumbersMode =
+ Configuration.getRenamingOptions().getLineNumberOptions().getLineNumbersMode();
+ Configuration.getRenamingOptions().getLineNumberOptions();
+ if (lineNumbersMode == 1) {
+ LineNumberGen[] lineNumbers = methodGen.getLineNumbers();
+ int value = Integer.MAX_VALUE;
+ int value2 = Integer.MIN_VALUE;
+ int value3;
+ for (int value4 = value3 = lineNumbers.length - 1; value4 >= 0; value4 = value3) {
+ LineNumberGen lineNumberGen;
+ int value5;
+ if ((value5 = (lineNumberGen = lineNumbers[value3]).getSourceLine()) < value) {
+ value = value5;
+ }
+ if (value5 > value2) {
+ value2 = value5;
+ }
+ if (value5 > this.values.size() - 1) {
+ int size2 = this.values.size();
+ int value6 = value5 - size2 + 200;
+ Vector vector = new Vector(value6);
+ int value7;
+ for (int value8 = value7 = 0; value8 < value6; value8 = value7) {
+ vector.add(new Integer(size2 + value7++));
+ }
+ RandomUtils.processValues(vector);
+ this.values.addAll(vector);
+ }
+ Object result = this.values.get(value5);
+ LineNumberGen lineNumberGen2 = lineNumberGen;
+ value3--;
+ lineNumberGen2.setSourceLine((Integer) result);
+ }
+ if (value < Integer.MAX_VALUE) {
+ this.lookupTable2.processText(
+ "" + text3 + "&" + methodGen.getName() + "&" + methodGen.getText(),
+ "" + this.text2 + value + this.text + value2);
+ }
+ }
+ }
+ }
+ }
+
+ public void processText(String text, String text2) {
+ this.values2.add(new NameMapping(text, text2));
+ this.lookupTable.processText(text, text2);
+ this.values3.add(text2);
+ }
+}
diff --git a/src/main/java/com/allatori/naming/NameRenamer.java b/src/main/java/com/allatori/naming/NameRenamer.java
new file mode 100644
index 0000000..367a8fc
--- /dev/null
+++ b/src/main/java/com/allatori/naming/NameRenamer.java
@@ -0,0 +1,1793 @@
+package com.allatori.naming;
+
+import com.allatori.bytecode.ClassHierarchy;
+import com.allatori.bytecode.MethodFactory;
+import com.allatori.config.Configuration;
+import com.allatori.engine.ObfuscationAbortException;
+import com.allatori.lib.bcel.classfile.Attribute;
+import com.allatori.lib.bcel.classfile.BootstrapMethods;
+import com.allatori.lib.bcel.classfile.Code;
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.classfile.ConstantCP;
+import com.allatori.lib.bcel.classfile.ConstantClass;
+import com.allatori.lib.bcel.classfile.ConstantFieldref;
+import com.allatori.lib.bcel.classfile.ConstantInterfaceMethodref;
+import com.allatori.lib.bcel.classfile.ConstantInvokeDynamic;
+import com.allatori.lib.bcel.classfile.ConstantMethodType;
+import com.allatori.lib.bcel.classfile.ConstantMethodref;
+import com.allatori.lib.bcel.classfile.ConstantNameAndType;
+import com.allatori.lib.bcel.classfile.ConstantPool;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.classfile.ConstantValue;
+import com.allatori.lib.bcel.classfile.Deprecated;
+import com.allatori.lib.bcel.classfile.EnclosingMethod;
+import com.allatori.lib.bcel.classfile.ExceptionTable;
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.classfile.InnerClass;
+import com.allatori.lib.bcel.classfile.InnerClasses;
+import com.allatori.lib.bcel.classfile.LineNumberTable;
+import com.allatori.lib.bcel.classfile.LocalVariableTable;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.classfile.NestHost;
+import com.allatori.lib.bcel.classfile.NestMembers;
+import com.allatori.lib.bcel.classfile.PMGClass;
+import com.allatori.lib.bcel.classfile.Signature;
+import com.allatori.lib.bcel.classfile.SourceFile;
+import com.allatori.lib.bcel.classfile.StackMap;
+import com.allatori.lib.bcel.classfile.Synthetic;
+import com.allatori.lib.bcel.classfile.Unknown;
+import com.allatori.lib.bcel.generic.AnnotationElementValueGen;
+import com.allatori.lib.bcel.generic.AnnotationEntryGen;
+import com.allatori.lib.bcel.generic.ArrayElementValueGen;
+import com.allatori.lib.bcel.generic.ClassElementValueGen;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.ConstantPoolGen;
+import com.allatori.lib.bcel.generic.ElementValueGen;
+import com.allatori.lib.bcel.generic.ElementValuePairGen;
+import com.allatori.lib.bcel.generic.EnumElementValueGen;
+import com.allatori.lib.bcel.generic.FieldGen;
+import com.allatori.lib.bcel.generic.LocalVariableGen;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.generic.SimpleElementValueGen;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.model.ClassStorage;
+import com.allatori.naming.generator.LowercaseNameGenerator;
+import com.allatori.naming.generator.MainNameGenerator;
+import com.allatori.util.Log;
+import com.allatori.util.LookupTable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+public class NameRenamer {
+
+ public ClassHierarchy classHierarchy;
+
+ public static final String TEXT = "&";
+
+ public static boolean enabled = false;
+
+ public static LookupTable lookupTable = new LookupTable();
+
+ public NamingContext namingContext = new NamingContext(this, null);
+
+ public ClassStorage classStorage;
+
+ public NameMappingEntry nameMappingEntry = new NameMappingEntry();
+
+ public static NameMappingEntry getNameMappingEntry(NameRenamer nameRenamer) {
+ return nameRenamer.nameMappingEntry;
+ }
+
+ public void update() throws ObfuscationAbortException {
+ MainNameGenerator.reset2();
+ Iterator iterator2;
+ Iterator iterator3 = iterator2 = this.classHierarchy.getValues().iterator();
+ while (iterator3.hasNext()) {
+ ClassGen classGen = (ClassGen) iterator2.next();
+ if (Configuration.getIgnoreClassesOptions().matchesClassGen(this.classStorage, classGen)) {
+ iterator3 = iterator2;
+ } else {
+ this.processClassGen9(classGen);
+ this.processClassGen8(classGen);
+ this.processClassGen7(classGen);
+ iterator3 = iterator2;
+ }
+ }
+ if (!enabled && lookupTable.getEntries() > 0) {
+ enabled = true;
+ throw new ObfuscationAbortException();
+ }
+ }
+
+ public void update2() {
+ Iterator iterator2;
+ Iterator iterator3 = iterator2 = this.classHierarchy.getValues().iterator();
+ while (iterator3.hasNext()) {
+ ClassGen classGen = (ClassGen) iterator2.next();
+ if (Configuration.getIgnoreClassesOptions().matchesClassGen(this.classStorage, classGen)) {
+ iterator3 = iterator2;
+ } else {
+ this.processClassGen4(classGen);
+ this.processClassGen5(classGen);
+ iterator3 = iterator2;
+ }
+ }
+ }
+
+ public NameRenamer(ClassStorage classStorage2) {
+ this.classStorage = classStorage2;
+ NameRenamer nameRenamer;
+ if (Configuration.getRenamingOptions().isText2()) {
+ try {
+ MappingImportHandler.processMappingImportHandler(new MappingImportHandler(this, null));
+ } catch (Exception exception) {
+ throw new RuntimeException(exception);
+ }
+ nameRenamer = this;
+ } else {
+ nameRenamer = this;
+ }
+ nameRenamer.classHierarchy = new ClassHierarchy(classStorage2);
+ }
+
+ public boolean matchesEnabled(ClassGen classGen, String text, String text2, boolean matches) {
+ if (FieldNameTable.getLookupTable3(NamingContext.getFieldNameTable(this.namingContext))
+ .matchesText("" + classGen.getClassName() + "&" + text + "&" + text2)) {
+ return true;
+ }
+ if (!matches) {
+ return false;
+ }
+ int value;
+ Vector vector;
+ for (int value2 =
+ value = (vector = this.classHierarchy.getValues(classGen.getClassName())).size() - 1;
+ value2 >= 0;
+ value2 = --value) {
+ if (this.matchesEnabled((ClassGen) vector.get(value), text, text2, matches)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void processClassGen(ClassGen classGen) {
+ int value;
+ ConstantPoolGen constantPoolGen;
+ for (int value2 = value = (constantPoolGen = classGen.getConstantPool()).getSize() - 1;
+ value2 >= 0;
+ value2 = --value) {
+ Constant constant;
+ if (!((constant = constantPoolGen.getConstant(value)) instanceof ConstantClass)) {
+ if (constant instanceof ConstantCP) {
+ ConstantPool constantPool = constantPoolGen.getConstantPool();
+ ConstantCP constantCP;
+ String classValue = (constantCP = (ConstantCP) constant).getClass(constantPool);
+ String text;
+ if ((text =
+ ParameterNameTable.getLookupTable3(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(classValue))
+ != null) {
+ classValue = text;
+ }
+ ConstantNameAndType constantNameAndType =
+ (ConstantNameAndType)
+ constantPoolGen.getConstant(constantCP.getName_and_type_index());
+ String text2 = constantNameAndType.getText(constantPool);
+ String text22 = constantNameAndType.getText2(constantPool);
+ String text3 = null;
+ String text4 = null;
+ String text5;
+ if (!(constantCP instanceof ConstantMethodref)
+ && !(constantCP instanceof ConstantInterfaceMethodref)) {
+ if (constantCP instanceof ConstantFieldref) {
+ text3 =
+ FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .getText("" + classValue + "&" + text2 + "&" + text22);
+ text4 =
+ FieldNameTable.getLookupTable2(
+ NamingContext.getFieldNameTable(this.namingContext))
+ .getText(text22);
+ }
+ text5 = text3;
+ } else {
+ text3 =
+ MethodNameTable.getLookupTable2(
+ NamingContext.getMethodNameTable(this.namingContext))
+ .getText("" + classValue + "&" + text2 + "&" + text22);
+ text4 =
+ MethodNameTable.getLookupTable(NamingContext.getMethodNameTable(this.namingContext))
+ .getText(text22);
+ text5 = text3;
+ }
+ if (text5 != null && !text3.equals(text2) || text4 != null) {
+ if (text3 == null) {
+ text3 = text2;
+ }
+ if (text4 == null) {
+ text4 = text22;
+ }
+ int value3 = constantPoolGen.addNameAndType(text3, text4);
+ constantCP.setName_and_type_index(value3);
+ }
+ } else if (!(constant instanceof ConstantUtf8)
+ && !(constant instanceof ConstantMethodType)
+ && constant instanceof ConstantInvokeDynamic) {
+ ConstantInvokeDynamic constantInvokeDynamic = (ConstantInvokeDynamic) constant;
+ ConstantPool constantPool2 = constantPoolGen.getConstantPool();
+ ConstantNameAndType constantNameAndType2;
+ ConstantNameAndType constantNameAndType3 =
+ constantNameAndType2 =
+ (ConstantNameAndType)
+ constantPoolGen.getConstant(
+ constantInvokeDynamic.getBootstrapMethodAttrIndex2());
+ String text23 = constantNameAndType3.getText2(constantPool2);
+ String text6 = constantNameAndType3.getText(constantPool2);
+ if (text23.contains(")L")) {
+ String text7 =
+ text23
+ .substring(text23.lastIndexOf(")L") + 2, text23.length() - 1)
+ .replace('/', '.');
+ if (ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text7)
+ != null) {
+ String text8 = null;
+ if (classGen.getAttributes() != null) {
+ Attribute[] attributes;
+ int value4 = (attributes = classGen.getAttributes()).length;
+ int value5;
+ for (int value6 = value5 = 0; value6 < value4; value6 = ++value5) {
+ int[] values;
+ Attribute attribute;
+ if ((attribute = attributes[value5]) instanceof BootstrapMethods
+ && (values =
+ ((BootstrapMethods) attribute)
+ .getBootstrapMethods()[
+ constantInvokeDynamic.getBootstrapMethodAttrIndex()]
+ .getBootstrapArguments())
+ != null) {
+ int[] values2 = values;
+ int value7 = values.length;
+ int value8;
+ for (int value9 = value8 = 0; value9 < value7; value9 = ++value8) {
+ int value10;
+ if (constantPoolGen.getConstant(value10 = values2[value8])
+ instanceof ConstantMethodType) {
+ ConstantMethodType constantMethodType =
+ (ConstantMethodType) constantPoolGen.getConstant(value10);
+ text8 =
+ ((ConstantUtf8)
+ constantPoolGen.getConstant(
+ constantMethodType.getDescriptorIndex()))
+ .getBytes();
+ break;
+ }
+ }
+ }
+ }
+ }
+ String text9;
+ if (text8 != null
+ && (text9 =
+ MethodNameTable.getLookupTable2(
+ NamingContext.getMethodNameTable(this.namingContext))
+ .getText("" + text7 + "&" + text6 + "&" + text8))
+ != null) {
+ constantNameAndType2.setName_index(constantPoolGen.addUtf8(text9));
+ }
+ }
+ }
+ String text24 = constantNameAndType2.getText2(constantPool2);
+ String text10 = this.createText(text24);
+ if (!text24.equals(text10)) {
+ constantNameAndType2.setSignature_index(constantPoolGen.addUtf8(text10));
+ }
+ }
+ }
+ }
+ int value11;
+ for (int value12 = value11 = constantPoolGen.getSize() - 1; value12 >= 0; value12 = --value11) {
+ Constant constant2;
+ if ((constant2 = constantPoolGen.getConstant(value11)) instanceof ConstantClass) {
+ ConstantPool constantPool3 = constantPoolGen.getConstantPool();
+ ConstantClass constantClass;
+ String text11 =
+ ((String) (constantClass = (ConstantClass) constant2).getConstantValue(constantPool3))
+ .replace('/', '.');
+ byte value13 = 0;
+ int value14;
+ value12 = value14 = 0;
+ while (value12 < text11.length() && text11.charAt(value14) == '[') {
+ value12 = ++value14;
+ }
+ if (value14 > 0 && text11.endsWith(";") && text11.charAt(value14) == 'L') {
+ text11 = text11.substring(value14 + 1, text11.length() - 1);
+ value13 = 1;
+ }
+ String text12;
+ if ((text12 =
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text11))
+ != null) {
+ String text13 = text12.replace('.', '/');
+ if (value13 != 0) {
+ text13 = "[L" + text13 + ";";
+ for (int value15 = value14; value15 > 1; value15 = value14) {
+ StringBuilder stringBuilder = new StringBuilder().insert(0, "[");
+ String text14 = text13;
+ value14--;
+ text13 = stringBuilder.append(text14).toString();
+ }
+ }
+ constantClass.setNameIndex(constantPoolGen.addUtf8(text13));
+ Object result;
+ Map entries;
+ if ((result = (entries = constantPoolGen.class_table).get(text11.replace('.', '/')))
+ != null) {
+ entries.put(text13, result);
+ }
+ }
+ } else if (!(constant2 instanceof ConstantCP)) {
+ if (!(constant2 instanceof ConstantUtf8)) {
+ if (constant2 instanceof ConstantMethodType) {
+ ConstantMethodType constantMethodType2 = (ConstantMethodType) constant2;
+ ConstantUtf8 constantUtf8 =
+ (ConstantUtf8)
+ constantPoolGen.getConstant(constantMethodType2.getDescriptorIndex());
+ constantUtf8.setBytes(this.createText(constantUtf8.getBytes()));
+ }
+ } else {
+ ConstantUtf8 constantUtf82;
+ String bytes = (constantUtf82 = (ConstantUtf8) constant2).getBytes();
+ String text15;
+ if ((text15 =
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(bytes))
+ != null) {
+ constantUtf82.setBytes(text15);
+ } else {
+ int value16;
+ value12 = value16 = 0;
+ while (value12 < bytes.length() && bytes.charAt(value16) == '[') {
+ value12 = ++value16;
+ }
+ if (value16 > 0 && bytes.endsWith(";") && bytes.charAt(value16) == 'L') {
+ bytes = bytes.substring(value16 + 1, bytes.length() - 1).replace('/', '.');
+ String text16;
+ if ((text16 =
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(bytes))
+ != null) {
+ String text17 = "[L" + text16.replace('.', '/') + ";";
+ for (int value17 = value16; value17 > 1; value17 = value16) {
+ StringBuilder stringBuilder2 = new StringBuilder().insert(0, "[");
+ String text18 = text17;
+ value16--;
+ text17 = stringBuilder2.append(text18).toString();
+ }
+ constantUtf82.setBytes(text17);
+ continue;
+ }
+ }
+ if (bytes.startsWith("L") && bytes.endsWith(";")) {
+ String text19 = bytes.substring(1, bytes.length() - 1).replace('/', '.');
+ String text20;
+ if ((text20 =
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text19))
+ != null) {
+ String text21 = "L" + text20.replace('.', '/') + ";";
+ constantUtf82.setBytes(text21);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static boolean isEnabled() {
+ return enabled;
+ }
+
+ public void processEnabled(
+ ClassGen classGen,
+ String text,
+ String text2,
+ String text3,
+ boolean matches,
+ boolean matches2) {
+ if (matches) {
+ ClassGen classGen2 = classGen;
+ do {
+ String superclassName = classGen2.getSuperclassName();
+ if ((classGen2 = this.classStorage.getClassGen(superclassName)) != null) {
+ MethodNameTable.getLookupTable2(NamingContext.getMethodNameTable(this.namingContext))
+ .processText("" + classGen2.getClassName() + "&" + text + "&" + text3, text2);
+ if (classGen2.isEnabled2()) {
+ MethodNameTable.getLookupTable5(NamingContext.getMethodNameTable(this.namingContext))
+ .processText("" + classGen2.getClassName() + "&" + text, text2);
+ }
+ MethodNameTable.getLookupTable3(NamingContext.getMethodNameTable(this.namingContext))
+ .processText(
+ "" + classGen2.getClassName() + "&" + text2 + "&" + NameUtils.getText(text3),
+ "&");
+ }
+ } while (classGen2 != null);
+ }
+ int value;
+ Vector vector;
+ for (int value2 =
+ value = (vector = this.classHierarchy.getValues(classGen.getClassName())).size() - 1;
+ value2 >= 0;
+ value2 = value) {
+ ClassGen classGen3 = (ClassGen) vector.get(value);
+ NameRenamer nameRenamer;
+ if (matches2
+ && Configuration.getRenamingOptions().isText()
+ && !NameUtils.getText2(classGen.getClassName())
+ .equals(NameUtils.getText2(classGen3.getClassName()))) {
+ nameRenamer = this;
+ MethodNameTable.getLookupTable3(NamingContext.getMethodNameTable(this.namingContext))
+ .processText(
+ "" + classGen3.getClassName() + "&" + text2 + "&" + NameUtils.getText(text3), "&");
+ } else {
+ MethodNameTable.getLookupTable2(NamingContext.getMethodNameTable(this.namingContext))
+ .processText("" + classGen3.getClassName() + "&" + text + "&" + text3, text2);
+ if (classGen3.isEnabled2()) {
+ MethodNameTable.getLookupTable5(NamingContext.getMethodNameTable(this.namingContext))
+ .processText("" + classGen3.getClassName() + "&" + text, text2);
+ }
+ nameRenamer = this;
+ MethodNameTable.getLookupTable3(NamingContext.getMethodNameTable(this.namingContext))
+ .processText(
+ "" + classGen3.getClassName() + "&" + text2 + "&" + NameUtils.getText(text3), "&");
+ }
+ NameRenamer nameRenamer2 = nameRenamer;
+ value--;
+ nameRenamer2.processEnabled(classGen3, text, text2, text3, matches, matches2);
+ }
+ }
+
+ public void processConstantPoolGen(List values, ConstantPoolGen constantPoolGen) {
+ if (values != null) {
+ int value;
+ for (int value2 = value = values.size() - 1; value2 >= 0; value2 = value) {
+ Object result = values.get(value);
+ value--;
+ this.processConstantPoolGen((AnnotationEntryGen) result, constantPoolGen);
+ }
+ }
+ }
+
+ public void processClassGen2(ClassGen classGen) {
+ String className = classGen.getClassName();
+ Field[] fields = classGen.getFields();
+ if (!Configuration.getRenamingOptions().isFieldsNamingEnabled()) {
+ FieldNameTable.getNameGenerator(NamingContext.getFieldNameTable(this.namingContext)).reset();
+ }
+ int value;
+ for (int value2 = value = fields.length - 1; value2 >= 0; value2 = --value) {
+ Field field;
+ Field field2 = field = fields[value];
+ String text = field2.getText();
+ String text2 = field2.getText2();
+ String text3;
+ if ((text3 =
+ FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .getText("" + className + "&" + text + "&" + text2))
+ == null) {
+ NameRenamer nameRenamer = this;
+ for (text3 =
+ FieldNameTable.getNameGenerator(NamingContext.getFieldNameTable(this.namingContext))
+ .nextName();
+ nameRenamer.matchesEnabled(classGen, text3, text2, !field.isEnabled9());
+ text3 =
+ FieldNameTable.getNameGenerator(NamingContext.getFieldNameTable(this.namingContext))
+ .nextName()) {
+ nameRenamer = this;
+ }
+ FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .processText("" + className + "&" + text + "&" + text2, text3);
+ FieldNameTable.getLookupTable3(NamingContext.getFieldNameTable(this.namingContext))
+ .processText("" + className + "&" + text3 + "&" + text2, "&");
+ }
+ if (!field.isEnabled9()) {
+ this.processText(classGen, text, text3, text2);
+ }
+ }
+ }
+
+ public void processConstantPoolGen(
+ ElementValueGen elementValueGen, ConstantPoolGen constantPoolGen) {
+ if (elementValueGen instanceof AnnotationElementValueGen) {
+ this.processConstantPoolGen(
+ ((AnnotationElementValueGen) elementValueGen).getAnnotation(), constantPoolGen);
+ } else {
+ int value;
+ if (elementValueGen instanceof ArrayElementValueGen) {
+ List values;
+ for (int value2 =
+ value =
+ (values = ((ArrayElementValueGen) elementValueGen).getElementValues()).size()
+ - 1;
+ value2 >= 0;
+ value2 = value) {
+ Object result = values.get(value);
+ value--;
+ this.processConstantPoolGen((ElementValueGen) result, constantPoolGen);
+ }
+ } else {
+ if (elementValueGen instanceof ClassElementValueGen) {
+ return;
+ }
+ if (elementValueGen instanceof EnumElementValueGen) {
+ EnumElementValueGen enumElementValueGen;
+ String typeIdx2 =
+ (enumElementValueGen = (EnumElementValueGen) elementValueGen).getTypeIdx2();
+ String text = null;
+ if (typeIdx2.startsWith("L") && typeIdx2.endsWith(";")) {
+ String text2;
+ text = text2 = typeIdx2.substring(1, typeIdx2.length() - 1).replace('/', '.');
+ String text3;
+ if ((text3 =
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text2))
+ != null) {
+ String text4 = "L" + text3.replace('.', '/') + ";";
+ enumElementValueGen.setTypeIdx(constantPoolGen.addUtf8(text4));
+ }
+ }
+ if (text != null) {
+ String valueIdx2 = enumElementValueGen.getValueIdx2();
+ String text5 = "" + text + "&" + valueIdx2 + "&" + typeIdx2;
+ if (FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .matchesText(text5)) {
+ String text6 =
+ FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .getText(text5);
+ enumElementValueGen.setValueIdx(constantPoolGen.addUtf8(text6));
+ return;
+ }
+ }
+ } else if (elementValueGen instanceof SimpleElementValueGen) {
+ }
+ }
+ }
+ }
+
+ public void processClassGen3(ClassGen classGen) {
+ String className = classGen.getClassName();
+ Method[] methods;
+ int value;
+ for (int value2 = value = (methods = classGen.getMethods()).length - 1;
+ value2 >= 0;
+ value2 = --value) {
+ Method method;
+ Method method2 = method = methods[value];
+ String text = method2.getText();
+ String text2 = method2.getText2();
+ String text3;
+ if (!method2.isEnabled9()) {
+ text3 = this.createText(classGen, text, text2);
+ } else {
+ text3 =
+ MethodNameTable.getLookupTable2(NamingContext.getMethodNameTable(this.namingContext))
+ .getText("" + className + "&" + text + "&" + text2);
+ }
+ boolean matches =
+ Configuration.getRenamingOptions().matchesClassGen(this.classStorage, classGen);
+ if (text3 == null && matches) {
+ text3 =
+ MethodNameTable.getLookupTable4(NamingContext.getMethodNameTable(this.namingContext))
+ .getText("" + text + "&" + NameUtils.getText(text2));
+ }
+ if (text3 == null) {
+ if (!Configuration.getRenamingOptions().isEnabled8() && !classGen.isEnabled2()) {
+ MethodNameTable.getNameGenerator(NamingContext.getMethodNameTable(this.namingContext))
+ .reset();
+ }
+ String text4;
+ byte value3;
+ ClassGen classGen2;
+ do {
+ text3 =
+ MethodNameTable.getNameGenerator(NamingContext.getMethodNameTable(this.namingContext))
+ .nextName();
+ text4 = NameUtils.getText(text2);
+ if (!method.isEnabled9()) {
+ value3 = 1;
+ classGen2 = classGen;
+ } else {
+ value3 = 0;
+ classGen2 = classGen;
+ }
+ } while (this.matchesEnabled(classGen, text3, text4, value3 != 0, classGen2.isEnabled5()));
+ }
+ MethodNameTable.getLookupTable2(NamingContext.getMethodNameTable(this.namingContext))
+ .processText("" + className + "&" + text + "&" + text2, text3);
+ if (classGen.isEnabled2()) {
+ MethodNameTable.getLookupTable5(NamingContext.getMethodNameTable(this.namingContext))
+ .processText("" + className + "&" + text, text3);
+ }
+ MethodNameTable.getLookupTable3(NamingContext.getMethodNameTable(this.namingContext))
+ .processText("" + className + "&" + text3 + "&" + NameUtils.getText(text2), "&");
+ if (!method.isEnabled9()) {
+ this.processEnabled(
+ classGen,
+ text,
+ text3,
+ text2,
+ classGen.isEnabled5(),
+ NameUtils.matchesAccessFlags2(method));
+ }
+ if (Configuration.getRenamingOptions().isEnabled8() && !text3.equals(text)) {
+ MethodNameTable.getLookupTable4(NamingContext.getMethodNameTable(this.namingContext))
+ .processText("" + text + "&" + NameUtils.getText(text2), text3);
+ }
+ }
+ }
+
+ public String createText(String text) {
+ String text2;
+ String text3 = text;
+ int value;
+ if (text3.contains(">.")) {
+ for (int value2 = value = 0; value2 < text3.length(); value2 = ++value) {
+ if (text3.charAt(value) == 'L') {
+ int value3;
+ int value4 = value3 = value + 1;
+ int value5 = 0;
+ int value6;
+ value2 = value6 = value3;
+ while (true) {
+ if (value2 >= text3.length()) {
+ text2 = text3;
+ break;
+ }
+ if (text3.charAt(value6) == '<') {
+ value5++;
+ }
+ if (text3.charAt(value6) == '>') {
+ value5--;
+ }
+ if (text3.charAt(value6) == ';' && value5 == 0) {
+ value4 = value6;
+ text2 = text3;
+ break;
+ }
+ value2 = ++value6;
+ }
+ String text4;
+ if ((text4 = text2.substring(value3, value4)).indexOf(46) > 0) {
+ String text5;
+ String text6 = text5 = text4;
+ while (text6.contains(">")) {
+ int value7 = text5.indexOf(62);
+ int value8 = text5.lastIndexOf(60, value7);
+ text6 = text5 = "" + text5.substring(0, value8) + text5.substring(value7 + 1);
+ }
+ String text7 = text5.replace('.', '$').replace('/', '.');
+ String text8;
+ if ((text8 =
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text7))
+ != null
+ && !text8.equals(text7)) {
+ text3 =
+ ""
+ + text3.substring(0, value3)
+ + text8.replace('.', '/')
+ + text3.substring(value3 + text4.length());
+ }
+ }
+ }
+ }
+ }
+ int value9;
+ for (int value10 = value9 = text3.length() - 1; value10 >= 0; value10 = --value9) {
+ if (text3.charAt(value9) == 'L') {
+ int value11 = text3.indexOf(59, value9);
+ int value12 = text3.indexOf(60, value9);
+ if (value11 == -1) {
+ value11 = value12;
+ }
+ if (value12 != -1 && value12 < value11) {
+ value11 = value12;
+ }
+ if (value11 > value9) {
+ String text9 = text3.substring(value9 + 1, value11).replace('/', '.');
+ String text10;
+ if ((text10 =
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text9))
+ != null
+ && !text10.equals(text9)) {
+ text3 =
+ ""
+ + text3.substring(0, value9 + 1)
+ + text10.replace('.', '/')
+ + text3.substring(value9 + text9.length() + 1);
+ }
+ }
+ }
+ }
+ return text3;
+ }
+
+ public void processClassGen4(ClassGen classGen) {
+ int value;
+ Field[] fields;
+ for (int value2 = value = (fields = classGen.getFields()).length - 1;
+ value2 >= 0;
+ value2 = --value) {
+ Field field = fields[value];
+ String text =
+ FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .getText(
+ "" + classGen.getClassName() + "&" + field.getText() + "&" + field.getText2());
+ Type type =
+ NameUtils.getType(
+ field.getType(),
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext)));
+ boolean matches;
+ if (!(matches =
+ Configuration.getMemberOrderOptions()
+ .matchesField(this.classStorage, classGen, field))
+ && !field.isEnabled9()
+ && (ParameterNameTable.getLookupTable2(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .matchesText(classGen.getClassName())
+ || Configuration.getRenamingOptions().isForceDefaultPackageEnabled())) {
+ matches = true;
+ }
+ if (!text.equals(field.getText())
+ || type != null
+ || matches
+ || field.getAnnotationEntries().length > 0) {
+ FieldGen fieldGen = new FieldGen(field, classGen.getConstantPool());
+ if (!text.equals(field.getText())) {
+ fieldGen.setName(text);
+ RenameStatistics.count2++;
+ }
+ if (type != null) {
+ fieldGen.setType(type);
+ FieldNameTable.getLookupTable2(NamingContext.getFieldNameTable(this.namingContext))
+ .processText(field.getText2(), fieldGen.getText());
+ }
+ if (matches) {
+ NameUtils.processAccessFlags(fieldGen);
+ }
+ this.processConstantPoolGen(fieldGen.getAnnotationEntryGens(), classGen.getConstantPool());
+ classGen.replaceField(field, fieldGen.getField());
+ }
+ }
+ }
+
+ public void update3() {
+ ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext))
+ .processText("", "");
+ Iterator iterator2;
+ Iterator iterator3 = iterator2 = this.classHierarchy.getValues().iterator();
+ while (iterator3.hasNext()) {
+ ClassGen classGen = (ClassGen) iterator2.next();
+ if (Configuration.getIgnoreClassesOptions().matchesClassGen(this.classStorage, classGen)) {
+ iterator3 = iterator2;
+ } else {
+ this.processClassGen6(classGen);
+ this.processClassGen3(classGen);
+ this.processClassGen2(classGen);
+ iterator3 = iterator2;
+ }
+ }
+ if (Configuration.getRenamingOptions().isClassesNamingEnabled()) {
+ this.update4();
+ }
+ }
+
+ public void processClassGen5(ClassGen classGen) {
+ Method[] methods;
+ int value;
+ for (int value2 = value = (methods = classGen.getMethods()).length - 1;
+ value2 >= 0;
+ value2 = value) {
+ Method method;
+ MethodGen methodGen =
+ MethodFactory.createMethodGen(
+ method = methods[value],
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool());
+ this.processMethodGen(classGen, methodGen);
+ this.nameMappingEntry.processMethodGen(classGen.getClassName(), methodGen);
+ String text =
+ MethodNameTable.getLookupTable2(NamingContext.getMethodNameTable(this.namingContext))
+ .getText(
+ "" + classGen.getClassName() + "&" + method.getText() + "&" + method.getText2());
+ if (!methodGen.getName().equals(text)) {
+ methodGen.setName(text);
+ RenameStatistics.count++;
+ }
+ byte value3 = 0;
+ Type[] types;
+ int value4;
+ for (int value5 = value4 = (types = methodGen.getArgumentTypes()).length - 1;
+ value5 >= 0;
+ value5 = --value4) {
+ Type type;
+ if ((type =
+ NameUtils.getType(
+ types[value4],
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))))
+ != null) {
+ methodGen.setArgumentType(value4, type);
+ value3 = 1;
+ }
+ }
+ Type type2;
+ if ((type2 =
+ NameUtils.getType(
+ methodGen.getReturnType(),
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))))
+ != null) {
+ methodGen.setReturnType(type2);
+ value3 = 1;
+ }
+ if (value3 != 0) {
+ MethodNameTable.getLookupTable(NamingContext.getMethodNameTable(this.namingContext))
+ .processText(method.getText2(), methodGen.getText());
+ }
+ if (Configuration.getMemberOrderOptions().matchesMethod(this.classStorage, classGen, method)
+ || !method.isEnabled9()
+ && (ParameterNameTable.getLookupTable2(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .matchesText(classGen.getClassName())
+ || Configuration.getRenamingOptions().isForceDefaultPackageEnabled())) {
+ NameUtils.processAccessFlags(methodGen);
+ }
+ this.processConstantPoolGen(methodGen.getAnnotationEntryGens(), classGen.getConstantPool());
+ int value6;
+ for (int value7 = value6 = methodGen.getArgumentTypes().length - 1;
+ value7 >= 0;
+ value7 = value6) {
+ List annotationsOnParameter = methodGen.getAnnotationsOnParameter(value6);
+ value6--;
+ this.processConstantPoolGen(annotationsOnParameter, classGen.getConstantPool());
+ }
+ Method method2 = method;
+ value--;
+ classGen.replaceMethod(method2, methodGen.getMethod());
+ }
+ }
+
+ public void processText(ClassGen classGen, String text, String text2, String text3) {
+ Vector vector;
+ int value;
+ for (int value2 =
+ value = (vector = this.classHierarchy.getValues(classGen.getClassName())).size() - 1;
+ value2 >= 0;
+ value2 = value) {
+ ClassGen classGen2;
+ ClassGen classGen3 = classGen2 = (ClassGen) vector.get(value);
+ FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .processText("" + classGen2.getClassName() + "&" + text + "&" + text3, text2);
+ FieldNameTable.getLookupTable3(NamingContext.getFieldNameTable(this.namingContext))
+ .processText("" + classGen2.getClassName() + "&" + text2 + "&" + text3, "&");
+ value--;
+ this.processText(classGen3, text, text2, text3);
+ }
+ }
+
+ public static NamingContext getNamingContext(NameRenamer nameRenamer) {
+ return nameRenamer.namingContext;
+ }
+
+ public void processClassGen6(ClassGen classGen) {
+ String className = classGen.getClassName();
+ if (!ParameterNameTable.getLookupTable(NamingContext.getParameterNameTable(this.namingContext))
+ .matchesText(className)) {
+ String text2 = NameUtils.getText2(className);
+ String text = this.createText2(text2);
+ if (Configuration.getRenamingOptions().isText()
+ && (!text2.equals(text)
+ || Configuration.getRenamingOptions().isForceDefaultPackageEnabled())) {
+ text = Configuration.getRenamingOptions().getDefaultPackage();
+ ParameterNameTable.getLookupTable2(NamingContext.getParameterNameTable(this.namingContext))
+ .processText(className, "&");
+ }
+ if (text.length() > 0) {
+ text = "" + text + ".";
+ }
+ if (!Configuration.getRenamingOptions().getNameGenerationOptions().isClassesNamingEnabled()) {
+ ParameterNameTable.getNameGenerator(NamingContext.getParameterNameTable(this.namingContext))
+ .reset();
+ }
+ String text3;
+ do {
+ text3 =
+ ""
+ + text
+ + ParameterNameTable.getNameGenerator(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .nextName();
+ } while (ParameterNameTable.getLookupTable3(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .matchesText(text3)
+ || this.classStorage.getClassGen(text3) != null);
+ ParameterNameTable.getLookupTable(NamingContext.getParameterNameTable(this.namingContext))
+ .processText(className, text3);
+ ParameterNameTable.getLookupTable3(NamingContext.getParameterNameTable(this.namingContext))
+ .processText(text3, className);
+ }
+ }
+
+ public void processClassGen7(ClassGen classGen) {
+ String className = classGen.getClassName();
+ Field[] fields;
+ int value;
+ for (int value2 = value = (fields = classGen.getFields()).length - 1;
+ value2 >= 0;
+ value2 = --value) {
+ Field field = fields[value];
+ if (!Configuration.getRenamingOptions()
+ .getKeepNamesOptions()
+ .matchesField(this.classStorage, classGen, field)) {
+ String text = field.getText();
+ String text2 = field.getText2();
+ if (Configuration.getRenamingOptions().getNameGenerationOptions().isFieldsNamingEnabled()) {
+ MainNameGenerator.processText2(text);
+ }
+ if (!FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .matchesText("" + className + "&" + text + "&" + text2)) {
+ FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .processText("" + className + "&" + text + "&" + text2, text);
+ FieldNameTable.getLookupTable3(NamingContext.getFieldNameTable(this.namingContext))
+ .processText("" + className + "&" + text + "&" + text2, "&");
+ if (!field.isEnabled9()) {
+ this.processText(classGen, text, text, text2);
+ }
+ } else if (!field.isEnabled9()) {
+ this.processText(
+ classGen,
+ text,
+ FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .getText("" + className + "&" + text + "&" + text2),
+ text2);
+ }
+ }
+ }
+ ClassGen classGen2 = classGen;
+ do {
+ String superclassName = classGen2.getSuperclassName();
+ int value3;
+ if ((classGen2 = this.classStorage.getClassGen(superclassName)) != null) {
+ Field[] fields2;
+ for (int value4 = value3 = (fields2 = classGen2.getFields()).length - 1;
+ value4 >= 0;
+ value4 = --value3) {
+ Field field2 = fields2[value3];
+ if (!Configuration.getRenamingOptions()
+ .getKeepNamesOptions()
+ .matchesField(this.classStorage, classGen, field2)) {
+ String text3 = field2.getText();
+ String text22 = field2.getText2();
+ if (Configuration.getRenamingOptions()
+ .getNameGenerationOptions()
+ .isFieldsNamingEnabled()) {
+ MainNameGenerator.processText2(text3);
+ }
+ if (!FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .matchesText("" + superclassName + "&" + text3 + "&" + text22)) {
+ FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .processText("" + superclassName + "&" + text3 + "&" + text22, text3);
+ FieldNameTable.getLookupTable3(NamingContext.getFieldNameTable(this.namingContext))
+ .processText("" + superclassName + "&" + text3 + "&" + text22, "&");
+ if (!field2.isEnabled9()) {
+ this.processText(classGen2, text3, text3, text22);
+ }
+ } else if (!field2.isEnabled9()) {
+ this.processText(
+ classGen2,
+ text3,
+ FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext))
+ .getText("" + superclassName + "&" + text3 + "&" + text22),
+ text22);
+ }
+ }
+ }
+ }
+ } while (classGen2 != null);
+ }
+
+ public String createText(ClassGen classGen, String text, String text2) {
+ String text3;
+ if ((text3 =
+ MethodNameTable.getLookupTable2(NamingContext.getMethodNameTable(this.namingContext))
+ .getText("" + classGen.getClassName() + "&" + text + "&" + text2))
+ != null) {
+ return text3;
+ }
+ Vector vector;
+ int value;
+ for (int value2 =
+ value = (vector = this.classHierarchy.getValues(classGen.getClassName())).size() - 1;
+ value2 >= 0;
+ value2 = --value) {
+ String text4;
+ if ((text4 = this.createText((ClassGen) vector.get(value), text, text2)) != null) {
+ return text4;
+ }
+ }
+ return null;
+ }
+
+ public void update4() {
+ for (String text :
+ ((Iterable)
+ ((Iterable>)
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getEntries2()))) {
+ String text2 =
+ ParameterNameTable.getLookupTable(NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text);
+ String text3 = this.createText3(text);
+ if (!text2.equals(text3)) {
+ ParameterNameTable.getLookupTable(NamingContext.getParameterNameTable(this.namingContext))
+ .processText(text, text3);
+ ParameterNameTable.getLookupTable3(NamingContext.getParameterNameTable(this.namingContext))
+ .processText(text2);
+ ParameterNameTable.getLookupTable3(NamingContext.getParameterNameTable(this.namingContext))
+ .processText(text3, text);
+ }
+ }
+ }
+
+ public void rename() throws ObfuscationAbortException {
+ this.classHierarchy.update3();
+ this.update();
+ this.update3();
+ this.update2();
+ this.update6();
+ this.update7();
+ Configuration.getMappingOptions().renamingLog =
+ new RenamingLog(
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext)),
+ MethodNameTable.getLookupTable2(NamingContext.getMethodNameTable(this.namingContext)),
+ FieldNameTable.getLookupTable(NamingContext.getFieldNameTable(this.namingContext)),
+ this.nameMappingEntry.getValues2(),
+ this.nameMappingEntry.getValues(),
+ this.nameMappingEntry.getLookupTable2(),
+ MethodNameTable.getLookupTable5(NamingContext.getMethodNameTable(this.namingContext)));
+ Configuration.getMappingOptions().lookupTable =
+ ParameterNameTable.getLookupTable3(NamingContext.getParameterNameTable(this.namingContext));
+ Configuration.getMappingOptions().lookupTable2 =
+ ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext));
+ }
+
+ public void processConstantPoolGen(
+ AnnotationEntryGen[] annotationEntryGens, ConstantPoolGen constantPoolGen) {
+ if (annotationEntryGens != null) {
+ int value;
+ for (int value2 = value = annotationEntryGens.length - 1; value2 >= 0; value2 = value) {
+ int value3 = value;
+ value--;
+ this.processConstantPoolGen(annotationEntryGens[value3], constantPoolGen);
+ }
+ }
+ }
+
+ public void processMethodGen(ClassGen classGen, MethodGen methodGen) {
+ int value;
+ int value2 =
+ value =
+ Configuration.getRenamingOptions()
+ .getLocalVariableOptions()
+ .calculateCount(this.classStorage, classGen, methodGen);
+ Configuration.getRenamingOptions().getLocalVariableOptions();
+ if (value2 == 4) {
+ methodGen.getVariable_vec();
+ } else {
+ Configuration.getRenamingOptions().getLocalVariableOptions();
+ int value3 = value == 3 ? 1 : 0;
+ LocalVariableGen[] localVariables = methodGen.getLocalVariables();
+ int value4 = methodGen.getArgumentNames().length;
+ if (!methodGen.isEnabled11()) {
+ value4++;
+ }
+ Type[] types;
+ int value5 = (types = methodGen.getArgumentTypes()).length;
+ int value6;
+ for (int value7 = value6 = 0; value7 < value5; value7 = ++value6) {
+ Type type;
+ if ((type = types[value6]) == Type.LONG || type == Type.DOUBLE) {
+ value4++;
+ }
+ }
+ PackageNameTable.getNameGenerator(NamingContext.getPackageNameTable(this.namingContext))
+ .reset();
+ LowercaseNameGenerator lowercaseNameGenerator = null;
+ if (Configuration.getObfuscationOptions().isEnabled3()) {
+ lowercaseNameGenerator = new LowercaseNameGenerator();
+ }
+ int value8;
+ for (int value9 = value8 = localVariables.length - 1; value9 >= 0; value9 = --value8) {
+ LocalVariableGen localVariableGen;
+ Type type2;
+ if ((type2 =
+ NameUtils.getType(
+ (localVariableGen = localVariables[value8]).getType(),
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))))
+ != null) {
+ localVariableGen.setType(type2);
+ }
+ try {
+ if (methodGen.getAnnotationsOnParameter(localVariableGen.getIndex()) != null) {
+ continue;
+ }
+ } catch (ArrayIndexOutOfBoundsException arrayIndexOutOfBoundsException) {
+ }
+ Configuration.getRenamingOptions().getLocalVariableOptions();
+ if (value == 5) {
+ if (localVariableGen.getIndex() >= value4) {
+ localVariableGen.setName(
+ Configuration.getObfuscationOptions().isEnabled3()
+ ? lowercaseNameGenerator.nextName()
+ : Configuration.getRenamingOptions().getNameGenerationOptions().getText());
+ }
+ } else {
+ Configuration.getRenamingOptions().getLocalVariableOptions();
+ if (value == 6) {
+ if (localVariableGen.getIndex() < value4) {
+ localVariableGen.setName(
+ Configuration.getObfuscationOptions().isEnabled3()
+ ? lowercaseNameGenerator.nextName()
+ : Configuration.getRenamingOptions().getNameGenerationOptions().getText());
+ } else {
+ localVariableGen.setName(
+ Configuration.getObfuscationOptions().isEnabled3()
+ ? lowercaseNameGenerator.nextName()
+ : Configuration.getRenamingOptions().getNameGenerationOptions().getText());
+ }
+ } else {
+ Configuration.getRenamingOptions().getLocalVariableOptions();
+ if (value == 1) {
+ localVariableGen.setName(
+ Configuration.getRenamingOptions().getNameGenerationOptions().getText());
+ } else if (value3 == 0) {
+ localVariableGen.setName(
+ PackageNameTable.getNameGenerator(
+ NamingContext.getPackageNameTable(this.namingContext))
+ .nextName());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void update6() {
+ Iterator iterator2 = this.classHierarchy.getValues().iterator();
+ label35:
+ while (true) {
+ for (Iterator iterator3 = iterator2; iterator3.hasNext(); iterator3 = iterator2) {
+ ClassGen classGen = (ClassGen) iterator2.next();
+ if (!Configuration.getIgnoreClassesOptions().matchesClassGen(this.classStorage, classGen)) {
+ this.processClassGen(classGen);
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ this.processConstantPoolGen(classGen.getAttributes(), constantPool);
+ int value;
+ Method[] methods;
+ for (int value2 = value = (methods = classGen.getMethods()).length - 1;
+ value2 >= 0;
+ value2 = value) {
+ Method method = methods[value];
+ value--;
+ this.processConstantPoolGen(method.getAttributes(), constantPool);
+ }
+ Field[] fields;
+ int value3;
+ for (int value4 = value3 = (fields = classGen.getFields()).length - 1;
+ value4 >= 0;
+ value4 = value3) {
+ Field field = fields[value3];
+ value3--;
+ this.processConstantPoolGen(field.getAttributes(), constantPool);
+ }
+ continue label35;
+ }
+ }
+ return;
+ }
+ }
+
+ public static ClassStorage getClassStorage(NameRenamer nameRenamer) {
+ return nameRenamer.classStorage;
+ }
+
+ public boolean matchesClassGen(ClassGen classGen) {
+ int value;
+ Method[] methods;
+ for (int value2 = value = (methods = classGen.getMethods()).length - 1;
+ value2 >= 0;
+ value2 = --value) {
+ if (methods[value].isEnabled14()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void processConstantPoolGen(
+ AnnotationEntryGen annotationEntryGen, ConstantPoolGen constantPoolGen) {
+ String text;
+ AnnotationEntryGen annotationEntryGen2;
+ label29:
+ {
+ String text2 = annotationEntryGen.getText2();
+ text = null;
+ if (text2.startsWith("L") && text2.endsWith(";")) {
+ String text3;
+ text = text3 = text2.substring(1, text2.length() - 1).replace('/', '.');
+ String text4;
+ if ((text4 =
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text3))
+ != null) {
+ String text5 = "L" + text4.replace('.', '/') + ";";
+ annotationEntryGen2 = annotationEntryGen;
+ annotationEntryGen.setTypeIndex(constantPoolGen.addUtf8(text5));
+ break label29;
+ }
+ text =
+ ParameterNameTable.getLookupTable3(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text);
+ }
+ annotationEntryGen2 = annotationEntryGen;
+ }
+ List values;
+ int value;
+ for (int value2 = value = (values = annotationEntryGen2.getValues()).size() - 1;
+ value2 >= 0;
+ value2 = value) {
+ ElementValuePairGen elementValuePairGen = (ElementValuePairGen) values.get(value);
+ if (text != null) {
+ String text6 = elementValuePairGen.getText();
+ String text7 = "" + text + "&" + text6;
+ if (MethodNameTable.getLookupTable5(NamingContext.getMethodNameTable(this.namingContext))
+ .matchesText(text7)) {
+ String text8 =
+ MethodNameTable.getLookupTable5(NamingContext.getMethodNameTable(this.namingContext))
+ .getText(text7);
+ elementValuePairGen.setNameIdx(constantPoolGen.addUtf8(text8));
+ }
+ }
+ value--;
+ this.processConstantPoolGen(elementValuePairGen.getValue(), constantPoolGen);
+ }
+ }
+
+ public void processConstantPoolGen(Attribute[] attributes, ConstantPoolGen constantPoolGen) {
+ int value;
+ for (int value2 = value = attributes.length - 1; value2 >= 0; value2 = --value) {
+ Attribute attribute;
+ if ((attribute = attributes[value]) instanceof Code) {
+ Code code = (Code) attribute;
+ this.processConstantPoolGen(code.getAttributes(), constantPoolGen);
+ } else if (!(attribute instanceof ConstantValue)
+ && !(attribute instanceof Deprecated)
+ && !(attribute instanceof ExceptionTable)) {
+ if (attribute instanceof InnerClasses) {
+ InnerClass[] innerClasss;
+ if ((innerClasss = ((InnerClasses) attribute).getInnerClasses()).length > 0) {
+ ConstantPool constantPool = constantPoolGen.getConstantPool();
+ int value3;
+ for (int value4 = value3 = innerClasss.length - 1; value4 >= 0; value4 = --value3) {
+ InnerClass innerClass = innerClasss[value3];
+ if (!constantPool
+ .createText(innerClass.getInner_class_index(), (byte) 7)
+ .contains("$")) {
+ innerClass.setInner_name_index(0);
+ }
+ }
+ }
+ } else if (!(attribute instanceof LineNumberTable)
+ && !(attribute instanceof LocalVariableTable)
+ && !(attribute instanceof PMGClass)) {
+ if (attribute instanceof Signature) {
+ Signature signature = (Signature) attribute;
+ String text = ((Signature) attribute).getText();
+ String text2 = this.createText(text);
+ signature.setSignatureIndex(constantPoolGen.addUtf8(text2));
+ } else if (!(attribute instanceof SourceFile)
+ && !(attribute instanceof StackMap)
+ && !(attribute instanceof Synthetic)) {
+ if (attribute instanceof EnclosingMethod) {
+ EnclosingMethod enclosingMethod;
+ if ((enclosingMethod = (EnclosingMethod) attribute).getMethodIndex() != 0) {
+ ConstantPool constantPool2 = constantPoolGen.getConstantPool();
+ String text3 =
+ enclosingMethod.getEnclosingClass().getBytes(constantPool2).replace('/', '.');
+ String text4;
+ if ((text4 =
+ ParameterNameTable.getLookupTable3(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text3))
+ != null) {
+ text3 = text4;
+ }
+ ConstantNameAndType constantNameAndType;
+ if ((constantNameAndType = enclosingMethod.getEnclosingMethod()) != null) {
+ String text5 = constantNameAndType.getText(constantPool2);
+ String text22 = constantNameAndType.getText2(constantPool2);
+ String text6 =
+ MethodNameTable.getLookupTable2(
+ NamingContext.getMethodNameTable(this.namingContext))
+ .getText("" + text3 + "&" + text5 + "&" + text22);
+ String text7 =
+ MethodNameTable.getLookupTable(
+ NamingContext.getMethodNameTable(this.namingContext))
+ .getText(text22);
+ if (text6 != null && !text6.equals(text5) || text7 != null) {
+ if (text6 == null) {
+ text6 = text5;
+ }
+ if (text7 == null) {
+ text7 = text22;
+ }
+ int value5 = constantPoolGen.addNameAndType(text6, text7);
+ enclosingMethod.setMethodIndex(value5);
+ }
+ }
+ }
+ } else if (!(attribute instanceof NestHost)
+ && !(attribute instanceof NestMembers)
+ && attribute instanceof Unknown) {
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public static LookupTable getLookupTable() {
+ return lookupTable;
+ }
+
+ public boolean matchesMethod(String text, Method method) {
+ return method.isEnabled14()
+ || this.classHierarchy.matchesText(text, method.getText(), method.getText2())
+ ? true
+ : "".equals(method.getText())
+ || "".equals(method.getText())
+ || "main".equals(method.getText())
+ && "([Ljava/lang/String;)V".equals(method.getText2());
+ }
+
+ public void processClassGen8(ClassGen classGen) {
+ String className = classGen.getClassName();
+ int value;
+ Method[] methods;
+ for (int value2 = value = (methods = classGen.getMethods()).length - 1;
+ value2 >= 0;
+ value2 = --value) {
+ Method method = methods[value];
+ if (this.matchesMethod(className, method)
+ || !Configuration.getRenamingOptions()
+ .getKeepNamesOptions()
+ .matchesMethod(this.classStorage, classGen, method)) {
+ String text = method.getText();
+ String text2 = method.getText2();
+ if (Configuration.getRenamingOptions()
+ .getNameGenerationOptions()
+ .isMethodsNamingEnabled()) {
+ MainNameGenerator.processText(text);
+ }
+ if (!MethodNameTable.getLookupTable2(NamingContext.getMethodNameTable(this.namingContext))
+ .matchesText("" + className + "&" + text + "&" + text2)) {
+ MethodNameTable.getLookupTable2(NamingContext.getMethodNameTable(this.namingContext))
+ .processText("" + className + "&" + text + "&" + text2, text);
+ MethodNameTable.getLookupTable3(NamingContext.getMethodNameTable(this.namingContext))
+ .processText("" + className + "&" + text + "&" + NameUtils.getText(text2), "&");
+ if (!method.isEnabled9()) {
+ this.processEnabled(
+ classGen,
+ text,
+ text,
+ text2,
+ classGen.isEnabled5(),
+ NameUtils.matchesAccessFlags2(method));
+ }
+ } else if (!method.isEnabled9()) {
+ this.processEnabled(
+ classGen,
+ text,
+ MethodNameTable.getLookupTable2(NamingContext.getMethodNameTable(this.namingContext))
+ .getText("" + className + "&" + text + "&" + text2),
+ text2,
+ classGen.isEnabled5(),
+ NameUtils.matchesAccessFlags2(method));
+ }
+ }
+ }
+ ClassGen classGen2 = classGen;
+ do {
+ String superclassName = classGen2.getSuperclassName();
+ int value3;
+ if ((classGen2 = this.classStorage.getClassGen(superclassName)) != null) {
+ Method[] methods2;
+ for (int value4 = value3 = (methods2 = classGen2.getMethods()).length - 1;
+ value4 >= 0;
+ value4 = --value3) {
+ Method method2 = methods2[value3];
+ if (!this.matchesMethod(superclassName, method2)
+ && !Configuration.getRenamingOptions()
+ .getKeepNamesOptions()
+ .matchesMethod(this.classStorage, classGen, method2)) {
+ String text3 = method2.getText();
+ String text22 = method2.getText2();
+ if (Configuration.getRenamingOptions()
+ .getNameGenerationOptions()
+ .isMethodsNamingEnabled()) {
+ MainNameGenerator.processText(text3);
+ }
+ if (!MethodNameTable.getLookupTable2(
+ NamingContext.getMethodNameTable(this.namingContext))
+ .matchesText("" + superclassName + "&" + text3 + "&" + text22)) {
+ MethodNameTable.getLookupTable2(NamingContext.getMethodNameTable(this.namingContext))
+ .processText("" + superclassName + "&" + text3 + "&" + text22, text3);
+ MethodNameTable.getLookupTable3(NamingContext.getMethodNameTable(this.namingContext))
+ .processText(
+ "" + superclassName + "&" + text3 + "&" + NameUtils.getText(text22), "&");
+ if (!method2.isEnabled9()) {
+ this.processEnabled(
+ classGen2,
+ text3,
+ text3,
+ text22,
+ classGen2.isEnabled5(),
+ NameUtils.matchesAccessFlags2(method2));
+ }
+ } else if (!method2.isEnabled9()) {
+ this.processEnabled(
+ classGen2,
+ text3,
+ MethodNameTable.getLookupTable2(
+ NamingContext.getMethodNameTable(this.namingContext))
+ .getText("" + superclassName + "&" + text3 + "&" + text22),
+ text22,
+ classGen2.isEnabled5(),
+ NameUtils.matchesAccessFlags2(method2));
+ }
+ }
+ }
+ }
+ } while (classGen2 != null);
+ }
+
+ public String createText2(String text) {
+ String text2;
+ if ((text2 =
+ ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext))
+ .getText(text))
+ != null) {
+ return text2;
+ }
+ if (Configuration.getRenamingOptions().isEnabled()) {
+ String text3 = text;
+ LookupTable lookupTable2 =
+ ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext));
+ String text4 = text3;
+ lookupTable2.processText(text3, text3);
+ ClassNameTable.getLookupTable(NamingContext.getClassNameTable(this.namingContext))
+ .processText(text3, "&");
+ while (text4.lastIndexOf(46) > 0) {
+ text3 = text3.substring(0, text3.lastIndexOf(46));
+ lookupTable2 =
+ ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext));
+ text4 = text3;
+ lookupTable2.processText(text3, text3);
+ ClassNameTable.getLookupTable(NamingContext.getClassNameTable(this.namingContext))
+ .processText(text3, "&");
+ }
+ return ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext))
+ .getText(text);
+ } else {
+ StringTokenizer stringTokenizer = new StringTokenizer(text, ".");
+ String text5 = "";
+ label38:
+ while (true) {
+ StringTokenizer stringTokenizer2 = stringTokenizer;
+ while (stringTokenizer2.hasMoreTokens()) {
+ if (text5.length() > 0) {
+ text5 = "" + text5 + ".";
+ }
+ text5 = "" + text5 + stringTokenizer.nextToken();
+ if (ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext))
+ .matchesText(text5)) {
+ continue label38;
+ }
+ ClassNameTable.getNameGenerator(NamingContext.getClassNameTable(this.namingContext))
+ .reset();
+ String text22 = NameUtils.getText2(text5);
+ String text6;
+ if ((text6 =
+ ClassNameTable.getLookupTable2(
+ NamingContext.getClassNameTable(this.namingContext))
+ .getText(text22))
+ .length()
+ > 0) {
+ text6 = "" + text6 + ".";
+ }
+ String text7;
+ do {
+ text7 =
+ ""
+ + text6
+ + ClassNameTable.getNameGenerator(
+ NamingContext.getClassNameTable(this.namingContext))
+ .nextName();
+ } while (ClassNameTable.getLookupTable(
+ NamingContext.getClassNameTable(this.namingContext))
+ .matchesText(text7));
+ stringTokenizer2 = stringTokenizer;
+ ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext))
+ .processText(text5, text7);
+ ClassNameTable.getLookupTable(NamingContext.getClassNameTable(this.namingContext))
+ .processText(text7, "&");
+ }
+ return ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext))
+ .getText(text);
+ }
+ }
+ }
+
+ public boolean matchesEnabled2(ClassGen classGen, String text, String text2, boolean matches) {
+ if (MethodNameTable.getLookupTable3(NamingContext.getMethodNameTable(this.namingContext))
+ .matchesText("" + classGen.getClassName() + "&" + text + "&" + text2)) {
+ return true;
+ }
+ if (!matches) {
+ return false;
+ }
+ int value;
+ Vector vector;
+ for (int value2 =
+ value = (vector = this.classHierarchy.getValues(classGen.getClassName())).size() - 1;
+ value2 >= 0;
+ value2 = --value) {
+ if (this.matchesEnabled2((ClassGen) vector.get(value), text, text2, matches)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String createText3(String text) {
+ if (!text.contains("$")) {
+ return ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text);
+ }
+ String text2;
+ if ((text2 =
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text))
+ == null) {
+ return this.createText3(text.substring(0, text.lastIndexOf(36)));
+ }
+ int value;
+ if ((value = text2.lastIndexOf(46)) != -1) {
+ text2 = text2.substring(value + 1);
+ }
+ int value2;
+ if ((value2 = text2.lastIndexOf(36)) != -1) {
+ text2 = text2.substring(value2 + 1);
+ }
+ return text2.charAt(0) >= '0' && text2.charAt(0) <= '9'
+ ? ("" + this.createText3(text.substring(0, text.lastIndexOf(36))) + '$' + '0' + text2)
+ : ("" + this.createText3(text.substring(0, text.lastIndexOf(36))) + '$' + text2);
+ }
+
+ public void processClassGen9(ClassGen classGen) {
+ if (this.matchesClassGen(classGen)
+ || !Configuration.getRenamingOptions()
+ .getKeepNamesOptions()
+ .matchesClassGen(this.classStorage, classGen)) {
+ String className = classGen.getClassName();
+ byte value = 0;
+ if (ParameterNameTable.getLookupTable(NamingContext.getParameterNameTable(this.namingContext))
+ .matchesText(className)
+ && !className.equals(
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(className))) {
+ value = 1;
+ }
+ if (value == 0) {
+ ParameterNameTable.getLookupTable(NamingContext.getParameterNameTable(this.namingContext))
+ .processText(className, className);
+ ParameterNameTable.getLookupTable3(NamingContext.getParameterNameTable(this.namingContext))
+ .processText(className, className);
+ String text2 = NameUtils.getText2(className);
+ String text;
+ if (Configuration.getRenamingOptions().isText2()
+ && (text =
+ ClassNameTable.getLookupTable2(
+ NamingContext.getClassNameTable(this.namingContext))
+ .getText(text2))
+ != null
+ && !text.equals(text2)) {
+ if (lookupTable.getText(text) == null) {
+ Log.warn("Package '" + text + "' should be un-renamed.");
+ }
+ lookupTable.processText(text, text2);
+ }
+ ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext))
+ .processText(text2, text2);
+ ClassNameTable.getLookupTable(NamingContext.getClassNameTable(this.namingContext))
+ .processText(text2, "&");
+ for (String text3 = text2; text3.lastIndexOf(46) > 0; text3 = text2) {
+ text2 = text2.substring(0, text2.lastIndexOf(46));
+ String text4;
+ if (Configuration.getRenamingOptions().isText2()
+ && (text4 =
+ ClassNameTable.getLookupTable2(
+ NamingContext.getClassNameTable(this.namingContext))
+ .getText(text2))
+ != null
+ && !text4.equals(text2)) {
+ if (lookupTable.getText(text4) == null) {
+ Log.warn("Package '" + text4 + "' should be un-renamed.");
+ }
+ lookupTable.processText(text4, text2);
+ }
+ ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext))
+ .processText(text2, text2);
+ ClassNameTable.getLookupTable(NamingContext.getClassNameTable(this.namingContext))
+ .processText(text2, "&");
+ }
+ } else {
+ String text22 = NameUtils.getText2(className);
+ String text23 =
+ NameUtils.getText2(
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(className));
+ if (!Configuration.getRenamingOptions().isText()
+ || !text23.equals(Configuration.getRenamingOptions().getDefaultPackage())) {
+ if (new StringTokenizer(text22, ".").countTokens()
+ == new StringTokenizer(text23, ".").countTokens()) {
+ ClassNameTable.getLookupTable2(NamingContext.getClassNameTable(this.namingContext))
+ .processText(text22, text23);
+ ClassNameTable.getLookupTable(NamingContext.getClassNameTable(this.namingContext))
+ .processText(text23, "&");
+ String text5 = text22;
+ while (text5.lastIndexOf(46) > 0) {
+ text22 = text22.substring(0, text22.lastIndexOf(46));
+ text23 = text23.substring(0, text23.lastIndexOf(46));
+ LookupTable lookupTable2 =
+ ClassNameTable.getLookupTable2(
+ NamingContext.getClassNameTable(this.namingContext));
+ text5 = text22;
+ lookupTable2.processText(text22, text23);
+ ClassNameTable.getLookupTable(NamingContext.getClassNameTable(this.namingContext))
+ .processText(text23, "&");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void update7() {
+ Iterator iterator2;
+ Iterator iterator3 = iterator2 = this.classHierarchy.getValues().iterator();
+ while (iterator3.hasNext()) {
+ ClassGen classGen = (ClassGen) iterator2.next();
+ if (Configuration.getIgnoreClassesOptions().matchesClassGen(this.classStorage, classGen)) {
+ iterator3 = iterator2;
+ } else {
+ this.processClassGen10(classGen);
+ iterator3 = iterator2;
+ }
+ }
+ }
+
+ public void processClassGen10(ClassGen classGen) {
+ if (ParameterNameTable.getLookupTable2(NamingContext.getParameterNameTable(this.namingContext))
+ .matchesText(classGen.getClassName())
+ || Configuration.getRenamingOptions().isForceDefaultPackageEnabled()) {
+ NameUtils.processAccessFlags(classGen);
+ }
+ if (Configuration.getObfuscationOptions().isFinalizeEnabled()
+ && !classGen.isEnabled15()
+ && !classGen.isEnabled5()
+ && !classGen.isEnabled2()
+ && !classGen.isEnabled10()
+ && this.classHierarchy.getValues(classGen.getClassName()).isEmpty()) {
+ classGen.processEnabled2(true);
+ }
+ String text =
+ ParameterNameTable.getLookupTable(NamingContext.getParameterNameTable(this.namingContext))
+ .getText(classGen.getClassName());
+ if (!classGen.getClassName().equals(text)) {
+ classGen.processText4(text);
+ RenameStatistics.count3++;
+ }
+ this.nameMappingEntry.processClassGen(classGen);
+ String[] texts;
+ int value = (texts = classGen.getInterfaceNames()).length;
+ int value2;
+ for (int value3 = value2 = 0; value3 < value; value3 = ++value2) {
+ String text2 = texts[value2];
+ String text3;
+ if ((text3 =
+ ParameterNameTable.getLookupTable(
+ NamingContext.getParameterNameTable(this.namingContext))
+ .getText(text2))
+ != null) {
+ classGen.processText3(text2);
+ classGen.processText(text3);
+ classGen.getConstantPool().addClass(text3);
+ } else {
+ classGen.processText3(text2);
+ classGen.processText(text2);
+ }
+ }
+ this.processConstantPoolGen(classGen.getAnnotationEntries(), classGen.getConstantPool());
+ }
+
+ public boolean matchesEnabled(
+ ClassGen classGen, String text, String text2, boolean matches, boolean matches2) {
+ if (matches2) {
+ ClassGen classGen2 = classGen;
+ do {
+ String superclassName = classGen2.getSuperclassName();
+ if ((classGen2 = this.classStorage.getClassGen(superclassName)) != null
+ && MethodNameTable.getLookupTable3(NamingContext.getMethodNameTable(this.namingContext))
+ .matchesText("" + classGen2.getClassName() + "&" + text + "&" + text2)) {
+ return true;
+ }
+ } while (classGen2 != null);
+ }
+ if (MethodNameTable.getLookupTable3(NamingContext.getMethodNameTable(this.namingContext))
+ .matchesText("" + classGen.getClassName() + "&" + text + "&" + text2)) {
+ return true;
+ }
+ if (!matches) {
+ return false;
+ }
+ Vector vector;
+ int value;
+ for (int value2 =
+ value = (vector = this.classHierarchy.getValues(classGen.getClassName())).size() - 1;
+ value2 >= 0;
+ value2 = --value) {
+ if (this.matchesEnabled((ClassGen) vector.get(value), text, text2, matches, matches2)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/NameUtils.java b/src/main/java/com/allatori/naming/NameUtils.java
new file mode 100644
index 0000000..25ae614
--- /dev/null
+++ b/src/main/java/com/allatori/naming/NameUtils.java
@@ -0,0 +1,77 @@
+package com.allatori.naming;
+
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.AccessFlags;
+import com.allatori.lib.bcel.generic.ArrayType;
+import com.allatori.lib.bcel.generic.ObjectType;
+import com.allatori.lib.bcel.generic.ReferenceType;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.util.LookupTable;
+
+public class NameUtils {
+
+ public static String getText(String text) {
+ return getText4(text);
+ }
+
+ public static boolean matchesAccessFlags(AccessFlags accessFlags) {
+ return !accessFlags.isEnabled6() && !accessFlags.isEnabled13() && !accessFlags.isEnabled9();
+ }
+
+ public static String getText2(String text) {
+ return getText3(text);
+ }
+
+ public static boolean matchesAccessFlags2(AccessFlags accessFlags) {
+ return matchesAccessFlags(accessFlags);
+ }
+
+ public static String getText3(String text) {
+ int value;
+ return (value = text.lastIndexOf(46)) == -1 ? "" : text.substring(0, value);
+ }
+
+ public static void processAccessFlags(AccessFlags accessFlags) {
+ processAccessFlags2(accessFlags);
+ }
+
+ public static Type getType(Type type, LookupTable lookupTable) {
+ return createType(type, lookupTable);
+ }
+
+ public static String getText4(String text) {
+ return !Configuration.getRenamingOptions().isCompatibleRenamingEnabled()
+ && !Configuration.getRenamingOptions().isEnabled8()
+ ? text
+ : text.substring(0, text.lastIndexOf(41));
+ }
+
+ public static void processAccessFlags2(AccessFlags accessFlags) {
+ accessFlags.processEnabled5(false);
+ accessFlags.processEnabled7(false);
+ accessFlags.processEnabled13(true);
+ }
+
+ public static Type createType(Type type, LookupTable lookupTable) {
+ ReferenceType referenceType = null;
+ if (type instanceof ObjectType) {
+ String className = ((ObjectType) type).getClassName();
+ String text;
+ if ((text = lookupTable.getText(className)) != null && !text.equals(className)) {
+ referenceType = new ObjectType(text);
+ }
+ } else {
+ Type type2;
+ ArrayType arrayType;
+ if (type instanceof ArrayType
+ && (type2 = (arrayType = (ArrayType) type).getBasicType()) instanceof ObjectType) {
+ String className2 = ((ObjectType) type2).getClassName();
+ String text2;
+ if ((text2 = lookupTable.getText(className2)) != null && !text2.equals(className2)) {
+ referenceType = new ArrayType(text2, arrayType.getDimensions());
+ }
+ }
+ }
+ return referenceType;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/NamingConstructorToken.java b/src/main/java/com/allatori/naming/NamingConstructorToken.java
new file mode 100644
index 0000000..8e3494c
--- /dev/null
+++ b/src/main/java/com/allatori/naming/NamingConstructorToken.java
@@ -0,0 +1,3 @@
+package com.allatori.naming;
+
+public class NamingConstructorToken {}
diff --git a/src/main/java/com/allatori/naming/NamingContext.java b/src/main/java/com/allatori/naming/NamingContext.java
new file mode 100644
index 0000000..d71233d
--- /dev/null
+++ b/src/main/java/com/allatori/naming/NamingContext.java
@@ -0,0 +1,50 @@
+package com.allatori.naming;
+
+public class NamingContext {
+
+ public PackageNameTable packageNameTable;
+
+ public MethodNameTable methodNameTable;
+
+ public ParameterNameTable parameterNameTable;
+
+ public FieldNameTable fieldNameTable;
+
+ public final NameRenamer nameRenamer;
+
+ public ClassNameTable classNameTable;
+
+ public static MethodNameTable getMethodNameTable(NamingContext namingContext) {
+ return namingContext.methodNameTable;
+ }
+
+ public NamingContext(NameRenamer nameRenamer, NamingConstructorToken namingConstructorToken) {
+ this(nameRenamer);
+ }
+
+ public static ParameterNameTable getParameterNameTable(NamingContext namingContext) {
+ return namingContext.parameterNameTable;
+ }
+
+ public static ClassNameTable getClassNameTable(NamingContext namingContext) {
+ return namingContext.classNameTable;
+ }
+
+ public static PackageNameTable getPackageNameTable(NamingContext namingContext) {
+ return namingContext.packageNameTable;
+ }
+
+ public NamingContext(NameRenamer nameRenamer2) {
+ super();
+ this.nameRenamer = nameRenamer2;
+ this.classNameTable = new ClassNameTable(this, null);
+ this.parameterNameTable = new ParameterNameTable(this, null);
+ this.methodNameTable = new MethodNameTable(this, null);
+ this.fieldNameTable = new FieldNameTable(this, null);
+ this.packageNameTable = new PackageNameTable(this, null);
+ }
+
+ public static FieldNameTable getFieldNameTable(NamingContext namingContext) {
+ return namingContext.fieldNameTable;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/PackageNameTable.java b/src/main/java/com/allatori/naming/PackageNameTable.java
new file mode 100644
index 0000000..68f6cf5
--- /dev/null
+++ b/src/main/java/com/allatori/naming/PackageNameTable.java
@@ -0,0 +1,27 @@
+package com.allatori.naming;
+
+import com.allatori.config.Configuration;
+import com.allatori.naming.generator.NameGenerator;
+
+public class PackageNameTable {
+
+ public final NamingContext namingContext;
+
+ public NameGenerator nameGenerator;
+
+ public static NameGenerator getNameGenerator(PackageNameTable packageNameTable) {
+ return packageNameTable.nameGenerator;
+ }
+
+ public PackageNameTable(NamingContext namingContext2) {
+ super();
+ this.namingContext = namingContext2;
+ this.nameGenerator =
+ Configuration.getRenamingOptions().getNameGenerationOptions().createNameGenerator3();
+ }
+
+ public PackageNameTable(
+ NamingContext namingContext, NamingConstructorToken namingConstructorToken) {
+ this(namingContext);
+ }
+}
diff --git a/src/main/java/com/allatori/naming/ParameterNameTable.java b/src/main/java/com/allatori/naming/ParameterNameTable.java
new file mode 100644
index 0000000..ceb2ab6
--- /dev/null
+++ b/src/main/java/com/allatori/naming/ParameterNameTable.java
@@ -0,0 +1,49 @@
+package com.allatori.naming;
+
+import com.allatori.config.Configuration;
+import com.allatori.naming.generator.NameGenerator;
+import com.allatori.util.LookupTable;
+
+public class ParameterNameTable {
+
+ public LookupTable lookupTable;
+
+ public LookupTable lookupTable2;
+
+ public LookupTable lookupTable3;
+
+ public NameGenerator nameGenerator;
+
+ public final NamingContext namingContext;
+
+ public ParameterNameTable(NamingContext namingContext2) {
+ super();
+ this.namingContext = namingContext2;
+ this.nameGenerator =
+ Configuration.getRenamingOptions().getNameGenerationOptions().createNameGenerator6();
+ this.lookupTable = new LookupTable();
+ this.lookupTable3 = new LookupTable();
+ this.lookupTable2 = new LookupTable();
+ }
+
+ public static LookupTable getLookupTable(ParameterNameTable parameterNameTable) {
+ return parameterNameTable.lookupTable;
+ }
+
+ public static LookupTable getLookupTable2(ParameterNameTable parameterNameTable) {
+ return parameterNameTable.lookupTable2;
+ }
+
+ public ParameterNameTable(
+ NamingContext namingContext, NamingConstructorToken namingConstructorToken) {
+ this(namingContext);
+ }
+
+ public static NameGenerator getNameGenerator(ParameterNameTable parameterNameTable) {
+ return parameterNameTable.nameGenerator;
+ }
+
+ public static LookupTable getLookupTable3(ParameterNameTable parameterNameTable) {
+ return parameterNameTable.lookupTable3;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/RenameStatistics.java b/src/main/java/com/allatori/naming/RenameStatistics.java
new file mode 100644
index 0000000..1c5f4fd
--- /dev/null
+++ b/src/main/java/com/allatori/naming/RenameStatistics.java
@@ -0,0 +1,10 @@
+package com.allatori.naming;
+
+public class RenameStatistics {
+
+ public static int count;
+
+ public static int count2;
+
+ public static int count3;
+}
diff --git a/src/main/java/com/allatori/naming/RenamingLog.java b/src/main/java/com/allatori/naming/RenamingLog.java
new file mode 100644
index 0000000..d975664
--- /dev/null
+++ b/src/main/java/com/allatori/naming/RenamingLog.java
@@ -0,0 +1,39 @@
+package com.allatori.naming;
+
+import com.allatori.util.LookupTable;
+import java.util.Vector;
+
+public class RenamingLog {
+
+ public LookupTable lookupTable;
+
+ public LookupTable lookupTable2;
+
+ public Vector values;
+
+ public LookupTable lookupTable3;
+
+ public LookupTable lookupTable4;
+
+ public LookupTable lookupTable5;
+
+ public Vector values2;
+
+ public RenamingLog(
+ LookupTable lookupTable6,
+ LookupTable lookupTable7,
+ LookupTable lookupTable8,
+ Vector vector,
+ Vector vector2,
+ LookupTable lookupTable9,
+ LookupTable lookupTable10) {
+ super();
+ this.lookupTable4 = lookupTable6;
+ this.lookupTable5 = lookupTable7;
+ this.lookupTable2 = lookupTable8;
+ this.values2 = vector;
+ this.values = vector2;
+ this.lookupTable3 = lookupTable9;
+ this.lookupTable = lookupTable10;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/AsciiNameGenerator.java b/src/main/java/com/allatori/naming/generator/AsciiNameGenerator.java
new file mode 100644
index 0000000..835eff3
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/AsciiNameGenerator.java
@@ -0,0 +1,39 @@
+package com.allatori.naming.generator;
+
+public class AsciiNameGenerator implements NameGenerator {
+
+ public long seed = 0L;
+
+ public static String text = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
+
+ public static int count = text.length();
+
+ @Override
+ public String nextName() {
+ String text2 = "";
+ long value = this.seed;
+ int value2 = 1;
+ long value3 = count;
+ for (long value4 = value; value4 >= value3; value4 = value) {
+ long value5 = value;
+ value2++;
+ value = value5 - value3;
+ value3 *= count;
+ }
+ int value6;
+ for (int value7 = value6 = 0; value7 < value2; value7 = value6) {
+ text2 = "" + text2 + text.charAt((int) (value % count));
+ int value8 = count;
+ long value9 = value;
+ value6++;
+ value = value9 / value8;
+ }
+ this.seed++;
+ return text2;
+ }
+
+ @Override
+ public void reset() {
+ this.seed = 0L;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/DictionaryNameGenerator.java b/src/main/java/com/allatori/naming/generator/DictionaryNameGenerator.java
new file mode 100644
index 0000000..1b98339
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/DictionaryNameGenerator.java
@@ -0,0 +1,30 @@
+package com.allatori.naming.generator;
+
+public class DictionaryNameGenerator implements NameGenerator {
+
+ public AsciiNameGenerator asciiNameGenerator;
+
+ public int count;
+
+ public String[] texts;
+
+ @Override
+ public String nextName() {
+ return this.count < this.texts.length
+ ? this.texts[this.count++]
+ : this.asciiNameGenerator.nextName();
+ }
+
+ public DictionaryNameGenerator(String[] texts2) {
+ super();
+ this.asciiNameGenerator = new AsciiNameGenerator();
+ this.count = 0;
+ this.texts = texts2;
+ }
+
+ @Override
+ public void reset() {
+ this.count = 0;
+ this.asciiNameGenerator.reset();
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/JavaKeywordNameGenerator.java b/src/main/java/com/allatori/naming/generator/JavaKeywordNameGenerator.java
new file mode 100644
index 0000000..bb7d07e
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/JavaKeywordNameGenerator.java
@@ -0,0 +1,72 @@
+package com.allatori.naming.generator;
+
+import com.allatori.naming.NameComparator;
+import java.util.Arrays;
+
+public class JavaKeywordNameGenerator extends DictionaryNameGenerator {
+
+ public static String[] texts =
+ new String[] {
+ "abstract",
+ "assert",
+ "boolean",
+ "break",
+ "byte",
+ "case",
+ "catch",
+ "char",
+ "class",
+ "const",
+ "continue",
+ "default",
+ "do",
+ "double",
+ "else",
+ "enum",
+ "extends",
+ "false",
+ "final",
+ "finally",
+ "float",
+ "for",
+ "goto",
+ "if",
+ "implements",
+ "import",
+ "instanceof",
+ "int",
+ "interface",
+ "long",
+ "native",
+ "new",
+ "null",
+ "package",
+ "private",
+ "protected",
+ "public",
+ "return",
+ "short",
+ "static",
+ "strictfp",
+ "super",
+ "switch",
+ "synchronized",
+ "this",
+ "throw",
+ "throws",
+ "transient",
+ "true",
+ "try",
+ "void",
+ "volatile",
+ "while"
+ };
+
+ static {
+ Arrays.sort(texts, new NameComparator());
+ }
+
+ public JavaKeywordNameGenerator() {
+ super(texts);
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/LengthBoundNameGenerator.java b/src/main/java/com/allatori/naming/generator/LengthBoundNameGenerator.java
new file mode 100644
index 0000000..38c4fb9
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/LengthBoundNameGenerator.java
@@ -0,0 +1,74 @@
+package com.allatori.naming.generator;
+
+import com.allatori.config.Configuration;
+import com.allatori.util.random.RandomUtils;
+import java.util.Vector;
+
+public class LengthBoundNameGenerator implements NameGenerator {
+
+ public int count;
+
+ public int count2;
+
+ public NameGenerator nameGenerator;
+
+ public Vector values;
+
+ public boolean enabled;
+
+ public boolean enabled2;
+
+ public Vector values2;
+
+ @Override
+ public void reset() {
+ this.count = 0;
+ }
+
+ public LengthBoundNameGenerator(NameGenerator nameGenerator2) {
+ super();
+ this.values = new Vector();
+ this.count = 0;
+ this.values2 = new Vector();
+ this.count2 = 26;
+ this.enabled2 = false;
+ this.enabled = false;
+ this.nameGenerator = nameGenerator2;
+ if (nameGenerator2 instanceof MixedConfusableNameGenerator) {
+ this.enabled2 = true;
+ this.count2 = 1024;
+ }
+ if (nameGenerator2 instanceof LowercaseConfusableNameGenerator) {
+ this.enabled = true;
+ this.count2 = 1024;
+ }
+ }
+
+ @Override
+ public String nextName() {
+ if (this.count < this.values.size()) {
+ return (String) this.values.get(this.count++);
+ }
+ if (!this.enabled2 && this.values.size() == 104) {
+ this.count2 = 299;
+ }
+ int value;
+ for (int value2 = value = 0; value2 < this.count2; value2 = value) {
+ Vector vector = this.values2;
+ value++;
+ vector.add(this.nameGenerator.nextName());
+ }
+ if (Configuration.getRenamingOptions().isRandomizeNamesEnabled()) {
+ RandomUtils.processValues(this.values2);
+ }
+ this.values.addAll(this.values2);
+ this.values2.clear();
+ if (this.enabled2) {
+ MixedConfusableNameGenerator.setText((String) this.values.get(0));
+ }
+ if (this.enabled) {
+ LowercaseConfusableNameGenerator.setText((String) this.values.get(0));
+ }
+ return (String) this.values.get(this.count++);
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/LowercaseConfusableNameGenerator.java b/src/main/java/com/allatori/naming/generator/LowercaseConfusableNameGenerator.java
new file mode 100644
index 0000000..f745c4c
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/LowercaseConfusableNameGenerator.java
@@ -0,0 +1,48 @@
+package com.allatori.naming.generator;
+
+public class LowercaseConfusableNameGenerator implements NameGenerator {
+
+ public static int count = 10;
+
+ public static String text = "l11l1l11l1";
+
+ public long seed = 0L;
+
+ @Override
+ public String nextName() {
+ String text;
+ String text2 = text = Long.toBinaryString(this.seed++);
+ while (text2.length() < count) {
+ text2 = text = '0' + text;
+ }
+ StringBuffer stringBuffer = new StringBuffer(text.length());
+ int value;
+ for (int value2 = value = 0; value2 < text.length(); value2 = ++value) {
+ if (value % 2 == 0) {
+ stringBuffer.append((char) (text.charAt(value) == '0' ? '1' : 'l'));
+ } else {
+ stringBuffer.insert(0, (char) (text.charAt(value) == '0' ? '1' : 'l'));
+ }
+ }
+ return stringBuffer.insert(0, 'l').toString();
+ }
+
+ public static void processCount(int value) {
+ if (value - 1 > count) {
+ count = value - 1;
+ }
+ }
+
+ public static void setText(String text2) {
+ text = text2;
+ }
+
+ @Override
+ public void reset() {
+ this.seed = 0L;
+ }
+
+ public static String nextName2() {
+ return text;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/LowercaseNameGenerator.java b/src/main/java/com/allatori/naming/generator/LowercaseNameGenerator.java
new file mode 100644
index 0000000..6b14fec
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/LowercaseNameGenerator.java
@@ -0,0 +1,38 @@
+package com.allatori.naming.generator;
+
+public class LowercaseNameGenerator implements NameGenerator {
+
+ public static final int COUNT = 26;
+
+ public static String text = "abcdefghijklmnopqrstuvwxyz";
+
+ public long seed = 0L;
+
+ @Override
+ public String nextName() {
+ String text2 = "";
+ long value = this.seed;
+ int value2 = 1;
+ long value3 = 26L;
+ for (long value4 = value; value4 >= value3; value4 = value) {
+ long value5 = value;
+ value2++;
+ value = value5 - value3;
+ value3 *= 26L;
+ }
+ int value6;
+ for (int value7 = value6 = 0; value7 < value2; value7 = value6) {
+ text2 = "" + text2 + text.charAt((int) (value % 26L));
+ long value8 = value;
+ value6++;
+ value = value8 / 26L;
+ }
+ this.seed++;
+ return text2;
+ }
+
+ @Override
+ public void reset() {
+ this.seed = 0L;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/MainNameGenerator.java b/src/main/java/com/allatori/naming/generator/MainNameGenerator.java
new file mode 100644
index 0000000..130fbe2
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/MainNameGenerator.java
@@ -0,0 +1,62 @@
+package com.allatori.naming.generator;
+
+import java.util.Vector;
+
+public class MainNameGenerator implements NameGenerator {
+
+ public boolean enabled;
+
+ public boolean enabled2;
+
+ public static Vector values = new Vector();
+
+ public NameGenerator nameGenerator;
+
+ public static Vector values2 = new Vector();
+
+ public int count;
+
+ public static void processText(String text) {
+ if (text.charAt(0) != '<' && !"main".equals(text)) {
+ if (!values2.contains(text)) {
+ values2.add(text);
+ }
+ }
+ }
+
+ @Override
+ public void reset() {
+ this.count = 0;
+ this.nameGenerator.reset();
+ }
+
+ public static void reset2() {
+ values = new Vector();
+ values2 = new Vector();
+ }
+
+ public static void processText2(String text) {
+ if (!values.contains(text)) {
+ values.add(text);
+ }
+ }
+
+ public MainNameGenerator(NameGenerator nameGenerator2, boolean enabled2, boolean enabled) {
+ super();
+ this.count = 0;
+ this.nameGenerator = nameGenerator2;
+ this.enabled2 = enabled2;
+ this.enabled = enabled;
+ }
+
+ @Override
+ public String nextName() {
+ if (this.enabled2 && this.count < values.size()) {
+ return (String) values.get(this.count++);
+ } else {
+ return this.enabled && this.count < values2.size()
+ ? (String) values2.get(this.count++)
+ : this.nameGenerator.nextName();
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/MemberNameGenerator.java b/src/main/java/com/allatori/naming/generator/MemberNameGenerator.java
new file mode 100644
index 0000000..1302535
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/MemberNameGenerator.java
@@ -0,0 +1,24 @@
+package com.allatori.naming.generator;
+
+public class MemberNameGenerator implements NameGenerator {
+
+ public long seed;
+
+ public String text;
+
+ @Override
+ public String nextName() {
+ return "" + this.text + (this.seed++);
+ }
+
+ @Override
+ public void reset() {
+ this.seed = 0L;
+ }
+
+ public MemberNameGenerator(String text) {
+ super();
+ this.seed = 0L;
+ this.text = text;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/MethodNameGenerator.java b/src/main/java/com/allatori/naming/generator/MethodNameGenerator.java
new file mode 100644
index 0000000..8307651
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/MethodNameGenerator.java
@@ -0,0 +1,28 @@
+package com.allatori.naming.generator;
+
+public class MethodNameGenerator implements NameGenerator {
+
+ public NameGenerator nameGenerator;
+
+ public String text;
+
+ public int count;
+
+ @Override
+ public String nextName() {
+ return this.count++ == 0 ? this.text : this.nameGenerator.nextName();
+ }
+
+ public MethodNameGenerator(String text, NameGenerator nameGenerator2) {
+ super();
+ this.count = 0;
+ this.text = text;
+ this.nameGenerator = nameGenerator2;
+ }
+
+ @Override
+ public void reset() {
+ this.count = 0;
+ this.nameGenerator.reset();
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/MixedConfusableNameGenerator.java b/src/main/java/com/allatori/naming/generator/MixedConfusableNameGenerator.java
new file mode 100644
index 0000000..f8a2c3c
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/MixedConfusableNameGenerator.java
@@ -0,0 +1,48 @@
+package com.allatori.naming.generator;
+
+public class MixedConfusableNameGenerator implements NameGenerator {
+
+ public static int count = 10;
+
+ public static String text = "IiiIiIiiII";
+
+ public long seed = 0L;
+
+ public static void processCount(int value) {
+ if (value > count) {
+ count = value;
+ }
+ }
+
+ public static String nextName2() {
+ return text;
+ }
+
+ @Override
+ public void reset() {
+ this.seed = 0L;
+ }
+
+ @Override
+ public String nextName() {
+ String text;
+ String text2 = text = Long.toBinaryString(this.seed++);
+ while (text2.length() < count) {
+ text2 = text = '0' + text;
+ }
+ StringBuffer stringBuffer = new StringBuffer(text.length());
+ int value;
+ for (int value2 = value = 0; value2 < text.length(); value2 = ++value) {
+ if (value % 2 == 0) {
+ stringBuffer.append((char) (text.charAt(value) == '0' ? 'i' : 'I'));
+ } else {
+ stringBuffer.insert(0, (char) (text.charAt(value) == '0' ? 'i' : 'I'));
+ }
+ }
+ return stringBuffer.toString();
+ }
+
+ public static void setText(String text2) {
+ text = text2;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/NameGenerator.java b/src/main/java/com/allatori/naming/generator/NameGenerator.java
new file mode 100644
index 0000000..1761d16
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/NameGenerator.java
@@ -0,0 +1,8 @@
+package com.allatori.naming.generator;
+
+public interface NameGenerator {
+
+ String nextName();
+
+ void reset();
+}
diff --git a/src/main/java/com/allatori/naming/generator/NumericNameGenerator.java b/src/main/java/com/allatori/naming/generator/NumericNameGenerator.java
new file mode 100644
index 0000000..3cbbee3
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/NumericNameGenerator.java
@@ -0,0 +1,38 @@
+package com.allatori.naming.generator;
+
+public class NumericNameGenerator implements NameGenerator {
+
+ public static String text = "0123456789";
+
+ public long seed = 0L;
+
+ public static final int COUNT = 10;
+
+ @Override
+ public void reset() {
+ this.seed = 0L;
+ }
+
+ @Override
+ public String nextName() {
+ String text2 = "";
+ long value = this.seed;
+ int value2 = 1;
+ long value3 = 10L;
+ for (long value4 = value; value4 >= value3; value4 = value) {
+ long value5 = value;
+ value2++;
+ value = value5 - value3;
+ value3 *= 10L;
+ }
+ int value6;
+ for (int value7 = value6 = 0; value7 < value2; value7 = value6) {
+ text2 = "" + text2 + text.charAt((int) (value % 10L));
+ long value8 = value;
+ value6++;
+ value = value8 / 10L;
+ }
+ this.seed++;
+ return text2;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/PackageNameGenerator.java b/src/main/java/com/allatori/naming/generator/PackageNameGenerator.java
new file mode 100644
index 0000000..e7b7abb
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/PackageNameGenerator.java
@@ -0,0 +1,46 @@
+package com.allatori.naming.generator;
+
+public class PackageNameGenerator implements NameGenerator {
+
+ public String[] texts;
+
+ public int count;
+
+ public long seed;
+
+ @Override
+ public String nextName() {
+ String text = "";
+ long value = this.seed;
+ int value2 = 1;
+ long value3 = this.count;
+ for (long value4 = value; value4 >= value3; value4 = value) {
+ long value5 = value;
+ value2++;
+ value = value5 - value3;
+ value3 *= this.count;
+ }
+ int value6;
+ for (int value7 = value6 = 0; value7 < value2; value7 = value6) {
+ text = "" + text + this.texts[(int) (value % this.count)];
+ int value8 = this.count;
+ long value9 = value;
+ value6++;
+ value = value9 / value8;
+ }
+ this.seed++;
+ return text;
+ }
+
+ public PackageNameGenerator(String[] texts2) {
+ super();
+ this.seed = 0L;
+ this.texts = texts2;
+ this.count = texts2.length;
+ }
+
+ @Override
+ public void reset() {
+ this.seed = 0L;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/PrefixedNameGenerator.java b/src/main/java/com/allatori/naming/generator/PrefixedNameGenerator.java
new file mode 100644
index 0000000..5826ab6
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/PrefixedNameGenerator.java
@@ -0,0 +1,19 @@
+package com.allatori.naming.generator;
+
+public class PrefixedNameGenerator implements NameGenerator {
+
+ public String text;
+
+ @Override
+ public void reset() {}
+
+ @Override
+ public String nextName() {
+ return this.text;
+ }
+
+ public PrefixedNameGenerator(String text) {
+ super();
+ this.text = text;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/RandomizedNameGenerator.java b/src/main/java/com/allatori/naming/generator/RandomizedNameGenerator.java
new file mode 100644
index 0000000..46d8b09
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/RandomizedNameGenerator.java
@@ -0,0 +1,22 @@
+package com.allatori.naming.generator;
+
+public class RandomizedNameGenerator implements NameGenerator {
+
+ public NameGenerator nameGenerator;
+
+ @Override
+ public String nextName() {
+ String text = this.nameGenerator.nextName();
+ return !"r".equals(text) && !"R".equals(text) ? text : this.nextName();
+ }
+
+ @Override
+ public void reset() {
+ this.nameGenerator.reset();
+ }
+
+ public RandomizedNameGenerator(NameGenerator nameGenerator2) {
+ super();
+ this.nameGenerator = nameGenerator2;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/TypeNameGenerator.java b/src/main/java/com/allatori/naming/generator/TypeNameGenerator.java
new file mode 100644
index 0000000..7399409
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/TypeNameGenerator.java
@@ -0,0 +1,24 @@
+package com.allatori.naming.generator;
+
+public class TypeNameGenerator implements NameGenerator {
+
+ public String text;
+
+ public NameGenerator nameGenerator;
+
+ public TypeNameGenerator(String text, NameGenerator nameGenerator2) {
+ super();
+ this.nameGenerator = nameGenerator2;
+ this.text = text;
+ }
+
+ @Override
+ public String nextName() {
+ return "" + this.text + this.nameGenerator.nextName();
+ }
+
+ @Override
+ public void reset() {
+ this.nameGenerator.reset();
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/UppercaseNameGenerator.java b/src/main/java/com/allatori/naming/generator/UppercaseNameGenerator.java
new file mode 100644
index 0000000..0410819
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/UppercaseNameGenerator.java
@@ -0,0 +1,38 @@
+package com.allatori.naming.generator;
+
+public class UppercaseNameGenerator implements NameGenerator {
+
+ public static final int COUNT = 26;
+
+ public static String text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ public long seed = 0L;
+
+ @Override
+ public void reset() {
+ this.seed = 0L;
+ }
+
+ @Override
+ public String nextName() {
+ String text2 = "";
+ long value = this.seed;
+ int value2 = 1;
+ long value3 = 26L;
+ for (long value4 = value; value4 >= value3; value4 = value) {
+ long value5 = value;
+ value2++;
+ value = value5 - value3;
+ value3 *= 26L;
+ }
+ int value6;
+ for (int value7 = value6 = 0; value7 < value2; value7 = value6) {
+ text2 = "" + text2 + text.charAt((int) (value % 26L));
+ long value8 = value;
+ value6++;
+ value = value8 / 26L;
+ }
+ this.seed++;
+ return text2;
+ }
+}
diff --git a/src/main/java/com/allatori/naming/generator/WindowsDeviceNameGenerator.java b/src/main/java/com/allatori/naming/generator/WindowsDeviceNameGenerator.java
new file mode 100644
index 0000000..3726bae
--- /dev/null
+++ b/src/main/java/com/allatori/naming/generator/WindowsDeviceNameGenerator.java
@@ -0,0 +1,35 @@
+package com.allatori.naming.generator;
+
+import com.allatori.naming.NameLengthComparator;
+import java.util.Arrays;
+
+public class WindowsDeviceNameGenerator extends DictionaryNameGenerator {
+
+ public static String[] texts =
+ new String[] {
+ "aux", "Aux", "aUx", "AUx", "auX", "AuX", "aUX", "AUX", "con", "Con", "cOn", "COn", "coN",
+ "CoN", "cON", "CON", "nul", "Nul", "nUl", "NUl", "nuL", "NuL", "nUL", "NUL", "prn", "Prn",
+ "pRn", "PRn", "prN", "PrN", "pRN", "PRN", "com1", "Com1", "cOm1", "COm1", "coM1", "CoM1",
+ "cOM1", "COM1", "com2", "Com2", "cOm2", "COm2", "coM2", "CoM2", "cOM2", "COM2", "com3",
+ "Com3", "cOm3", "COm3", "coM3", "CoM3", "cOM3", "COM3", "com4", "Com4", "cOm4", "COm4",
+ "coM4", "CoM4", "cOM4", "COM4", "com5", "Com5", "cOm5", "COm5", "coM5", "CoM5", "cOM5",
+ "COM5", "com6", "Com6", "cOm6", "COm6", "coM6", "CoM6", "cOM6", "COM6", "com7", "Com7",
+ "cOm7", "COm7", "coM7", "CoM7", "cOM7", "COM7", "com8", "Com8", "cOm8", "COm8", "coM8",
+ "CoM8", "cOM8", "COM8", "com9", "Com9", "cOm9", "COm9", "coM9", "CoM9", "cOM9", "COM9",
+ "lpt1", "Lpt1", "lPt1", "LPt1", "lpT1", "LpT1", "lPT1", "LPT1", "lpt2", "Lpt2", "lPt2",
+ "LPt2", "lpT2", "LpT2", "lPT2", "LPT2", "lpt3", "Lpt3", "lPt3", "LPt3", "lpT3", "LpT3",
+ "lPT3", "LPT3", "lpt4", "Lpt4", "lPt4", "LPt4", "lpT4", "LpT4", "lPT4", "LPT4", "lpt5",
+ "Lpt5", "lPt5", "LPt5", "lpT5", "LpT5", "lPT5", "LPT5", "lpt6", "Lpt6", "lPt6", "LPt6",
+ "lpT6", "LpT6", "lPT6", "LPT6", "lpt7", "Lpt7", "lPt7", "LPt7", "lpT7", "LpT7", "lPT7",
+ "LPT7", "lpt8", "Lpt8", "lPt8", "LPt8", "lpT8", "LpT8", "lPT8", "LPT8", "lpt9", "Lpt9",
+ "lPt9", "LPt9", "lpT9", "LpT9", "lPT9", "LPT9"
+ };
+
+ public WindowsDeviceNameGenerator() {
+ super(texts);
+ }
+
+ static {
+ Arrays.sort(texts, new NameLengthComparator());
+ }
+}
diff --git a/src/main/java/com/allatori/optimizer/ClassUpdateObserver.java b/src/main/java/com/allatori/optimizer/ClassUpdateObserver.java
new file mode 100644
index 0000000..75befa7
--- /dev/null
+++ b/src/main/java/com/allatori/optimizer/ClassUpdateObserver.java
@@ -0,0 +1,10 @@
+package com.allatori.optimizer;
+
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.ClassObserver;
+
+public class ClassUpdateObserver implements ClassObserver {
+
+ @Override
+ public void notify(ClassGen classGen) {}
+}
diff --git a/src/main/java/com/allatori/optimizer/ControlFlowOptimizer.java b/src/main/java/com/allatori/optimizer/ControlFlowOptimizer.java
new file mode 100644
index 0000000..2d735a7
--- /dev/null
+++ b/src/main/java/com/allatori/optimizer/ControlFlowOptimizer.java
@@ -0,0 +1,66 @@
+package com.allatori.optimizer;
+
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.ClassObserver;
+import com.allatori.lib.bcel.generic.InstructionList;
+import com.allatori.lib.bcel.generic.MethodGen;
+
+public class ControlFlowOptimizer implements ClassObserver {
+
+ @Override
+ public void notify(ClassGen classGen) {}
+
+ public void processInstructionList(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList2(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList3(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList4(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList5(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList6(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList7(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processEnabled(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList, boolean matches) {}
+
+ public void processInstructionList8(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList9(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList10(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList11(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList12(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList13(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processEnabled2(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList, boolean matches) {}
+
+ public void processInstructionList14(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList15(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList16(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+}
diff --git a/src/main/java/com/allatori/optimizer/MethodOptimizer.java b/src/main/java/com/allatori/optimizer/MethodOptimizer.java
new file mode 100644
index 0000000..38e81fb
--- /dev/null
+++ b/src/main/java/com/allatori/optimizer/MethodOptimizer.java
@@ -0,0 +1,4817 @@
+package com.allatori.optimizer;
+
+import com.allatori.bytecode.MethodFactory;
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ACONST_NULL;
+import com.allatori.lib.bcel.generic.ALOAD;
+import com.allatori.lib.bcel.generic.ANEWARRAY;
+import com.allatori.lib.bcel.generic.ASTORE;
+import com.allatori.lib.bcel.generic.ATHROW;
+import com.allatori.lib.bcel.generic.ArithmeticInstruction;
+import com.allatori.lib.bcel.generic.ArrayInstruction;
+import com.allatori.lib.bcel.generic.ArrayType;
+import com.allatori.lib.bcel.generic.BIPUSH;
+import com.allatori.lib.bcel.generic.BranchInstruction;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.ClassGenException;
+import com.allatori.lib.bcel.generic.ClassObserver;
+import com.allatori.lib.bcel.generic.CodeExceptionGen;
+import com.allatori.lib.bcel.generic.ConstantPoolGen;
+import com.allatori.lib.bcel.generic.ConstantPushInstruction;
+import com.allatori.lib.bcel.generic.ConversionInstruction;
+import com.allatori.lib.bcel.generic.DCONST;
+import com.allatori.lib.bcel.generic.DLOAD;
+import com.allatori.lib.bcel.generic.DSTORE;
+import com.allatori.lib.bcel.generic.DUP;
+import com.allatori.lib.bcel.generic.FCONST;
+import com.allatori.lib.bcel.generic.FLOAD;
+import com.allatori.lib.bcel.generic.FSTORE;
+import com.allatori.lib.bcel.generic.FieldInstruction;
+import com.allatori.lib.bcel.generic.FieldOrMethod;
+import com.allatori.lib.bcel.generic.GETFIELD;
+import com.allatori.lib.bcel.generic.GETSTATIC;
+import com.allatori.lib.bcel.generic.GOTO;
+import com.allatori.lib.bcel.generic.GotoInstruction;
+import com.allatori.lib.bcel.generic.ICONST;
+import com.allatori.lib.bcel.generic.IFNE;
+import com.allatori.lib.bcel.generic.IINC;
+import com.allatori.lib.bcel.generic.ILOAD;
+import com.allatori.lib.bcel.generic.INVOKESPECIAL;
+import com.allatori.lib.bcel.generic.INVOKEVIRTUAL;
+import com.allatori.lib.bcel.generic.ISTORE;
+import com.allatori.lib.bcel.generic.IfInstruction;
+import com.allatori.lib.bcel.generic.Instruction;
+import com.allatori.lib.bcel.generic.InstructionConstants;
+import com.allatori.lib.bcel.generic.InstructionFactory;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.InstructionList;
+import com.allatori.lib.bcel.generic.InstructionTargeter;
+import com.allatori.lib.bcel.generic.InvokeInstruction;
+import com.allatori.lib.bcel.generic.LCONST;
+import com.allatori.lib.bcel.generic.LDC;
+import com.allatori.lib.bcel.generic.LDC2_W;
+import com.allatori.lib.bcel.generic.LLOAD;
+import com.allatori.lib.bcel.generic.LSTORE;
+import com.allatori.lib.bcel.generic.LineNumberGen;
+import com.allatori.lib.bcel.generic.LoadInstruction;
+import com.allatori.lib.bcel.generic.LocalVariableGen;
+import com.allatori.lib.bcel.generic.LocalVariableInstruction;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.generic.NEW;
+import com.allatori.lib.bcel.generic.NEWARRAY;
+import com.allatori.lib.bcel.generic.NOP;
+import com.allatori.lib.bcel.generic.ObjectType;
+import com.allatori.lib.bcel.generic.POP;
+import com.allatori.lib.bcel.generic.POP2;
+import com.allatori.lib.bcel.generic.PUSH;
+import com.allatori.lib.bcel.generic.PopInstruction;
+import com.allatori.lib.bcel.generic.PushInstruction;
+import com.allatori.lib.bcel.generic.RET;
+import com.allatori.lib.bcel.generic.ReturnInstruction;
+import com.allatori.lib.bcel.generic.Select;
+import com.allatori.lib.bcel.generic.StoreInstruction;
+import com.allatori.lib.bcel.generic.TargetLostException;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.model.ClassStorage;
+import com.allatori.util.Log;
+import com.allatori.util.random.RandomUtils;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Vector;
+
+public class MethodOptimizer implements ClassObserver {
+
+ public ClassStorage classStorage;
+
+ public void processInstructionList(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ int value;
+ int value2;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!this.matchesInstruction(instructionHandle.getInstruction())) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ int value3 = 1;
+ InstructionHandle instructionHandle3;
+ instructionHandle2 = instructionHandle3 = instructionHandle.getInstructionHandle2();
+ while (true) {
+ if (instructionHandle2 == null) {
+ value2 = value3;
+ break;
+ }
+ if (!this.matchesInstruction(instructionHandle3.getInstruction())) {
+ value2 = value3;
+ break;
+ }
+ if (!this.matchesConstantPoolGen(
+ instructionHandle3.getInstruction(),
+ instructionHandle.getInstruction(),
+ classGen.getConstantPool())) {
+ value2 = value3;
+ break;
+ }
+ InstructionHandle instructionHandle4 = instructionHandle3;
+ value3++;
+ instructionHandle3 = instructionHandle4.getInstructionHandle2();
+ instructionHandle2 = instructionHandle3;
+ }
+ if (value2 < 2) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ byte value4 = 1;
+ InstructionHandle instructionHandle22 = instructionHandle.getInstructionHandle2();
+ int value5;
+ int value6 = value5 = 1;
+ while (true) {
+ if (value6 >= value3) {
+ value = value4;
+ break;
+ }
+ if (!this.matchesInstructionTargeters(instructionHandle22.getTargeters())) {
+ value = 0;
+ break;
+ }
+ InstructionHandle instructionHandle5 = instructionHandle22;
+ value5++;
+ instructionHandle22 = instructionHandle5.getInstructionHandle2();
+ value6 = value5;
+ }
+ if (value == 0) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ OptimizationStatistics.count5++;
+ InstructionHandle instructionHandle23 = instructionHandle.getInstructionHandle2();
+ int value7;
+ for (int value8 = value7 = 1; value8 < value3; value8 = value7) {
+ this.processInstructionHandle2(instructionHandle23, instructionHandle);
+ label68:
+ {
+ try {
+ instructionList.processInstructionHandle2(instructionHandle23);
+ } catch (TargetLostException targetLostException) {
+ instructionHandle2 = instructionHandle;
+ break label68;
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ InstructionHandle instructionHandle24 = instructionHandle2.getInstructionHandle2();
+ value7++;
+ instructionHandle23 = instructionHandle24;
+ }
+ int value9;
+ for (int value10 = value9 = 1; value10 < value3; value10 = ++value9) {
+ if (instructionHandle.getInstruction().produceStack(classGen.getConstantPool())
+ == 1) {
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.DUP);
+ } else if (instructionHandle.getInstruction().produceStack(classGen.getConstantPool())
+ == 2) {
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.DUP2);
+ }
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processEnabled(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList, boolean matches) {
+ int value;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof LoadInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else if (!this.matchesInstructionTargeters(instructionHandle.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ int index = ((LoadInstruction) instructionHandle.getInstruction()).getIndex();
+ int value2 = 0;
+ InstructionHandle instructionHandle3 = null;
+ InstructionHandle instructionHandle4 = null;
+ InstructionHandle instructionHandle22 = instructionHandle.getInstructionHandle2();
+ int value3 = 0;
+ while (true) {
+ if (instructionHandle22 != null) {
+ Instruction instruction;
+ if (!((instruction = instructionHandle22.getInstruction())
+ instanceof ArithmeticInstruction)
+ && !(instruction instanceof ArrayInstruction)
+ && !(instruction instanceof ConversionInstruction)
+ && !(instruction instanceof ConstantPushInstruction)
+ && !(instruction instanceof FieldOrMethod)
+ && !(instruction instanceof LocalVariableInstruction)
+ && !(instruction instanceof PushInstruction)
+ && !(instruction instanceof PopInstruction)
+ && !(instruction instanceof NEW)
+ && !(instruction instanceof NEWARRAY)
+ && !(instruction instanceof NOP)) {
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ if ((instruction instanceof StoreInstruction || instruction instanceof IINC)
+ && ((LocalVariableInstruction) instruction).getIndex() == index) {
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ if (!this.matchesInstructionTargeters(instructionHandle22.getTargeters())) {
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ if (value2 == 1) {
+ Instruction instruction2;
+ if ((instruction2 = instructionHandle22.getInstruction()) instanceof LoadInstruction
+ && ((LoadInstruction) instruction2).getIndex() == index) {
+ instructionHandle3 = instructionHandle22;
+ }
+ } else {
+ Instruction instruction3;
+ if (value2 == 2
+ && (instruction3 = instructionHandle22.getInstruction())
+ instanceof LoadInstruction
+ && ((LoadInstruction) instruction3).getIndex() == index) {
+ instructionHandle2 = instructionHandle4 = instructionHandle22;
+ break;
+ }
+ }
+ int value4 = instructionHandle22.getInstruction().produceStack(constantPool);
+ int value5 = instructionHandle22.getInstruction().consumeStack(constantPool);
+ if (value4 != -2) {
+ if (value5 == -2) {
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ int value6;
+ if ((value6 = value2 - value5) < 0) {
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ value2 = value6 + value4;
+ instructionHandle22 = instructionHandle22.getInstructionHandle2();
+ int value7 = value3++;
+ if (value7 <= (short) 777) {
+ continue;
+ }
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ }
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ InstructionHandle instructionHandle5 =
+ instructionHandle2 != null ? instructionHandle4 : instructionHandle3;
+ int value8 = instructionHandle4 != null ? 2 : 1;
+ if (instructionHandle5 == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ label172:
+ {
+ if (!matches) {
+ InstructionHandle instructionHandle23 = instructionHandle.getInstructionHandle2();
+ byte value9 = 0;
+ instructionHandle2 = instructionHandle23;
+ while (true) {
+ if (instructionHandle2 != null && instructionHandle23 != instructionHandle5) {
+ if (instructionHandle23.getInstruction() instanceof LoadInstruction
+ && ((LoadInstruction) instructionHandle23.getInstruction()).getIndex()
+ == index) {
+ instructionHandle2 =
+ instructionHandle23 = instructionHandle23.getInstructionHandle2();
+ continue;
+ }
+ value = 1;
+ break;
+ }
+ value = value9;
+ break;
+ }
+ if (value == 0) {
+ instructionHandle2 = instructionHandle;
+ break label172;
+ }
+ }
+ OptimizationStatistics.count++;
+ InstructionHandle instructionHandle6;
+ InstructionHandle instructionHandle7 =
+ instructionHandle6 = instructionHandle.getInstructionHandle2();
+ this.processInstructionHandle(
+ instructionHandle6.getInstructionHandle(), instructionHandle6);
+ this.processInstructionHandle2(
+ instructionHandle7.getInstructionHandle(), instructionHandle5);
+ label106:
+ {
+ try {
+ instructionList.processInstructionHandle2(
+ instructionHandle6.getInstructionHandle());
+ } catch (TargetLostException targetLostException) {
+ instructionHandle2 = instructionHandle5;
+ break label106;
+ }
+ instructionHandle2 = instructionHandle5;
+ }
+ if (instructionHandle2.getInstruction().produceStack(constantPool) == 1) {
+ if (value8 == 2) {
+ instructionHandle2 = instructionHandle6;
+ instructionList.createInstructionHandle2(
+ instructionHandle5, InstructionConstants.DUP_X2);
+ } else {
+ instructionList.createInstructionHandle2(
+ instructionHandle5, InstructionConstants.DUP_X1);
+ instructionHandle2 = instructionHandle6;
+ }
+ } else {
+ label173:
+ {
+ if (instructionHandle5.getInstruction().produceStack(constantPool) == 2) {
+ if (value8 == 2) {
+ instructionHandle2 = instructionHandle6;
+ instructionList.createInstructionHandle2(
+ instructionHandle5, InstructionConstants.DUP2_X2);
+ break label173;
+ }
+ instructionList.createInstructionHandle2(
+ instructionHandle5, InstructionConstants.DUP2_X1);
+ }
+ instructionHandle2 = instructionHandle6;
+ }
+ }
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList2(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ int value;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof ALOAD)) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle.getInstructionHandle2() == null) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle.getInstructionHandle2().getInstructionHandle2() == null) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ == null) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle.getInstructionHandle2().getInstruction()
+ instanceof GETFIELD)) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstruction()
+ instanceof ALOAD)) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstruction()
+ instanceof GETFIELD)) {
+ instructionHandle2 = instructionHandle;
+ } else if (((ALOAD) instructionHandle.getInstruction()).getIndex()
+ != ((ALOAD)
+ instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstruction())
+ .getIndex()) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle
+ .getInstructionHandle2()
+ .getInstruction()
+ .produceStack(classGen.getConstantPool())
+ != 1) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ byte value2 = 1;
+ InstructionHandle instructionHandle22 = instructionHandle.getInstructionHandle2();
+ int value3;
+ int value4 = value3 = 1;
+ while (true) {
+ if (value4 >= 4) {
+ value = value2;
+ break;
+ }
+ if (!this.matchesInstructionTargeters(instructionHandle22.getTargeters())) {
+ value = 0;
+ break;
+ }
+ InstructionHandle instructionHandle3 = instructionHandle22;
+ value3++;
+ instructionHandle22 = instructionHandle3.getInstructionHandle2();
+ value4 = value3;
+ }
+ if (value == 0) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ OptimizationStatistics.count11++;
+ instructionHandle2 = instructionHandle;
+ this.processInstructionHandle(
+ instructionHandle.getInstructionHandle2().getInstructionHandle2(),
+ instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2());
+ instructionList.processInstructionHandle3(
+ instructionHandle.getInstructionHandle2(),
+ instructionHandle.getInstructionHandle2().getInstructionHandle2());
+ instructionList.createInstructionHandle2(
+ instructionHandle.getInstructionHandle2().getInstructionHandle2(),
+ InstructionConstants.SWAP);
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList3(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ byte value;
+ int value2;
+ FieldInstruction fieldInstruction;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof FieldInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ FieldInstruction fieldInstruction2 = (FieldInstruction) instructionHandle.getInstruction();
+ if (!Configuration.getFieldRemovalOptions()
+ .matchesText(
+ ""
+ + fieldInstruction2.getText2(classGen.getConstantPool())
+ + "."
+ + fieldInstruction2.getFieldName(classGen.getConstantPool())
+ + fieldInstruction2.getText3(classGen.getConstantPool()))) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ label238:
+ {
+ InstructionHandle instructionHandle3;
+ ConstantPoolGen constantPoolGen;
+ label220:
+ {
+ constantPoolGen = classGen.getConstantPool();
+ int value3 = fieldInstruction2.produceStack(constantPoolGen);
+ instructionHandle3 = null;
+ if (value3 > 0) {
+ if (instructionHandle.getInstructionHandle2() != null
+ && (instructionHandle.getInstructionHandle2().getInstruction() instanceof POP
+ || instructionHandle.getInstructionHandle2().getInstruction()
+ instanceof POP2)
+ && instructionHandle
+ .getInstructionHandle2()
+ .getInstruction()
+ .consumeStack(constantPoolGen)
+ == value3) {
+ instructionHandle3 = instructionHandle.getInstructionHandle2();
+ }
+ if (instructionHandle3 == null) {
+ instructionHandle3 = instructionHandle;
+ if (Type.INT.equals(fieldInstruction2.getType2(constantPoolGen))
+ || Type.SHORT.equals(fieldInstruction2.getType2(constantPoolGen))
+ || Type.BYTE.equals(fieldInstruction2.getType2(constantPoolGen))
+ || Type.BOOLEAN.equals(fieldInstruction2.getType2(constantPoolGen))
+ || Type.CHAR.equals(fieldInstruction2.getType2(constantPoolGen))) {
+ instructionList.createInstructionHandle2(instructionHandle3, new ICONST(0));
+ } else if (Type.LONG.equals(fieldInstruction2.getType2(constantPoolGen))) {
+ instructionList.createInstructionHandle2(instructionHandle3, new LCONST(0L));
+ } else if (Type.FLOAT.equals(fieldInstruction2.getType2(constantPoolGen))) {
+ instructionList.createInstructionHandle2(instructionHandle3, new FCONST(0.0F));
+ } else if (Type.DOUBLE.equals(fieldInstruction2.getType2(constantPoolGen))) {
+ instructionList.createInstructionHandle2(instructionHandle3, new DCONST(0.0));
+ } else if (fieldInstruction2.getType2(constantPoolGen) instanceof ArrayType) {
+ instructionList.createInstructionHandle2(instructionHandle3, new ACONST_NULL());
+ } else {
+ if (!(fieldInstruction2.getType2(constantPoolGen) instanceof ObjectType)) {
+ Log.warn(
+ "[remove-fields] Cannot remove field usage ("
+ + fieldInstruction2.getText2(constantPoolGen)
+ + "."
+ + fieldInstruction2.getFieldName(constantPoolGen)
+ + ") in "
+ + classGen.getClassName()
+ + "."
+ + methodGen.getName()
+ + " - the value is used");
+ instructionHandle2 = instructionHandle;
+ break label238;
+ }
+ instructionList.createInstructionHandle2(instructionHandle3, new ACONST_NULL());
+ }
+ Log.warn(
+ "[remove-fields] the value of "
+ + fieldInstruction2.getText2(constantPoolGen)
+ + "."
+ + fieldInstruction2.getFieldName(constantPoolGen)
+ + " in "
+ + classGen.getClassName()
+ + "."
+ + methodGen.getName()
+ + " was replaced with null(0)");
+ fieldInstruction = fieldInstruction2;
+ break label220;
+ }
+ } else {
+ instructionHandle3 = instructionHandle;
+ }
+ fieldInstruction = fieldInstruction2;
+ }
+ int value4 = fieldInstruction.consumeStack(constantPoolGen);
+ InstructionHandle instructionHandle4;
+ instructionHandle2 = instructionHandle4 = instructionHandle;
+ while (true) {
+ if (instructionHandle2.getInstructionHandle() == null) {
+ value2 = value4;
+ break;
+ }
+ if (value4 == 0) {
+ value2 = value4;
+ break;
+ }
+ instructionHandle4 = instructionHandle4.getInstructionHandle();
+ value4 -=
+ instructionHandle4.getInstruction().produceStack(constantPoolGen)
+ - instructionHandle4.getInstruction().consumeStack(constantPoolGen);
+ instructionHandle2 = instructionHandle4;
+ }
+ if (value2 != 0) {
+ Log.warn(
+ "[remove-fields] Cannot remove field usage ("
+ + fieldInstruction2.getText2(constantPoolGen)
+ + "."
+ + fieldInstruction2.getFieldName(constantPoolGen)
+ + ") in "
+ + classGen.getClassName()
+ + "."
+ + methodGen.getName()
+ + " - object not found");
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle5 = instructionHandle4;
+ InstructionHandle instructionHandle6 = instructionHandle4;
+ int value5 = 0;
+ label191:
+ while (true) {
+ instructionHandle2 = instructionHandle6;
+ while (instructionHandle2 != instructionHandle3
+ && instructionHandle6.getInstructionHandle2() != null) {
+ instructionHandle6 = instructionHandle6.getInstructionHandle2();
+ if (this.matchesInstructionTargeters(instructionHandle6.getTargeters())) {
+ continue label191;
+ }
+ InstructionHandle instructionHandle7 = instructionHandle6;
+ value5++;
+ instructionHandle2 = instructionHandle7;
+ }
+ if (value5 == 1) {
+ byte value6 = 0;
+ InstructionTargeter[] instructionTargeters;
+ if ((instructionTargeters = instructionHandle3.getTargeters()) != null) {
+ InstructionTargeter[] instructionTargeters2 = instructionTargeters;
+ int value7 = instructionTargeters.length;
+ int value8;
+ for (int value9 = value8 = 0; value9 < value7; value9 = ++value8) {
+ InstructionTargeter instructionTargeter;
+ if (!((instructionTargeter = instructionTargeters2[value8])
+ instanceof LineNumberGen)
+ && !(instructionTargeter instanceof LocalVariableGen)
+ && instructionTargeter instanceof CodeExceptionGen) {
+ value6 = 1;
+ }
+ }
+ }
+ if (value6 != 0 && instructionHandle5 != instructionHandle3) {
+ instructionHandle3.setInstruction(InstructionConstants.NOP);
+ instructionHandle3 = instructionHandle3.getInstructionHandle();
+ value5 = 0;
+ }
+ }
+ if (value5 > 0) {
+ Log.warn(
+ "[remove-fields] Cannot remove field usage ("
+ + fieldInstruction2.getText2(constantPoolGen)
+ + "."
+ + fieldInstruction2.getFieldName(constantPoolGen)
+ + ") in "
+ + classGen.getClassName()
+ + "."
+ + methodGen.getName()
+ + " - targeters inside block");
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle8;
+ if ((instructionHandle8 = instructionHandle3.getInstructionHandle2()) == null) {
+ Log.warn(
+ "[remove-fields] Cannot remove field usage ("
+ + fieldInstruction2.getText2(constantPoolGen)
+ + "."
+ + fieldInstruction2.getFieldName(constantPoolGen)
+ + ") in "
+ + classGen.getClassName()
+ + "."
+ + methodGen.getName()
+ + " - unexpected end of block");
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionTargeter[] instructionTargeters3;
+ if ((instructionTargeters3 = instructionHandle5.getTargeters()) != null) {
+ InstructionTargeter[] instructionTargeters4 = instructionTargeters3;
+ int value10 = instructionTargeters3.length;
+ int value11;
+ for (int value12 = value11 = 0; value12 < value10; value12 = ++value11) {
+ InstructionTargeter instructionTargeter2;
+ if (!((instructionTargeter2 = instructionTargeters4[value11])
+ instanceof LineNumberGen)
+ && !(instructionTargeter2 instanceof LocalVariableGen)) {
+ instructionTargeter2.updateTarget(instructionHandle5, instructionHandle8);
+ }
+ }
+ }
+ InstructionHandle instructionHandle9 = instructionHandle8;
+ do {
+ instructionHandle9 = instructionHandle9.getInstructionHandle();
+ this.processInstructionHandle(instructionHandle9, instructionHandle8);
+ this.processInstructionHandle2(instructionHandle9, instructionHandle8);
+ } while (instructionHandle9 != instructionHandle5
+ && instructionHandle9.getInstructionHandle() != null);
+ byte value13 = 0;
+ InstructionHandle instructionHandle10;
+ instructionHandle2 = instructionHandle10 = instructionHandle3;
+ while (true) {
+ if (instructionHandle2 == instructionHandle5) {
+ value = value13;
+ break;
+ }
+ if (instructionHandle10.getInstruction() instanceof IfInstruction) {
+ byte value14 = 1;
+ instructionHandle5 = instructionHandle10.getInstructionHandle2();
+ value = value14;
+ break;
+ }
+ instructionHandle2 =
+ instructionHandle10 = instructionHandle10.getInstructionHandle();
+ }
+ label145:
+ if (value == 0) {
+ try {
+ instructionList.processInstructionHandle(
+ instructionHandle5, instructionHandle3);
+ } catch (TargetLostException targetLostException) {
+ instructionHandle2 = instructionHandle8;
+ break label145;
+ }
+ instructionHandle2 = instructionHandle8;
+ } else {
+ label236:
+ {
+ int value15 =
+ instructionHandle3.getInstruction().consumeStack(constantPoolGen);
+ InstructionHandle instructionHandle11;
+ for (InstructionHandle instructionHandle12 =
+ instructionHandle11 = instructionHandle5;
+ instructionHandle12 != instructionHandle3;
+ instructionHandle12 =
+ instructionHandle11 = instructionHandle11.getInstructionHandle2()) {
+ value15 -=
+ instructionHandle11.getInstruction().produceStack(constantPoolGen)
+ - instructionHandle11
+ .getInstruction()
+ .consumeStack(constantPoolGen);
+ }
+ int value16;
+ for (int value17 = value16 = 0; value17 < value15; value17 = value16) {
+ value16++;
+ instructionList.createInstructionHandle2(instructionHandle3, new POP());
+ }
+ try {
+ instructionList.processInstructionHandle(
+ instructionHandle5, instructionHandle3);
+ } catch (TargetLostException targetLostException2) {
+ instructionHandle2 = instructionHandle8;
+ break label236;
+ }
+ instructionHandle2 = instructionHandle8;
+ }
+ }
+ if (instructionHandle2.getInstructionHandle() != null) {
+ instructionHandle2 = instructionHandle8.getInstructionHandle();
+ } else {
+ InstructionHandle instructionHandle13 = instructionHandle8;
+ instructionHandle2 = instructionHandle13;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList4(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ InstructionHandle instructionHandle;
+ int value;
+ for (InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ instructionHandle2 != null;
+ instructionHandle2 = instructionHandle = instructionHandle.getInstructionHandle2()) {
+ for (int value2 = value = 0; value2 < 1 + RandomUtils.calculateCount(3); value2 = value) {
+ instructionList.createInstructionHandle(
+ instructionHandle, new BIPUSH((byte) (RandomUtils.calculateCount(120) - 120)));
+ value++;
+ instructionList.createInstructionHandle(instructionHandle, InstructionConstants.POP);
+ }
+ }
+ }
+
+ public void processInstructionList5(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ LocalVariableGen[] localVariableGens;
+ if ((localVariableGens = methodGen.getLocalVariables()) != null) {
+ if (localVariableGens.length != 0) {
+ boolean[] matchess = new boolean[methodGen.getCount()];
+ int value = methodGen.getArgumentNames().length;
+ if (!methodGen.isEnabled11()) {
+ value++;
+ }
+ Type[] types;
+ int value2 = (types = methodGen.getArgumentTypes()).length;
+ int value3;
+ for (int value4 = value3 = 0; value4 < value2; value4 = ++value3) {
+ Type type;
+ if ((type = types[value3]) == Type.LONG || type == Type.DOUBLE) {
+ value++;
+ }
+ }
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (instructionHandle.getInstruction() instanceof LoadInstruction) {
+ LoadInstruction loadInstruction = (LoadInstruction) instructionHandle.getInstruction();
+ instructionHandle2 = instructionHandle;
+ matchess[loadInstruction.getIndex()] = true;
+ } else {
+ if (instructionHandle.getInstruction() instanceof RET) {
+ RET rET = (RET) instructionHandle.getInstruction();
+ matchess[rET.getIndex()] = true;
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ InstructionHandle instructionHandle3;
+ instructionHandle2 = instructionHandle3 = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (instructionHandle3.getInstruction() instanceof StoreInstruction) {
+ StoreInstruction storeInstruction =
+ (StoreInstruction) instructionHandle3.getInstruction();
+ if (!matchess[storeInstruction.getIndex()] && storeInstruction.getIndex() >= value) {
+ if (storeInstruction instanceof ASTORE
+ || storeInstruction instanceof ISTORE
+ || storeInstruction instanceof FSTORE) {
+ instructionHandle3.setInstruction(InstructionConstants.POP);
+ } else if (storeInstruction instanceof LSTORE || storeInstruction instanceof DSTORE) {
+ instructionHandle3.setInstruction(InstructionConstants.POP2);
+ }
+ }
+ } else if (instructionHandle3.getInstruction() instanceof IINC) {
+ IINC iNC = (IINC) instructionHandle3.getInstruction();
+ if (!matchess[iNC.getIndex()] && iNC.getIndex() >= value) {
+ InstructionHandle instructionHandle4 = instructionHandle3;
+ instructionHandle3 = instructionHandle3.getInstructionHandle2();
+ if (this.matchesInstructionTargeters(instructionHandle4.getTargeters())) {
+ try {
+ instructionList.processInstructionHandle2(instructionHandle4);
+ } catch (TargetLostException targetLostException) {
+ instructionHandle2 = instructionHandle3;
+ continue;
+ }
+ instructionHandle2 = instructionHandle3;
+ continue;
+ }
+ instructionHandle4.setInstruction(InstructionConstants.NOP);
+ instructionHandle2 = instructionHandle3;
+ continue;
+ }
+ }
+ instructionHandle2 = instructionHandle3 = instructionHandle3.getInstructionHandle2();
+ }
+ LocalVariableGen[] localVariableGens2 = localVariableGens;
+ int value5 = localVariableGens.length;
+ int value6;
+ for (int value7 = value6 = 0; value7 < value5; value7 = ++value6) {
+ LocalVariableGen localVariableGen;
+ if ((localVariableGen = localVariableGens2[value6]).getIndex() >= value
+ && !matchess[localVariableGen.getIndex()]) {
+ methodGen.removeLocalVariable(localVariableGen);
+ OptimizationStatistics.count16++;
+ }
+ }
+ }
+ }
+ }
+
+ public boolean matchesInstructionHandle(
+ InstructionList instructionList,
+ InstructionHandle instructionHandle,
+ InstructionHandle instructionHandle2) {
+ int index = ((LocalVariableInstruction) instructionHandle.getInstruction()).getIndex();
+ InstructionHandle instructionHandle3;
+ for (InstructionHandle instructionHandle4 = instructionHandle3 = instructionList.getStart();
+ instructionHandle4 != null;
+ instructionHandle4 = instructionHandle3 = instructionHandle3.getInstructionHandle2()) {
+ Instruction instruction;
+ if ((instruction = instructionHandle3.getInstruction()) instanceof LocalVariableInstruction
+ && ((LocalVariableInstruction) instruction).getIndex() == index
+ && instructionHandle3 != instructionHandle
+ && instructionHandle3 != instructionHandle2) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void processInstructionList6(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ int value;
+ int value2;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof IINC)) {
+ instructionHandle2 = instructionHandle;
+ } else if (!this.matchesInstructionTargeters(instructionHandle.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ IINC iNC = (IINC) instructionHandle.getInstruction();
+ int value3 = 0;
+ byte value4 = 0;
+ InstructionHandle instructionHandle3 = instructionHandle.getInstructionHandle();
+ label141:
+ while (true) {
+ instructionHandle2 = instructionHandle3;
+ while (instructionHandle2 != null && value3 < 3) {
+ if (!this.matchesInstructionTargeters(instructionHandle3.getTargeters())) {
+ value2 = value4;
+ break label141;
+ }
+ if (instructionHandle3.getInstruction() instanceof BranchInstruction) {
+ value2 = value4;
+ break label141;
+ }
+ if (instructionHandle3.getInstruction() instanceof LocalVariableInstruction
+ && ((LocalVariableInstruction) instructionHandle3.getInstruction()).getIndex()
+ == iNC.getIndex()) {
+ value2 = value4;
+ break label141;
+ }
+ if (instructionHandle3.getInstruction() instanceof ArrayInstruction) {
+ value2 = 1;
+ break label141;
+ }
+ if ((instructionHandle3 = instructionHandle3.getInstructionHandle()) == null) {
+ continue label141;
+ }
+ InstructionHandle instructionHandle4 = instructionHandle3;
+ value3++;
+ instructionHandle2 = instructionHandle4;
+ }
+ value2 = value4;
+ break;
+ }
+ if (value2 != 0) {
+ InstructionHandle instructionHandle22 = instructionHandle.getInstructionHandle2();
+ instructionHandle2 = instructionHandle22;
+ this.processInstructionHandle(
+ instructionHandle22.getInstructionHandle(), instructionHandle22);
+ instructionList.processInstructionHandle3(
+ instructionHandle22.getInstructionHandle(),
+ instructionHandle3.getInstructionHandle());
+ OptimizationStatistics.count27++;
+ OptimizationStatistics.count20++;
+ } else {
+ label155:
+ {
+ int value5 = 0;
+ if (value3 < 3) {
+ byte value6 = 0;
+ InstructionHandle instructionHandle23 = instructionHandle.getInstructionHandle2();
+ label115:
+ while (true) {
+ instructionHandle2 = instructionHandle23;
+ while (instructionHandle2 != null && value5 < 3) {
+ if (!this.matchesInstructionTargeters(instructionHandle23.getTargeters())) {
+ value = value6;
+ break label115;
+ }
+ if (instructionHandle23.getInstruction() instanceof BranchInstruction) {
+ value = value6;
+ break label115;
+ }
+ if (instructionHandle23.getInstruction() instanceof LocalVariableInstruction
+ && ((LocalVariableInstruction) instructionHandle23.getInstruction())
+ .getIndex()
+ == iNC.getIndex()) {
+ value = value6;
+ break label115;
+ }
+ if (value5 > 0
+ && instructionHandle23.getInstruction() instanceof ArrayInstruction) {
+ value = 1;
+ break label115;
+ }
+ if ((instructionHandle23 = instructionHandle23.getInstructionHandle2()) == null) {
+ continue label115;
+ }
+ InstructionHandle instructionHandle5 = instructionHandle23;
+ value5++;
+ instructionHandle2 = instructionHandle5;
+ }
+ value = value6;
+ break;
+ }
+ if (value != 0) {
+ this.processInstructionHandle(
+ instructionHandle, instructionHandle.getInstructionHandle2());
+ instructionList.processInstructionHandle3(
+ instructionHandle, instructionHandle23.getInstructionHandle());
+ InstructionHandle instructionHandle6 = instructionHandle23;
+ OptimizationStatistics.count27++;
+ OptimizationStatistics.count20++;
+ instructionHandle2 = instructionHandle6;
+ break label155;
+ }
+ }
+ if (value3 == 0 && value5 == 0) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ OptimizationStatistics.count27++;
+ this.processInstructionHandle(
+ instructionHandle, instructionHandle.getInstructionHandle2());
+ if (value3 > 3) {
+ value3 = 3;
+ }
+ if (value5 > 3) {
+ value5 = 3;
+ }
+ if (value3 == 3) {
+ InstructionHandle instructionHandle24 = instructionHandle.getInstructionHandle2();
+ InstructionHandle instructionHandle7 = instructionHandle24.getInstructionHandle();
+ instructionHandle2 = instructionHandle24;
+ instructionList.processInstructionHandle3(
+ instructionHandle7,
+ instructionHandle24
+ .getInstructionHandle()
+ .getInstructionHandle()
+ .getInstructionHandle()
+ .getInstructionHandle()
+ .getInstructionHandle());
+ } else if (value5 == 3) {
+ instructionHandle2 = instructionHandle;
+ instructionList.processInstructionHandle3(
+ instructionHandle,
+ instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2());
+ } else if (value3 == 2) {
+ InstructionHandle instructionHandle25 = instructionHandle.getInstructionHandle2();
+ InstructionHandle instructionHandle8 = instructionHandle25.getInstructionHandle();
+ instructionHandle2 = instructionHandle25;
+ instructionList.processInstructionHandle3(
+ instructionHandle8,
+ instructionHandle25
+ .getInstructionHandle()
+ .getInstructionHandle()
+ .getInstructionHandle()
+ .getInstructionHandle());
+ } else if (value5 == 2) {
+ instructionHandle2 = instructionHandle;
+ instructionList.processInstructionHandle3(
+ instructionHandle,
+ instructionHandle.getInstructionHandle2().getInstructionHandle2());
+ } else if (value3 == 1) {
+ InstructionHandle instructionHandle26 = instructionHandle.getInstructionHandle2();
+ InstructionHandle instructionHandle9 = instructionHandle26.getInstructionHandle();
+ instructionHandle2 = instructionHandle26;
+ instructionList.processInstructionHandle3(
+ instructionHandle9,
+ instructionHandle26
+ .getInstructionHandle()
+ .getInstructionHandle()
+ .getInstructionHandle());
+ } else {
+ if (value5 == 1) {
+ instructionList.processInstructionHandle3(
+ instructionHandle, instructionHandle.getInstructionHandle2());
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ }
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList7(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ if (classGen.getMajor() <= 50) {
+ InstructionHandle instructionHandle = null;
+ InstructionHandle instructionHandle2 = null;
+ InstructionHandle instructionHandle3;
+ InstructionHandle instructionHandle4 = instructionHandle3 = instructionList.getStart();
+ while (true) {
+ if (instructionHandle4 == null) {
+ instructionHandle4 = instructionHandle;
+ break;
+ }
+ if (!(instructionHandle3.getInstruction() instanceof GOTO)
+ && !(instructionHandle3.getInstruction() instanceof ReturnInstruction)) {
+ instructionHandle4 = instructionHandle2;
+ } else if (instructionHandle3.getInstructionHandle2() == null) {
+ instructionHandle4 = instructionHandle2;
+ } else {
+ label46:
+ {
+ if (instructionHandle3.getInstruction() instanceof GOTO) {
+ GOTO gOTO;
+ if ((gOTO = (GOTO) instructionHandle3.getInstruction()).getTarget() == null) {
+ instructionHandle4 = instructionHandle2;
+ break label46;
+ }
+ if (Math.abs(instructionHandle3.getPosition() - gOTO.getTarget().getPosition())
+ > 32000) {
+ instructionHandle4 = instructionHandle2;
+ break label46;
+ }
+ }
+ if (instructionHandle == null) {
+ instructionHandle = instructionHandle3;
+ instructionHandle4 = instructionHandle2;
+ } else {
+ instructionHandle2 = instructionHandle3;
+ instructionHandle4 = instructionHandle2;
+ }
+ }
+ }
+ if (instructionHandle4 != null) {
+ instructionHandle4 = instructionHandle;
+ break;
+ }
+ instructionHandle4 = instructionHandle3 = instructionHandle3.getInstructionHandle2();
+ }
+ if (instructionHandle4 != null) {
+ instructionList.createInstructionHandle2(instructionHandle, InstructionConstants.POP);
+ OptimizationStatistics.count32++;
+ if (instructionHandle2 != null) {
+ instructionList.createInstructionHandle2(
+ instructionHandle2, InstructionConstants.ICONST_0);
+ }
+ }
+ }
+ }
+
+ public void processEnabled2(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList, boolean matches) {
+ Vector vector;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof ALOAD)) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ int index = ((ALOAD) instructionHandle.getInstruction()).getIndex();
+ if (!matches && !this.matchesInstructionTargeters(instructionHandle.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ int value = instructionHandle.getInstruction().produceStack(constantPool);
+ Vector vector2;
+ (vector2 = new Vector()).add(instructionHandle);
+ InstructionHandle instructionHandle22 = instructionHandle.getInstructionHandle2();
+ int value2 = 0;
+ while (true) {
+ if (instructionHandle22 != null) {
+ Instruction instruction;
+ if (!((instruction = instructionHandle22.getInstruction())
+ instanceof ArithmeticInstruction)
+ && !(instruction instanceof ArrayInstruction)
+ && !(instruction instanceof ConversionInstruction)
+ && !(instruction instanceof ConstantPushInstruction)
+ && !(instruction instanceof FieldOrMethod)
+ && !(instruction instanceof LocalVariableInstruction)
+ && !(instruction instanceof PushInstruction)
+ && !(instruction instanceof PopInstruction)
+ && !(instruction instanceof NEW)
+ && !(instruction instanceof NEWARRAY)
+ && !(instruction instanceof NOP)) {
+ vector = vector2;
+ break;
+ }
+ if (!this.matchesInstructionTargeters(instructionHandle22.getTargeters())) {
+ vector = vector2;
+ break;
+ }
+ label121:
+ {
+ if (value == 0 && instructionHandle22.getInstruction() instanceof ALOAD) {
+ if (!matches) {
+ instructionHandle2 = instructionHandle22;
+ vector2.add(instructionHandle22);
+ break label121;
+ }
+ if (((ALOAD) instructionHandle22.getInstruction()).getIndex() == index) {
+ vector2.add(instructionHandle22);
+ }
+ }
+ instructionHandle2 = instructionHandle22;
+ }
+ if (instructionHandle2.getInstruction() instanceof ASTORE) {
+ if (matches
+ && ((ASTORE) instructionHandle22.getInstruction()).getIndex() == index) {
+ vector = vector2;
+ break;
+ }
+ if (!matches) {
+ vector = vector2;
+ break;
+ }
+ }
+ int value3 = instructionHandle22.getInstruction().produceStack(constantPool);
+ int value4 = instructionHandle22.getInstruction().consumeStack(constantPool);
+ if (value3 != -2) {
+ if (value4 == -2) {
+ vector = vector2;
+ break;
+ }
+ int value5;
+ if ((value5 = value - value4) < 0) {
+ vector = vector2;
+ break;
+ }
+ value = value5 + value3;
+ instructionHandle22 = instructionHandle22.getInstructionHandle2();
+ int value6 = value2++;
+ if (value6 <= (short) 777) {
+ continue;
+ }
+ vector = vector2;
+ break;
+ }
+ }
+ vector = vector2;
+ break;
+ }
+ if (vector.size() < 2) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ if (vector2.size() > 1) {
+ OptimizationStatistics.count14++;
+ }
+ if (vector2.size() > 2) {
+ OptimizationStatistics.count33++;
+ }
+ int value7;
+ int value8;
+ if (matches) {
+ for (int value9 = value8 = vector2.size() - 1; value9 >= 1; value9 = value8) {
+ this.processInstructionHandle(
+ (InstructionHandle) vector2.get(value8),
+ ((InstructionHandle) vector2.get(value8)).getInstructionHandle2());
+ InstructionHandle instructionHandle3 = (InstructionHandle) vector2.get(value8);
+ Vector vector3 = vector2;
+ value8--;
+ instructionList.processInstructionHandle3(
+ instructionHandle3, (InstructionHandle) vector3.get((byte) 0));
+ }
+ } else {
+ for (int value10 = value7 = vector2.size() - 1; value10 >= 1; value10 = value7) {
+ this.processInstructionHandle(
+ (InstructionHandle) vector2.get(value7),
+ ((InstructionHandle) vector2.get(value7)).getInstructionHandle2());
+ InstructionHandle instructionHandle4 = (InstructionHandle) vector2.get(value7);
+ Object result = vector2.get(0);
+ value7--;
+ instructionList.processInstructionHandle3(
+ instructionHandle4, ((InstructionHandle) result).getInstructionHandle());
+ }
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList8(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ OptimizationStatistics.count30++;
+ LocalVariableGen[] localVariableGens;
+ if ((localVariableGens = methodGen.getLocalVariables()) != null) {
+ if (localVariableGens.length != 0) {
+ boolean[] matchess = new boolean[methodGen.getCount()];
+ int value = methodGen.getArgumentNames().length;
+ if (!methodGen.isEnabled11()) {
+ value++;
+ }
+ Type[] types;
+ int value2 = (types = methodGen.getArgumentTypes()).length;
+ int value3;
+ for (int value4 = value3 = 0; value4 < value2; value4 = ++value3) {
+ Type type;
+ if ((type = types[value3]) == Type.LONG || type == Type.DOUBLE) {
+ value++;
+ }
+ }
+ LocalVariableGen[] localVariableGens2 = localVariableGens;
+ int value5 = localVariableGens.length;
+ int value6;
+ for (int value7 = value6 = 0; value7 < value5; value7 = ++value6) {
+ LocalVariableGen localVariableGen;
+ if ((localVariableGen = localVariableGens2[value6]).getType() == Type.BOOLEAN
+ || localVariableGen.getType() == Type.BYTE
+ || localVariableGen.getType() == Type.SHORT
+ || localVariableGen.getType() == Type.CHAR) {
+ localVariableGen.setType(Type.INT);
+ }
+ }
+ InstructionHandle instructionHandle;
+ for (InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ instructionHandle2 != null;
+ instructionHandle2 = instructionHandle = instructionHandle.getInstructionHandle2()) {
+ if (instructionHandle.getInstruction() instanceof LocalVariableInstruction) {
+ LocalVariableInstruction localVariableInstruction =
+ (LocalVariableInstruction) instructionHandle.getInstruction();
+ matchess[localVariableInstruction.getIndex()] = true;
+ }
+ }
+ LocalVariableGen[] localVariableGens3 = localVariableGens;
+ int value8 = localVariableGens.length;
+ int value9;
+ for (int value10 = value9 = 0; value10 < value8; value10 = ++value9) {
+ LocalVariableGen localVariableGen2;
+ if ((localVariableGen2 = localVariableGens3[value9]).getIndex() >= value
+ && !matchess[localVariableGen2.getIndex()]) {
+ methodGen.removeLocalVariable(localVariableGen2);
+ OptimizationStatistics.count6++;
+ }
+ }
+ instructionList.update();
+ LocalVariableGen[] localVariableGens4 = localVariableGens;
+ int value11 = localVariableGens.length;
+ int value12;
+ for (int value13 = value12 = 0; value13 < value11; value13 = ++value12) {
+ LocalVariableGen localVariableGen3;
+ if ((localVariableGen3 = localVariableGens4[value12]).getInstructionHandle() != null
+ && localVariableGen3.getInstructionHandle2() != null
+ && localVariableGen3.getInstructionHandle().getPosition()
+ > localVariableGen3.getInstructionHandle2().getPosition()) {
+ InstructionHandle instructionHandle3 = localVariableGen3.getInstructionHandle();
+ localVariableGen3.processInstructionHandle2(localVariableGen3.getInstructionHandle2());
+ localVariableGen3.processInstructionHandle(instructionHandle3);
+ }
+ }
+ }
+ }
+ }
+
+ public void processCount(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList, int value) {
+ InstructionList instructionList2;
+ InstructionList instructionList3;
+ InstructionList instructionList4;
+ int value2 = 0;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (value2 >= value) {
+ instructionHandle2 = instructionHandle;
+ } else if (!this.matchesInstructionTargeters(instructionHandle.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ if (instructionHandle.getInstruction() instanceof ConstantPushInstruction) {
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ ConstantPushInstruction constantPushInstruction;
+ if ((constantPushInstruction =
+ (ConstantPushInstruction) instructionHandle.getInstruction())
+ .getType(constantPool)
+ == Type.LONG
+ && constantPushInstruction instanceof LCONST) {
+ LCONST lCONST;
+ if ((lCONST = (LCONST) constantPushInstruction).getValue().longValue() == 0L) {
+ InstructionHandle instructionHandle3 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.I2L);
+ InstructionHandle instructionHandle4 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_0);
+ this.processInstructionHandle(instructionHandle, instructionHandle4);
+ label113:
+ {
+ label94:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle3);
+ } catch (ClassGenException classGenException) {
+ {
+ instructionList4 = instructionList;
+ break label94;
+ }
+ }
+ instructionList4 = instructionList;
+ }
+ try {
+ instructionList4.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException) {
+ instructionHandle2 = instructionHandle3;
+ break label113;
+ }
+ instructionHandle2 = instructionHandle3;
+ }
+ instructionHandle = instructionHandle2;
+ value2++;
+ } else if (lCONST.getValue().longValue() == 1L) {
+ InstructionHandle instructionHandle5 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.I2L);
+ InstructionHandle instructionHandle6 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_1);
+ this.processInstructionHandle(instructionHandle, instructionHandle6);
+ label115:
+ {
+ label82:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle5);
+ } catch (ClassGenException classGenException2) {
+ {
+ instructionList3 = instructionList;
+ break label82;
+ }
+ }
+ instructionList3 = instructionList;
+ }
+ try {
+ instructionList3.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException2) {
+ instructionHandle2 = instructionHandle5;
+ break label115;
+ }
+ instructionHandle2 = instructionHandle5;
+ }
+ instructionHandle = instructionHandle2;
+ value2++;
+ }
+ }
+ } else if (instructionHandle.getInstruction() instanceof LDC2_W) {
+ LDC2_W lDC2_W = (LDC2_W) instructionHandle.getInstruction();
+ ConstantPoolGen constantPool2 = classGen.getConstantPool();
+ if (lDC2_W.getType(constantPool2) == Type.LONG) {
+ long value3;
+ long value4 = value3 = lDC2_W.getValue(constantPool2).longValue();
+ if (value4 == (short) value4) {
+ InstructionHandle instructionHandle7 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.I2L);
+ InstructionHandle instructionHandle22 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), (short) value3));
+ this.processInstructionHandle(instructionHandle, instructionHandle22);
+ label117:
+ {
+ label68:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle7);
+ } catch (ClassGenException classGenException3) {
+ {
+ instructionList2 = instructionList;
+ break label68;
+ }
+ }
+ instructionList2 = instructionList;
+ }
+ try {
+ instructionList2.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException3) {
+ instructionHandle2 = instructionHandle7;
+ break label117;
+ }
+ instructionHandle2 = instructionHandle7;
+ }
+ instructionHandle = instructionHandle2;
+ value2++;
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public static int[] getCounts(int value) {
+ int value2 = 0;
+ int value3 = 0;
+ int value4;
+ for (int value5 = value4 = 0; value5 < 32; value5 = ++value4) {
+ if ((value >> value4) % 2 == 1) {
+ if (RandomUtils.calculateValue() < 0.5) {
+ value2 |= 1 << value4;
+ } else {
+ value3 |= 1 << value4;
+ }
+ }
+ }
+ return new int[] {value2, value3};
+ }
+
+ public void processInstructionList9(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ IfInstruction ifInstruction;
+ int value;
+ instructionList.update();
+ InstructionHandle instructionHandle = null;
+ InstructionHandle instructionHandle2;
+ InstructionHandle instructionHandle3 = instructionHandle2 = instructionList.getStart();
+ while (instructionHandle3 != null) {
+ if (instructionHandle2.getInstruction() instanceof IfInstruction) {
+ instructionHandle = instructionHandle2;
+ }
+ if (!(instructionHandle2.getInstruction() instanceof GOTO)) {
+ instructionHandle3 = instructionHandle2;
+ } else {
+ label176:
+ {
+ InstructionHandle instructionHandle4 = instructionHandle2;
+ GOTO gOTO = (GOTO) instructionHandle2.getInstruction();
+ if (instructionHandle4.getInstructionHandle2() != null) {
+ if (gOTO.getTarget() == null) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ if (instructionHandle4.getInstructionHandle2() == gOTO.getTarget()) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ if (instructionHandle4.getInstructionHandle2().getInstructionHandle2()
+ == gOTO.getTarget()) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ if (instructionHandle4.getPosition() > gOTO.getTarget().getPosition()) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ IfInstruction ifInstruction2 = null;
+ InstructionHandle instructionHandle5;
+ if ((instructionHandle5 = instructionHandle4.getInstructionHandle2()).getTargeters()
+ == null) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ InstructionTargeter[] instructionTargeters;
+ int value2 = (instructionTargeters = instructionHandle5.getTargeters()).length;
+ int value3;
+ for (int value4 = value3 = 0; value4 < value2; value4 = ++value3) {
+ InstructionTargeter instructionTargeter;
+ if ((instructionTargeter = instructionTargeters[value3]) instanceof IfInstruction) {
+ ifInstruction2 = (IfInstruction) instructionTargeter;
+ }
+ }
+ if (instructionHandle == null) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ if (instructionHandle.getInstruction() != ifInstruction2) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ if (instructionHandle.getInstructionHandle2() != null) {
+ if (instructionHandle.getInstructionHandle2().getInstructionHandle2() == null) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ label150:
+ if (instructionHandle.getInstructionHandle2() != instructionHandle4) {
+ if (instructionHandle.getInstructionHandle2().getInstructionHandle2()
+ == instructionHandle4) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ InstructionHandle instructionHandle6 = instructionHandle;
+ byte value5 = 1;
+ instructionHandle3 = instructionHandle6;
+ while (true) {
+ if (instructionHandle3 != null) {
+ if (instructionHandle6 != instructionHandle5) {
+ if (!this.matchesInstructionTargeters(instructionHandle6.getTargeters())) {
+ value = 0;
+ break;
+ }
+ instructionHandle3 =
+ instructionHandle6 = instructionHandle6.getInstructionHandle2();
+ continue;
+ }
+ InstructionTargeter[] instructionTargeters2;
+ int value6 = (instructionTargeters2 = instructionHandle5.getTargeters()).length;
+ int value7;
+ for (int value8 = value7 = 0; value8 < value6; value8 = ++value7) {
+ InstructionTargeter instructionTargeter2;
+ if (!((instructionTargeter2 = instructionTargeters2[value7])
+ instanceof LineNumberGen)
+ && !(instructionTargeter2 instanceof LocalVariableGen)
+ && instructionTargeter2 != ifInstruction2) {
+ value5 = 0;
+ break;
+ }
+ }
+ }
+ value = value5;
+ break;
+ }
+ if (value == 0) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ Instruction instruction;
+ if ((!((instruction = instructionHandle5.getInstruction())
+ instanceof LoadInstruction)
+ || !instruction.equals(
+ instructionHandle.getInstructionHandle2().getInstruction()))
+ && (!this.matchesInstruction(instruction)
+ || !this.matchesConstantPoolGen(
+ instruction,
+ instructionHandle.getInstructionHandle2().getInstruction(),
+ classGen.getConstantPool()))) {
+ if (!(instruction instanceof NEW)) {
+ break label150;
+ }
+ if (!instruction.equals(
+ instructionHandle.getInstructionHandle2().getInstruction())) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ }
+ if (instruction.produceStack(classGen.getConstantPool()) != 1) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ if (ifInstruction2.consumeStack(classGen.getConstantPool()) != 1) {
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ OptimizationStatistics.count12++;
+ instructionList.createInstructionHandle(instructionHandle, instruction.copy());
+ instructionList.createInstructionHandle(
+ instructionHandle, InstructionConstants.SWAP);
+ this.processInstructionHandle(
+ instructionHandle.getInstructionHandle2(),
+ instructionHandle.getInstructionHandle2().getInstructionHandle2());
+ this.processInstructionHandle2(
+ instructionHandle.getInstructionHandle2(),
+ instructionHandle.getInstructionHandle2().getInstructionHandle2());
+ label106:
+ {
+ try {
+ instructionList.processInstructionHandle2(
+ instructionHandle.getInstructionHandle2());
+ } catch (TargetLostException targetLostException) {
+ ifInstruction = ifInstruction2;
+ break label106;
+ }
+ ifInstruction = ifInstruction2;
+ }
+ ifInstruction.setTarget(instructionHandle5.getInstructionHandle2());
+ this.processInstructionHandle(
+ instructionHandle5, instructionHandle5.getInstructionHandle2());
+ this.processInstructionHandle2(
+ instructionHandle5, instructionHandle5.getInstructionHandle2());
+ try {
+ instructionList.processInstructionHandle2(instructionHandle5);
+ } catch (TargetLostException targetLostException2) {
+ break label150;
+ }
+ instructionHandle3 = instructionHandle2;
+ break label176;
+ }
+ }
+ }
+ instructionHandle3 = instructionHandle2;
+ }
+ }
+ instructionHandle3 = instructionHandle2 = instructionHandle3.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList10(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof Select)) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ label80:
+ {
+ Select select;
+ InstructionHandle[] instructionHandles;
+ if ((instructionHandles =
+ (select = (Select) instructionHandle.getInstruction()).getTargets())
+ != null) {
+ if (instructionHandles.length == 0) {
+ instructionHandle2 = instructionHandle;
+ break label80;
+ }
+ InstructionHandle instructionHandle3 = null;
+ InstructionHandle instructionHandle4 = null;
+ InstructionHandle[] instructionHandles2 = instructionHandles;
+ int value = instructionHandles.length;
+ int value2;
+ for (int value3 = value2 = 0; value3 < value; value3 = ++value2) {
+ InstructionHandle instructionHandle5;
+ if ((instructionHandle5 = instructionHandles2[value2]) != null
+ && instructionHandle3 == null
+ && !(instructionHandle5.getInstruction() instanceof BranchInstruction)
+ && !(instructionHandle5.getInstruction() instanceof NEW)
+ && instructionHandle5 != select.getTarget()) {
+ instructionHandle3 = instructionHandle5;
+ }
+ if (instructionHandle5 != null
+ && instructionHandle5.getInstructionHandle() != null
+ && (instructionHandle5.getInstructionHandle().getInstruction() instanceof GOTO
+ || instructionHandle5.getInstructionHandle().getInstruction()
+ instanceof ReturnInstruction)) {
+ instructionHandle4 = instructionHandle5.getInstructionHandle();
+ }
+ }
+ if (instructionHandle3 != null && instructionHandle4 != null) {
+ instructionList.update();
+ if (Math.abs(instructionHandle3.getPosition() - instructionHandle4.getPosition())
+ > 32000) {
+ instructionHandle4 = null;
+ }
+ }
+ if (instructionHandle3 != null && instructionHandle4 != null) {
+ OptimizationStatistics.count29++;
+ BranchInstruction branchInstruction =
+ InstructionFactory.createBranchInstruction((short) 154, null);
+ instructionList.createBranchHandle(instructionHandle3, branchInstruction);
+ InstructionHandle instructionHandle6 =
+ instructionList.createInstructionHandle2(instructionHandle3, new ICONST(0));
+ branchInstruction.setTarget(
+ instructionList.createBranchHandle(
+ instructionHandle4, new GOTO(instructionHandle6)));
+ instructionHandle2 = instructionHandle;
+ break label80;
+ }
+ if (instructionHandle3 != null) {
+ OptimizationStatistics.count29++;
+ InstructionHandle instructionHandle7 =
+ instructionList.createInstructionHandle2(instructionHandle3, new ICONST(0));
+ instructionList.createBranchHandle(instructionHandle7, new IFNE(instructionHandle7));
+ }
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public static long[] getSeeds(long value, int value2) {
+ long value3 = value;
+ long value4 = value;
+ int value5;
+ for (int value6 = value5 = 0; value6 < value2; value6 = ++value5) {
+ if ((value >> value5) % 2L == 0L) {
+ if (RandomUtils.calculateValue() < 0.5) {
+ value3 |= 1L << value5;
+ } else {
+ value4 |= 1L << value5;
+ }
+ }
+ }
+ return new long[] {value3, value4};
+ }
+
+ public void processInstructionList11(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ InstructionHandle instructionHandle;
+ LocalVariableGen[] localVariableGens;
+ if ((localVariableGens = methodGen.getLocalVariables()) != null) {
+ if (localVariableGens.length != 0) {
+ int value;
+ if ((value = methodGen.getCount()) >= 4) {
+ int value2 = methodGen.getArgumentNames().length;
+ if (!methodGen.isEnabled11()) {
+ value2++;
+ }
+ Type[] types;
+ int value3 = (types = methodGen.getArgumentTypes()).length;
+ int value4;
+ for (int value5 = value4 = 0; value5 < value3; value5 = ++value4) {
+ Type type;
+ if ((type = types[value4]) == Type.LONG || type == Type.DOUBLE) {
+ value2++;
+ }
+ }
+ if (value2 < 4) {
+ int[] values = new int[value];
+ boolean[] matchess = new boolean[value];
+ InstructionHandle instructionHandle2;
+ for (InstructionHandle instructionHandle3 =
+ instructionHandle2 = instructionList.getStart();
+ instructionHandle3 != null;
+ instructionHandle3 =
+ instructionHandle2 = instructionHandle2.getInstructionHandle2()) {
+ if (instructionHandle2.getInstruction() instanceof LoadInstruction
+ || instructionHandle2.getInstruction() instanceof StoreInstruction) {
+ LocalVariableInstruction localVariableInstruction =
+ (LocalVariableInstruction) instructionHandle2.getInstruction();
+ int value6;
+ values[value6 = localVariableInstruction.getIndex()]++;
+ if ((localVariableInstruction.produceStack(classGen.getConstantPool()) == 2
+ || localVariableInstruction.consumeStack(classGen.getConstantPool()) == 2)
+ && value6 + 1 < value) {
+ matchess[value6] = true;
+ matchess[value6 + 1] = true;
+ }
+ }
+ }
+ int value7;
+ for (int value8 = value7 = 0; value8 < values.length; value8 = value7) {
+ int value9 = values[value7] << 16 | value7;
+ int value10 = value7;
+ value7++;
+ values[value10] = value9;
+ }
+ Arrays.sort(values, 4, value);
+ int value11;
+ for (int value12 = value11 = value2; value12 < 4; value12 = ++value11) {
+ if (!matchess[value11]) {
+ int value13 = values[value11] >> 16;
+ int value14;
+ for (int value15 = value14 = value - 1; value15 >= 4; value15 = --value14) {
+ int value16 = values[value14] & 65535;
+ int value17 = values[value14] >> 16;
+ if (value16 > 3 && !matchess[value16] && value17 > value13) {
+ OptimizationStatistics.count24++;
+ values[value14] = 0;
+ InstructionHandle instructionHandle4;
+ InstructionHandle instructionHandle5 =
+ instructionHandle4 = instructionList.getStart();
+ while (instructionHandle5 != null) {
+ label84:
+ {
+ if (instructionHandle4.getInstruction()
+ instanceof LocalVariableInstruction) {
+ LocalVariableInstruction localVariableInstruction2;
+ if ((localVariableInstruction2 =
+ (LocalVariableInstruction)
+ instructionHandle4.getInstruction())
+ .getIndex()
+ == value11) {
+ localVariableInstruction2.setIndex(value16);
+ } else if (localVariableInstruction2.getIndex() == value16) {
+ localVariableInstruction2.setIndex(value11);
+ }
+ } else if (instructionHandle4.getInstruction() instanceof RET) {
+ RET rET;
+ if ((rET = (RET) instructionHandle4.getInstruction()).getIndex()
+ == value11) {
+ instructionHandle = instructionHandle4;
+ rET.setIndex(value16);
+ break label84;
+ }
+ if (rET.getIndex() == value16) {
+ rET.setIndex(value11);
+ }
+ }
+ instructionHandle = instructionHandle4;
+ }
+ instructionHandle5 =
+ instructionHandle4 = instructionHandle.getInstructionHandle2();
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void processInstructionList12(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ byte value;
+ int value2;
+ InvokeInstruction invokeInstruction;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof InvokeInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InvokeInstruction invokeInstruction2 =
+ (InvokeInstruction) instructionHandle.getInstruction();
+ if (!Configuration.getMethodCallRemovalOptions()
+ .matchesText(
+ this.classStorage,
+ classGen,
+ methodGen,
+ invokeInstruction2.getText2(classGen.getConstantPool()),
+ invokeInstruction2.getText4(classGen.getConstantPool()),
+ invokeInstruction2.getText3(classGen.getConstantPool()))) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ label238:
+ {
+ InstructionHandle instructionHandle3;
+ ConstantPoolGen constantPoolGen;
+ label220:
+ {
+ constantPoolGen = classGen.getConstantPool();
+ int value3 = invokeInstruction2.produceStack(constantPoolGen);
+ instructionHandle3 = null;
+ if (value3 > 0) {
+ if (instructionHandle.getInstructionHandle2() != null
+ && (instructionHandle.getInstructionHandle2().getInstruction() instanceof POP
+ || instructionHandle.getInstructionHandle2().getInstruction()
+ instanceof POP2)
+ && instructionHandle
+ .getInstructionHandle2()
+ .getInstruction()
+ .consumeStack(constantPoolGen)
+ == value3) {
+ instructionHandle3 = instructionHandle.getInstructionHandle2();
+ }
+ if (instructionHandle3 == null) {
+ instructionHandle3 = instructionHandle;
+ if (Type.INT.equals(invokeInstruction2.getType2(classGen.getConstantPool()))
+ || Type.SHORT.equals(invokeInstruction2.getType2(classGen.getConstantPool()))
+ || Type.BYTE.equals(invokeInstruction2.getType2(classGen.getConstantPool()))
+ || Type.BOOLEAN.equals(
+ invokeInstruction2.getType2(classGen.getConstantPool()))
+ || Type.CHAR.equals(
+ invokeInstruction2.getType2(classGen.getConstantPool()))) {
+ instructionList.createInstructionHandle2(instructionHandle3, new ICONST(0));
+ } else if (Type.LONG.equals(
+ invokeInstruction2.getType2(classGen.getConstantPool()))) {
+ instructionList.createInstructionHandle2(instructionHandle3, new LCONST(0L));
+ } else if (Type.FLOAT.equals(
+ invokeInstruction2.getType2(classGen.getConstantPool()))) {
+ instructionList.createInstructionHandle2(instructionHandle3, new FCONST(0.0F));
+ } else if (Type.DOUBLE.equals(
+ invokeInstruction2.getType2(classGen.getConstantPool()))) {
+ instructionList.createInstructionHandle2(instructionHandle3, new DCONST(0.0));
+ } else if (invokeInstruction2.getType2(classGen.getConstantPool())
+ instanceof ArrayType) {
+ instructionList.createInstructionHandle2(instructionHandle3, new ACONST_NULL());
+ } else {
+ if (!(invokeInstruction2.getType2(classGen.getConstantPool())
+ instanceof ObjectType)) {
+ Log.warn(
+ "[remove-calls] Cannot remove call ("
+ + invokeInstruction2.getText2(constantPoolGen)
+ + "."
+ + invokeInstruction2.getText4(constantPoolGen)
+ + ") in "
+ + classGen.getClassName()
+ + "."
+ + methodGen.getName()
+ + " - return value is used");
+ instructionHandle2 = instructionHandle;
+ break label238;
+ }
+ instructionList.createInstructionHandle2(instructionHandle3, new ACONST_NULL());
+ }
+ Log.warn(
+ "[remove-calls] return value of "
+ + invokeInstruction2.getText2(constantPoolGen)
+ + "."
+ + invokeInstruction2.getText4(constantPoolGen)
+ + " in "
+ + classGen.getClassName()
+ + "."
+ + methodGen.getName()
+ + " was replaced with null(0)");
+ invokeInstruction = invokeInstruction2;
+ break label220;
+ }
+ } else {
+ instructionHandle3 = instructionHandle;
+ }
+ invokeInstruction = invokeInstruction2;
+ }
+ int value4 = invokeInstruction.consumeStack(constantPoolGen);
+ InstructionHandle instructionHandle4;
+ instructionHandle2 = instructionHandle4 = instructionHandle;
+ while (true) {
+ if (instructionHandle2.getInstructionHandle() == null) {
+ value2 = value4;
+ break;
+ }
+ if (value4 == 0) {
+ value2 = value4;
+ break;
+ }
+ instructionHandle4 = instructionHandle4.getInstructionHandle();
+ value4 -=
+ instructionHandle4.getInstruction().produceStack(constantPoolGen)
+ - instructionHandle4.getInstruction().consumeStack(constantPoolGen);
+ instructionHandle2 = instructionHandle4;
+ }
+ if (value2 != 0) {
+ Log.warn(
+ "[remove-calls] Cannot remove call ("
+ + invokeInstruction2.getText2(constantPoolGen)
+ + "."
+ + invokeInstruction2.getText4(constantPoolGen)
+ + ") in "
+ + classGen.getClassName()
+ + "."
+ + methodGen.getName()
+ + " - parameters not found");
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle5 = instructionHandle4;
+ InstructionHandle instructionHandle6 = instructionHandle4;
+ int value5 = 0;
+ label191:
+ while (true) {
+ instructionHandle2 = instructionHandle6;
+ while (instructionHandle2 != instructionHandle3
+ && instructionHandle6.getInstructionHandle2() != null) {
+ instructionHandle6 = instructionHandle6.getInstructionHandle2();
+ if (this.matchesInstructionTargeters(instructionHandle6.getTargeters())) {
+ continue label191;
+ }
+ InstructionHandle instructionHandle7 = instructionHandle6;
+ value5++;
+ instructionHandle2 = instructionHandle7;
+ }
+ if (value5 == 1) {
+ byte value6 = 0;
+ InstructionTargeter[] instructionTargeters;
+ if ((instructionTargeters = instructionHandle3.getTargeters()) != null) {
+ InstructionTargeter[] instructionTargeters2 = instructionTargeters;
+ int value7 = instructionTargeters.length;
+ int value8;
+ for (int value9 = value8 = 0; value9 < value7; value9 = ++value8) {
+ InstructionTargeter instructionTargeter;
+ if (!((instructionTargeter = instructionTargeters2[value8])
+ instanceof LineNumberGen)
+ && !(instructionTargeter instanceof LocalVariableGen)
+ && instructionTargeter instanceof CodeExceptionGen) {
+ value6 = 1;
+ }
+ }
+ }
+ if (value6 != 0 && instructionHandle5 != instructionHandle3) {
+ instructionHandle3.setInstruction(InstructionConstants.NOP);
+ instructionHandle3 = instructionHandle3.getInstructionHandle();
+ value5 = 0;
+ }
+ }
+ if (value5 > 0) {
+ Log.warn(
+ "[remove-calls] Cannot remove call ("
+ + invokeInstruction2.getText2(constantPoolGen)
+ + "."
+ + invokeInstruction2.getText4(constantPoolGen)
+ + ") in "
+ + classGen.getClassName()
+ + "."
+ + methodGen.getName()
+ + " - targeters inside block");
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle8;
+ if ((instructionHandle8 = instructionHandle3.getInstructionHandle2()) == null) {
+ Log.warn(
+ "[remove-calls] Cannot remove call ("
+ + invokeInstruction2.getText2(constantPoolGen)
+ + "."
+ + invokeInstruction2.getText4(constantPoolGen)
+ + ") in "
+ + classGen.getClassName()
+ + "."
+ + methodGen.getName()
+ + " - unexpected end of block");
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionTargeter[] instructionTargeters3;
+ if ((instructionTargeters3 = instructionHandle5.getTargeters()) != null) {
+ InstructionTargeter[] instructionTargeters4 = instructionTargeters3;
+ int value10 = instructionTargeters3.length;
+ int value11;
+ for (int value12 = value11 = 0; value12 < value10; value12 = ++value11) {
+ InstructionTargeter instructionTargeter2;
+ if (!((instructionTargeter2 = instructionTargeters4[value11])
+ instanceof LineNumberGen)
+ && !(instructionTargeter2 instanceof LocalVariableGen)) {
+ instructionTargeter2.updateTarget(instructionHandle5, instructionHandle8);
+ }
+ }
+ }
+ InstructionHandle instructionHandle9 = instructionHandle8;
+ do {
+ instructionHandle9 = instructionHandle9.getInstructionHandle();
+ this.processInstructionHandle(instructionHandle9, instructionHandle8);
+ this.processInstructionHandle2(instructionHandle9, instructionHandle8);
+ } while (instructionHandle9 != instructionHandle5
+ && instructionHandle9.getInstructionHandle() != null);
+ byte value13 = 0;
+ InstructionHandle instructionHandle10;
+ instructionHandle2 = instructionHandle10 = instructionHandle3;
+ while (true) {
+ if (instructionHandle2 == instructionHandle5) {
+ value = value13;
+ break;
+ }
+ if (instructionHandle10.getInstruction() instanceof IfInstruction) {
+ byte value14 = 1;
+ instructionHandle5 = instructionHandle10.getInstructionHandle2();
+ value = value14;
+ break;
+ }
+ instructionHandle2 =
+ instructionHandle10 = instructionHandle10.getInstructionHandle();
+ }
+ label145:
+ if (value == 0) {
+ try {
+ instructionList.processInstructionHandle(
+ instructionHandle5, instructionHandle3);
+ } catch (TargetLostException targetLostException) {
+ instructionHandle2 = instructionHandle8;
+ break label145;
+ }
+ instructionHandle2 = instructionHandle8;
+ } else {
+ label236:
+ {
+ int value15 =
+ instructionHandle3.getInstruction().consumeStack(constantPoolGen);
+ InstructionHandle instructionHandle11;
+ for (InstructionHandle instructionHandle12 =
+ instructionHandle11 = instructionHandle5;
+ instructionHandle12 != instructionHandle3;
+ instructionHandle12 =
+ instructionHandle11 = instructionHandle11.getInstructionHandle2()) {
+ value15 -=
+ instructionHandle11.getInstruction().produceStack(constantPoolGen)
+ - instructionHandle11
+ .getInstruction()
+ .consumeStack(constantPoolGen);
+ }
+ int value16;
+ for (int value17 = value16 = 0; value17 < value15; value17 = value16) {
+ value16++;
+ instructionList.createInstructionHandle2(instructionHandle3, new POP());
+ }
+ try {
+ instructionList.processInstructionHandle(
+ instructionHandle5, instructionHandle3);
+ } catch (TargetLostException targetLostException2) {
+ instructionHandle2 = instructionHandle8;
+ break label236;
+ }
+ instructionHandle2 = instructionHandle8;
+ }
+ }
+ if (instructionHandle2.getInstructionHandle() != null) {
+ instructionHandle2 = instructionHandle8.getInstructionHandle();
+ } else {
+ InstructionHandle instructionHandle13 = instructionHandle8;
+ instructionHandle2 = instructionHandle13;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList13(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ InstructionList instructionList2;
+ int value;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof POP)
+ && !(instructionHandle.getInstruction() instanceof POP2)) {
+ instructionHandle2 = instructionHandle;
+ } else if (!this.matchesInstructionTargeters(instructionHandle.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ boolean matches = instructionHandle.getInstruction() instanceof POP;
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ int value2 = 0;
+ int value3 = 0;
+ InstructionHandle instructionHandle3 = null;
+ InstructionHandle instructionHandle22 = instructionHandle.getInstructionHandle2();
+ while (true) {
+ if (instructionHandle22 != null) {
+ Instruction instruction;
+ if (!((instruction = instructionHandle22.getInstruction())
+ instanceof ArithmeticInstruction)
+ && !(instruction instanceof ArrayInstruction)
+ && !(instruction instanceof ConversionInstruction)
+ && !(instruction instanceof ConstantPushInstruction)
+ && !(instruction instanceof FieldOrMethod)
+ && !(instruction instanceof LocalVariableInstruction)
+ && !(instruction instanceof PushInstruction)
+ && !(instruction instanceof PopInstruction)
+ && !(instruction instanceof NEW)
+ && !(instruction instanceof NEWARRAY)
+ && !(instruction instanceof NOP)) {
+ value = value3;
+ break;
+ }
+ if (!this.matchesInstructionTargeters(instructionHandle22.getTargeters())) {
+ value = value3;
+ break;
+ }
+ int value4 = instructionHandle22.getInstruction().produceStack(constantPool);
+ int value5 = instructionHandle22.getInstruction().consumeStack(constantPool);
+ if (value4 != -2) {
+ if (value5 == -2) {
+ value = value3;
+ break;
+ }
+ int value6;
+ if ((value6 = value2 - value5) < 0) {
+ value = value3;
+ break;
+ }
+ if ((value2 = value6 + value4) == 0) {
+ instructionHandle3 = instructionHandle22;
+ if (matches && instructionHandle3.getInstruction() instanceof POP) {
+ value = value3;
+ break;
+ }
+ }
+ value3++;
+ instructionHandle22 = instructionHandle22.getInstructionHandle2();
+ if (value3 <= 777) {
+ continue;
+ }
+ value = value3;
+ break;
+ }
+ }
+ value = value3;
+ break;
+ }
+ if (value == 0) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle3 == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ label77:
+ if (matches && instructionHandle3.getInstruction() instanceof POP) {
+ OptimizationStatistics.count9++;
+ InstructionHandle instructionHandle23 = instructionHandle.getInstructionHandle2();
+ this.processInstructionHandle(
+ instructionHandle23.getInstructionHandle().getTargeters(),
+ instructionHandle23.getInstructionHandle(),
+ instructionHandle23);
+ label73:
+ {
+ try {
+ instructionList.processInstructionHandle2(
+ instructionHandle23.getInstructionHandle());
+ } catch (TargetLostException targetLostException) {
+ instructionList2 = instructionList;
+ this.processInstructionHandle(targetLostException, instructionHandle23);
+ break label73;
+ }
+ instructionList2 = instructionList;
+ }
+ instructionList2.createInstructionHandle2(
+ instructionHandle3, InstructionConstants.POP2);
+ InstructionHandle instructionHandle24 = instructionHandle3.getInstructionHandle2();
+ this.processInstructionHandle(
+ instructionHandle24.getInstructionHandle().getTargeters(),
+ instructionHandle24.getInstructionHandle(),
+ instructionHandle24);
+ try {
+ instructionList.processInstructionHandle2(instructionHandle24.getInstructionHandle());
+ } catch (TargetLostException targetLostException2) {
+ instructionHandle2 = instructionHandle23;
+ this.processInstructionHandle(targetLostException2, instructionHandle24);
+ break label77;
+ }
+ instructionHandle2 = instructionHandle23;
+ } else {
+ OptimizationStatistics.count8++;
+ InstructionHandle instructionHandle25 = instructionHandle.getInstructionHandle2();
+ instructionHandle2 = instructionHandle25;
+ instructionList.processInstructionHandle3(
+ instructionHandle25.getInstructionHandle(), instructionHandle3);
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList14(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ instructionList.update();
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ label107:
+ {
+ if (instructionHandle.getInstruction() instanceof GotoInstruction) {
+ InstructionHandle instructionHandle3;
+ if ((instructionHandle3 =
+ ((GotoInstruction) instructionHandle.getInstruction()).getTarget())
+ == null) {
+ instructionHandle2 = instructionHandle;
+ break label107;
+ }
+ if (instructionHandle3 == instructionHandle) {
+ instructionHandle2 = instructionHandle;
+ break label107;
+ }
+ if (!(instructionHandle3.getInstruction() instanceof GotoInstruction)
+ && !(instructionHandle3.getInstruction() instanceof ReturnInstruction)) {
+ instructionHandle2 = instructionHandle;
+ break label107;
+ }
+ if (instructionHandle3.getInstruction() instanceof GotoInstruction) {
+ int value = 0;
+ for (InstructionHandle instructionHandle4 = instructionHandle3;
+ instructionHandle4 != null
+ && instructionHandle3.getInstruction() instanceof GotoInstruction
+ && value < 100;
+ instructionHandle4 = instructionHandle3) {
+ Instruction instruction = instructionHandle3.getInstruction();
+ value++;
+ instructionHandle3 = ((GotoInstruction) instruction).getTarget();
+ }
+ if (value == 100) {
+ instructionHandle2 = instructionHandle;
+ break label107;
+ }
+ }
+ if (instructionHandle3 == null) {
+ instructionHandle2 = instructionHandle;
+ break label107;
+ }
+ if (instructionHandle3.getInstruction() instanceof ReturnInstruction) {
+ OptimizationStatistics.count19++;
+ instructionList.createInstructionHandle2(
+ instructionHandle, instructionHandle3.getInstruction());
+ instructionHandle = instructionHandle.getInstructionHandle2();
+ this.processInstructionHandle(
+ instructionHandle.getInstructionHandle().getTargeters(),
+ instructionHandle.getInstructionHandle(),
+ instructionHandle);
+ try {
+ instructionList.processInstructionHandle2(instructionHandle.getInstructionHandle());
+ } catch (TargetLostException targetLostException) {
+ this.processInstructionHandle(targetLostException, instructionHandle);
+ }
+ } else {
+ if (Math.abs(instructionHandle.getPosition() - instructionHandle3.getPosition())
+ > 32000) {
+ instructionHandle2 = instructionHandle;
+ break label107;
+ }
+ OptimizationStatistics.count13++;
+ ((GotoInstruction) instructionHandle.getInstruction()).setTarget(instructionHandle3);
+ }
+ } else if (instructionHandle.getInstruction() instanceof IfInstruction) {
+ InstructionHandle instructionHandle5;
+ if ((instructionHandle5 =
+ ((IfInstruction) instructionHandle.getInstruction()).getTarget())
+ == null) {
+ instructionHandle2 = instructionHandle;
+ break label107;
+ }
+ if (!(instructionHandle5.getInstruction() instanceof GotoInstruction)) {
+ instructionHandle2 = instructionHandle;
+ break label107;
+ }
+ int value2 = 0;
+ for (InstructionHandle instructionHandle6 = instructionHandle5;
+ instructionHandle6 != null
+ && instructionHandle5.getInstruction() instanceof GotoInstruction
+ && value2 < 100;
+ instructionHandle6 = instructionHandle5) {
+ Instruction instruction2 = instructionHandle5.getInstruction();
+ value2++;
+ instructionHandle5 = ((GotoInstruction) instruction2).getTarget();
+ }
+ if (value2 == 100) {
+ instructionHandle2 = instructionHandle;
+ break label107;
+ }
+ if (instructionHandle5 == null) {
+ instructionHandle2 = instructionHandle;
+ break label107;
+ }
+ if (Math.abs(instructionHandle.getPosition() - instructionHandle5.getPosition())
+ > 32000) {
+ instructionHandle2 = instructionHandle;
+ break label107;
+ }
+ OptimizationStatistics.count25++;
+ ((IfInstruction) instructionHandle.getInstruction()).setTarget(instructionHandle5);
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList15(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof ALOAD)) {
+ instructionHandle2 = instructionHandle;
+ } else if (!this.matchesInstructionTargeters(instructionHandle.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ int value = instructionHandle.getInstruction().produceStack(constantPool);
+ InstructionHandle instructionHandle3 = null;
+ InstructionHandle instructionHandle22 = instructionHandle.getInstructionHandle2();
+ int value2 = 0;
+ while (true) {
+ if (instructionHandle22 != null) {
+ Instruction instruction;
+ if (!((instruction = instructionHandle22.getInstruction())
+ instanceof ArithmeticInstruction)
+ && !(instruction instanceof ArrayInstruction)
+ && !(instruction instanceof ConversionInstruction)
+ && !(instruction instanceof ConstantPushInstruction)
+ && !(instruction instanceof FieldOrMethod)
+ && !(instruction instanceof LoadInstruction)
+ && !(instruction instanceof PushInstruction)
+ && !(instruction instanceof NEW)
+ && !(instruction instanceof NEWARRAY)
+ && !(instruction instanceof NOP)
+ && !(instruction instanceof POP)
+ && !(instruction instanceof POP2)) {
+ instructionHandle2 = instructionHandle3;
+ break;
+ }
+ if (!this.matchesInstructionTargeters(instructionHandle22.getTargeters())) {
+ instructionHandle2 = instructionHandle3;
+ break;
+ }
+ Instruction instruction2;
+ if (value == 0
+ && ((instruction2 = instructionHandle22.getInstruction()) instanceof LoadInstruction
+ || instruction2 instanceof ConstantPushInstruction
+ || instruction2 instanceof LDC
+ || instruction2 instanceof LDC2_W
+ || instruction2 instanceof ACONST_NULL)) {
+ instructionHandle2 = instructionHandle3 = instructionHandle22;
+ break;
+ }
+ int value3 = instructionHandle22.getInstruction().produceStack(constantPool);
+ int value4 = instructionHandle22.getInstruction().consumeStack(constantPool);
+ if (value3 != -2) {
+ if (value4 == -2) {
+ instructionHandle2 = instructionHandle3;
+ break;
+ }
+ int value5;
+ if ((value5 = value - value4) < 0) {
+ instructionHandle2 = instructionHandle3;
+ break;
+ }
+ value = value5 + value3;
+ instructionHandle22 = instructionHandle22.getInstructionHandle2();
+ int value6 = value2++;
+ if (value6 <= (short) 777) {
+ continue;
+ }
+ instructionHandle2 = instructionHandle3;
+ break;
+ }
+ }
+ instructionHandle2 = instructionHandle3;
+ break;
+ }
+ if (instructionHandle2 == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ OptimizationStatistics.count18++;
+ this.processInstructionHandle(
+ instructionHandle3, instructionHandle3.getInstructionHandle2());
+ instructionHandle2 = instructionHandle;
+ instructionList.processInstructionHandle3(
+ instructionHandle3, instructionHandle.getInstructionHandle());
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList16(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!this.matchesInstruction(instructionHandle.getInstruction())) {
+ instructionHandle2 = instructionHandle;
+ } else if (!this.matchesInstructionTargeters(instructionHandle.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ Instruction instruction = instructionHandle.getInstruction();
+ int value = 0;
+ InstructionHandle instructionHandle3 = null;
+ InstructionHandle instructionHandle4 = null;
+ InstructionHandle instructionHandle22 = instructionHandle.getInstructionHandle2();
+ int value2 = 0;
+ while (true) {
+ if (instructionHandle22 != null) {
+ Instruction instruction2;
+ if (!((instruction2 = instructionHandle22.getInstruction())
+ instanceof ArithmeticInstruction)
+ && !(instruction2 instanceof ArrayInstruction)
+ && !(instruction2 instanceof ConversionInstruction)
+ && !(instruction2 instanceof ConstantPushInstruction)
+ && !(instruction2 instanceof FieldOrMethod)
+ && !(instruction2 instanceof LocalVariableInstruction)
+ && !(instruction2 instanceof PushInstruction)
+ && !(instruction2 instanceof PopInstruction)
+ && !(instruction2 instanceof NEW)
+ && !(instruction2 instanceof NEWARRAY)
+ && !(instruction2 instanceof NOP)) {
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ if (!this.matchesInstructionTargeters(instructionHandle22.getTargeters())) {
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ if (value == 1) {
+ Instruction instruction3 = instructionHandle22.getInstruction();
+ if (this.matchesInstruction(instruction3)
+ && this.matchesConstantPoolGen(instruction, instruction3, constantPool)) {
+ instructionHandle3 = instructionHandle22;
+ }
+ } else if (value == 2) {
+ Instruction instruction4 = instructionHandle22.getInstruction();
+ if (this.matchesInstruction(instruction4)
+ && this.matchesConstantPoolGen(instruction, instruction4, constantPool)) {
+ instructionHandle2 = instructionHandle4 = instructionHandle22;
+ break;
+ }
+ }
+ int value3 = instructionHandle22.getInstruction().produceStack(constantPool);
+ int value4 = instructionHandle22.getInstruction().consumeStack(constantPool);
+ if (value3 != -2) {
+ if (value4 == -2) {
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ int value5;
+ if ((value5 = value - value4) < 0) {
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ value = value5 + value3;
+ instructionHandle22 = instructionHandle22.getInstructionHandle2();
+ int value6 = value2++;
+ if (value6 <= (short) 777) {
+ continue;
+ }
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ }
+ instructionHandle2 = instructionHandle4;
+ break;
+ }
+ InstructionHandle instructionHandle5 =
+ instructionHandle2 != null ? instructionHandle4 : instructionHandle3;
+ int value7 = instructionHandle4 != null ? 2 : 1;
+ if (instructionHandle5 == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ OptimizationStatistics.count17++;
+ InstructionHandle instructionHandle6;
+ InstructionHandle instructionHandle7 =
+ instructionHandle6 = instructionHandle.getInstructionHandle2();
+ this.processInstructionHandle(
+ instructionHandle6.getInstructionHandle(), instructionHandle6);
+ this.processInstructionHandle2(
+ instructionHandle7.getInstructionHandle(), instructionHandle5);
+ label88:
+ {
+ try {
+ instructionList.processInstructionHandle2(instructionHandle6.getInstructionHandle());
+ } catch (TargetLostException targetLostException) {
+ instructionHandle2 = instructionHandle5;
+ break label88;
+ }
+ instructionHandle2 = instructionHandle5;
+ }
+ if (instructionHandle2.getInstruction().produceStack(constantPool) == 1) {
+ if (value7 == 2) {
+ instructionHandle2 = instructionHandle6;
+ instructionList.createInstructionHandle2(
+ instructionHandle5, InstructionConstants.DUP_X2);
+ } else {
+ instructionList.createInstructionHandle2(
+ instructionHandle5, InstructionConstants.DUP_X1);
+ instructionHandle2 = instructionHandle6;
+ }
+ } else {
+ label137:
+ {
+ if (instructionHandle5.getInstruction().produceStack(constantPool) == 2) {
+ if (value7 == 2) {
+ instructionHandle2 = instructionHandle6;
+ instructionList.createInstructionHandle2(
+ instructionHandle5, InstructionConstants.DUP2_X2);
+ break label137;
+ }
+ instructionList.createInstructionHandle2(
+ instructionHandle5, InstructionConstants.DUP2_X1);
+ }
+ instructionHandle2 = instructionHandle6;
+ }
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList17(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ MethodOptimizer methodOptimizer;
+ int value;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof LoadInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle.getInstructionHandle2() == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle3;
+ if ((instructionHandle3 = instructionHandle.getInstructionHandle2()).getInstructionHandle2()
+ == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle4;
+ if ((instructionHandle4 = instructionHandle3.getInstructionHandle2())
+ .getInstructionHandle2()
+ == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle5;
+ if ((instructionHandle5 = instructionHandle4.getInstructionHandle2())
+ .getInstructionHandle2()
+ == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle6;
+ if ((instructionHandle6 = instructionHandle5.getInstructionHandle2())
+ .getInstructionHandle2()
+ == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle22 = instructionHandle6.getInstructionHandle2();
+ if (!(instructionHandle3.getInstruction() instanceof StoreInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle4.getInstruction() instanceof LoadInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle5.getInstruction() instanceof StoreInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle6.getInstruction() instanceof LoadInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle22.getInstruction() instanceof StoreInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else if (((LoadInstruction) instructionHandle.getInstruction()).getIndex()
+ != ((StoreInstruction) instructionHandle5.getInstruction()).getIndex()) {
+ instructionHandle2 = instructionHandle;
+ } else if (((StoreInstruction) instructionHandle3.getInstruction()).getIndex()
+ != ((LoadInstruction) instructionHandle6.getInstruction()).getIndex()) {
+ instructionHandle2 = instructionHandle;
+ } else if (((LoadInstruction) instructionHandle4.getInstruction()).getIndex()
+ != ((StoreInstruction) instructionHandle22.getInstruction()).getIndex()) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ byte value2 = 1;
+ InstructionHandle instructionHandle23 = instructionHandle.getInstructionHandle2();
+ int value3;
+ int value4 = value3 = 1;
+ while (true) {
+ if (value4 >= 6) {
+ value = value2;
+ break;
+ }
+ if (!this.matchesInstructionTargeters(instructionHandle23.getTargeters())) {
+ value = 0;
+ break;
+ }
+ InstructionHandle instructionHandle7 = instructionHandle23;
+ value3++;
+ instructionHandle23 = instructionHandle7.getInstructionHandle2();
+ value4 = value3;
+ }
+ if (value == 0) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ label122:
+ {
+ OptimizationStatistics.count28++;
+ this.processInstructionHandle(instructionHandle3, instructionHandle);
+ this.processInstructionHandle2(instructionHandle3, instructionHandle);
+ label91:
+ {
+ try {
+ instructionList.processInstructionHandle2(instructionHandle3);
+ } catch (TargetLostException targetLostException) {
+ methodOptimizer = this;
+ break label91;
+ }
+ methodOptimizer = this;
+ }
+ methodOptimizer.processInstructionHandle(
+ instructionHandle6, instructionHandle22);
+ this.processInstructionHandle2(instructionHandle6, instructionHandle22);
+ try {
+ instructionList.processInstructionHandle2(instructionHandle6);
+ } catch (TargetLostException targetLostException2) {
+ instructionHandle2 = instructionHandle;
+ break label122;
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public static int[] getCounts(int value, int value2) {
+ int value3 = value;
+ int value4 = value;
+ int value5;
+ for (int value6 = value5 = 0; value6 < value2; value6 = ++value5) {
+ if ((value >> value5) % 2 == 0) {
+ if (RandomUtils.calculateValue() < 0.5) {
+ value3 |= 1 << value5;
+ } else {
+ value4 |= 1 << value5;
+ }
+ }
+ }
+ return new int[] {value3, value4};
+ }
+
+ public boolean matchesConstantPoolGen(
+ Instruction instruction, Instruction instruction2, ConstantPoolGen constantPoolGen) {
+ if (instruction instanceof ConstantPushInstruction
+ && instruction2 instanceof ConstantPushInstruction) {
+ if (((ConstantPushInstruction) instruction).getType(constantPoolGen)
+ == ((ConstantPushInstruction) instruction2).getType(constantPoolGen)
+ && ((ConstantPushInstruction) instruction)
+ .getValue()
+ .equals(((ConstantPushInstruction) instruction2).getValue())) {
+ return true;
+ }
+ } else {
+ if (instruction instanceof ACONST_NULL && instruction2 instanceof ACONST_NULL) {
+ return true;
+ }
+ if (instruction instanceof LDC && instruction2 instanceof LDC) {
+ if (((LDC) instruction).getIndex() == ((LDC) instruction2).getIndex()) {
+ return true;
+ }
+ } else if (instruction instanceof LDC2_W && instruction2 instanceof LDC2_W) {
+ if (((LDC2_W) instruction).getIndex() == ((LDC2_W) instruction2).getIndex()) {
+ return true;
+ }
+ } else if (instruction instanceof GETSTATIC
+ && instruction2 instanceof GETSTATIC
+ && ((GETSTATIC) instruction).getIndex() == ((GETSTATIC) instruction2).getIndex()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void notify(ClassGen classGen) {
+ Method[] methods = classGen.getMethods();
+ int value;
+ for (int value2 = value = 0; value2 < methods.length; value2 = ++value) {
+ Method method;
+ if ((method = methods[value]).getCode() != null) {
+ MethodGen methodGen =
+ MethodFactory.createMethodGen(
+ method,
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool());
+ if (!Configuration.getObfuscationOptions()
+ .matchesMethodGen(this.classStorage, classGen, methodGen)) {
+ if (Configuration.getMethodCallRemovalOptions().isEnabled()) {
+ InstructionList instructionList = methodGen.getInstructionList();
+ instructionList.update();
+ this.processInstructionList12(classGen, methodGen, instructionList);
+ methodGen.update5();
+ methodGen.update4();
+ classGen.replaceMethod(method, methodGen.getMethod());
+ }
+ if (Configuration.getFieldRemovalOptions().isValues()) {
+ InstructionList instructionList2 = methodGen.getInstructionList();
+ instructionList2.update();
+ this.processInstructionList3(classGen, methodGen, instructionList2);
+ methodGen.update5();
+ methodGen.update4();
+ classGen.replaceMethod(method, methodGen.getMethod());
+ }
+ } else {
+ InstructionList instructionList3;
+ (instructionList3 = methodGen.getInstructionList()).update();
+ if (Configuration.getMethodCallRemovalOptions().isEnabled()) {
+ this.processInstructionList12(classGen, methodGen, instructionList3);
+ }
+ if (Configuration.getFieldRemovalOptions().isValues()) {
+ this.processInstructionList3(classGen, methodGen, instructionList3);
+ }
+ int value3;
+ value2 =
+ value3 =
+ Configuration.getExtensiveFlowOptions()
+ .calculateCount(this.classStorage, classGen, methodGen);
+ Configuration.getExtensiveFlowOptions();
+ if (value2 != 0 && !method.getText().startsWith("Allatori")) {
+ this.processInstructionList7(classGen, methodGen, instructionList3);
+ }
+ this.processInstructionList20(classGen, methodGen, instructionList3);
+ this.processInstructionList18(classGen, methodGen, instructionList3);
+ this.processInstructionList25(classGen, methodGen, instructionList3);
+ this.processInstructionList17(classGen, methodGen, instructionList3);
+ this.processInstructionList13(classGen, methodGen, instructionList3);
+ this.processInstructionList9(classGen, methodGen, instructionList3);
+ this.processEnabled2(classGen, methodGen, instructionList3, true);
+ this.processEnabled2(classGen, methodGen, instructionList3, false);
+ this.processInstructionList15(classGen, methodGen, instructionList3);
+ this.processEnabled(classGen, methodGen, instructionList3, false);
+ this.processInstructionList2(classGen, methodGen, instructionList3);
+ this.processInstructionList27(classGen, methodGen, instructionList3);
+ this.processEnabled(classGen, methodGen, instructionList3, true);
+ this.processInstructionList16(classGen, methodGen, instructionList3);
+ this.processInstructionList16(classGen, methodGen, instructionList3);
+ this.processInstructionList26(classGen, methodGen, instructionList3);
+ this.processInstructionList(classGen, methodGen, instructionList3);
+ this.processInstructionList19(classGen, methodGen, instructionList3);
+ this.processInstructionList6(classGen, methodGen, instructionList3);
+ this.processInstructionList14(classGen, methodGen, instructionList3);
+ this.processInstructionList8(classGen, methodGen, instructionList3);
+ this.processInstructionList5(classGen, methodGen, instructionList3);
+ this.processInstructionList21(classGen, methodGen, instructionList3);
+ this.processInstructionList11(classGen, methodGen, instructionList3);
+ Configuration.getExtensiveFlowOptions();
+ if (value3 != 0) {
+ this.processInstructionList23(classGen, methodGen, instructionList3);
+ }
+ this.processInstructionList10(classGen, methodGen, instructionList3);
+ Configuration.getExtensiveFlowOptions();
+ if (value3 == 1) {
+ this.processCount(
+ classGen, methodGen, instructionList3, 20, 16, 16, 20, 16, 16, 8, 4, 4);
+ } else {
+ Configuration.getExtensiveFlowOptions();
+ if (value3 == 2) {
+ this.processCount(
+ classGen, methodGen, instructionList3, 64, 32, 32, 64, 32, 64, 32, 8, 8);
+ } else if (Configuration.getObfuscationOptions().isEnabled3()
+ && Configuration.getObfuscationOptions().isMethodsNamingEnabled()) {
+ this.processCount(classGen, methodGen, instructionList3, 8, 4, 4, 8, 4, 4, 4, 2, 2);
+ }
+ }
+ if (Configuration.getMethodRemovalOptions()
+ .matchesMethod(this.classStorage, classGen, method)) {
+ this.processInstructionList4(classGen, methodGen, instructionList3);
+ }
+ methodGen.update5();
+ methodGen.update4();
+ classGen.replaceMethod(method, methodGen.getMethod());
+ }
+ }
+ }
+ }
+
+ public void processInstructionList18(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof GotoInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else if (!this.matchesInstructionTargeters(instructionHandle.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ label27:
+ {
+ GotoInstruction gotoInstruction;
+ InstructionHandle instructionHandle3;
+ if ((instructionHandle3 =
+ (gotoInstruction = (GotoInstruction) instructionHandle.getInstruction())
+ .getTarget())
+ != null) {
+ if (instructionHandle3.getInstructionHandle2() == null) {
+ instructionHandle2 = instructionHandle;
+ break label27;
+ }
+ if (!(instructionHandle3.getInstruction() instanceof LoadInstruction)) {
+ instructionHandle2 = instructionHandle;
+ break label27;
+ }
+ gotoInstruction.setTarget(instructionHandle3.getInstructionHandle2());
+ instructionList.createInstructionHandle2(
+ gotoInstruction, instructionHandle3.getInstruction().copy());
+ OptimizationStatistics.count26++;
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processCount(
+ ClassGen classGen,
+ MethodGen methodGen,
+ InstructionList instructionList,
+ int value,
+ int value2,
+ int value3,
+ int value4,
+ int value5,
+ int value6,
+ int value7,
+ int value8,
+ int value9) {
+ InstructionList instructionList2;
+ InstructionList instructionList3;
+ InstructionList instructionList4;
+ InstructionList instructionList5;
+ InstructionList instructionList6;
+ InstructionList instructionList7;
+ InstructionList instructionList8;
+ InstructionList instructionList9;
+ InstructionList instructionList10;
+ InstructionList instructionList11;
+ InstructionList instructionList12;
+ InstructionList instructionList13;
+ InstructionList instructionList14;
+ InstructionList instructionList15;
+ InstructionList instructionList16;
+ this.processCount(classGen, methodGen, instructionList, value4);
+ int value10 = 0;
+ int value11 = 0;
+ int value12 = 0;
+ int value13 = 0;
+ int value14 = 0;
+ int value15 = 0;
+ int value16 = 0;
+ int value17 = 0;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null
+ && (value10 < value || value11 < value2 || value12 < value3)) {
+ if (!this.matchesInstructionTargeters(instructionHandle.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle.getInstruction() == InstructionConstants.ICONST_0) {
+ if (value10 >= value) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ int value18;
+ InstructionHandle instructionHandle3;
+ InstructionHandle instructionHandle4;
+ MethodOptimizer methodOptimizer;
+ if ((value18 = RandomUtils.calculateCount(5)) == 0) {
+ instructionHandle3 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.IAND);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_5);
+ instructionHandle4 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_2);
+ methodOptimizer = this;
+ } else if (value18 == 1) {
+ instructionHandle3 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ISHR);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_2);
+ instructionHandle4 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_3);
+ methodOptimizer = this;
+ } else if (value18 == 2) {
+ instructionHandle3 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ISHR);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_3);
+ instructionHandle4 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_5);
+ methodOptimizer = this;
+ } else if (value18 == 3) {
+ instructionHandle3 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.IAND);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_4);
+ instructionHandle4 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_3);
+ methodOptimizer = this;
+ } else {
+ instructionHandle3 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.IXOR);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_3);
+ instructionHandle4 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_3);
+ methodOptimizer = this;
+ }
+ methodOptimizer.processInstructionHandle(instructionHandle, instructionHandle4);
+ label580:
+ {
+ label565:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle3);
+ } catch (ClassGenException classGenException) {
+ {
+ instructionList16 = instructionList;
+ break label565;
+ }
+ }
+ instructionList16 = instructionList;
+ }
+ try {
+ instructionList16.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException) {
+ instructionHandle2 = instructionHandle3;
+ break label580;
+ }
+ instructionHandle2 = instructionHandle3;
+ }
+ InstructionHandle instructionHandle5 = instructionHandle2;
+ value10++;
+ instructionHandle2 = instructionHandle5;
+ }
+ } else if (instructionHandle.getInstruction() == InstructionConstants.ICONST_1) {
+ if (value10 >= value) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle.getInstructionHandle2() != null
+ && instructionHandle.getInstructionHandle2().getInstructionHandle2() != null
+ && instructionHandle.getInstructionHandle2().getInstruction()
+ == InstructionConstants.DUP
+ && instructionHandle.getInstructionHandle2().getInstructionHandle2().getInstruction()
+ == InstructionConstants.POP2) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ int value19;
+ InstructionHandle instructionHandle6;
+ InstructionHandle instructionHandle7;
+ MethodOptimizer methodOptimizer2;
+ if ((value19 = RandomUtils.calculateCount(7)) == 0) {
+ instructionHandle6 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.IAND);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_5);
+ instructionHandle7 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_3);
+ methodOptimizer2 = this;
+ } else if (value19 == 1) {
+ instructionHandle6 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ISHR);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_1);
+ instructionHandle7 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_3);
+ methodOptimizer2 = this;
+ } else if (value19 == 2) {
+ instructionHandle6 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ISHR);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_2);
+ instructionHandle7 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_5);
+ methodOptimizer2 = this;
+ } else if (value19 == 3) {
+ instructionHandle6 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.IXOR);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_3);
+ instructionHandle7 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_2);
+ methodOptimizer2 = this;
+ } else if (value19 != 4 && value19 != 5) {
+ instructionHandle6 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.IXOR);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_5);
+ instructionHandle7 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_4);
+ methodOptimizer2 = this;
+ } else {
+ instructionHandle6 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.INEG);
+ instructionHandle7 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_M1);
+ methodOptimizer2 = this;
+ }
+ methodOptimizer2.processInstructionHandle(instructionHandle, instructionHandle7);
+ label583:
+ {
+ label533:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle6);
+ } catch (ClassGenException classGenException2) {
+ {
+ instructionList15 = instructionList;
+ break label533;
+ }
+ }
+ instructionList15 = instructionList;
+ }
+ try {
+ instructionList15.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException2) {
+ instructionHandle2 = instructionHandle6;
+ break label583;
+ }
+ instructionHandle2 = instructionHandle6;
+ }
+ InstructionHandle instructionHandle8 = instructionHandle2;
+ value10++;
+ instructionHandle2 = instructionHandle8;
+ }
+ } else if (instructionHandle.getInstruction() == InstructionConstants.ICONST_2) {
+ if (value11 >= value2) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle9;
+ InstructionHandle instructionHandle10;
+ int value20;
+ MethodOptimizer methodOptimizer3;
+ if ((value20 = RandomUtils.calculateCount(3)) == 0) {
+ instructionHandle9 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ISHR);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_1);
+ instructionHandle10 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_5);
+ methodOptimizer3 = this;
+ } else if (value20 == 1) {
+ instructionHandle9 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.INEG);
+ instructionHandle10 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), -2));
+ methodOptimizer3 = this;
+ } else {
+ instructionHandle9 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.IXOR);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_3);
+ instructionHandle10 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_1);
+ methodOptimizer3 = this;
+ }
+ methodOptimizer3.processInstructionHandle(instructionHandle, instructionHandle10);
+ label585:
+ {
+ label520:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle9);
+ } catch (ClassGenException classGenException3) {
+ {
+ instructionList14 = instructionList;
+ break label520;
+ }
+ }
+ instructionList14 = instructionList;
+ }
+ try {
+ instructionList14.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException3) {
+ instructionHandle2 = instructionHandle9;
+ break label585;
+ }
+ instructionHandle2 = instructionHandle9;
+ }
+ InstructionHandle instructionHandle11 = instructionHandle2;
+ value11++;
+ instructionHandle2 = instructionHandle11;
+ }
+ } else if (instructionHandle.getInstruction() == InstructionConstants.ICONST_3) {
+ if (value11 >= value2) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle12 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.INEG);
+ InstructionHandle instructionHandle22 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), -3));
+ this.processInstructionHandle(instructionHandle, instructionHandle22);
+ label587:
+ {
+ label507:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle12);
+ } catch (ClassGenException classGenException4) {
+ {
+ instructionList13 = instructionList;
+ break label507;
+ }
+ }
+ instructionList13 = instructionList;
+ }
+ try {
+ instructionList13.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException4) {
+ instructionHandle2 = instructionHandle12;
+ break label587;
+ }
+ instructionHandle2 = instructionHandle12;
+ }
+ InstructionHandle instructionHandle13 = instructionHandle2;
+ value11++;
+ instructionHandle2 = instructionHandle13;
+ }
+ } else if (instructionHandle.getInstruction() == InstructionConstants.ICONST_4) {
+ if (value11 >= value2) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle14 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.INEG);
+ InstructionHandle instructionHandle23 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), -4));
+ this.processInstructionHandle(instructionHandle, instructionHandle23);
+ label589:
+ {
+ label494:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle14);
+ } catch (ClassGenException classGenException5) {
+ {
+ instructionList12 = instructionList;
+ break label494;
+ }
+ }
+ instructionList12 = instructionList;
+ }
+ try {
+ instructionList12.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException5) {
+ instructionHandle2 = instructionHandle14;
+ break label589;
+ }
+ instructionHandle2 = instructionHandle14;
+ }
+ InstructionHandle instructionHandle15 = instructionHandle2;
+ value11++;
+ instructionHandle2 = instructionHandle15;
+ }
+ } else if (instructionHandle.getInstruction() == InstructionConstants.ICONST_5) {
+ if (value11 >= value2) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle16 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.INEG);
+ InstructionHandle instructionHandle24 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), -5));
+ this.processInstructionHandle(instructionHandle, instructionHandle24);
+ label591:
+ {
+ label481:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle16);
+ } catch (ClassGenException classGenException6) {
+ {
+ instructionList11 = instructionList;
+ break label481;
+ }
+ }
+ instructionList11 = instructionList;
+ }
+ try {
+ instructionList11.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException6) {
+ instructionHandle2 = instructionHandle16;
+ break label591;
+ }
+ instructionHandle2 = instructionHandle16;
+ }
+ InstructionHandle instructionHandle17 = instructionHandle2;
+ value11++;
+ instructionHandle2 = instructionHandle17;
+ }
+ } else if (instructionHandle.getInstruction() == InstructionConstants.ICONST_M1) {
+ if (value11 >= value2) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle18 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ISHR);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ICONST_2);
+ InstructionHandle instructionHandle25 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), -4));
+ this.processInstructionHandle(instructionHandle, instructionHandle25);
+ label593:
+ {
+ label468:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle18);
+ } catch (ClassGenException classGenException7) {
+ {
+ instructionList10 = instructionList;
+ break label468;
+ }
+ }
+ instructionList10 = instructionList;
+ }
+ try {
+ instructionList10.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException7) {
+ instructionHandle2 = instructionHandle18;
+ break label593;
+ }
+ instructionHandle2 = instructionHandle18;
+ }
+ InstructionHandle instructionHandle19 = instructionHandle2;
+ value11++;
+ instructionHandle2 = instructionHandle19;
+ }
+ } else {
+ label460:
+ {
+ if (instructionHandle.getInstruction() instanceof ConstantPushInstruction) {
+ if (value12 >= value3) {
+ instructionHandle2 = instructionHandle;
+ break label460;
+ }
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ ConstantPushInstruction constantPushInstruction;
+ if ((constantPushInstruction =
+ (ConstantPushInstruction) instructionHandle.getInstruction())
+ .getType(constantPool)
+ != Type.BYTE
+ && constantPushInstruction.getType(constantPool) != Type.SHORT) {
+ if (constantPushInstruction.getType(constantPool) != Type.CHAR
+ && constantPushInstruction.getType(constantPool) != Type.INT
+ && constantPushInstruction.getType(constantPool) == Type.LONG) {}
+ } else {
+ byte value21 = 7;
+ if (constantPushInstruction.getType(constantPool) == Type.SHORT) {
+ value21 = 15;
+ }
+ int value22;
+ int[] counts =
+ getCounts(value22 = constantPushInstruction.getValue().intValue(), value21);
+ int value23 = counts[0];
+ int value24 = counts[1];
+ if ((value23 & value24) != value22) {
+ instructionHandle2 = instructionHandle;
+ break label460;
+ }
+ InstructionHandle instructionHandle20 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.IAND);
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value23));
+ InstructionHandle instructionHandle26 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value24));
+ this.processInstructionHandle(instructionHandle, instructionHandle26);
+ label595:
+ {
+ label447:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle20);
+ } catch (ClassGenException classGenException8) {
+ {
+ instructionList9 = instructionList;
+ break label447;
+ }
+ }
+ instructionList9 = instructionList;
+ }
+ try {
+ instructionList9.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException8) {
+ instructionHandle2 = instructionHandle20;
+ break label595;
+ }
+ instructionHandle2 = instructionHandle20;
+ }
+ instructionHandle = instructionHandle2;
+ value12++;
+ }
+ } else if (instructionHandle.getInstruction() instanceof LDC) {
+ LDC lDC = (LDC) instructionHandle.getInstruction();
+ ConstantPoolGen constantPool2 = classGen.getConstantPool();
+ if (lDC.getType(constantPool2) == Type.INT) {
+ int value25 = (Integer) lDC.getValue(constantPool2);
+ int value26 = 0;
+ int value27 = value25;
+ while (value27 > 0 && (value25 & 1) == 0) {
+ int value28 = value25 >> 1;
+ value26++;
+ value27 = value25 = value28;
+ }
+ if (value25 == (short) value25 && value26 > 0 && value13 < value5) {
+ InstructionHandle instructionHandle21 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ISHL);
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value26));
+ InstructionHandle instructionHandle27 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value25));
+ this.processInstructionHandle(instructionHandle, instructionHandle27);
+ label599:
+ {
+ label421:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle21);
+ } catch (ClassGenException classGenException9) {
+ {
+ instructionList8 = instructionList;
+ break label421;
+ }
+ }
+ instructionList8 = instructionList;
+ }
+ try {
+ instructionList8.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException9) {
+ instructionHandle2 = instructionHandle21;
+ break label599;
+ }
+ instructionHandle2 = instructionHandle21;
+ }
+ instructionHandle = instructionHandle2;
+ value13++;
+ } else if (value26 > 0 && value16 < value8) {
+ InstructionHandle instructionHandle28 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.ISHL);
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value26));
+ InstructionHandle instructionHandle29 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value25));
+ this.processInstructionHandle(instructionHandle, instructionHandle29);
+ label601:
+ {
+ label406:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle28);
+ } catch (ClassGenException classGenException10) {
+ {
+ instructionList7 = instructionList;
+ break label406;
+ }
+ }
+ instructionList7 = instructionList;
+ }
+ try {
+ instructionList7.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException10) {
+ instructionHandle2 = instructionHandle28;
+ break label601;
+ }
+ instructionHandle2 = instructionHandle28;
+ }
+ instructionHandle = instructionHandle2;
+ value16++;
+ } else if (value26 == 0 && value16 < value8) {
+ int value29 = RandomUtils.calculateCount(32000) + 555;
+ int value30;
+ int value31;
+ if (((value31 = (value30 = (Integer) lDC.getValue(constantPool2)) ^ value29)
+ ^ value29)
+ != value30) {
+ instructionHandle2 = instructionHandle;
+ break label460;
+ }
+ InstructionHandle instructionHandle30 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.IXOR);
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value29));
+ InstructionHandle instructionHandle210 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value31));
+ this.processInstructionHandle(instructionHandle, instructionHandle210);
+ label603:
+ {
+ label391:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle30);
+ } catch (ClassGenException classGenException11) {
+ {
+ instructionList6 = instructionList;
+ break label391;
+ }
+ }
+ instructionList6 = instructionList;
+ }
+ try {
+ instructionList6.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException11) {
+ instructionHandle2 = instructionHandle30;
+ break label603;
+ }
+ instructionHandle2 = instructionHandle30;
+ }
+ instructionHandle = instructionHandle2;
+ value16++;
+ }
+ }
+ } else if (instructionHandle.getInstruction() instanceof LDC2_W) {
+ LDC2_W lDC2_W = (LDC2_W) instructionHandle.getInstruction();
+ ConstantPoolGen constantPool3 = classGen.getConstantPool();
+ if (lDC2_W.getType(constantPool3) == Type.LONG) {
+ long value32 = lDC2_W.getValue(constantPool3).longValue();
+ int value33 = 0;
+ long value34 = value32;
+ while (value34 > 0L && (value32 & 1L) == 0L) {
+ long value35 = value32 >> 1;
+ value33++;
+ value34 = value32 = value35;
+ }
+ if (value32 == (short) value32 && value33 > 0 && value14 < value6) {
+ InstructionHandle instructionHandle31 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.LSHL);
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value33));
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.I2L);
+ InstructionHandle instructionHandle211 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), (int) value32));
+ this.processInstructionHandle(instructionHandle, instructionHandle211);
+ label607:
+ {
+ label342:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle31);
+ } catch (ClassGenException classGenException12) {
+ {
+ instructionList5 = instructionList;
+ break label342;
+ }
+ }
+ instructionList5 = instructionList;
+ }
+ try {
+ instructionList5.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException12) {
+ instructionHandle2 = instructionHandle31;
+ break label607;
+ }
+ instructionHandle2 = instructionHandle31;
+ }
+ InstructionHandle instructionHandle32 = instructionHandle2;
+ value14 += 1;
+ instructionHandle2 = instructionHandle32;
+ break label460;
+ }
+ if (value32 == (int) value32 && value33 > 0 && value15 < value7) {
+ InstructionHandle instructionHandle33 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.LSHL);
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value33));
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.I2L);
+ InstructionHandle instructionHandle212 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), (int) value32));
+ this.processInstructionHandle(instructionHandle, instructionHandle212);
+ label609:
+ {
+ label331:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle33);
+ } catch (ClassGenException classGenException13) {
+ {
+ instructionList4 = instructionList;
+ break label331;
+ }
+ }
+ instructionList4 = instructionList;
+ }
+ try {
+ instructionList4.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException13) {
+ instructionHandle2 = instructionHandle33;
+ break label609;
+ }
+ instructionHandle2 = instructionHandle33;
+ }
+ InstructionHandle instructionHandle34 = instructionHandle2;
+ value15++;
+ instructionHandle2 = instructionHandle34;
+ break label460;
+ }
+ if (value33 > 0 && value17 < value9) {
+ InstructionHandle instructionHandle35 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.LSHL);
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value33));
+ InstructionHandle instructionHandle213 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value32));
+ this.processInstructionHandle(instructionHandle, instructionHandle213);
+ label611:
+ {
+ label320:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle35);
+ } catch (ClassGenException classGenException14) {
+ {
+ instructionList3 = instructionList;
+ break label320;
+ }
+ }
+ instructionList3 = instructionList;
+ }
+ try {
+ instructionList3.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException14) {
+ instructionHandle2 = instructionHandle35;
+ break label611;
+ }
+ instructionHandle2 = instructionHandle35;
+ }
+ InstructionHandle instructionHandle36 = instructionHandle2;
+ value17++;
+ instructionHandle2 = instructionHandle36;
+ break label460;
+ }
+ if (value33 == 0 && value17 < value9) {
+ int value36 = RandomUtils.calculateCount(32000) + 555;
+ long value37;
+ long value38;
+ if (((value37 = (value38 = lDC2_W.getValue(constantPool3).longValue()) ^ value36)
+ ^ value36)
+ != value38) {
+ instructionHandle2 = instructionHandle;
+ break label460;
+ }
+ InstructionHandle instructionHandle37 =
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.LXOR);
+ instructionList.createInstructionHandle2(
+ instructionHandle, InstructionConstants.I2L);
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value36));
+ InstructionHandle instructionHandle214 =
+ instructionList.getInstructionHandle2(
+ instructionHandle, new PUSH(classGen.getConstantPool(), value37));
+ this.processInstructionHandle(instructionHandle, instructionHandle214);
+ label613:
+ {
+ label362:
+ {
+ try {
+ this.processInstructionHandle2(instructionHandle, instructionHandle37);
+ } catch (ClassGenException classGenException15) {
+ {
+ instructionList2 = instructionList;
+ break label362;
+ }
+ }
+ instructionList2 = instructionList;
+ }
+ try {
+ instructionList2.processInstructionHandle2(instructionHandle);
+ } catch (TargetLostException targetLostException15) {
+ instructionHandle2 = instructionHandle37;
+ break label613;
+ }
+ instructionHandle2 = instructionHandle37;
+ }
+ instructionHandle = instructionHandle2;
+ value17++;
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ OptimizationStatistics.count22 += value10;
+ OptimizationStatistics.count15 += value11;
+ OptimizationStatistics.count21 += value12;
+ }
+
+ public void processInstructionList19(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ InstructionList instructionList2;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof StoreInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle.getInstructionHandle2() == null) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle.getInstructionHandle2().getInstruction()
+ instanceof LoadInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle3 = instructionHandle;
+ InstructionHandle instructionHandle22 = instructionHandle.getInstructionHandle2();
+ StoreInstruction storeInstruction = (StoreInstruction) instructionHandle3.getInstruction();
+ LoadInstruction loadInstruction = (LoadInstruction) instructionHandle22.getInstruction();
+ if (storeInstruction.getIndex() != loadInstruction.getIndex()) {
+ instructionHandle2 = instructionHandle;
+ } else if (!this.matchesInstructionTargeters(instructionHandle22.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else if (!this.matchesInstructionTargeters(instructionHandle3.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle4;
+ if ((instructionHandle4 = instructionHandle22.getInstructionHandle2()) == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle5 = instructionHandle4;
+ label67:
+ if (this.matchesInstructionHandle(
+ instructionList, instructionHandle3, instructionHandle22)) {
+ OptimizationStatistics.count3++;
+ this.processInstructionHandle(instructionHandle22, instructionHandle4);
+ this.processInstructionHandle(instructionHandle3, instructionHandle4);
+ this.processInstructionHandle2(instructionHandle22, instructionHandle4);
+ this.processInstructionHandle2(instructionHandle3, instructionHandle4);
+ label64:
+ {
+ try {
+ instructionList.processInstructionHandle2(instructionHandle3);
+ } catch (TargetLostException targetLostException) {
+ {
+ instructionList2 = instructionList;
+ break label64;
+ }
+ }
+ instructionList2 = instructionList;
+ }
+ try {
+ instructionList2.processInstructionHandle2(instructionHandle22);
+ } catch (TargetLostException targetLostException2) {
+ instructionHandle2 = instructionHandle5;
+ break label67;
+ }
+ instructionHandle2 = instructionHandle5;
+ } else {
+ label104:
+ {
+ OptimizationStatistics.count2++;
+ MethodOptimizer methodOptimizer;
+ if (!(storeInstruction instanceof ASTORE)
+ && !(storeInstruction instanceof FSTORE)
+ && !(storeInstruction instanceof ISTORE)) {
+ if (storeInstruction instanceof DSTORE || storeInstruction instanceof LSTORE) {
+ instructionList.createInstructionHandle(
+ instructionHandle3, InstructionConstants.DUP2);
+ }
+ methodOptimizer = this;
+ } else {
+ instructionList.createInstructionHandle(
+ instructionHandle3, InstructionConstants.DUP);
+ methodOptimizer = this;
+ }
+ methodOptimizer.processInstructionHandle(instructionHandle22, instructionHandle4);
+ this.processInstructionHandle2(instructionHandle22, instructionHandle3);
+ try {
+ instructionList.processInstructionHandle2(instructionHandle22);
+ } catch (TargetLostException targetLostException3) {
+ instructionHandle2 = instructionHandle5;
+ break label104;
+ }
+ instructionHandle2 = instructionHandle5;
+ }
+ }
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public MethodOptimizer(ClassStorage classStorage2) {
+ super();
+ this.classStorage = classStorage2;
+ }
+
+ public void processInstructionHandle(
+ TargetLostException targetLostException, InstructionHandle instructionHandle) {
+ InstructionHandle[] targets = targetLostException.getTargets();
+ int value;
+ for (int value2 = value = 0; value2 < targets.length; value2 = ++value) {
+ int value3;
+ InstructionTargeter[] instructionTargeters;
+ if ((instructionTargeters = targets[value].getTargeters()) != null) {
+ for (int value4 = value3 = 0; value4 < instructionTargeters.length; value4 = value3) {
+ InstructionTargeter instructionTargeter = instructionTargeters[value3];
+ int value5 = value;
+ value3++;
+ instructionTargeter.updateTarget(targets[value5], instructionHandle);
+ }
+ }
+ }
+ }
+
+ public void processInstructionHandle(
+ InstructionHandle instructionHandle, InstructionHandle instructionHandle2) {
+ if (instructionHandle2 != null) {
+ if (instructionHandle.getTargeters() != null) {
+ if (instructionHandle2.getTargeters() != null) {
+ InstructionTargeter[] instructionTargeters;
+ int value = (instructionTargeters = instructionHandle2.getTargeters()).length;
+ int value2;
+ for (int value3 = value2 = 0; value3 < value; value3 = ++value2) {
+ if (instructionTargeters[value2] instanceof LineNumberGen) {
+ return;
+ }
+ }
+ }
+ InstructionTargeter[] instructionTargeters2;
+ int value4 = (instructionTargeters2 = instructionHandle.getTargeters()).length;
+ int value5;
+ for (int value6 = value5 = 0; value6 < value4; value6 = ++value5) {
+ InstructionTargeter instructionTargeter;
+ if ((instructionTargeter = instructionTargeters2[value5]) instanceof LineNumberGen) {
+ instructionTargeter.updateTarget(instructionHandle, instructionHandle2);
+ }
+ }
+ }
+ }
+ }
+
+ public void processInstructionList20(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof NEW)) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ String className =
+ ((NEW) instructionHandle.getInstruction())
+ .getLoadClassType(classGen.getConstantPool())
+ .getClassName();
+ if (!"java.lang.StringBuffer".equals(className)
+ && !"java.lang.StringBuilder".equals(className)) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ String text = "L" + className.replace('.', '/') + ";";
+ if (instructionHandle.getInstructionHandle2() == null) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle.getInstructionHandle2().getInstruction() instanceof DUP)) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle.getInstructionHandle2().getInstructionHandle2() == null) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstruction()
+ instanceof INVOKESPECIAL)) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ INVOKESPECIAL nVOKESPECIAL =
+ (INVOKESPECIAL)
+ instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstruction();
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ if (!className.equals(nVOKESPECIAL.getText2(constantPool))) {
+ instructionHandle2 = instructionHandle;
+ } else if (!"".equals(nVOKESPECIAL.getText4(constantPool))) {
+ instructionHandle2 = instructionHandle;
+ } else if (!"()V".equals(nVOKESPECIAL.getText3(constantPool))) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ int value = 0;
+ InstructionHandle instructionHandle3 = null;
+ InstructionHandle instructionHandle4;
+ instructionHandle2 =
+ instructionHandle4 =
+ instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2();
+ while (true) {
+ label109:
+ if (instructionHandle2 != null) {
+ Instruction instruction;
+ if (!((instruction = instructionHandle4.getInstruction())
+ instanceof ArithmeticInstruction)
+ && !(instruction instanceof ArrayInstruction)
+ && !(instruction instanceof ConversionInstruction)
+ && !(instruction instanceof ConstantPushInstruction)
+ && !(instruction instanceof FieldOrMethod)
+ && !(instruction instanceof LocalVariableInstruction)
+ && !(instruction instanceof PushInstruction)
+ && !(instruction instanceof PopInstruction)
+ && !(instruction instanceof NEW)
+ && !(instruction instanceof NEWARRAY)
+ && !(instruction instanceof NOP)) {
+ instructionHandle2 = instructionHandle3;
+ break;
+ }
+ if (!this.matchesInstructionTargeters(instructionHandle4.getTargeters())) {
+ instructionHandle2 = instructionHandle3;
+ break;
+ }
+ if (instructionHandle4.getInstruction() instanceof INVOKEVIRTUAL) {
+ INVOKEVIRTUAL nVOKEVIRTUAL =
+ (INVOKEVIRTUAL) instructionHandle4.getInstruction();
+ if (className.equals(nVOKEVIRTUAL.getText2(constantPool))
+ && "append".equals(nVOKEVIRTUAL.getText4(constantPool))
+ && ("(Ljava/lang/String;)" + text)
+ .equals(nVOKEVIRTUAL.getText3(constantPool))) {
+ if (value == 1) {
+ instructionHandle2 = instructionHandle3 = instructionHandle4;
+ break;
+ }
+ break label109;
+ }
+ }
+ int value2 = instructionHandle4.getInstruction().produceStack(constantPool);
+ int value3 = instructionHandle4.getInstruction().consumeStack(constantPool);
+ if (value2 != -2) {
+ if (value3 == -2) {
+ instructionHandle2 = instructionHandle3;
+ break;
+ }
+ int value4;
+ if ((value4 = value - value3) < 0) {
+ instructionHandle2 = instructionHandle3;
+ break;
+ }
+ value = value4 + value2;
+ instructionHandle2 =
+ instructionHandle4 = instructionHandle4.getInstructionHandle2();
+ continue;
+ }
+ }
+ instructionHandle2 = instructionHandle3;
+ break;
+ }
+ if (instructionHandle2 == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ OptimizationStatistics.count31++;
+ instructionList.createInstructionHandle2(
+ instructionHandle.getInstructionHandle2().getInstructionHandle2(),
+ InstructionConstants.ICONST_0);
+ ((INVOKEVIRTUAL) instructionHandle3.getInstruction())
+ .setIndex(
+ constantPool.addMethodref(
+ className, "insert", "(ILjava/lang/String;)" + text));
+ instructionHandle2 = instructionHandle;
+ }
+ }
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionHandle(
+ InstructionTargeter[] instructionTargeters,
+ InstructionHandle instructionHandle,
+ InstructionHandle instructionHandle2) {
+ if (instructionTargeters != null) {
+ int value;
+ for (int value2 = value = 0; value2 < instructionTargeters.length; value2 = value) {
+ InstructionTargeter instructionTargeter = instructionTargeters[value];
+ value++;
+ instructionTargeter.updateTarget(instructionHandle, instructionHandle2);
+ }
+ }
+ }
+
+ public static int[] getCounts() {
+ int value = 0;
+ int value2 = 0;
+ int value3;
+ for (int value4 = value3 = 0; value4 < 32; value4 = ++value3) {
+ if (RandomUtils.calculateValue() < 0.5) {
+ value |= 1 << value3;
+ } else {
+ value2 |= 1 << value3;
+ }
+ }
+ return new int[] {value, value2};
+ }
+
+ public void processInstructionHandle2(
+ InstructionHandle instructionHandle, InstructionHandle instructionHandle2) {
+ if (instructionHandle2 != null) {
+ if (instructionHandle.getTargeters() != null) {
+ InstructionTargeter[] instructionTargeters;
+ int value = (instructionTargeters = instructionHandle.getTargeters()).length;
+ int value2;
+ for (int value3 = value2 = 0; value3 < value; value3 = ++value2) {
+ InstructionTargeter instructionTargeter;
+ if ((instructionTargeter = instructionTargeters[value2]) instanceof LocalVariableGen) {
+ instructionTargeter.updateTarget(instructionHandle, instructionHandle2);
+ }
+ }
+ }
+ }
+ }
+
+ public void processInstructionList21(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ boolean matches;
+ instructionList.update();
+ LocalVariableGen[] localVariableGens;
+ if ((localVariableGens = methodGen.getLocalVariables()) != null) {
+ int value = methodGen.getArgumentNames().length;
+ if (!methodGen.isEnabled11()) {
+ value++;
+ }
+ Type[] types;
+ int value2 = (types = methodGen.getArgumentTypes()).length;
+ int value3;
+ for (int value4 = value3 = 0; value4 < value2; value4 = ++value3) {
+ Type type;
+ if ((type = types[value3]) == Type.LONG || type == Type.DOUBLE) {
+ value++;
+ }
+ }
+ LocalVariableGen[] localVariableGens2 = localVariableGens;
+ int value5 = localVariableGens.length;
+ int value6;
+ for (int value7 = value6 = 0; value7 < value5; value7 = ++value6) {
+ LocalVariableGen localVariableGen;
+ if ((localVariableGen = localVariableGens2[value6]).getType() == Type.BOOLEAN
+ || localVariableGen.getType() == Type.BYTE
+ || localVariableGen.getType() == Type.SHORT
+ || localVariableGen.getType() == Type.CHAR) {
+ localVariableGen.setType(Type.INT);
+ }
+ }
+ int value8;
+ InstructionHandle[] instructionHandles = new InstructionHandle[value8 = methodGen.getCount()];
+ InstructionHandle[] instructionHandles2 = new InstructionHandle[value8];
+ boolean[] matchess = new boolean[value8];
+ Hashtable hashtable = new Hashtable();
+ InstructionHandle instructionHandle;
+ for (InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ instructionHandle2 != null;
+ instructionHandle2 = instructionHandle = instructionHandle.getInstructionHandle2()) {
+ if (instructionHandle.getInstruction() instanceof LocalVariableInstruction) {
+ LocalVariableInstruction localVariableInstruction =
+ (LocalVariableInstruction) instructionHandle.getInstruction();
+ int value9;
+ LocalVariableInstruction localVariableInstruction2;
+ if (instructionHandles[value9 = localVariableInstruction.getIndex()] == null) {
+ if (value9 < value) {
+ localVariableInstruction2 = localVariableInstruction;
+ instructionHandles[value9] = instructionList.getStart();
+ instructionHandles2[value9] = instructionHandle;
+ } else {
+ instructionHandles[value9] = instructionHandles2[value9] = instructionHandle;
+ localVariableInstruction2 = localVariableInstruction;
+ }
+ } else {
+ instructionHandles2[value9] = instructionHandle;
+ localVariableInstruction2 = localVariableInstruction;
+ }
+ boolean matches2 =
+ localVariableInstruction2.produceStack(classGen.getConstantPool()) == 2
+ || localVariableInstruction.consumeStack(classGen.getConstantPool()) == 2;
+ if (matches2 && value9 + 1 < value8) {
+ matchess[value9] = true;
+ if (instructionHandles[value9 + 1] == null) {
+ if (value9 + 1 < value) {
+ instructionHandles[value9 + 1] = instructionList.getStart();
+ instructionHandles2[value9 + 1] = instructionHandle;
+ } else {
+ instructionHandles[value9 + 1] =
+ instructionHandles2[value9 + 1] = instructionHandle;
+ }
+ } else {
+ instructionHandles2[value9 + 1] = instructionHandle;
+ }
+ }
+ } else if (instructionHandle.getInstruction() instanceof RET) {
+ RET rET = (RET) instructionHandle.getInstruction();
+ int value10;
+ if (instructionHandles[value10 = rET.getIndex()] == null) {
+ if (value10 < value) {
+ instructionHandles[value10] = instructionList.getStart();
+ instructionHandles2[value10] = instructionHandle;
+ } else {
+ instructionHandles[value10] = instructionHandles2[value10] = instructionHandle;
+ }
+ } else {
+ instructionHandles2[value10] = instructionHandle;
+ }
+ } else if (instructionHandle.getInstruction() instanceof BranchInstruction) {
+ hashtable.put((BranchInstruction) instructionHandle.getInstruction(), instructionHandle);
+ }
+ }
+ InstructionHandle instructionHandle3;
+ for (InstructionHandle instructionHandle4 = instructionHandle3 = instructionList.getStart();
+ instructionHandle4 != null;
+ instructionHandle4 = instructionHandle3 = instructionHandle3.getInstructionHandle2()) {
+ if (instructionHandle3.getInstructionHandle2() != null
+ && instructionHandle3.getInstruction() instanceof ALOAD
+ && instructionHandle3.getInstructionHandle2().getInstruction() instanceof ATHROW) {
+ int index = ((ALOAD) instructionHandle3.getInstruction()).getIndex();
+ instructionHandles[index] = instructionList.getStart();
+ instructionHandles2[index] = instructionList.getEnd();
+ }
+ }
+ int value11;
+ for (int value12 = value11 = 0; value12 < value8; value12 = ++value11) {
+ if (instructionHandles[value11] != null) {
+ while (true) {
+ boolean matches3 = false;
+ InstructionHandle instructionHandle5;
+ InstructionHandle instructionHandle6 = instructionHandle5 = instructionHandles[value11];
+ while (true) {
+ if (instructionHandle6 == null) {
+ matches = matches3;
+ break;
+ }
+ InstructionTargeter[] instructionTargeters;
+ if ((instructionTargeters = instructionHandle5.getTargeters()) != null) {
+ InstructionTargeter[] instructionTargeters2 = instructionTargeters;
+ int value13 = instructionTargeters.length;
+ int value14;
+ for (int value15 = value14 = 0; value15 < value13; value15 = ++value14) {
+ InstructionHandle instructionHandle7;
+ InstructionTargeter instructionTargeter;
+ if ((instructionTargeter = instructionTargeters2[value14])
+ instanceof BranchInstruction
+ && (instructionHandle7 =
+ (InstructionHandle) hashtable.get(instructionTargeter))
+ != null) {
+ if (instructionHandle7.getPosition()
+ < instructionHandles[value11].getPosition()) {
+ instructionHandles[value11] = instructionHandle7;
+ if (matchess[value11] && value11 + 1 < value8) {
+ instructionHandles[value11 + 1] = instructionHandle7;
+ }
+ matches3 = true;
+ }
+ if (instructionHandle7.getPosition()
+ > instructionHandles2[value11].getPosition()) {
+ instructionHandles2[value11] = instructionHandle7;
+ if (matchess[value11] && value11 + 1 < value8) {
+ instructionHandles2[value11 + 1] = instructionHandle7;
+ }
+ matches3 = true;
+ }
+ }
+ }
+ }
+ if (instructionHandle5 == instructionHandles2[value11]) {
+ matches = matches3;
+ break;
+ }
+ instructionHandle6 = instructionHandle5 = instructionHandle5.getInstructionHandle2();
+ }
+ if (!matches) {
+ break;
+ }
+ }
+ }
+ }
+ int[] values = new int[value8];
+ byte value16 = 1;
+ int value17 = 1;
+ for (int value18 = value17; value18 < value8; value18 = ++value17) {
+ int value19;
+ if (matchess[value17]
+ && values[value17] == 0
+ && value17 + 1 < value8
+ && values[value17 + 1] == 0
+ && !matchess[value17 - 1]) {
+ for (int value20 = value19 = Math.max(value17 + 2, value);
+ value20 < value8;
+ value20 = ++value19) {
+ if (matchess[value19]
+ && values[value19] == 0
+ && !matchess[value19 - 1]
+ && instructionHandles2[value17] != null
+ && instructionHandles[value19] != null
+ && instructionHandles2[value17].getPosition()
+ < instructionHandles[value19].getPosition()
+ && instructionHandles2[value17 + 1] != null
+ && instructionHandles2[value17 + 1].getPosition()
+ < instructionHandles[value19].getPosition()) {
+ instructionHandles2[value17] = instructionHandles2[value19];
+ instructionHandles2[value17 + 1] = instructionHandles2[value19];
+ values[value19] = value17;
+ OptimizationStatistics.count4 += 2;
+ }
+ }
+ }
+ }
+ int value21;
+ for (int value22 = value21 = value16; value22 < value8; value22 = ++value21) {
+ int value23;
+ if (!matchess[value21] && !matchess[value21 - 1] && values[value21] == 0) {
+ for (int value24 = value23 = Math.max(value21 + 1, value);
+ value24 < value8;
+ value24 = ++value23) {
+ if (!matchess[value23]
+ && !matchess[value23 - 1]
+ && values[value23] == 0
+ && (instructionHandles2[value21] != null
+ && instructionHandles[value23] != null
+ && instructionHandles2[value21].getPosition()
+ < instructionHandles[value23].getPosition()
+ || instructionHandles2[value21] == null
+ && instructionHandles[value23] != null)) {
+ instructionHandles2[value21] = instructionHandles2[value23];
+ values[value23] = value21;
+ OptimizationStatistics.count4++;
+ }
+ }
+ }
+ }
+ int value25;
+ for (int value26 = value25 = value16; value26 < value8; value26 = ++value25) {
+ int value27;
+ if ((matchess[value25] || matchess[value25 - 1]) && values[value25] == 0) {
+ for (int value28 = value27 = Math.max(value25 + 2, value);
+ value28 < value8;
+ value28 = ++value27) {
+ if (!matchess[value27]
+ && !matchess[value27 - 1]
+ && values[value27] == 0
+ && instructionHandles2[value25] != null
+ && instructionHandles[value27] != null
+ && instructionHandles2[value25].getPosition()
+ < instructionHandles[value27].getPosition()) {
+ instructionHandles2[value25] = instructionHandles2[value27];
+ values[value27] = value25;
+ OptimizationStatistics.count4++;
+ }
+ }
+ }
+ }
+ InstructionHandle instructionHandle8;
+ for (InstructionHandle instructionHandle9 = instructionHandle8 = instructionList.getStart();
+ instructionHandle9 != null;
+ instructionHandle9 = instructionHandle8 = instructionHandle8.getInstructionHandle2()) {
+ if (instructionHandle8.getInstruction() instanceof LocalVariableInstruction) {
+ LocalVariableInstruction localVariableInstruction3 =
+ (LocalVariableInstruction) instructionHandle8.getInstruction();
+ if (values[localVariableInstruction3.getIndex()] != 0) {
+ localVariableInstruction3.setIndex(values[localVariableInstruction3.getIndex()]);
+ }
+ } else if (instructionHandle8.getInstruction() instanceof RET) {
+ RET rET2 = (RET) instructionHandle8.getInstruction();
+ if (values[rET2.getIndex()] != 0) {
+ rET2.setIndex(values[rET2.getIndex()]);
+ }
+ }
+ }
+ Arrays.fill(matchess, false);
+ InstructionHandle instructionHandle10;
+ for (InstructionHandle instructionHandle11 = instructionHandle10 = instructionList.getStart();
+ instructionHandle11 != null;
+ instructionHandle11 = instructionHandle10 = instructionHandle10.getInstructionHandle2()) {
+ if (instructionHandle10.getInstruction() instanceof LocalVariableInstruction) {
+ LocalVariableInstruction localVariableInstruction4 =
+ (LocalVariableInstruction) instructionHandle10.getInstruction();
+ int value29;
+ matchess[value29 = localVariableInstruction4.getIndex()] = true;
+ boolean matches4 =
+ localVariableInstruction4.produceStack(classGen.getConstantPool()) == 2
+ || localVariableInstruction4.consumeStack(classGen.getConstantPool()) == 2;
+ if (matches4 && value29 + 1 < value8) {
+ matchess[value29 + 1] = true;
+ }
+ } else if (instructionHandle10.getInstruction() instanceof RET) {
+ RET rET3 = (RET) instructionHandle10.getInstruction();
+ matchess[rET3.getIndex()] = true;
+ }
+ }
+ int value30;
+ for (int value31 = value30 = value; value31 < value8; value31 = value30) {
+ int value32 = value30;
+ int value33 = value30;
+ value30++;
+ values[value33] = value32;
+ }
+ int value34;
+ for (int value35 = value34 = value; value35 < value8; value35 = ++value34) {
+ int value36;
+ if (!matchess[value34]) {
+ for (int value37 = value36 = value34 + 1; value37 < value8; value37 = value36) {
+ int value38 = values[value36] - 1;
+ int value39 = value36;
+ value36++;
+ values[value39] = value38;
+ }
+ }
+ }
+ InstructionHandle instructionHandle12;
+ for (InstructionHandle instructionHandle13 = instructionHandle12 = instructionList.getStart();
+ instructionHandle13 != null;
+ instructionHandle13 = instructionHandle12 = instructionHandle12.getInstructionHandle2()) {
+ if (instructionHandle12.getInstruction() instanceof LocalVariableInstruction) {
+ LocalVariableInstruction localVariableInstruction5;
+ if ((localVariableInstruction5 =
+ (LocalVariableInstruction) instructionHandle12.getInstruction())
+ .getIndex()
+ >= value) {
+ localVariableInstruction5.setIndex(values[localVariableInstruction5.getIndex()]);
+ }
+ } else {
+ RET rET4;
+ if (instructionHandle12.getInstruction() instanceof RET
+ && (rET4 = (RET) instructionHandle12.getInstruction()).getIndex() >= value) {
+ rET4.setIndex(values[rET4.getIndex()]);
+ }
+ }
+ }
+ LocalVariableGen[] localVariableGens3 = localVariableGens;
+ int value40 = localVariableGens.length;
+ int value41;
+ for (int value42 = value41 = 0; value42 < value40; value42 = ++value41) {
+ LocalVariableGen localVariableGen2;
+ if ((localVariableGen2 = localVariableGens3[value41]).getIndex() < value) {
+ localVariableGen2.processInstructionHandle2(instructionList.getStart());
+ localVariableGen2.processInstructionHandle(instructionList.getEnd());
+ } else {
+ methodGen.removeLocalVariable(localVariableGen2);
+ }
+ }
+ }
+ }
+
+ public boolean matchesInstruction(Instruction instruction) {
+ return instruction instanceof ConstantPushInstruction
+ || instruction instanceof ACONST_NULL
+ || instruction instanceof LDC
+ || instruction instanceof LDC2_W;
+ }
+
+ public void processInstructionList22(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList23(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ InstructionHandle instructionHandle;
+ LocalVariableGen[] localVariableGens;
+ if ((localVariableGens = methodGen.getLocalVariables()) != null) {
+ if (localVariableGens.length != 0) {
+ int value;
+ if ((value = methodGen.getCount()) >= 2) {
+ int[] values = new int[value];
+ boolean[] matchess = new boolean[value];
+ Type[] types = new Type[value];
+ int value2 = 0;
+ if (!methodGen.isEnabled11()) {
+ types[0] = Type.OBJECT;
+ value2 = 1;
+ }
+ int value3 = methodGen.getArgumentNames().length;
+ if (!methodGen.isEnabled11()) {
+ value3++;
+ }
+ Type[] types2;
+ int value4 = (types2 = methodGen.getArgumentTypes()).length;
+ int value5;
+ for (int value6 = value5 = 0; value6 < value4; value6 = ++value5) {
+ Type type = types2[value5];
+ Type type2;
+ Type type3 = type2 = type;
+ int value7 = value2;
+ value2++;
+ types[value7] = type2;
+ if (type3 == Type.LONG || type == Type.DOUBLE) {
+ int value8 = value2 - 1;
+ boolean matches = matchess[value2] = true;
+ value3++;
+ matchess[value8] = matches;
+ int value9 = value2;
+ value2++;
+ types[value9] = type;
+ }
+ }
+ InstructionHandle instructionHandle2;
+ for (InstructionHandle instructionHandle3 =
+ instructionHandle2 = instructionList.getStart();
+ instructionHandle3 != null;
+ instructionHandle3 =
+ instructionHandle2 = instructionHandle2.getInstructionHandle2()) {
+ if (instructionHandle2.getInstruction() instanceof LoadInstruction
+ || instructionHandle2.getInstruction() instanceof StoreInstruction) {
+ LocalVariableInstruction localVariableInstruction =
+ (LocalVariableInstruction) instructionHandle2.getInstruction();
+ int value10;
+ values[value10 = localVariableInstruction.getIndex()]++;
+ if (types[value10] == null) {
+ types[value10] = localVariableInstruction.getType(classGen.getConstantPool());
+ }
+ if ((localVariableInstruction.produceStack(classGen.getConstantPool()) == 2
+ || localVariableInstruction.consumeStack(classGen.getConstantPool()) == 2)
+ && value10 + 1 < value) {
+ matchess[value10] = true;
+ matchess[value10 + 1] = true;
+ }
+ }
+ }
+ int value11;
+ for (int value12 = value11 = 0; value12 < values.length; value12 = value11) {
+ int value13 = values[value11] << 16 | value11;
+ int value14 = value11;
+ value11++;
+ values[value14] = value13;
+ }
+ Arrays.sort(values);
+ byte value15 = 0;
+ int value16;
+ for (int value17 = value16 = 0; value17 < value3 && value15 == 0; value17 = ++value16) {
+ int value18;
+ if (types[value16] != null) {
+ for (int value19 = value18 = value - 1; value19 >= 0; value19 = --value18) {
+ int value20;
+ if ((value20 = values[value18] & 65535) > value16
+ && !matchess[value16]
+ && !matchess[value20]
+ && types[value20] != null) {
+ OptimizationStatistics.count7++;
+ InstructionHandle instructionHandle4;
+ InstructionHandle instructionHandle5 =
+ instructionHandle4 = instructionList.getStart();
+ while (instructionHandle5 != null) {
+ label95:
+ {
+ if (instructionHandle4.getInstruction() instanceof LocalVariableInstruction) {
+ LocalVariableInstruction localVariableInstruction2;
+ if ((localVariableInstruction2 =
+ (LocalVariableInstruction) instructionHandle4.getInstruction())
+ .getIndex()
+ == value16) {
+ localVariableInstruction2.setIndex(value20);
+ } else if (localVariableInstruction2.getIndex() == value20) {
+ localVariableInstruction2.setIndex(value16);
+ }
+ } else if (instructionHandle4.getInstruction() instanceof RET) {
+ RET rET;
+ if ((rET = (RET) instructionHandle4.getInstruction()).getIndex()
+ == value16) {
+ instructionHandle = instructionHandle4;
+ rET.setIndex(value20);
+ break label95;
+ }
+ if (rET.getIndex() == value20) {
+ rET.setIndex(value16);
+ }
+ }
+ instructionHandle = instructionHandle4;
+ }
+ instructionHandle5 =
+ instructionHandle4 = instructionHandle.getInstructionHandle2();
+ }
+ InstructionHandle start = instructionList.getStart();
+ if (value20 < value3) {
+ instructionList.createInstructionHandle(
+ instructionList.createInstructionHandle(
+ instructionList.createInstructionHandle(
+ instructionList.createInstructionHandle(
+ start,
+ InstructionFactory.createLocalVariableInstruction(
+ types[value16], value20)),
+ InstructionFactory.createLocalVariableInstruction(
+ types[value20], value16)),
+ InstructionFactory.createLocalVariableInstruction2(
+ types[value20], value20)),
+ InstructionFactory.createLocalVariableInstruction2(
+ types[value16], value16));
+ } else {
+ instructionList.createInstructionHandle(
+ instructionList.createInstructionHandle(
+ start,
+ InstructionFactory.createLocalVariableInstruction(
+ types[value16], value20)),
+ InstructionFactory.createLocalVariableInstruction2(
+ types[value16], value16));
+ }
+ value15 = 1;
+ break;
+ }
+ }
+ }
+ }
+ if (value15 != 0) {}
+ }
+ }
+ }
+ }
+
+ public boolean matchesInstructionTargeters(InstructionTargeter[] instructionTargeters) {
+ if (instructionTargeters == null) {
+ return true;
+ }
+ int value;
+ for (int value2 = value = 0; value2 < instructionTargeters.length; value2 = ++value) {
+ InstructionTargeter instructionTargeter;
+ if (!((instructionTargeter = instructionTargeters[value]) instanceof LineNumberGen)
+ && !(instructionTargeter instanceof LocalVariableGen)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void processInstructionList24(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ instructionList.update();
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ label72:
+ {
+ if (instructionHandle.getInstruction() instanceof IfInstruction) {
+ byte value = 1;
+ byte value2 = 1;
+ InstructionHandle instructionHandle3 = instructionHandle;
+ InstructionHandle instructionHandle4;
+ if ((instructionHandle4 =
+ ((IfInstruction) instructionHandle.getInstruction()).getTarget())
+ .getPosition()
+ >= instructionHandle3.getPosition()) {
+ value = 0;
+ }
+ if (instructionHandle4.getPosition() <= instructionHandle3.getPosition()) {
+ value2 = 0;
+ }
+ if (value == 0 && value2 == 0) {
+ instructionHandle2 = instructionHandle;
+ break label72;
+ }
+ InstructionHandle instructionHandle5;
+ if ((instructionHandle5 = instructionHandle4.getInstructionHandle()) == null) {
+ instructionHandle2 = instructionHandle;
+ break label72;
+ }
+ if (!(instructionHandle5.getInstruction() instanceof GotoInstruction)) {
+ instructionHandle2 = instructionHandle;
+ break label72;
+ }
+ GotoInstruction gotoInstruction;
+ InstructionHandle target =
+ (gotoInstruction = (GotoInstruction) instructionHandle5.getInstruction()).getTarget();
+ if (value != 0) {
+ if (target.getPosition() >= instructionHandle3.getPosition()) {
+ instructionHandle2 = instructionHandle;
+ break label72;
+ }
+ if (instructionHandle4.getPosition() >= target.getPosition()) {
+ instructionHandle2 = instructionHandle;
+ break label72;
+ }
+ } else if (value2 != 0 && target.getPosition() >= instructionHandle3.getPosition()) {
+ instructionHandle2 = instructionHandle;
+ break label72;
+ }
+ if (target.getInstruction() instanceof BranchInstruction) {
+ instructionHandle2 = instructionHandle;
+ break label72;
+ }
+ if (target.getInstruction() instanceof NEW) {
+ instructionHandle2 = instructionHandle;
+ break label72;
+ }
+ if (target.getInstruction() instanceof NEWARRAY) {
+ instructionHandle2 = instructionHandle;
+ break label72;
+ }
+ if (target.getInstruction() instanceof ANEWARRAY) {
+ instructionHandle2 = instructionHandle;
+ break label72;
+ }
+ if (!this.matchesInstructionTargeters(
+ instructionHandle4.getInstructionHandle().getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ break label72;
+ }
+ OptimizationStatistics.count26++;
+ gotoInstruction.setTarget(target.getInstructionHandle2());
+ instructionList.createInstructionHandle(
+ instructionHandle4.getInstructionHandle(), target.getInstruction());
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList25(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ InstructionList instructionList2;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof StoreInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle.getInstructionHandle2() == null) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle.getInstructionHandle2().getInstruction()
+ instanceof LoadInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle3 = instructionHandle;
+ InstructionHandle instructionHandle22 = instructionHandle.getInstructionHandle2();
+ StoreInstruction storeInstruction = (StoreInstruction) instructionHandle3.getInstruction();
+ LoadInstruction loadInstruction = (LoadInstruction) instructionHandle22.getInstruction();
+ if (storeInstruction.getIndex() != loadInstruction.getIndex()) {
+ instructionHandle2 = instructionHandle;
+ } else if (!this.matchesInstructionTargeters(instructionHandle22.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else if (!this.matchesInstructionTargeters(instructionHandle3.getTargeters())) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle4;
+ if ((instructionHandle4 = instructionHandle22.getInstructionHandle2()) == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ label78:
+ {
+ InstructionHandle instructionHandle5;
+ instructionHandle5 = instructionHandle4;
+ label55:
+ if (this.matchesInstructionHandle(
+ instructionList, instructionHandle3, instructionHandle22)) {
+ OptimizationStatistics.count3++;
+ this.processInstructionHandle(instructionHandle22, instructionHandle4);
+ this.processInstructionHandle(instructionHandle3, instructionHandle4);
+ this.processInstructionHandle2(instructionHandle22, instructionHandle4);
+ this.processInstructionHandle2(instructionHandle3, instructionHandle4);
+ label52:
+ {
+ try {
+ instructionList.processInstructionHandle2(instructionHandle3);
+ } catch (TargetLostException targetLostException) {
+ {
+ instructionList2 = instructionList;
+ break label52;
+ }
+ }
+ instructionList2 = instructionList;
+ }
+ try {
+ instructionList2.processInstructionHandle2(instructionHandle22);
+ } catch (TargetLostException targetLostException2) {
+ break label55;
+ }
+ instructionHandle2 = instructionHandle5;
+ break label78;
+ }
+ instructionHandle2 = instructionHandle5;
+ }
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+
+ public void processInstructionList26(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {}
+
+ public void processInstructionList27(
+ ClassGen classGen, MethodGen methodGen, InstructionList instructionList) {
+ int value;
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2 = instructionHandle = instructionList.getStart();
+ while (instructionHandle2 != null) {
+ if (!(instructionHandle.getInstruction() instanceof LoadInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle.getInstructionHandle2() == null) {
+ instructionHandle2 = instructionHandle;
+ } else if (!(instructionHandle.getInstructionHandle2().getInstruction()
+ instanceof LoadInstruction)) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ InstructionHandle instructionHandle3 = instructionHandle;
+ LoadInstruction loadInstruction = (LoadInstruction) instructionHandle.getInstruction();
+ int index = loadInstruction.getIndex();
+ int value2 = 1;
+ InstructionHandle instructionHandle4;
+ instructionHandle2 = instructionHandle4 = instructionHandle3.getInstructionHandle2();
+ while (instructionHandle2 != null
+ && instructionHandle4.getInstruction() instanceof LoadInstruction
+ && ((LoadInstruction) instructionHandle4.getInstruction()).getIndex() == index) {
+ InstructionHandle instructionHandle5;
+ InstructionHandle instructionHandle6 =
+ instructionHandle5 = instructionHandle4.getInstructionHandle2();
+ value2++;
+ instructionHandle2 = instructionHandle6;
+ instructionHandle4 = instructionHandle5;
+ }
+ if (value2 == 1) {
+ instructionHandle2 = instructionHandle;
+ } else if (instructionHandle4 == null) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ byte value3 = 1;
+ InstructionHandle instructionHandle22 = instructionHandle3.getInstructionHandle2();
+ int value4;
+ int value5 = value4 = 1;
+ while (true) {
+ if (value5 >= value2) {
+ value = value3;
+ break;
+ }
+ if (!this.matchesInstructionTargeters(instructionHandle22.getTargeters())) {
+ value = 0;
+ break;
+ }
+ InstructionHandle instructionHandle7 = instructionHandle22;
+ value4++;
+ instructionHandle22 = instructionHandle7.getInstructionHandle2();
+ value5 = value4;
+ }
+ if (value == 0) {
+ instructionHandle2 = instructionHandle;
+ } else {
+ OptimizationStatistics.count10++;
+ if (value2 > 2) {
+ OptimizationStatistics.count23++;
+ }
+ InstructionHandle instructionHandle23 = instructionHandle3.getInstructionHandle2();
+ int value6;
+ for (int value7 = value6 = 1; value7 < value2; value7 = value6) {
+ this.processInstructionHandle2(instructionHandle23, instructionHandle3);
+ label111:
+ {
+ try {
+ instructionList.processInstructionHandle2(instructionHandle23);
+ } catch (TargetLostException targetLostException) {
+ instructionHandle2 = instructionHandle3;
+ break label111;
+ }
+ instructionHandle2 = instructionHandle3;
+ }
+ InstructionHandle instructionHandle24 = instructionHandle2.getInstructionHandle2();
+ value6++;
+ instructionHandle23 = instructionHandle24;
+ }
+ if (!(loadInstruction instanceof ALOAD)
+ && !(loadInstruction instanceof FLOAD)
+ && !(loadInstruction instanceof ILOAD)) {
+ int value8;
+ if (loadInstruction instanceof DLOAD || loadInstruction instanceof LLOAD) {
+ for (int value9 = value8 = 1; value9 < value2; value9 = value8) {
+ value8++;
+ instructionList.createInstructionHandle2(
+ instructionHandle3, InstructionConstants.DUP2);
+ }
+ }
+ } else {
+ int value10 = 1;
+ label98:
+ while (true) {
+ int value11 = value10;
+ while (true) {
+ if (value11 >= value2) {
+ break label98;
+ }
+ if (value2 - value10 > 2) {
+ value10 += 2;
+ instructionList.createInstructionHandle2(
+ instructionHandle3, InstructionConstants.DUP2);
+ }
+ if (value2 - value10 == 2) {
+ value10++;
+ instructionList.createInstructionHandle2(
+ instructionHandle3, InstructionConstants.DUP_X1);
+ }
+ if (value2 - value10 != 1) {
+ break;
+ }
+ value10++;
+ instructionList.createInstructionHandle2(
+ instructionHandle3, InstructionConstants.DUP);
+ value11 = value10;
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle;
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle2.getInstructionHandle2();
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/optimizer/OptimizationStatistics.java b/src/main/java/com/allatori/optimizer/OptimizationStatistics.java
new file mode 100644
index 0000000..f80ac53
--- /dev/null
+++ b/src/main/java/com/allatori/optimizer/OptimizationStatistics.java
@@ -0,0 +1,70 @@
+package com.allatori.optimizer;
+
+public class OptimizationStatistics {
+
+ public static int count;
+
+ public static int count2;
+
+ public static int count3;
+
+ public static int count4;
+
+ public static int count5;
+
+ public static int count6;
+
+ public static int count7;
+
+ public static int count8;
+
+ public static int count9;
+
+ public static int count10;
+
+ public static int count11;
+
+ public static int count12;
+
+ public static int count13;
+
+ public static int count14;
+
+ public static int count15;
+
+ public static int count16;
+
+ public static int count17;
+
+ public static int count18;
+
+ public static int count19;
+
+ public static int count20;
+
+ public static int count21;
+
+ public static int count22;
+
+ public static int count23;
+
+ public static int count24;
+
+ public static int count25;
+
+ public static int count26;
+
+ public static int count27;
+
+ public static int count28;
+
+ public static int count29;
+
+ public static int count30;
+
+ public static int count31;
+
+ public static int count32;
+
+ public static int count33;
+}
diff --git a/src/main/java/com/allatori/stacktrace/MappingConstructorToken.java b/src/main/java/com/allatori/stacktrace/MappingConstructorToken.java
new file mode 100644
index 0000000..7fc1193
--- /dev/null
+++ b/src/main/java/com/allatori/stacktrace/MappingConstructorToken.java
@@ -0,0 +1,3 @@
+package com.allatori.stacktrace;
+
+public class MappingConstructorToken {}
diff --git a/src/main/java/com/allatori/stacktrace/MappingXmlHandler.java b/src/main/java/com/allatori/stacktrace/MappingXmlHandler.java
new file mode 100644
index 0000000..14f447e
--- /dev/null
+++ b/src/main/java/com/allatori/stacktrace/MappingXmlHandler.java
@@ -0,0 +1,92 @@
+package com.allatori.stacktrace;
+
+import com.allatori.util.LookupTable;
+import java.util.Vector;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class MappingXmlHandler extends DefaultHandler {
+
+ public StackTraceMappings stackTraceMappings;
+
+ public String text;
+
+ public String text2;
+
+ public String text3;
+
+ public String text4;
+
+ public String text5;
+
+ public String text6;
+
+ public String text7;
+
+ public String text8;
+
+ public String text9;
+
+ public String text10;
+
+ public String text11;
+
+ public String text12;
+
+ public String text13;
+
+ public MappingXmlHandler(StackTraceMappings stackTraceMappings2) {
+ super();
+ this.text5 = "old";
+ this.text8 = "new";
+ this.text = "class";
+ this.text9 = "method";
+ this.text3 = "source";
+ this.text11 = "line";
+ this.text10 = "l";
+ this.text2 = "";
+ this.text6 = "";
+ this.text7 = "s";
+ this.text13 = "e";
+ this.stackTraceMappings = stackTraceMappings2;
+ stackTraceMappings2.lookupTable2 = new LookupTable();
+ stackTraceMappings2.lookupTable = new LookupTable();
+ stackTraceMappings2.values = new Vector();
+ }
+
+ @Override
+ public void startElement(String text14, String text15, String text16, Attributes attributes) {
+ if (this.text.equals(text16)) {
+ String value = attributes.getValue(this.text5);
+ String value2 = attributes.getValue(this.text8);
+ this.stackTraceMappings.lookupTable2.processText(value2, value);
+ this.text4 = value + ".";
+ this.text12 = "" + value2 + ".";
+ this.stackTraceMappings.processText(
+ "" + this.text12 + this.text2, "" + this.text4 + this.text2);
+ this.stackTraceMappings.processText(
+ "" + this.text12 + this.text6, "" + this.text4 + this.text6);
+ } else if (this.text9.equals(text16)) {
+ String value3 = attributes.getValue(this.text5);
+ String value4 = attributes.getValue(this.text8);
+ String text17 = value3.substring(0, value3.indexOf(40));
+ if (attributes.getValue(this.text7) != null && attributes.getValue(this.text13) != null) {
+ int value5 = Integer.valueOf(attributes.getValue(this.text7));
+ int value6 = Integer.valueOf(attributes.getValue(this.text13));
+ this.stackTraceMappings.processCount(
+ "" + this.text12 + value4, "" + this.text4 + text17, value5, value6);
+ } else {
+ this.stackTraceMappings.processText("" + this.text12 + value4, "" + this.text4 + text17);
+ }
+ } else if (this.text3.equals(text16)) {
+ String value7 = attributes.getValue(this.text5);
+ String value8 = attributes.getValue(this.text8);
+ this.stackTraceMappings.lookupTable.processText(value8, value7);
+ } else {
+ if (this.text11.equals(text16)) {
+ Integer value9 = Integer.valueOf(attributes.getValue(this.text10));
+ this.stackTraceMappings.values.add(value9);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/stacktrace/MappingXmlReader.java b/src/main/java/com/allatori/stacktrace/MappingXmlReader.java
new file mode 100644
index 0000000..cdc90d2
--- /dev/null
+++ b/src/main/java/com/allatori/stacktrace/MappingXmlReader.java
@@ -0,0 +1,22 @@
+package com.allatori.stacktrace;
+
+import java.io.IOException;
+import java.io.Reader;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+public class MappingXmlReader {
+
+ public static StackTraceMappings createStackTraceMappings(Reader reader)
+ throws ParserConfigurationException, SAXException, IOException {
+ XMLReader xMLReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
+ StackTraceMappings stackTraceMappings;
+ StackTraceMappings stackTraceMappings2 = stackTraceMappings = new StackTraceMappings();
+ xMLReader.setContentHandler(new MappingXmlHandler(stackTraceMappings));
+ xMLReader.parse(new InputSource(reader));
+ return stackTraceMappings2;
+ }
+}
diff --git a/src/main/java/com/allatori/stacktrace/StackTraceMappingEntry.java b/src/main/java/com/allatori/stacktrace/StackTraceMappingEntry.java
new file mode 100644
index 0000000..d6b3abb
--- /dev/null
+++ b/src/main/java/com/allatori/stacktrace/StackTraceMappingEntry.java
@@ -0,0 +1,34 @@
+package com.allatori.stacktrace;
+
+public class StackTraceMappingEntry {
+
+ public int count;
+
+ public int count2;
+
+ public String text;
+
+ public StackTraceMappingEntry(
+ String text, int value, int value2, MappingConstructorToken mappingConstructorToken) {
+ this(text, value, value2);
+ }
+
+ public StackTraceMappingEntry(String text, int count2, int count) {
+ super();
+ this.text = text;
+ this.count2 = count2;
+ this.count = count;
+ }
+
+ public static int calculateCount(StackTraceMappingEntry stackTraceMappingEntry) {
+ return stackTraceMappingEntry.count2;
+ }
+
+ public static String getText(StackTraceMappingEntry stackTraceMappingEntry) {
+ return stackTraceMappingEntry.text;
+ }
+
+ public static int calculateCount2(StackTraceMappingEntry stackTraceMappingEntry) {
+ return stackTraceMappingEntry.count;
+ }
+}
diff --git a/src/main/java/com/allatori/stacktrace/StackTraceMappings.java b/src/main/java/com/allatori/stacktrace/StackTraceMappings.java
new file mode 100644
index 0000000..3a43f89
--- /dev/null
+++ b/src/main/java/com/allatori/stacktrace/StackTraceMappings.java
@@ -0,0 +1,53 @@
+package com.allatori.stacktrace;
+
+import com.allatori.util.LookupTable;
+import java.util.Hashtable;
+import java.util.Vector;
+
+public class StackTraceMappings {
+
+ public Vector values;
+
+ public LookupTable lookupTable;
+
+ public LookupTable lookupTable2;
+
+ public Hashtable entries = new Hashtable();
+
+ public boolean matchesText(String text) {
+ return this.entries.containsKey(text);
+ }
+
+ public void processText(String text, String text2) {
+ this.processCount(text, text2, -1, -1);
+ }
+
+ public void processCount(String text, String text2, int value, int value2) {
+ if (!this.entries.containsKey(text)) {
+ this.entries.put(text, new Vector());
+ }
+ ((Vector) this.entries.get(text)).add(new StackTraceMappingEntry(text2, value, value2, null));
+ }
+
+ public String getText(String text, int value) {
+ Vector vector;
+ for (StackTraceMappingEntry stackTraceMappingEntry :
+ ((Iterable)
+ ((Iterable>) (vector = (Vector) this.entries.get(text))))) {
+ if (value >= StackTraceMappingEntry.calculateCount(stackTraceMappingEntry)
+ && value <= StackTraceMappingEntry.calculateCount2(stackTraceMappingEntry)) {
+ return StackTraceMappingEntry.getText(stackTraceMappingEntry);
+ }
+ }
+ return vector.size() > 0
+ ? StackTraceMappingEntry.getText((StackTraceMappingEntry) vector.get(0))
+ : null;
+ }
+
+ public String getText(String text) {
+ Vector vector;
+ return (vector = (Vector) this.entries.get(text)).size() > 0
+ ? StackTraceMappingEntry.getText((StackTraceMappingEntry) vector.get(0))
+ : null;
+ }
+}
diff --git a/src/main/java/com/allatori/stacktrace/StackTraceRestorer.java b/src/main/java/com/allatori/stacktrace/StackTraceRestorer.java
new file mode 100644
index 0000000..ba9ab4f
--- /dev/null
+++ b/src/main/java/com/allatori/stacktrace/StackTraceRestorer.java
@@ -0,0 +1,308 @@
+package com.allatori.stacktrace;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class StackTraceRestorer {
+
+ public static String getText(String text, StackTraceMappings stackTraceMappings) {
+ String text2 = text;
+ Matcher matcher2 = Pattern.compile("L(.*?);").matcher(text2);
+ while (matcher2.find()) {
+ String text3;
+ String text4 = (text3 = matcher2.group(1)).replace('/', '.');
+ if (stackTraceMappings.lookupTable2.matchesText(text4)) {
+ text2 =
+ text2.replace(text3, stackTraceMappings.lookupTable2.getText(text4).replace('.', '/'));
+ }
+ }
+ return text2;
+ }
+
+ public static void processPrintWriter(
+ BufferedReader bufferedReader, StackTraceMappings stackTraceMappings, PrintWriter printWriter)
+ throws IOException {
+ PrintWriter printWriter2;
+ PrintWriter printWriter3;
+ Pattern pattern = Pattern.compile("(.*(?:at|Frame)\\s+)(.*)\\((.*)\\)(.*)");
+ Pattern pattern2 = Pattern.compile("(.*syslog:\\s+)(.*?)\\((.*)\\)(.*)");
+ Pattern pattern3 = Pattern.compile("(\\s*)(.*?)\\((.*)\\)(.*)");
+ Pattern pattern4 =
+ Pattern.compile(
+ "(.*?\\s+)((?:\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*\\.)+\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*):(\\d+)(\\s+.*)");
+ Pattern pattern5 = Pattern.compile("(.*lock.*a\\s+)(.*?)(\\).*)");
+ String text = null;
+ String text2 = null;
+ String text3 = null;
+ String text4 = null;
+ BufferedReader bufferedReader2 = bufferedReader;
+ String text5;
+ while ((text5 = bufferedReader2.readLine()) != null) {
+ byte value = 0;
+ Matcher matcher2;
+ if ((matcher2 = pattern.matcher(text5)).matches()) {
+ value = 1;
+ text = matcher2.group(1);
+ if ((text2 = matcher2.group(2)).indexOf(40) > 0) {
+ text2 = text2.substring(0, text2.indexOf(40));
+ }
+ text3 = matcher2.group(3);
+ text4 = matcher2.group(4);
+ }
+ Matcher matcher3;
+ if (value == 0 && (matcher3 = pattern2.matcher(text5)).matches()) {
+ value = 1;
+ text = matcher3.group(1);
+ text2 = matcher3.group(2);
+ text3 = matcher3.group(3);
+ text4 = matcher3.group(4);
+ }
+ Matcher matcher4;
+ if (value == 0 && (matcher4 = pattern3.matcher(text5)).matches()) {
+ value = 1;
+ text = matcher4.group(1);
+ text2 = matcher4.group(2);
+ text3 = matcher4.group(3);
+ text4 = matcher4.group(4);
+ }
+ Matcher matcher5;
+ if (value == 0 && (matcher5 = pattern4.matcher(text5)).matches()) {
+ text = matcher5.group(1);
+ String text6 = matcher5.group(2);
+ text3 = matcher5.group(3);
+ text4 = matcher5.group(4);
+ if (stackTraceMappings.lookupTable2.matchesText(text6)) {
+ label96:
+ {
+ try {
+ text5 =
+ ""
+ + text
+ + stackTraceMappings.lookupTable2.getText(text6)
+ + ":"
+ + stackTraceMappings.values.indexOf(Integer.valueOf(text3))
+ + text4;
+ } catch (Exception exception) {
+ printWriter3 = printWriter;
+ break label96;
+ }
+ printWriter3 = printWriter;
+ }
+ printWriter3.println(text5);
+ bufferedReader2 = bufferedReader;
+ continue;
+ }
+ }
+ label89:
+ {
+ if (value != 0) {
+ if (stackTraceMappings.matchesText(text2)) {
+ byte value2 = 0;
+ if (text3.startsWith("(Compiled Method)")) {
+ value2 = 1;
+ text3 = text3.substring("(Compiled Method)".length());
+ }
+ int value3 = -1;
+ StackTraceMappings stackTraceMappings2;
+ if (text3.indexOf(58) >= 0) {
+ String text7 = text3.substring(0, text3.indexOf(58));
+ String text8 = text3.substring(text3.indexOf(58) + 1);
+ if (stackTraceMappings.lookupTable.matchesText(text7)) {
+ text7 = stackTraceMappings.lookupTable.getText(text7);
+ }
+ try {
+ if ((value3 = stackTraceMappings.values.indexOf(Integer.valueOf(text8))) >= 0) {
+ text8 = "" + value3;
+ }
+ } catch (NumberFormatException numberFormatException) {
+ }
+ text3 = "" + text7 + ":" + text8;
+ stackTraceMappings2 = stackTraceMappings;
+ } else {
+ if (stackTraceMappings.lookupTable.matchesText(text3)) {
+ text3 = stackTraceMappings.lookupTable.getText(text3);
+ }
+ stackTraceMappings2 = stackTraceMappings;
+ }
+ String text9;
+ if ((text9 = stackTraceMappings2.getText(text2, value3)) == null) {
+ text9 = stackTraceMappings.getText(text2);
+ }
+ text5 =
+ ""
+ + text
+ + text9
+ + (value2 != 0 ? "(Compiled Method)" : "")
+ + "("
+ + text3
+ + ")"
+ + text4;
+ printWriter2 = printWriter;
+ break label89;
+ }
+ } else {
+ Matcher matcher6;
+ if ((matcher6 = pattern5.matcher(text5)).matches()
+ && stackTraceMappings.lookupTable2.matchesText(matcher6.group(2))) {
+ text5 =
+ ""
+ + matcher6.group(1)
+ + stackTraceMappings.lookupTable2.getText(matcher6.group(2))
+ + matcher6.group(3);
+ }
+ }
+ printWriter2 = printWriter;
+ }
+ printWriter2.println(text5);
+ bufferedReader2 = bufferedReader;
+ }
+ }
+
+ public static void processPrintWriter2(
+ BufferedReader bufferedReader, StackTraceMappings stackTraceMappings, PrintWriter printWriter)
+ throws IOException {
+ StackTraceMappings stackTraceMappings2;
+ int value;
+ StringBuilder stringBuilder = new StringBuilder();
+ BufferedReader bufferedReader2 = bufferedReader;
+ String text;
+ while ((text = bufferedReader2.readLine()) != null) {
+ int value2 = 0;
+ int size = text.length();
+ stringBuilder.setLength(0);
+ do {
+ int value3 = -1;
+ int value4 = -1;
+ int value5 = -1;
+ int value6 = -1;
+ int value7 = value2;
+ int value8 = value2;
+ while (value8 < size && !Character.isJavaIdentifierStart(text.charAt(value2))) {
+ value8 = ++value2;
+ }
+ int value9 = value2;
+ int value10 = value2;
+ while (value10 < size
+ && (Character.isJavaIdentifierPart(text.charAt(value2))
+ || text.charAt(value2) == '.'
+ || text.charAt(value2) == '-'
+ || text.charAt(value2) == '<'
+ || text.charAt(value2) == '>')) {
+ value10 = ++value2;
+ }
+ int value11 = value2;
+ int value12 = value2;
+ while (value12 < size && text.charAt(value2) == ' ') {
+ value12 = ++value2;
+ }
+ label210:
+ {
+ if (value2 < size && text.charAt(value2) == '(') {
+ value6 = ++value2;
+ int value13 = value2;
+ while (value13 < size && Character.isLetter(text.charAt(value2))) {
+ value13 = ++value2;
+ }
+ value5 = value2;
+ if (value2 < size && text.charAt(value2) == ':') {
+ value4 = ++value2;
+ int value14 = value2;
+ while (value14 < size && Character.isDigit(text.charAt(value2))) {
+ value14 = ++value2;
+ }
+ value3 = value2;
+ value = value11;
+ break label210;
+ }
+ } else if (value2 < size && text.charAt(value2) == ':') {
+ value4 = ++value2;
+ int value15 = value2;
+ while (value15 < size && Character.isDigit(text.charAt(value2))) {
+ value15 = ++value2;
+ }
+ value3 = value2;
+ }
+ value = value11;
+ }
+ if (value <= value9) {
+ stringBuilder.append(text.substring(value7, value2));
+ } else {
+ String text2 = text.substring(value9, value11);
+ if (stackTraceMappings.matchesText(text2)) {
+ stringBuilder.append(text.substring(value7, value9));
+ int value16;
+ if (value3 > value4) {
+ String text3 = text.substring(value4, value3);
+ int value17 = -1;
+ label174:
+ {
+ try {
+ value17 = stackTraceMappings.values.indexOf(Integer.valueOf(text3));
+ } catch (NumberFormatException numberFormatException) {
+ stackTraceMappings2 = stackTraceMappings;
+ break label174;
+ }
+ stackTraceMappings2 = stackTraceMappings;
+ }
+ String text4;
+ if ((text4 = stackTraceMappings2.getText(text2, value17)) == null) {
+ text4 = stackTraceMappings.getText(text2);
+ }
+ stringBuilder.append(text4);
+ value16 = value5;
+ } else {
+ stringBuilder.append(stackTraceMappings.getText(text2));
+ value16 = value5;
+ }
+ if (value16 > value6) {
+ String text5 = text.substring(value6, value5);
+ stringBuilder.append(text.substring(value11, value6));
+ if (stackTraceMappings.lookupTable.matchesText(text5)) {
+ text5 = stackTraceMappings.lookupTable.getText(text5);
+ }
+ stringBuilder.append(text5);
+ if (value3 <= value4) {
+ stringBuilder.append(text.substring(value5, value2));
+ }
+ }
+ if (value3 > value4) {
+ String text6 = text.substring(value4, value3);
+ try {
+ int value18;
+ if ((value18 = stackTraceMappings.values.indexOf(Integer.valueOf(text6))) >= 0) {
+ text6 = "" + value18;
+ }
+ } catch (NumberFormatException numberFormatException2) {
+ }
+ StringBuilder stringBuilder2;
+ if (value5 > value6) {
+ stringBuilder2 = stringBuilder;
+ stringBuilder.append(text.substring(value5, value4));
+ } else {
+ stringBuilder2 = stringBuilder;
+ stringBuilder.append(text.substring(value11, value4));
+ }
+ stringBuilder2.append(text6);
+ stringBuilder.append(text.substring(value3, value2));
+ }
+ if (value5 <= value6 && value3 <= value4) {
+ stringBuilder.append(text.substring(value11, value2));
+ }
+ } else if ((text2.indexOf(46) > 0 || text2.length() > 3)
+ && stackTraceMappings.lookupTable2.matchesText(text2)) {
+ stringBuilder.append(text.substring(value7, value9));
+ stringBuilder.append(stackTraceMappings.lookupTable2.getText(text2));
+ stringBuilder.append(text.substring(value11, value2));
+ } else {
+ stringBuilder.append(text.substring(value7, value2));
+ }
+ }
+ } while (value2 < size);
+ bufferedReader2 = bufferedReader;
+ printWriter.println(getText(stringBuilder.toString(), stackTraceMappings));
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/transform/ClassConstantPoolTransformer.java b/src/main/java/com/allatori/transform/ClassConstantPoolTransformer.java
new file mode 100644
index 0000000..e3f8d78
--- /dev/null
+++ b/src/main/java/com/allatori/transform/ClassConstantPoolTransformer.java
@@ -0,0 +1,125 @@
+package com.allatori.transform;
+
+import com.allatori.bytecode.ConstantPoolEditor;
+import com.allatori.bytecode.MethodFactory;
+import com.allatori.crypto.CustomStringEncryption;
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.classfile.ConstantString;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.LDC;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.model.ClassStorage;
+
+public class ClassConstantPoolTransformer implements ClassTransformer {
+
+ public ClassStorage classStorage;
+
+ public ConstantPoolEditor constantPoolEditor;
+
+ public ClassConstantPoolTransformer(ClassStorage classStorage2) {
+ super();
+ this.constantPoolEditor = new ConstantPoolEditor(null);
+ this.classStorage = classStorage2;
+ }
+
+ @Override
+ public void finish() {
+ DistributedStringEncryptionTransformer.entries6 = null;
+ DistributedStringEncryptionTransformer.values = null;
+ }
+
+ @Override
+ public void transform(ClassGen classGen) {
+ if (DistributedStringEncryptionTransformer.values.contains(classGen)) {
+ try {
+ this.transform2(classGen);
+ } catch (Exception exception) {
+ this.constantPoolEditor.processClassGen(classGen);
+ this.transform2(classGen);
+ }
+ }
+ }
+
+ public void transform2(ClassGen classGen) {
+ InstructionHandle instructionHandle;
+ Method[] methods = classGen.getMethods();
+ int value;
+ for (int value2 = value = 0; value2 < methods.length; value2 = ++value) {
+ Method method;
+ if ((method = methods[value]).getCode() != null) {
+ InstructionHandle instructionHandle2;
+ MethodGen methodGen;
+ InstructionHandle instructionHandle3 =
+ instructionHandle2 =
+ (methodGen =
+ MethodFactory.createMethodGen(
+ method,
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool()))
+ .getInstructionList()
+ .getStart();
+ while (instructionHandle3 != null) {
+ label38:
+ {
+ if (instructionHandle2.getInstruction() instanceof LDC) {
+ LDC lDC = (LDC) instructionHandle2.getInstruction();
+ Constant constant;
+ if ((constant = classGen.getConstantPool().getConstant(lDC.getIndex()))
+ instanceof ConstantString) {
+ String text3;
+ if ((text3 =
+ ((ConstantUtf8)
+ classGen
+ .getConstantPool()
+ .getConstant(((ConstantString) constant).getStringIndex()))
+ .getBytes())
+ != null
+ && text3.startsWith(DistributedStringEncryptionTransformer.text2)) {
+ String text4 =
+ text3.substring(DistributedStringEncryptionTransformer.text2.length());
+ String text5;
+ String text6 =
+ text4.substring(
+ (text5 =
+ text4.substring(
+ 0,
+ text4.indexOf(
+ DistributedStringEncryptionTransformer.text2)))
+ .length()
+ + DistributedStringEncryptionTransformer.text2.length());
+ instructionHandle = instructionHandle2;
+ lDC.setIndex(
+ classGen
+ .getConstantPool()
+ .addString(
+ DistributedStringEncryptionTransformer.createText(
+ text6, classGen.getClassName(), methodGen.getName(), text5)));
+ break label38;
+ }
+ if (text3 != null && text3.startsWith(CustomStringEncryption.text)) {
+ lDC.setIndex(
+ classGen
+ .getConstantPool()
+ .addString(
+ CustomStringEncryption.createText(
+ text3,
+ this.classStorage.getClassLoader(),
+ classGen.getClassName(),
+ methodGen.getName())));
+ }
+ }
+ }
+ instructionHandle = instructionHandle2;
+ }
+ instructionHandle3 = instructionHandle2 = instructionHandle.getInstructionHandle2();
+ }
+ methodGen.update5();
+ classGen.replaceMethod(method, methodGen.getMethod());
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/transform/ClassTransformer.java b/src/main/java/com/allatori/transform/ClassTransformer.java
new file mode 100644
index 0000000..409df0c
--- /dev/null
+++ b/src/main/java/com/allatori/transform/ClassTransformer.java
@@ -0,0 +1,10 @@
+package com.allatori.transform;
+
+import com.allatori.lib.bcel.generic.ClassGen;
+
+public interface ClassTransformer {
+
+ void transform(ClassGen classGen);
+
+ void finish();
+}
diff --git a/src/main/java/com/allatori/transform/ControlFlowTransformer.java b/src/main/java/com/allatori/transform/ControlFlowTransformer.java
new file mode 100644
index 0000000..1839343
--- /dev/null
+++ b/src/main/java/com/allatori/transform/ControlFlowTransformer.java
@@ -0,0 +1,221 @@
+package com.allatori.transform;
+
+import com.allatori.bytecode.MethodFactory;
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ACONST_NULL;
+import com.allatori.lib.bcel.generic.ANEWARRAY;
+import com.allatori.lib.bcel.generic.BIPUSH;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.DLOAD;
+import com.allatori.lib.bcel.generic.ICONST;
+import com.allatori.lib.bcel.generic.Instruction;
+import com.allatori.lib.bcel.generic.InstructionConstants;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.InstructionList;
+import com.allatori.lib.bcel.generic.InstructionTargeter;
+import com.allatori.lib.bcel.generic.LLOAD;
+import com.allatori.lib.bcel.generic.LineNumberGen;
+import com.allatori.lib.bcel.generic.LoadInstruction;
+import com.allatori.lib.bcel.generic.LocalVariableGen;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.generic.NEW;
+import com.allatori.lib.bcel.generic.NEWARRAY;
+import com.allatori.lib.bcel.generic.PUSH;
+import com.allatori.lib.bcel.generic.SIPUSH;
+import com.allatori.model.ClassStorage;
+
+public class ControlFlowTransformer implements ClassTransformer {
+
+ public ClassStorage classStorage;
+
+ @Override
+ public void finish() {}
+
+ @Override
+ public void transform(ClassGen classGen) {
+ InstructionHandle instructionHandle;
+ try {
+ Method[] methods = classGen.getMethods();
+ int value = methods.length;
+ for (int index = 0; index < value; index++) {
+ Method method;
+ if ((method = methods[index]).getCode() != null) {
+ MethodGen methodGen =
+ MethodFactory.createMethodGen(
+ method,
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool());
+ if (Configuration.getObfuscationOptions()
+ .matchesMethodGen(this.classStorage, classGen, methodGen)) {
+ int value2;
+ int value3 =
+ value2 =
+ Configuration.getExtensiveFlowOptions()
+ .calculateCount(this.classStorage, classGen, methodGen);
+ Configuration.getExtensiveFlowOptions();
+ if (value3 != 0) {
+ InstructionList instructionList;
+ InstructionHandle start =
+ (instructionList = methodGen.getInstructionList()).getStart();
+ byte value4 = 0;
+ InstructionHandle instructionHandle2 = start;
+ while (instructionHandle2 != null) {
+ if (!(start.getInstruction() instanceof NEWARRAY)
+ && !(start.getInstruction() instanceof ANEWARRAY)) {
+ label115:
+ {
+ label114:
+ if (start.getInstruction() instanceof NEW) {
+ if (value4 != 0) {
+ Configuration.getExtensiveFlowOptions();
+ if (value2 != 2) {
+ break label114;
+ }
+ }
+ if (start.getInstructionHandle() == null) {
+ instructionHandle = start;
+ break label115;
+ }
+ if (!this.matchesInstructionTargeters(start.getTargeters())) {
+ instructionHandle = start;
+ break label115;
+ }
+ if (!this.matchesInstructionTargeters(
+ start.getInstructionHandle().getTargeters())) {
+ instructionHandle = start;
+ break label115;
+ }
+ if (!(start.getInstructionHandle().getInstruction() instanceof ICONST)
+ && !(start.getInstructionHandle().getInstruction()
+ instanceof ACONST_NULL)) {
+ instructionHandle = start;
+ break label115;
+ }
+ Instruction instruction = start.getInstructionHandle().getInstruction();
+ instructionList.createInstructionHandle2(
+ instructionList.createInstructionHandle2(
+ instructionList.createInstructionHandle2(start, instruction),
+ InstructionConstants.DUP),
+ InstructionConstants.POP2);
+ value4 = 1;
+ }
+ instructionHandle = start;
+ }
+ label98:
+ {
+ label97:
+ if (instructionHandle.getInstruction() instanceof NEW) {
+ if (value4 != 0) {
+ Configuration.getExtensiveFlowOptions();
+ if (value2 != 2) {
+ break label97;
+ }
+ }
+ if (start.getInstructionHandle() == null) {
+ value3 = value2;
+ break label98;
+ }
+ if (!this.matchesInstructionTargeters(start.getTargeters())) {
+ value3 = value2;
+ break label98;
+ }
+ if (!this.matchesInstructionTargeters(
+ start.getInstructionHandle().getTargeters())) {
+ value3 = value2;
+ break label98;
+ }
+ if (!(start.getInstructionHandle().getInstruction()
+ instanceof LoadInstruction)) {
+ value3 = value2;
+ break label98;
+ }
+ LoadInstruction loadInstruction;
+ if (!((loadInstruction =
+ (LoadInstruction) start.getInstructionHandle().getInstruction())
+ instanceof LLOAD)) {
+ if (loadInstruction instanceof DLOAD) {
+ value3 = value2;
+ break label98;
+ }
+ instructionList.createInstructionHandle2(
+ instructionList.createInstructionHandle2(
+ instructionList.createInstructionHandle2(
+ start, loadInstruction.copy()),
+ InstructionConstants.DUP),
+ InstructionConstants.POP2);
+ value4 = 1;
+ }
+ }
+ value3 = value2;
+ }
+ Configuration.getExtensiveFlowOptions();
+ if (value3 != 2
+ || !(start.getInstruction() instanceof BIPUSH)
+ && !(start.getInstruction() instanceof SIPUSH)
+ && !(start.getInstruction() instanceof ICONST)) {
+ instructionHandle2 = start = start.getInstructionHandle2();
+ } else {
+ instructionList.createInstructionHandle2(
+ instructionList.createInstructionHandle2(
+ instructionList.getInstructionHandle2(
+ start, new PUSH(classGen.getConstantPool(), 1)),
+ InstructionConstants.DUP),
+ InstructionConstants.POP2);
+ start =
+ start
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2();
+ instructionHandle2 = start;
+ }
+ } else {
+ instructionList.createInstructionHandle2(
+ instructionList.createInstructionHandle2(
+ instructionList.getInstructionHandle2(
+ start, new PUSH(classGen.getConstantPool(), 1)),
+ InstructionConstants.DUP),
+ InstructionConstants.POP2);
+ start =
+ start
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2();
+ instructionHandle2 = start;
+ }
+ }
+ methodGen.update5();
+ methodGen.update4();
+ classGen.replaceMethod(method, methodGen.getMethod());
+ }
+ }
+ }
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ public ControlFlowTransformer(ClassStorage classStorage2) {
+ super();
+ this.classStorage = classStorage2;
+ }
+
+ public boolean matchesInstructionTargeters(InstructionTargeter[] instructionTargeters) {
+ if (instructionTargeters == null) {
+ return true;
+ }
+ int value;
+ for (int value2 = value = 0; value2 < instructionTargeters.length; value2 = ++value) {
+ InstructionTargeter instructionTargeter;
+ if (!((instructionTargeter = instructionTargeters[value]) instanceof LineNumberGen)
+ && !(instructionTargeter instanceof LocalVariableGen)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/com/allatori/transform/DistributedStringEncryptionTransformer.java b/src/main/java/com/allatori/transform/DistributedStringEncryptionTransformer.java
new file mode 100644
index 0000000..9c3b637
--- /dev/null
+++ b/src/main/java/com/allatori/transform/DistributedStringEncryptionTransformer.java
@@ -0,0 +1,1331 @@
+package com.allatori.transform;
+
+import com.allatori.bytecode.ConstantPoolEditor;
+import com.allatori.bytecode.MethodFactory;
+import com.allatori.config.Configuration;
+import com.allatori.crypto.CustomStringEncryption;
+import com.allatori.crypto.StringEncryptionUtils;
+import com.allatori.internal.NameSignatureInstructionSupport;
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.classfile.ConstantString;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ArrayType;
+import com.allatori.lib.bcel.generic.BranchHandle;
+import com.allatori.lib.bcel.generic.BranchInstruction;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.ConstantPoolGen;
+import com.allatori.lib.bcel.generic.IINC;
+import com.allatori.lib.bcel.generic.Instruction;
+import com.allatori.lib.bcel.generic.InstructionConstants;
+import com.allatori.lib.bcel.generic.InstructionFactory;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.InstructionList;
+import com.allatori.lib.bcel.generic.LDC;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.generic.ObjectType;
+import com.allatori.lib.bcel.generic.PUSH;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.model.ClassStorage;
+import com.allatori.util.Log;
+import com.allatori.util.random.RandomUtils;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.TreeSet;
+import java.util.Vector;
+
+public class DistributedStringEncryptionTransformer implements ClassTransformer {
+
+ public static String text4 = "AllatoriDecryptString";
+
+ public static String text = "AllatoriDecryptString2";
+
+ public static String text2 = "allatori-12321-32123:";
+
+ public static char character = 'U';
+
+ public static Hashtable entries6 = new Hashtable();
+
+ public static Type type = Type.STRING;
+
+ public static boolean enabled2 = false;
+
+ public static String text5 = "makeConcatWithConstants";
+
+ public Hashtable entries;
+
+ public String text3;
+
+ public static Vector values;
+
+ public ClassStorage classStorage;
+
+ public Hashtable entries2;
+
+ public Collection collection;
+
+ public Hashtable entries3;
+
+ public Hashtable entries4;
+
+ public String text6;
+
+ public Hashtable entries5;
+
+ public boolean enabled;
+
+ public Hashtable entries7;
+
+ public Hashtable entries8;
+
+ public static String createText(String text, String text2, String text3, String text4) {
+ int value = ((int[]) entries6.get(text4))[2] == 0 ? 1 : 0;
+ String text5 = value != 0 ? ("" + text2 + text3) : ("" + text3 + text2);
+ int value2 = text5.length() - 1;
+ int value3 = text5.length() - 1;
+ char[] values = new char[text.length()];
+ char value4 = (char) ((int[]) entries6.get(text4))[0];
+ char value5 = (char) ((int[]) entries6.get(text4))[1];
+ int value6;
+ for (int value7 = value6 = values.length - 1; value7 >= 0; value7 = --value6) {
+ char value8 = (char) (text.charAt(value6) ^ value4 ^ text5.charAt(value3));
+ int value9 = value6;
+ value6--;
+ values[value9] = value8;
+ if (value6 < 0) {
+ break;
+ }
+ char value10 = (char) (text.charAt(value6) ^ value5 ^ text5.charAt(value3));
+ int value11 = value6;
+ value3--;
+ values[value11] = value10;
+ if (value3 < 0) {
+ value3 = value2;
+ }
+ }
+ return new String(values);
+ }
+
+ public void processValues(Vector vector, Vector vector2) {
+ if (vector == null) {
+ vector = new Vector();
+ }
+ if (vector2 == null) {
+ vector2 = new Vector();
+ }
+ if (Configuration.getObfuscationOptions().isEnabled()) {
+ Iterator iterator2;
+ Iterator iterator3 = iterator2 = vector.iterator();
+ while (iterator3.hasNext()) {
+ ClassGen classGen = (ClassGen) iterator2.next();
+ iterator3 = iterator2;
+ StringEncryptionUtils.processCharacter(classGen, text4, character);
+ }
+ } else {
+ Iterator iterator4;
+ Iterator iterator5 = iterator4 = vector.iterator();
+ while (iterator5.hasNext()) {
+ ClassGen classGen2 = (ClassGen) iterator4.next();
+ int value = RandomUtils.calculateCount(125) + 1;
+ int value2 = RandomUtils.calculateCount(125) + 1;
+ iterator5 = iterator4;
+ this.entries.put(classGen2.getClassName(), new int[] {value, value2});
+ this.transform2(classGen2);
+ }
+ Iterator iterator6;
+ for (Iterator iterator7 = iterator6 = vector2.iterator();
+ iterator7.hasNext();
+ iterator7 = iterator6) {
+ ClassGen classGen3 = (ClassGen) iterator6.next();
+ int value3 = RandomUtils.calculateCount(125) + 1;
+ int value4 = RandomUtils.calculateCount(125) + 1;
+ int value5 = RandomUtils.calculateValue() <= 0.5 ? 0 : 1;
+ entries6.put(classGen3.getClassName(), new int[] {value3, value4, value5});
+ this.transform3(classGen3);
+ }
+ }
+ }
+
+ public DistributedStringEncryptionTransformer(ClassStorage classStorage2) {
+ super();
+ this.collection = new TreeSet();
+ this.enabled = true;
+ this.entries7 = new Hashtable();
+ this.entries4 = new Hashtable();
+ this.entries3 = new Hashtable();
+ this.entries5 = new Hashtable();
+ this.entries8 = new Hashtable();
+ this.entries2 = new Hashtable();
+ this.entries = new Hashtable();
+ this.text3 = ".R";
+ this.text6 = "org.springframework.boot.";
+ this.classStorage = classStorage2;
+ character = Configuration.getObfuscationOptions().getCharacter();
+ values = new Vector();
+ entries6 = new Hashtable();
+ StringEncryptionUtils.update();
+ this.collection.add("");
+ this.finish2();
+ }
+
+ public void processValues(Vector vector) {
+ DistributedStringEncryptionTransformer distributedStringEncryptionTransformer;
+ Vector vector2;
+ if (vector.size() != 0) {
+ String text;
+ if ((text = Configuration.getObfuscationOptions().getDecryptorIncludePattern()).length()
+ > 0) {
+ String[] texts = text.split(";");
+ int value;
+ for (int value2 = value = vector.size() - 1; value2 >= 0; value2 = --value) {
+ ClassGen classGen = (ClassGen) vector.get(value);
+ int value3;
+ for (int value4 = value3 = texts.length - 1; value4 >= 0; value4 = --value3) {
+ if (texts[value3].length() > 0 && !classGen.getClassName().startsWith(texts[value3])) {
+ vector.removeElement(classGen);
+ }
+ }
+ }
+ }
+ String text2;
+ if ((text2 = Configuration.getObfuscationOptions().getDecryptorExcludePattern()).length()
+ > 0) {
+ String[] texts2 = text2.split(";");
+ int value5;
+ for (int value6 = value5 = vector.size() - 1; value6 >= 0; value6 = --value5) {
+ ClassGen classGen2 = (ClassGen) vector.get(value5);
+ int value7;
+ for (int value8 = value7 = texts2.length - 1; value8 >= 0; value8 = --value7) {
+ if (texts2[value7].length() > 0
+ && classGen2.getClassName().startsWith(texts2[value7])) {
+ vector.removeElement(classGen2);
+ }
+ }
+ }
+ }
+ ClassGen classGen3 = null;
+ ClassGen classGen4 = null;
+ ClassGen classGen5 = null;
+ String text3 = "java.";
+ int value9;
+ int value10 = value9 = vector.size() - 1;
+ while (true) {
+ if (value10 < 0) {
+ vector2 = vector;
+ break;
+ }
+ if (vector.size() == 1) {
+ vector2 = vector;
+ break;
+ }
+ ClassGen classGen6 = (ClassGen) vector.get(value9);
+ byte value11 = 1;
+ if (classGen6.containsMethod((String) "", (String) "()V") != null) {
+ value11 = 0;
+ }
+ byte value12 = 1;
+ int value13;
+ if (!classGen6.getSuperclassName().startsWith(text3)) {
+ value12 = 0;
+ value13 = value11;
+ } else {
+ String[] texts3;
+ int value14 = (texts3 = classGen6.getInterfaceNames()).length;
+ int value15;
+ value13 = value15 = 0;
+ while (true) {
+ if (value13 >= value14) {
+ value13 = value11;
+ break;
+ }
+ if (!texts3[value15].startsWith(text3)) {
+ value12 = 0;
+ value13 = value11;
+ break;
+ }
+ value13 = ++value15;
+ }
+ }
+ if (value13 != 0 && classGen3 == null) {
+ classGen3 = classGen6;
+ }
+ if (value12 != 0 && classGen4 == null) {
+ classGen4 = classGen6;
+ }
+ if (value11 != 0 && value12 != 0 && classGen5 == null) {
+ classGen5 = classGen6;
+ }
+ if (value11 == 0 || value12 == 0) {
+ vector.remove(classGen6);
+ }
+ value10 = --value9;
+ }
+ label93:
+ {
+ if (vector2.size() == 1) {
+ if (classGen5 != null) {
+ distributedStringEncryptionTransformer = this;
+ vector.clear();
+ vector.add(classGen5);
+ break label93;
+ }
+ if (classGen4 != null) {
+ distributedStringEncryptionTransformer = this;
+ vector.clear();
+ vector.add(classGen4);
+ break label93;
+ }
+ if (classGen3 != null) {
+ vector.clear();
+ vector.add(classGen3);
+ }
+ }
+ distributedStringEncryptionTransformer = this;
+ }
+ ClassGen classGen7;
+ if ((classGen7 =
+ distributedStringEncryptionTransformer.classStorage.getClassGen(
+ "com.allatori.ant.ObfuscatorTask"))
+ != null) {
+ vector.removeElement(classGen7);
+ }
+ ClassGen classGen8;
+ if ((classGen8 = this.classStorage.getClassGen("com.allatori.wtk.WTKObfuscator")) != null) {
+ vector.removeElement(classGen8);
+ }
+ }
+ }
+
+ public void transform2(ClassGen classGen) {
+ InstructionFactory instructionFactory = new InstructionFactory(classGen);
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ InstructionList instructionList = new InstructionList();
+ MethodGen methodGen =
+ new MethodGen(
+ 9,
+ Type.STRING,
+ new Type[] {type},
+ new String[] {"s"},
+ text4,
+ classGen.getClassName(),
+ instructionList,
+ constantPool);
+ int value = RandomUtils.calculateValue() <= 0.5 ? 1 : 0;
+ Vector vector;
+ Vector vector2;
+ if (value != 0) {
+ vector2 =
+ vector =
+ StringEncryptionUtils.createValues(
+ ((int[]) this.entries.get(classGen.getClassName()))[0]);
+ vector2.addAll(StringEncryptionUtils.createValues(RandomUtils.calculateCount(125) + 1));
+ } else {
+ (vector = StringEncryptionUtils.createValues(RandomUtils.calculateCount(125) + 1))
+ .addAll(
+ StringEncryptionUtils.createValues(
+ ((int[]) this.entries.get(classGen.getClassName()))[0]));
+ vector2 = vector;
+ }
+ vector2.addAll(
+ StringEncryptionUtils.createValues(((int[]) this.entries.get(classGen.getClassName()))[1]));
+ Iterator iterator2 = vector.iterator();
+ Iterator iterator3 = iterator2;
+ while (iterator3.hasNext()) {
+ Instruction instruction = (Instruction) iterator2.next();
+ iterator3 = iterator2;
+ instructionList.getInstructionHandle(instruction);
+ }
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(instructionFactory.createCheckCast(Type.STRING));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "length", Type.INT, Type.NO_ARGS, (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(instructionFactory.createNewArray(Type.CHAR, (short) 1));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(new PUSH(constantPool, 1));
+ instructionList.getInstructionHandle(InstructionConstants.ISUB);
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 3));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.OBJECT, 1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 4));
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ if (value != 0) {
+ instructionList.getInstructionHandle(InstructionFactory.POP2);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 2));
+ } else {
+ instructionList.getInstructionHandle(InstructionFactory.POP);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 2));
+ instructionList.getInstructionHandle(InstructionFactory.POP);
+ }
+ BranchInstruction branchInstruction =
+ InstructionFactory.createBranchInstruction((short) 155, null);
+ BranchHandle branchHandle = instructionList.getBranchHandle(branchInstruction);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 3));
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X1);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "charAt", Type.CHAR, new Type[] {Type.INT}, (short) 182));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 2));
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(new IINC(3, -1));
+ instructionList.getInstructionHandle(InstructionConstants.CASTORE);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 3));
+ BranchInstruction branchInstruction2 =
+ InstructionFactory.createBranchInstruction((short) 155, null);
+ instructionList.getBranchHandle(branchInstruction2);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 3));
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X1);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "charAt", Type.CHAR, new Type[] {Type.INT}, (short) 182));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 4));
+ instructionList.getInstructionHandle(new IINC(3, -1));
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(InstructionConstants.CASTORE);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 3));
+ instructionList.getBranchHandle(
+ InstructionFactory.createBranchInstruction((short) 167, branchHandle));
+ InstructionHandle instructionHandle =
+ instructionList.getInstructionHandle(instructionFactory.createNew("java.lang.String"));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 1));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String",
+ "",
+ Type.VOID,
+ new Type[] {new ArrayType(Type.CHAR, 1)},
+ (short) 183));
+ instructionList.getInstructionHandle(InstructionFactory.createReturn(Type.OBJECT));
+ branchInstruction.setTarget(instructionHandle);
+ branchInstruction2.setTarget(instructionHandle);
+ methodGen.update5();
+ methodGen.update4();
+ classGen.processMethod2(methodGen.getMethod());
+ instructionList.update3();
+ }
+
+ public boolean isEnabled() {
+ return this.enabled;
+ }
+
+ @Override
+ public void finish() {}
+
+ public boolean matchesClassGen(ClassGen classGen) {
+ return Configuration.getObfuscationOptions().isPackageStringEncryptionEnabled()
+ ? !classGen.isEnabled9()
+ && !classGen.isEnabled2()
+ && !classGen.isEnabled10()
+ && !classGen.isEnabled5()
+ && !classGen.isEnabled8()
+ && !classGen.getClassName().contains("$")
+ && !classGen.getClassName().endsWith(this.text3)
+ : classGen.isEnabled6()
+ && !classGen.isEnabled2()
+ && !classGen.isEnabled10()
+ && !classGen.isEnabled5()
+ && !classGen.isEnabled8()
+ && !classGen.getClassName().contains("$")
+ && !classGen.getClassName().endsWith(this.text3);
+ }
+
+ @Override
+ public void transform(ClassGen classGen) {
+ InstructionHandle instructionHandle;
+ byte value = 0;
+ Iterator iterator2 = this.entries7.values().iterator();
+ int value2;
+ while (true) {
+ if (iterator2.hasNext()) {
+ if (!((Vector) iterator2.next()).contains(classGen)) {
+ continue;
+ }
+ value2 = 1;
+ break;
+ }
+ value2 = value;
+ break;
+ }
+ if (value2 != 0) {
+ InstructionFactory instructionFactory = new InstructionFactory(classGen);
+ byte value3 = 2;
+ String[] texts = new String[2];
+ int value4;
+ if (((Vector) this.entries3.get(this.getText(classGen))).size() > 0) {
+ for (int value5 = value4 = 0; value5 < value3; value5 = value4) {
+ String className =
+ ((ClassGen)
+ ((Vector) this.entries3.get(this.getText(classGen)))
+ .get(
+ RandomUtils.calculateCount(
+ ((Vector) this.entries3.get(this.getText(classGen))).size())))
+ .getClassName();
+ int value6 = value4;
+ value4++;
+ texts[value6] = className;
+ }
+ }
+ int value7 = 0;
+ String[] texts2 = new String[value3];
+ int value8;
+ if (((Vector) this.entries5.get(this.getText(classGen))).size() > 0) {
+ for (int value9 = value8 = 0; value9 < value3; value9 = value8) {
+ String className2 =
+ ((ClassGen)
+ ((Vector) this.entries5.get(this.getText(classGen)))
+ .get(
+ RandomUtils.calculateCount(
+ ((Vector) this.entries5.get(this.getText(classGen))).size())))
+ .getClassName();
+ int value10 = value8;
+ value8++;
+ texts2[value10] = className2;
+ }
+ }
+ int value11 = 0;
+ Method[] methods = classGen.getMethods();
+ int value12;
+ for (value2 = value12 = 0; value2 < methods.length; value2 = ++value12) {
+ Method method;
+ if ((method = methods[value12]).getCode() != null) {
+ if (classGen.getConstantPool().getSize() > 20000) {
+ new ConstantPoolEditor(this.classStorage).processClassGen(classGen);
+ instructionFactory = new InstructionFactory(classGen);
+ method = (methods = classGen.getMethods())[value12];
+ }
+ InstructionHandle instructionHandle2;
+ InstructionList instructionList;
+ MethodGen methodGen;
+ InstructionHandle instructionHandle3 =
+ instructionHandle2 =
+ (instructionList =
+ (methodGen =
+ MethodFactory.createMethodGen(
+ method,
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool()))
+ .getInstructionList())
+ .getStart();
+ while (instructionHandle3 != null) {
+ label156:
+ {
+ if (!enabled2
+ && instructionHandle2.getInstruction()
+ instanceof NameSignatureInstructionSupport) {
+ NameSignatureInstructionSupport nameSignatureInstructionSupport =
+ (NameSignatureInstructionSupport) instructionHandle2.getInstruction();
+ if (text5.equals(
+ nameSignatureInstructionSupport.getText3(classGen.getConstantPool()))) {
+ Log.warn(
+ "javac Java compiler should be run with -XDstringConcat=inline flag to"
+ + " encrypt all strings.");
+ enabled2 = true;
+ }
+ } else if (instructionHandle2.getInstruction() instanceof LDC) {
+ LDC lDC = (LDC) instructionHandle2.getInstruction();
+ Constant constant;
+ if ((constant = classGen.getConstantPool().getConstant(lDC.getIndex()))
+ instanceof ConstantString) {
+ String bytes =
+ ((ConstantUtf8)
+ classGen
+ .getConstantPool()
+ .getConstant(((ConstantString) constant).getStringIndex()))
+ .getBytes();
+ if (this.classStorage.getClassGen(bytes) != null
+ || this.collection.contains(bytes)
+ || StringEncryptionUtils.matchesText(bytes)) {
+ instructionHandle3 =
+ instructionHandle2 = instructionHandle2.getInstructionHandle2();
+ continue;
+ }
+ int value13;
+ label107:
+ {
+ value13 =
+ Configuration.getObfuscationOptions()
+ .calculateCount(this.classStorage, classGen, methodGen);
+ String text3;
+ if ((text3 = classGen.getClassName()).startsWith((String) "com.allatori")) {
+ if (text3.startsWith("com.allatori.obfuscate.opt")) {
+ Configuration.getObfuscationOptions();
+ value13 = 0;
+ }
+ if (text3.startsWith("com.allatori.obfuscate.ren")) {
+ Configuration.getObfuscationOptions();
+ value13 = 0;
+ }
+ if (text3.startsWith("com.allatori.io.re")) {
+ Configuration.getObfuscationOptions();
+ value13 = 0;
+ value2 = value13;
+ break label107;
+ }
+ } else if (text3.startsWith((String) "org.apache.bcel")) {
+ Configuration.getObfuscationOptions();
+ value13 = 0;
+ }
+ value2 = value13;
+ }
+ Configuration.getObfuscationOptions();
+ if (value2 == 1) {
+ String text6 = texts2[value11];
+ lDC.setIndex(
+ classGen.getConstantPool().addString("" + text2 + text6 + text2 + bytes));
+ String text7 = text;
+ ObjectType objectType = Type.STRING;
+ Type[] types = new Type[] {type};
+ InstructionFactory instructionFactory2 = instructionFactory;
+ InstructionHandle instructionHandle4 = instructionHandle2;
+ InstructionList instructionList2 = instructionList;
+ value11++;
+ instructionList2.createInstructionHandle2(
+ instructionHandle4,
+ instructionFactory2.createInvoke(
+ text6, text7, objectType, types, (short) 184));
+ if (value11 >= value3) {
+ value11 = 0;
+ }
+ if (!values.contains(classGen)) {
+ values.add(classGen);
+ }
+ } else {
+ Configuration.getObfuscationOptions();
+ if (value13 >= 1000) {
+ String text8;
+ if ((text8 =
+ CustomStringEncryption.createText(
+ bytes, value13, this.classStorage.getClassLoader()))
+ .startsWith(CustomStringEncryption.text)
+ && !values.contains(classGen)) {
+ values.add(classGen);
+ }
+ lDC.setIndex(classGen.getConstantPool().addString(text8));
+ instructionHandle = instructionHandle2;
+ instructionList.createInstructionHandle2(
+ instructionHandle2,
+ CustomStringEncryption.getInvokeInstruction(instructionFactory, value13));
+ break label156;
+ }
+ String text9 = texts[value7];
+ lDC.setIndex(
+ classGen.getConstantPool().addString(this.createText(bytes, text9)));
+ String text10 = text4;
+ ObjectType objectType2 = Type.STRING;
+ Type[] types2 = new Type[] {type};
+ InstructionFactory instructionFactory3 = instructionFactory;
+ InstructionHandle instructionHandle5 = instructionHandle2;
+ InstructionList instructionList3 = instructionList;
+ value7++;
+ instructionList3.createInstructionHandle2(
+ instructionHandle5,
+ instructionFactory3.createInvoke(
+ text9, text10, objectType2, types2, (short) 184));
+ if (value7 >= value3) {
+ value7 = 0;
+ }
+ }
+ }
+ }
+ instructionHandle = instructionHandle2;
+ }
+ instructionHandle3 = instructionHandle2 = instructionHandle.getInstructionHandle2();
+ }
+ methodGen.update5();
+ try {
+ classGen.replaceMethod(method, methodGen.getMethod());
+ } catch (Exception exception) {
+ Log.error(
+ "Error processing "
+ + classGen.getClassName()
+ + "."
+ + methodGen.getName()
+ + " "
+ + exception.getMessage());
+ }
+ }
+ }
+ }
+ }
+
+ public void transform3(ClassGen classGen) {
+ InstructionFactory instructionFactory = new InstructionFactory(classGen);
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ InstructionList instructionList = new InstructionList();
+ MethodGen methodGen =
+ new MethodGen(
+ 9,
+ Type.STRING,
+ new Type[] {type},
+ new String[] {"arg0"},
+ text,
+ classGen.getClassName(),
+ instructionList,
+ constantPool);
+ instructionList.getInstructionHandle(instructionFactory.createNew("java.lang.StringBuffer"));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ String text2 = "java.lang.RuntimeException";
+ instructionList.getInstructionHandle(instructionFactory.createNew(text2));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(text2, "", Type.VOID, Type.NO_ARGS, (short) 183));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ text2,
+ "getStackTrace",
+ new ArrayType(new ObjectType("java.lang.StackTraceElement"), 1),
+ Type.NO_ARGS,
+ (short) 182));
+ instructionList.getInstructionHandle(new PUSH(constantPool, 1));
+ instructionList.getInstructionHandle(InstructionConstants.AALOAD);
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ int value = ((int[]) entries6.get(classGen.getClassName()))[2] == 0 ? 1 : 0;
+ int value2 = RandomUtils.calculateValue() > 0.5 ? 1 : 0;
+ InstructionList instructionList2;
+ if (value2 != 0) {
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StackTraceElement",
+ value != 0 ? "getClassName" : "getMethodName",
+ Type.STRING,
+ Type.NO_ARGS,
+ (short) 182));
+ instructionList2 = instructionList;
+ } else {
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StackTraceElement",
+ value != 0 ? "getMethodName" : "getClassName",
+ Type.STRING,
+ Type.NO_ARGS,
+ (short) 182));
+ instructionList2 = instructionList;
+ }
+ instructionList2.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StringBuffer", "", Type.VOID, new Type[] {Type.STRING}, (short) 183));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ if (value2 != 0) {
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StackTraceElement",
+ value != 0 ? "getMethodName" : "getClassName",
+ Type.STRING,
+ Type.NO_ARGS,
+ (short) 182));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StringBuffer",
+ "append",
+ Type.STRINGBUFFER,
+ new Type[] {Type.STRING},
+ (short) 182));
+ instructionList2 = instructionList;
+ } else {
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StackTraceElement",
+ value != 0 ? "getClassName" : "getMethodName",
+ Type.STRING,
+ Type.NO_ARGS,
+ (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.ICONST_0);
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StringBuffer",
+ "insert",
+ Type.STRINGBUFFER,
+ new Type[] {Type.INT, Type.STRING},
+ (short) 182));
+ instructionList2 = instructionList;
+ }
+ instructionList2.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StringBuffer", "toString", Type.STRING, Type.NO_ARGS, (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "length", Type.INT, Type.NO_ARGS, (short) 182));
+ instructionList.getInstructionHandle(new PUSH(constantPool, 1));
+ instructionList.getInstructionHandle(InstructionConstants.ISUB);
+ int value3 = RandomUtils.calculateValue() <= 0.5 ? 1 : 0;
+ Vector vector;
+ Vector vector2;
+ if (value3 != 0) {
+ vector2 =
+ vector =
+ StringEncryptionUtils.createValues(
+ ((int[]) entries6.get(classGen.getClassName()))[0]);
+ vector2.addAll(StringEncryptionUtils.createValues(RandomUtils.calculateCount(125) + 1));
+ } else {
+ (vector = StringEncryptionUtils.createValues(RandomUtils.calculateCount(125) + 1))
+ .addAll(
+ StringEncryptionUtils.createValues(
+ ((int[]) entries6.get(classGen.getClassName()))[0]));
+ vector2 = vector;
+ }
+ vector2.addAll(
+ StringEncryptionUtils.createValues(((int[]) entries6.get(classGen.getClassName()))[1]));
+ instructionList.getInstructionHandle(InstructionConstants.FCONST_2);
+ instructionList.getInstructionHandle(InstructionConstants.FCONST_1);
+ instructionList.getInstructionHandle(InstructionConstants.POP);
+ Iterator iterator2 = vector.iterator();
+ Iterator iterator3 = iterator2;
+ while (iterator3.hasNext()) {
+ Instruction instruction = (Instruction) iterator2.next();
+ iterator3 = iterator2;
+ instructionList.getInstructionHandle(instruction);
+ }
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(instructionFactory.createCheckCast(Type.STRING));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "length", Type.INT, Type.NO_ARGS, (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(instructionFactory.createNewArray(Type.CHAR, (short) 1));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(new PUSH(constantPool, 1));
+ instructionList.getInstructionHandle(InstructionConstants.ISUB);
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.OBJECT, 3));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 7));
+ if (value3 != 0) {
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ instructionList.getInstructionHandle(InstructionConstants.POP2);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 4));
+ instructionList2 = instructionList;
+ } else {
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ instructionList.getInstructionHandle(InstructionConstants.POP);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 4));
+ instructionList.getInstructionHandle(InstructionConstants.POP);
+ instructionList2 = instructionList;
+ }
+ instructionList2.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(InstructionConstants.POP);
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 2));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 5));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.OBJECT, 6));
+ BranchInstruction branchInstruction =
+ InstructionFactory.createBranchInstruction((short) 167, null);
+ instructionList.getBranchHandle(branchInstruction);
+ InstructionHandle instructionHandle =
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 3));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 4));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 1));
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "charAt", Type.CHAR, new Type[] {Type.INT}, (short) 182));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 6));
+ instructionList.getInstructionHandle(new IINC(1, -1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 2));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "charAt", Type.CHAR, new Type[] {Type.INT}, (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(InstructionConstants.CASTORE);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 1));
+ BranchInstruction branchInstruction2 =
+ InstructionFactory.createBranchInstruction((short) 156, null);
+ instructionList.getBranchHandle(branchInstruction2);
+ BranchInstruction branchInstruction3 =
+ InstructionFactory.createBranchInstruction((short) 167, null);
+ instructionList.getBranchHandle(branchInstruction3);
+ InstructionHandle instructionHandle2 =
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 3));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 7));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 1));
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "charAt", Type.CHAR, new Type[] {Type.INT}, (short) 182));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 6));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 2));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "charAt", Type.CHAR, new Type[] {Type.INT}, (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(new IINC(2, -1));
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(new IINC(1, -1));
+ instructionList.getInstructionHandle(InstructionConstants.CASTORE);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 2));
+ BranchInstruction branchInstruction4 =
+ InstructionFactory.createBranchInstruction((short) 156, null);
+ instructionList.getBranchHandle(branchInstruction4);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 5));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 2));
+ InstructionHandle instructionHandle3 =
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 1));
+ BranchHandle branchHandle =
+ instructionList.getBranchHandle(
+ InstructionFactory.createBranchInstruction((short) 156, instructionHandle));
+ InstructionHandle instructionHandle4 =
+ instructionList.getInstructionHandle(instructionFactory.createNew("java.lang.String"));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 3));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String",
+ "",
+ Type.VOID,
+ new Type[] {new ArrayType(Type.CHAR, 1)},
+ (short) 183));
+ instructionList.getInstructionHandle(InstructionFactory.createReturn(Type.OBJECT));
+ branchInstruction.setTarget(branchHandle);
+ branchInstruction2.setTarget(instructionHandle2);
+ branchInstruction3.setTarget(instructionHandle4);
+ branchInstruction4.setTarget(instructionHandle3);
+ methodGen.update5();
+ methodGen.update4();
+ classGen.processMethod2(methodGen.getMethod());
+ instructionList.update3();
+ }
+
+ public boolean matchesBoolean(Boolean matches) {
+ return matches == null ? false : matches;
+ }
+
+ public boolean matchesClassGen2(ClassGen classGen) {
+ int value = Configuration.getObfuscationOptions().calculateCount(this.classStorage, classGen);
+ Configuration.getObfuscationOptions();
+ if (value == 0) {
+ return false;
+ }
+ String text = this.getText(classGen);
+ byte value2 = 0;
+ Method[] methods;
+ int value3 = (methods = classGen.getMethods()).length;
+ int value4;
+ for (value = value4 = 0; value < value3; value = ++value4) {
+ Method method;
+ if ((method = methods[value4]).getCode() != null) {
+ InstructionHandle instructionHandle;
+ MethodGen methodGen;
+ InstructionHandle instructionHandle2 =
+ instructionHandle =
+ (methodGen =
+ MethodFactory.createMethodGen(
+ method,
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool()))
+ .getInstructionList()
+ .getStart();
+ while (instructionHandle2 != null) {
+ if (instructionHandle.getInstruction() instanceof LDC) {
+ LDC lDC = (LDC) instructionHandle.getInstruction();
+ Constant constant;
+ if ((constant = classGen.getConstantPool().getConstant(lDC.getIndex()))
+ instanceof ConstantString) {
+ String bytes =
+ ((ConstantUtf8)
+ classGen
+ .getConstantPool()
+ .getConstant(((ConstantString) constant).getStringIndex()))
+ .getBytes();
+ if (this.classStorage.getClassGen(bytes) != null
+ || this.collection.contains(bytes)
+ || StringEncryptionUtils.matchesText(bytes)) {
+ instructionHandle2 = instructionHandle = instructionHandle.getInstructionHandle2();
+ continue;
+ }
+ label56:
+ {
+ int value5 =
+ Configuration.getObfuscationOptions()
+ .calculateCount(this.classStorage, classGen, methodGen);
+ String text2;
+ if ((text2 = classGen.getClassName()).startsWith((String) "com.allatori")) {
+ if (text2.startsWith("com.allatori.obfuscate.opt")) {
+ Configuration.getObfuscationOptions();
+ value5 = 0;
+ }
+ if (text2.startsWith("com.allatori.obfuscate.ren")) {
+ Configuration.getObfuscationOptions();
+ value5 = 0;
+ }
+ if (text2.startsWith("com.allatori.io.re")) {
+ Configuration.getObfuscationOptions();
+ byte value6 = 0;
+ value = value6;
+ break label56;
+ }
+ } else if (text2.startsWith((String) "org.apache.bcel")) {
+ Configuration.getObfuscationOptions();
+ value5 = 0;
+ }
+ value = value5;
+ }
+ Configuration.getObfuscationOptions();
+ if (value == 1) {
+ value2 = 1;
+ this.entries2.put(text, true);
+ if (this.matchesBoolean((Boolean) this.entries8.get(text))) {
+ return true;
+ }
+ } else {
+ value2 = 1;
+ this.entries8.put(text, true);
+ if (this.matchesBoolean((Boolean) this.entries2.get(text))) {
+ return true;
+ }
+ }
+ }
+ }
+ instructionHandle2 = instructionHandle = instructionHandle.getInstructionHandle2();
+ }
+ }
+ }
+ return value2 != 0;
+ }
+
+ public void processValues2(Vector vector) {
+ if (vector.size() != 0) {
+ String text = this.getText((ClassGen) vector.get(0));
+ int value =
+ this.entries7.get(text) == null ? 0 : ((Vector) this.entries7.get(text)).size() / 8;
+ if (value == 0) {
+ value = 1;
+ }
+ int value2;
+ if ((value2 = vector.size() / value) == 0) {
+ value2 = 1;
+ }
+ Vector vector2;
+ Vector vector3;
+ DistributedStringEncryptionTransformer distributedStringEncryptionTransformer;
+ label108:
+ {
+ vector3 = new Vector();
+ vector2 = new Vector();
+ if (vector.size() < value2 + 1) {
+ if (vector.size() == 1) {
+ if (this.matchesBoolean((Boolean) this.entries8.get(text))) {
+ vector3.add(vector.get(0));
+ }
+ if (this.matchesBoolean((Boolean) this.entries2.get(text))) {
+ distributedStringEncryptionTransformer = this;
+ vector2.add(vector.get(0));
+ break label108;
+ }
+ } else if (vector.size() == 2) {
+ if (this.matchesBoolean((Boolean) this.entries8.get(text))) {
+ vector3.add(vector.get(0));
+ }
+ if (this.matchesBoolean((Boolean) this.entries2.get(text))) {
+ vector2.add(vector.get(0));
+ }
+ if (this.matchesBoolean((Boolean) this.entries8.get(text))) {
+ vector3.add(vector.get(1));
+ }
+ if (this.matchesBoolean((Boolean) this.entries2.get(text))) {
+ distributedStringEncryptionTransformer = this;
+ vector2.add(vector.get(1));
+ break label108;
+ }
+ } else if (vector.size() == 3) {
+ if (this.matchesBoolean((Boolean) this.entries8.get(text))) {
+ vector3.add(vector.get(0));
+ }
+ if (this.matchesBoolean((Boolean) this.entries2.get(text))) {
+ vector2.add(vector.get(0));
+ }
+ if (this.matchesBoolean((Boolean) this.entries8.get(text))) {
+ vector3.add(vector.get(1));
+ }
+ if (this.matchesBoolean((Boolean) this.entries2.get(text))) {
+ distributedStringEncryptionTransformer = this;
+ vector2.add(vector.get(2));
+ break label108;
+ }
+ } else {
+ if (this.matchesBoolean((Boolean) this.entries8.get(text))) {
+ vector3.add(vector.get(0));
+ }
+ if (this.matchesBoolean((Boolean) this.entries2.get(text))) {
+ vector2.add(vector.get(1));
+ }
+ if (this.matchesBoolean((Boolean) this.entries8.get(text))) {
+ vector3.add(vector.get(2));
+ }
+ if (this.matchesBoolean((Boolean) this.entries2.get(text))) {
+ distributedStringEncryptionTransformer = this;
+ vector2.add(vector.get(3));
+ break label108;
+ }
+ }
+ } else {
+ int value3;
+ int value4 = value3 = 0;
+ while (value4 < vector.size()) {
+ int value5;
+ if (this.matchesBoolean((Boolean) this.entries8.get(text))) {
+ value5 = value3;
+ vector3.add(vector.get(value3));
+ } else {
+ if (this.matchesBoolean((Boolean) this.entries2.get(text))) {
+ vector2.add(vector.get(value3));
+ }
+ value5 = value3;
+ }
+ int value6;
+ if ((value6 = value5 + value2) >= vector.size()) {
+ distributedStringEncryptionTransformer = this;
+ break label108;
+ }
+ int value7;
+ if (this.matchesBoolean((Boolean) this.entries2.get(text))) {
+ value7 = value6;
+ vector2.add(vector.get(value6));
+ } else {
+ if (this.matchesBoolean((Boolean) this.entries8.get(text))) {
+ vector3.add(vector.get(value6));
+ }
+ value7 = value6;
+ }
+ value4 = value3 = value7 + value2;
+ }
+ }
+ distributedStringEncryptionTransformer = this;
+ }
+ distributedStringEncryptionTransformer.entries3.put(text, vector3);
+ this.entries5.put(text, vector2);
+ }
+ }
+
+ public void finish2() {
+ Iterator classesByName2 = this.classStorage.getClassesByName2();
+ label133:
+ while (true) {
+ for (Iterator iterator2 = classesByName2; iterator2.hasNext(); iterator2 = classesByName2) {
+ ClassGen classGen = (ClassGen) classesByName2.next();
+ if (!Configuration.getIgnoreClassesOptions().matchesClassGen(this.classStorage, classGen)) {
+ int value;
+ int value2 =
+ value =
+ Configuration.getObfuscationOptions().calculateCount(this.classStorage, classGen);
+ Configuration.getObfuscationOptions();
+ if (value2 == 1) {
+ StringEncryptionUtils.processCollection(classGen, this.collection);
+ } else {
+ Configuration.getObfuscationOptions();
+ if (value == 2) {
+ StringEncryptionUtils.processClassGen2(classGen);
+ } else {
+ Configuration.getObfuscationOptions();
+ if (value == 3) {
+ StringEncryptionUtils.processClassGen2(classGen);
+ StringEncryptionUtils.processClassGen(classGen);
+ }
+ }
+ }
+ byte value3 = 0;
+ if (this.matchesClassGen2(classGen)) {
+ Vector vector;
+ if ((vector = (Vector) this.entries7.get(this.getText(classGen))) == null) {
+ vector = new Vector();
+ this.entries7.put(this.getText(classGen), vector);
+ if (this.entries4.get(this.getText(classGen)) == null) {
+ Vector vector2 = new Vector();
+ if (this.classStorage.matchesClassGen(classGen)
+ && !classGen.isEnabled2()
+ && !classGen.isEnabled5()) {
+ vector2.add(classGen);
+ value3 = 1;
+ }
+ this.entries4.put(this.getText(classGen), vector2);
+ }
+ }
+ if (!this.classStorage.matchesClassGen(classGen)
+ || !classGen.isEnabled2() && !classGen.isEnabled5()) {
+ vector.add(classGen);
+ }
+ }
+ if (value3 == 0 && this.matchesClassGen(classGen)) {
+ Vector vector3;
+ if ((vector3 = (Vector) this.entries4.get(this.getText(classGen))) == null) {
+ vector3 = new Vector();
+ this.entries4.put(this.getText(classGen), vector3);
+ }
+ vector3.add(classGen);
+ }
+ continue label133;
+ }
+ }
+ Iterator iterator3;
+ Iterator iterator4 = iterator3 = this.entries4.values().iterator();
+ while (iterator4.hasNext()) {
+ Vector vector4 = (Vector) iterator3.next();
+ iterator4 = iterator3;
+ this.processValues(vector4);
+ }
+ Vector vector5 = new Vector();
+ Iterator iterator5 = this.entries4.values().iterator();
+ while (iterator5.hasNext()) {
+ Vector vector6;
+ if ((vector6 = (Vector) iterator5.next()).size() > vector5.size()) {
+ vector5 = vector6;
+ }
+ }
+ if (vector5.size() == 0) {
+ this.enabled = false;
+ return;
+ }
+ String text = this.getText((ClassGen) vector5.get(0));
+ HashSet values2;
+ (values2 = new HashSet()).addAll(this.entries4.keySet());
+ for (String text2 : ((Iterable) ((Iterable>) values2))) {
+ if (((Vector) this.entries4.get(text2)).size() == 0) {
+ if (this.matchesBoolean((Boolean) this.entries8.get(text2))) {
+ this.entries8.put(text, true);
+ }
+ if (this.matchesBoolean((Boolean) this.entries2.get(text2))) {
+ this.entries2.put(text, true);
+ }
+ }
+ }
+ Iterator iterator6;
+ iterator4 = iterator6 = this.entries4.values().iterator();
+ while (iterator4.hasNext()) {
+ Vector vector7 = (Vector) iterator6.next();
+ iterator4 = iterator6;
+ this.processValues2(vector7);
+ }
+ values2.clear();
+ values2.addAll(this.entries3.keySet());
+ values2.addAll(this.entries5.keySet());
+ Iterator iterator7 = values2.iterator();
+ for (Iterator iterator8 = iterator7; iterator8.hasNext(); iterator8 = iterator7) {
+ String text3 = (String) iterator7.next();
+ this.processValues((Vector) this.entries3.get(text3), (Vector) this.entries5.get(text3));
+ }
+ values2.clear();
+ values2.addAll(this.entries4.keySet());
+ for (String text4 : ((Iterable) ((Iterable>) values2))) {
+ if (((Vector) this.entries4.get(text4)).size() == 0) {
+ this.entries4.put(text4, vector5);
+ this.entries3.put(text4, this.entries3.get(text));
+ this.entries5.put(text4, this.entries5.get(text));
+ }
+ }
+ return;
+ }
+ }
+
+ public String getText(ClassGen classGen) {
+ if (Configuration.getObfuscationOptions().isPackageStringEncryptionEnabled()) {
+ String text;
+ return (text = classGen.getClassName()).indexOf(46) > 0
+ ? text.substring(0, text.lastIndexOf(46))
+ : "";
+ }
+ if (classGen.getClassName().startsWith(this.text6)) {
+ return "SPRINGBOOT";
+ }
+ if (Configuration.getObfuscationOptions().isGlobalStringEncryptionEnabled()) {
+ return "GLOBAL";
+ }
+ if (!this.classStorage.matchesClassGen(classGen)) {
+ return this.classStorage.getText(classGen);
+ }
+ String text2;
+ if ((text2 = classGen.getClassName()).indexOf(36) > 0) {
+ text2 = text2.substring(0, text2.indexOf(36));
+ }
+ return text2;
+ }
+
+ public String createText(String text, String text2) {
+ char[] values = new char[text.length()];
+ char value = (char) ((int[]) this.entries.get(text2))[0];
+ char value2 = (char) ((int[]) this.entries.get(text2))[1];
+ int value3;
+ for (int value4 = value3 = values.length - 1; value4 >= 0; value4 = value3) {
+ char value5 = (char) (text.charAt(value3) ^ value);
+ int value6 = value3;
+ value3--;
+ values[value6] = value5;
+ if (value3 < 0) {
+ break;
+ }
+ char value7 = (char) (text.charAt(value3) ^ value2);
+ int value8 = value3;
+ value3--;
+ values[value8] = value7;
+ }
+ return new String(values);
+ }
+}
diff --git a/src/main/java/com/allatori/transform/FieldAccessTransformer.java b/src/main/java/com/allatori/transform/FieldAccessTransformer.java
new file mode 100644
index 0000000..59cfc08
--- /dev/null
+++ b/src/main/java/com/allatori/transform/FieldAccessTransformer.java
@@ -0,0 +1,91 @@
+package com.allatori.transform;
+
+import com.allatori.bytecode.MethodFactory;
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.InstructionFactory;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.InstructionList;
+import com.allatori.lib.bcel.generic.InstructionTargeter;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.model.ClassStorage;
+
+public class FieldAccessTransformer implements ClassTransformer {
+
+ public ClassStorage classStorage;
+
+ @Override
+ public void finish() {}
+
+ @Override
+ public void transform(ClassGen classGen) {
+ String text2 = Configuration.getDebugInfoOptions().getText2();
+ String text = Configuration.getDebugInfoOptions().getText();
+ if (text2 != null && text != null) {
+ if (Configuration.getDebugInfoOptions().matchesClassGen(this.classStorage, classGen)) {
+ try {
+ Method[] methods = classGen.getMethods();
+ for (int index = 0; index < methods.length; index++) {
+ Method method;
+ if ((method = methods[index]).getCode() != null) {
+ MethodGen methodGen =
+ MethodFactory.createMethodGen(
+ method,
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool());
+ if (Configuration.getDebugInfoOptions()
+ .matchesMethodGen(this.classStorage, classGen, methodGen)) {
+ InstructionFactory instructionFactory = new InstructionFactory(classGen);
+ InstructionList instructionList;
+ InstructionHandle end = (instructionList = methodGen.getInstructionList()).getEnd();
+ InstructionHandle instructionHandle;
+ InstructionHandle instructionHandle2;
+ if (Configuration.getDebugInfoOptions().isEnabled()) {
+ InstructionHandle instructionHandle3 =
+ instructionList.createInstructionHandle(
+ end,
+ instructionFactory.createInvoke(
+ text2, text, Type.VOID, new Type[] {Type.OBJECT}, (short) 184));
+ instructionHandle =
+ instructionList.createInstructionHandle(
+ instructionHandle3, InstructionFactory.createThis());
+ instructionHandle2 = end;
+ } else {
+ instructionHandle =
+ instructionList.createInstructionHandle(
+ end,
+ instructionFactory.createInvoke(
+ text2, text, Type.VOID, Type.NO_ARGS, (short) 184));
+ instructionHandle2 = end;
+ }
+ InstructionTargeter[] instructionTargeters;
+ int value;
+ for (int value2 =
+ value =
+ (instructionTargeters = instructionHandle2.getTargeters()).length - 1;
+ value2 >= 0;
+ value2 = value) {
+ InstructionTargeter instructionTargeter = instructionTargeters[value];
+ value--;
+ instructionTargeter.updateTarget(end, instructionHandle);
+ }
+ methodGen.update5();
+ classGen.replaceMethod(method, methodGen.getMethod());
+ }
+ }
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+ }
+ }
+
+ public FieldAccessTransformer(ClassStorage classStorage2) {
+ super();
+ this.classStorage = classStorage2;
+ }
+}
diff --git a/src/main/java/com/allatori/transform/FieldOrderComparator.java b/src/main/java/com/allatori/transform/FieldOrderComparator.java
new file mode 100644
index 0000000..2ab14e6
--- /dev/null
+++ b/src/main/java/com/allatori/transform/FieldOrderComparator.java
@@ -0,0 +1,31 @@
+package com.allatori.transform;
+
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.Field;
+import java.util.Comparator;
+
+public class FieldOrderComparator implements Comparator {
+
+ public final int count;
+
+ public final MemberReorderTransformer memberReorderTransformer;
+
+ @Override
+ public int compare(Object result, Object result2) {
+ return this.calculateCount((Field) result, (Field) result2);
+ }
+
+ public int calculateCount(Field field, Field field2) {
+ int value = this.count;
+ Configuration.getObfuscationOptions();
+ return value == 100
+ ? field2.getText().compareTo(field.getText())
+ : field.getText().compareTo(field2.getText());
+ }
+
+ public FieldOrderComparator(MemberReorderTransformer memberReorderTransformer2, int count) {
+ super();
+ this.memberReorderTransformer = memberReorderTransformer2;
+ this.count = count;
+ }
+}
diff --git a/src/main/java/com/allatori/transform/GlobalStringEncryptionTransformer.java b/src/main/java/com/allatori/transform/GlobalStringEncryptionTransformer.java
new file mode 100644
index 0000000..7190c91
--- /dev/null
+++ b/src/main/java/com/allatori/transform/GlobalStringEncryptionTransformer.java
@@ -0,0 +1,611 @@
+package com.allatori.transform;
+
+import com.allatori.bytecode.ConstantPoolEditor;
+import com.allatori.bytecode.MethodFactory;
+import com.allatori.config.Configuration;
+import com.allatori.crypto.CustomStringEncryption;
+import com.allatori.crypto.StringEncryptionUtils;
+import com.allatori.internal.NameSignatureInstructionSupport;
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.classfile.ConstantString;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ArrayType;
+import com.allatori.lib.bcel.generic.BranchHandle;
+import com.allatori.lib.bcel.generic.BranchInstruction;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.ConstantPoolGen;
+import com.allatori.lib.bcel.generic.IINC;
+import com.allatori.lib.bcel.generic.Instruction;
+import com.allatori.lib.bcel.generic.InstructionConstants;
+import com.allatori.lib.bcel.generic.InstructionFactory;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.InstructionList;
+import com.allatori.lib.bcel.generic.LDC;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.lib.bcel.generic.ObjectType;
+import com.allatori.lib.bcel.generic.PUSH;
+import com.allatori.lib.bcel.generic.Type;
+import com.allatori.model.ClassStorage;
+import com.allatori.util.Log;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.TreeSet;
+import java.util.Vector;
+
+public class GlobalStringEncryptionTransformer implements ClassTransformer {
+
+ public static String text2 = "com_allatori_string_decryptor";
+
+ public static String text5 = "DecryptString";
+
+ public static String text = "DecryptString2";
+
+ public static String text4 = "allatori-12321-32123:";
+
+ public static char character = 'U';
+
+ public static boolean enabled = false;
+
+ public static String text3 = "makeConcatWithConstants";
+
+ public Collection collection;
+
+ public ClassStorage classStorage;
+
+ public static Vector values;
+
+ public boolean enabled2 = false;
+
+ @Override
+ public void finish() {
+ if (this.enabled2) {
+ this.classStorage.processClassGen(this.createClassGen());
+ }
+ }
+
+ public void transform2(ClassGen classGen) {
+ InstructionFactory instructionFactory = new InstructionFactory(classGen);
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ InstructionList instructionList = new InstructionList();
+ MethodGen methodGen =
+ new MethodGen(
+ 9,
+ Type.STRING,
+ new Type[] {Type.STRING},
+ new String[] {"s"},
+ text5,
+ classGen.getClassName(),
+ instructionList,
+ constantPool);
+ instructionList.getInstructionHandle(instructionFactory.createNew("java.lang.String"));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "length", Type.INT, Type.NO_ARGS, (short) 182));
+ instructionList.getInstructionHandle(instructionFactory.createNewArray(Type.CHAR, (short) 1));
+ instructionList.getInstructionHandle(new PUSH(constantPool, 1));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(InstructionConstants.POP2);
+ Iterator iterator2 = StringEncryptionUtils.createValues(character).iterator();
+ Iterator iterator3 = iterator2;
+ while (iterator3.hasNext()) {
+ Instruction instruction = (Instruction) iterator2.next();
+ iterator3 = iterator2;
+ instructionList.getInstructionHandle(instruction);
+ }
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(InstructionConstants.ARRAYLENGTH);
+ instructionList.getInstructionHandle(new PUSH(constantPool, 1));
+ instructionList.getInstructionHandle(InstructionConstants.ISUB);
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 3));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.OBJECT, 1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 2));
+ BranchInstruction branchInstruction =
+ InstructionFactory.createBranchInstruction((short) 155, null);
+ BranchHandle branchHandle = instructionList.getBranchHandle(branchInstruction);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 3));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 3));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "charAt", Type.CHAR, new Type[] {Type.INT}, (short) 182));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 2));
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X1);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 2));
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(new PUSH(constantPool, 63));
+ instructionList.getInstructionHandle(InstructionConstants.IAND);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 2));
+ instructionList.getInstructionHandle(InstructionConstants.CASTORE);
+ instructionList.getInstructionHandle(new IINC(3, -1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 3));
+ BranchInstruction branchInstruction2 =
+ InstructionFactory.createBranchInstruction((short) 155, null);
+ instructionList.getBranchHandle(branchInstruction2);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 3));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 3));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "charAt", Type.CHAR, new Type[] {Type.INT}, (short) 182));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 2));
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X1);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 2));
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(new PUSH(constantPool, 63));
+ instructionList.getInstructionHandle(InstructionConstants.IAND);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 2));
+ instructionList.getInstructionHandle(InstructionConstants.CASTORE);
+ instructionList.getInstructionHandle(new IINC(3, -1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 3));
+ instructionList.getBranchHandle(
+ InstructionFactory.createBranchInstruction((short) 167, branchHandle));
+ InstructionHandle instructionHandle =
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 1));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String",
+ "",
+ Type.VOID,
+ new Type[] {new ArrayType(Type.CHAR, 1)},
+ (short) 183));
+ instructionList.getInstructionHandle(InstructionFactory.createReturn(Type.OBJECT));
+ branchInstruction.setTarget(instructionHandle);
+ branchInstruction2.setTarget(instructionHandle);
+ methodGen.update5();
+ methodGen.update4();
+ classGen.processMethod2(methodGen.getMethod());
+ instructionList.update3();
+ }
+
+ @Override
+ public void transform(ClassGen classGen) {
+ InstructionHandle instructionHandle;
+ int value = Configuration.getObfuscationOptions().calculateCount(this.classStorage, classGen);
+ Configuration.getObfuscationOptions();
+ if (value != 0) {
+ InstructionFactory instructionFactory = new InstructionFactory(classGen);
+ Method[] methods = classGen.getMethods();
+ int value2;
+ for (value = value2 = 0; value < methods.length; value = ++value2) {
+ Method method;
+ if ((method = methods[value2]).getCode() != null) {
+ if (classGen.getConstantPool().getSize() > 20000) {
+ new ConstantPoolEditor(this.classStorage).processClassGen(classGen);
+ instructionFactory = new InstructionFactory(classGen);
+ method = (methods = classGen.getMethods())[value2];
+ }
+ InstructionHandle instructionHandle2;
+ InstructionList instructionList;
+ MethodGen methodGen;
+ InstructionHandle instructionHandle3 =
+ instructionHandle2 =
+ (instructionList =
+ (methodGen =
+ MethodFactory.createMethodGen(
+ method,
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool()))
+ .getInstructionList())
+ .getStart();
+ while (instructionHandle3 != null) {
+ label111:
+ {
+ if (!enabled
+ && instructionHandle2.getInstruction()
+ instanceof NameSignatureInstructionSupport) {
+ NameSignatureInstructionSupport nameSignatureInstructionSupport =
+ (NameSignatureInstructionSupport) instructionHandle2.getInstruction();
+ if (text3.equals(
+ nameSignatureInstructionSupport.getText3(classGen.getConstantPool()))) {
+ Log.warn(
+ "javac Java compiler should be run with -XDstringConcat=inline flag to"
+ + " encrypt all strings.");
+ enabled = true;
+ }
+ } else if (instructionHandle2.getInstruction() instanceof LDC) {
+ LDC lDC = (LDC) instructionHandle2.getInstruction();
+ Constant constant;
+ if ((constant = classGen.getConstantPool().getConstant(lDC.getIndex()))
+ instanceof ConstantString) {
+ String bytes =
+ ((ConstantUtf8)
+ classGen
+ .getConstantPool()
+ .getConstant(((ConstantString) constant).getStringIndex()))
+ .getBytes();
+ if (this.classStorage.getClassGen(bytes) != null
+ || this.collection.contains(bytes)
+ || StringEncryptionUtils.matchesText(bytes)) {
+ instructionHandle3 =
+ instructionHandle2 = instructionHandle2.getInstructionHandle2();
+ continue;
+ }
+ int value3;
+ label85:
+ {
+ value3 =
+ Configuration.getObfuscationOptions()
+ .calculateCount(this.classStorage, classGen, methodGen);
+ String text6;
+ if ((text6 = classGen.getClassName()).startsWith((String) "com.allatori")) {
+ if (text6.startsWith("com.allatori.obfuscate.opt")) {
+ Configuration.getObfuscationOptions();
+ value3 = 0;
+ }
+ if (text6.startsWith("com.allatori.obfuscate.ren")) {
+ Configuration.getObfuscationOptions();
+ value3 = 0;
+ }
+ if (text6.startsWith("com.allatori.io.re")) {
+ Configuration.getObfuscationOptions();
+ value3 = 0;
+ value = value3;
+ break label85;
+ }
+ } else if (text6.startsWith((String) "org.apache.bcel")) {
+ Configuration.getObfuscationOptions();
+ value3 = 0;
+ }
+ value = value3;
+ }
+ Configuration.getObfuscationOptions();
+ if (value == 1) {
+ lDC.setIndex(classGen.getConstantPool().addString("" + text4 + bytes));
+ instructionList.createInstructionHandle2(
+ instructionHandle2,
+ instructionFactory.createInvoke(
+ text2, text, Type.STRING, new Type[] {Type.STRING}, (short) 184));
+ if (!values.contains(classGen)) {
+ values.add(classGen);
+ }
+ this.enabled2 = true;
+ instructionHandle = instructionHandle2;
+ break label111;
+ }
+ Configuration.getObfuscationOptions();
+ if (value3 >= 1000) {
+ String text7;
+ if ((text7 =
+ CustomStringEncryption.createText(
+ bytes, value3, this.classStorage.getClassLoader()))
+ .startsWith(CustomStringEncryption.text)
+ && !values.contains(classGen)) {
+ values.add(classGen);
+ }
+ lDC.setIndex(classGen.getConstantPool().addString(text7));
+ instructionHandle = instructionHandle2;
+ instructionList.createInstructionHandle2(
+ instructionHandle2,
+ CustomStringEncryption.getInvokeInstruction(instructionFactory, value3));
+ break label111;
+ }
+ lDC.setIndex(classGen.getConstantPool().addString(this.createText(bytes)));
+ instructionList.createInstructionHandle2(
+ instructionHandle2,
+ instructionFactory.createInvoke(
+ text2, text5, Type.STRING, new Type[] {Type.STRING}, (short) 184));
+ this.enabled2 = true;
+ }
+ }
+ instructionHandle = instructionHandle2;
+ }
+ instructionHandle3 = instructionHandle2 = instructionHandle.getInstructionHandle2();
+ }
+ methodGen.update5();
+ classGen.replaceMethod(method, methodGen.getMethod());
+ }
+ }
+ }
+ }
+
+ public GlobalStringEncryptionTransformer(ClassStorage classStorage2) {
+ this.collection = new TreeSet();
+ this.classStorage = classStorage2;
+ character = Configuration.getObfuscationOptions().getCharacter();
+ values = new Vector();
+ StringEncryptionUtils.update();
+ this.collection.add("");
+ Iterator classesByName2 = classStorage2.getClassesByName2();
+ label27:
+ while (true) {
+ for (Iterator iterator = classesByName2; iterator.hasNext(); iterator = classesByName2) {
+ ClassGen classGen = (ClassGen) classesByName2.next();
+ if (!Configuration.getIgnoreClassesOptions().matchesClassGen(classStorage2, classGen)) {
+ int value;
+ int value2 =
+ value = Configuration.getObfuscationOptions().calculateCount(classStorage2, classGen);
+ Configuration.getObfuscationOptions();
+ if (value2 == 1) {
+ StringEncryptionUtils.processCollection(classGen, this.collection);
+ } else {
+ Configuration.getObfuscationOptions();
+ if (value == 2) {
+ StringEncryptionUtils.processClassGen2(classGen);
+ } else {
+ Configuration.getObfuscationOptions();
+ if (value == 3) {
+ StringEncryptionUtils.processClassGen2(classGen);
+ StringEncryptionUtils.processClassGen(classGen);
+ }
+ }
+ }
+ continue label27;
+ }
+ }
+ return;
+ }
+ }
+
+ public String createText(String text) {
+ char[] values = new char[text.length()];
+ char value = character;
+ int value2;
+ for (int value3 = value2 = values.length - 1; value3 >= 0; value3 = value2) {
+ values[value2] = (char) (text.charAt(value2) ^ value);
+ char value4 = (char) (value ^ value2);
+ value2--;
+ value = (char) (value4 & (byte) 63);
+ }
+ return new String(values);
+ }
+
+ public void transform3(ClassGen classGen) {
+ InstructionFactory instructionFactory = new InstructionFactory(classGen);
+ ConstantPoolGen constantPool = classGen.getConstantPool();
+ InstructionList instructionList = new InstructionList();
+ MethodGen methodGen =
+ new MethodGen(
+ 9,
+ Type.STRING,
+ new Type[] {Type.STRING},
+ new String[] {"arg0"},
+ text,
+ classGen.getClassName(),
+ instructionList,
+ constantPool);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(new PUSH(constantPool, 1));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ String text2 = "java.lang.RuntimeException";
+ instructionList.getInstructionHandle(instructionFactory.createNew(text2));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(text2, "", Type.VOID, Type.NO_ARGS, (short) 183));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ text2,
+ "getStackTrace",
+ new ArrayType(new ObjectType("java.lang.StackTraceElement"), 1),
+ Type.NO_ARGS,
+ (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(InstructionConstants.AALOAD);
+ instructionList.getInstructionHandle(instructionFactory.createNew("java.lang.StringBuffer"));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StringBuffer", "", Type.VOID, Type.NO_ARGS, (short) 183));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StackTraceElement", "getClassName", Type.STRING, Type.NO_ARGS, (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StackTraceElement",
+ "getMethodName",
+ Type.STRING,
+ Type.NO_ARGS,
+ (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ instructionList.getInstructionHandle(InstructionConstants.POP);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StringBuffer",
+ "append",
+ Type.STRINGBUFFER,
+ new Type[] {Type.STRING},
+ (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StringBuffer",
+ "append",
+ Type.STRINGBUFFER,
+ new Type[] {Type.STRING},
+ (short) 182));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.StringBuffer", "toString", Type.STRING, Type.NO_ARGS, (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X1);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "length", Type.INT, Type.NO_ARGS, (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(InstructionConstants.ISUB);
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X1);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 3));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.OBJECT, 2));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 4));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "length", Type.INT, Type.NO_ARGS, (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ instructionList.getInstructionHandle(instructionFactory.createNewArray(Type.CHAR, (short) 1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.OBJECT, 5));
+ Iterator iterator2 = StringEncryptionUtils.createValues(character).iterator();
+ Iterator iterator3 = iterator2;
+ while (iterator3.hasNext()) {
+ Instruction instruction = (Instruction) iterator2.next();
+ iterator3 = iterator2;
+ instructionList.getInstructionHandle(instruction);
+ }
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 6));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(InstructionConstants.ISUB);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 7));
+ BranchInstruction branchInstruction =
+ InstructionFactory.createBranchInstruction((short) 167, null);
+ instructionList.getBranchHandle(branchInstruction);
+ InstructionHandle instructionHandle =
+ instructionList.getInstructionHandle(new PUSH(constantPool, 63));
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ instructionList.getInstructionHandle(InstructionConstants.POP);
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X1);
+ instructionList.getInstructionHandle(InstructionConstants.POP);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 6));
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X2);
+ instructionList.getInstructionHandle(InstructionConstants.POP);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 2));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 4));
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "charAt", Type.CHAR, new Type[] {Type.INT}, (short) 182));
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X1);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 7));
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X1);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 0));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String", "charAt", Type.CHAR, new Type[] {Type.INT}, (short) 182));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 6));
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(InstructionConstants.CASTORE);
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.IXOR);
+ instructionList.getInstructionHandle(InstructionConstants.IAND);
+ instructionList.getInstructionHandle(InstructionConstants.I2C);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 6));
+ instructionList.getInstructionHandle(new IINC(4, -1));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 4));
+ BranchInstruction branchInstruction2 =
+ InstructionFactory.createBranchInstruction((short) 156, null);
+ instructionList.getBranchHandle(branchInstruction2);
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 3));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction(Type.INT, 4));
+ InstructionHandle instructionHandle2 = instructionList.getInstructionHandle(new IINC(7, -1));
+ InstructionHandle instructionHandle3 =
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 5));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.INT, 7));
+ instructionList.getInstructionHandle(InstructionConstants.DUP);
+ BranchInstruction branchInstruction3 =
+ InstructionFactory.createBranchInstruction((short) 156, instructionHandle);
+ instructionList.getBranchHandle(branchInstruction3);
+ instructionList.getInstructionHandle(InstructionConstants.POP2);
+ instructionList.getInstructionHandle(instructionFactory.createNew("java.lang.String"));
+ instructionList.getInstructionHandle(
+ InstructionFactory.createLocalVariableInstruction2(Type.OBJECT, 5));
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(InstructionConstants.DUP_X1);
+ instructionList.getInstructionHandle(InstructionConstants.SWAP);
+ instructionList.getInstructionHandle(
+ instructionFactory.createInvoke(
+ "java.lang.String",
+ "",
+ Type.VOID,
+ new Type[] {new ArrayType(Type.CHAR, 1)},
+ (short) 183));
+ instructionList.getInstructionHandle(InstructionFactory.createReturn(Type.OBJECT));
+ branchInstruction.setTarget(instructionHandle3);
+ branchInstruction2.setTarget(instructionHandle2);
+ methodGen.update5();
+ methodGen.update4();
+ classGen.processMethod2(methodGen.getMethod());
+ instructionList.update3();
+ }
+
+ public void finish2() {}
+
+ public static String createText(String text, String text2) {
+ int value = text2.length() - 1;
+ int value2 = text2.length() - 1;
+ char[] values = new char[text.length()];
+ char value3 = character;
+ int value4;
+ for (int value5 = value4 = values.length - 1; value5 >= 0; value5 = --value4) {
+ values[value4] = (char) (text.charAt(value4) ^ value3 ^ text2.charAt(value2));
+ char value6 = (char) (value3 ^ value4 ^ text2.charAt(value2));
+ value2--;
+ value3 = (char) (value6 & (byte) 63);
+ if (value2 < 0) {
+ value2 = value;
+ }
+ }
+ return new String(values);
+ }
+
+ public ClassGen createClassGen() {
+ ClassGen classGen = new ClassGen(text2, "java.lang.Object", "", 33, new String[0]);
+ if (Configuration.getObfuscationOptions().isEnabled()) {
+ StringEncryptionUtils.processCharacter(classGen, text5, character);
+ return classGen;
+ } else {
+ this.transform2(classGen);
+ this.transform3(classGen);
+ return classGen;
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/transform/HardwareIdTransformer.java b/src/main/java/com/allatori/transform/HardwareIdTransformer.java
new file mode 100644
index 0000000..6b12421
--- /dev/null
+++ b/src/main/java/com/allatori/transform/HardwareIdTransformer.java
@@ -0,0 +1,35 @@
+package com.allatori.transform;
+
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.model.ClassStorage;
+
+public class HardwareIdTransformer implements ClassTransformer {
+
+ public ClassStorage classStorage;
+
+ @Override
+ public void transform(ClassGen classGen) {
+ try {
+ int value;
+ ClassGen classGen2;
+ if ((classGen2 = this.classStorage.getClassGen("com.license4j.HardwareID")) != null
+ && (value = classGen2.getConstantPool().lookupUtf8("resources/d.bfi")) != -1) {
+ ((ConstantUtf8) classGen2.getConstantPool().getConstant(value))
+ .setBytes(Configuration.getLogOptions().getComLicense4jSupport());
+ return;
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ public HardwareIdTransformer(ClassStorage classStorage2) {
+ super();
+ this.classStorage = classStorage2;
+ }
+
+ @Override
+ public void finish() {}
+}
diff --git a/src/main/java/com/allatori/transform/MemberConstantPoolTransformer.java b/src/main/java/com/allatori/transform/MemberConstantPoolTransformer.java
new file mode 100644
index 0000000..878e602
--- /dev/null
+++ b/src/main/java/com/allatori/transform/MemberConstantPoolTransformer.java
@@ -0,0 +1,112 @@
+package com.allatori.transform;
+
+import com.allatori.bytecode.ConstantPoolEditor;
+import com.allatori.bytecode.MethodFactory;
+import com.allatori.crypto.CustomStringEncryption;
+import com.allatori.lib.bcel.classfile.Constant;
+import com.allatori.lib.bcel.classfile.ConstantString;
+import com.allatori.lib.bcel.classfile.ConstantUtf8;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.LDC;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.model.ClassStorage;
+
+public class MemberConstantPoolTransformer implements ClassTransformer {
+
+ public ConstantPoolEditor constantPoolEditor;
+
+ public ClassStorage classStorage;
+
+ public void transform2(ClassGen classGen) {
+ InstructionHandle instructionHandle;
+ Method[] methods = classGen.getMethods();
+ int value;
+ for (int value2 = value = 0; value2 < methods.length; value2 = ++value) {
+ Method method;
+ if ((method = methods[value]).getCode() != null) {
+ MethodGen methodGen;
+ InstructionHandle instructionHandle2;
+ InstructionHandle instructionHandle3 =
+ instructionHandle2 =
+ (methodGen =
+ MethodFactory.createMethodGen(
+ method,
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool()))
+ .getInstructionList()
+ .getStart();
+ while (instructionHandle3 != null) {
+ label38:
+ {
+ if (instructionHandle2.getInstruction() instanceof LDC) {
+ LDC lDC = (LDC) instructionHandle2.getInstruction();
+ Constant constant;
+ if ((constant = classGen.getConstantPool().getConstant(lDC.getIndex()))
+ instanceof ConstantString) {
+ String text2;
+ if ((text2 =
+ ((ConstantUtf8)
+ classGen
+ .getConstantPool()
+ .getConstant(((ConstantString) constant).getStringIndex()))
+ .getBytes())
+ != null
+ && text2.startsWith(GlobalStringEncryptionTransformer.text4)) {
+ String text3 = text2.substring(GlobalStringEncryptionTransformer.text4.length());
+ String text5 = "" + classGen.getClassName() + methodGen.getName();
+ instructionHandle = instructionHandle2;
+ lDC.setIndex(
+ classGen
+ .getConstantPool()
+ .addString(GlobalStringEncryptionTransformer.createText(text3, text5)));
+ break label38;
+ }
+ if (text2 != null && text2.startsWith(CustomStringEncryption.text)) {
+ lDC.setIndex(
+ classGen
+ .getConstantPool()
+ .addString(
+ CustomStringEncryption.createText(
+ text2,
+ this.classStorage.getClassLoader(),
+ classGen.getClassName(),
+ methodGen.getName())));
+ }
+ }
+ }
+ instructionHandle = instructionHandle2;
+ }
+ instructionHandle3 = instructionHandle2 = instructionHandle.getInstructionHandle2();
+ }
+ methodGen.update5();
+ classGen.replaceMethod(method, methodGen.getMethod());
+ }
+ }
+ }
+
+ @Override
+ public void transform(ClassGen classGen) {
+ if (GlobalStringEncryptionTransformer.values.contains(classGen)) {
+ try {
+ this.transform2(classGen);
+ } catch (Exception exception) {
+ this.constantPoolEditor.processClassGen(classGen);
+ this.transform2(classGen);
+ }
+ }
+ }
+
+ @Override
+ public void finish() {
+ GlobalStringEncryptionTransformer.values = null;
+ }
+
+ public MemberConstantPoolTransformer(ClassStorage classStorage2) {
+ super();
+ this.constantPoolEditor = new ConstantPoolEditor(null);
+ this.classStorage = classStorage2;
+ }
+}
diff --git a/src/main/java/com/allatori/transform/MemberReorderTransformer.java b/src/main/java/com/allatori/transform/MemberReorderTransformer.java
new file mode 100644
index 0000000..2a4628a
--- /dev/null
+++ b/src/main/java/com/allatori/transform/MemberReorderTransformer.java
@@ -0,0 +1,169 @@
+package com.allatori.transform;
+
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.model.ClassStorage;
+import com.allatori.util.random.RandomUtils;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+public class MemberReorderTransformer implements ClassTransformer {
+
+ public ClassStorage classStorage;
+
+ public Vector values;
+
+ public Vector values2;
+
+ @Override
+ public void transform(ClassGen classGen) {
+ int value;
+ int value2 =
+ value = Configuration.getObfuscationOptions().calculateCount2(this.classStorage, classGen);
+ Configuration.getObfuscationOptions();
+ if (value2 == 100) {
+ this.values.add(classGen);
+ } else {
+ Configuration.getObfuscationOptions();
+ if (value == 101) {
+ this.values2.add(classGen);
+ } else {
+ this.processCount(classGen, value);
+ this.processCount2(classGen, value);
+ }
+ }
+ }
+
+ @Override
+ public void finish() {
+ Iterator iterator2;
+ Iterator iterator3 = iterator2 = this.values.iterator();
+ while (iterator3.hasNext()) {
+ ClassGen classGen = (ClassGen) iterator2.next();
+ iterator3 = iterator2;
+ Configuration.getObfuscationOptions();
+ this.processCount(classGen, 100);
+ Configuration.getObfuscationOptions();
+ this.processCount2(classGen, 100);
+ }
+ Iterator iterator4;
+ iterator3 = iterator4 = this.values2.iterator();
+ while (iterator3.hasNext()) {
+ ClassGen classGen2 = (ClassGen) iterator4.next();
+ iterator3 = iterator4;
+ Configuration.getObfuscationOptions();
+ this.processCount(classGen2, 101);
+ Configuration.getObfuscationOptions();
+ this.processCount2(classGen2, 101);
+ }
+ this.values2 = this.values = null;
+ }
+
+ public MemberReorderTransformer(ClassStorage classStorage2) {
+ super();
+ this.classStorage = classStorage2;
+ this.values = new Vector();
+ this.values2 = new Vector();
+ }
+
+ public void processCount(ClassGen classGen, int value) {
+ Configuration.getObfuscationOptions();
+ if (value == 1) {
+ int value2;
+ Field[] fields;
+ for (int value3 = value2 = (fields = classGen.getFields()).length - 1;
+ value3 >= 0;
+ value3 = value2) {
+ int value4 = value2;
+ Field[] fields2 = fields;
+ value2--;
+ classGen.processField2(fields2[value4]);
+ }
+ List values;
+ List values2 = values = Arrays.asList(fields);
+ RandomUtils.processValues(values2);
+ int value5;
+ for (int value6 = value5 = values2.size() - 1; value6 >= 0; value6 = value5) {
+ int value7 = value5;
+ List values3 = values;
+ value5--;
+ classGen.processField((Field) values3.get(value7));
+ }
+ } else {
+ Configuration.getObfuscationOptions();
+ if (value >= 100) {
+ int value8;
+ Field[] fields3;
+ for (int value9 = value8 = (fields3 = classGen.getFields()).length - 1;
+ value9 >= 0;
+ value9 = value8) {
+ int value10 = value8;
+ Field[] fields4 = fields3;
+ value8--;
+ classGen.processField2(fields4[value10]);
+ }
+ List values4 = Arrays.asList(fields3);
+ Collections.sort(values4, new FieldOrderComparator(this, value));
+ int value11;
+ for (int value12 = value11 = values4.size() - 1; value12 >= 0; value12 = value11) {
+ int value13 = value11;
+ value11--;
+ classGen.processField((Field) values4.get(value13));
+ }
+ }
+ }
+ }
+
+ public void processCount2(ClassGen classGen, int value) {
+ Configuration.getObfuscationOptions();
+ if (value == 1) {
+ Method[] methods;
+ int value2;
+ for (int value3 = value2 = (methods = classGen.getMethods()).length - 1;
+ value3 >= 0;
+ value3 = value2) {
+ int value4 = value2;
+ Method[] methods2 = methods;
+ value2--;
+ classGen.processMethod(methods2[value4]);
+ }
+ List values = Arrays.asList(methods);
+ RandomUtils.processValues(values);
+ int value5;
+ for (int value6 = value5 = values.size() - 1; value6 >= 0; value6 = value5) {
+ int value7 = value5;
+ Method[] methods3 = methods;
+ value5--;
+ classGen.processMethod2(methods3[value7]);
+ }
+ } else {
+ Configuration.getObfuscationOptions();
+ if (value >= 100) {
+ Method[] methods4;
+ int value8;
+ for (int value9 = value8 = (methods4 = classGen.getMethods()).length - 1;
+ value9 >= 0;
+ value9 = value8) {
+ int value10 = value8;
+ Method[] methods5 = methods4;
+ value8--;
+ classGen.processMethod(methods5[value10]);
+ }
+ List values2 = Arrays.asList(methods4);
+ Collections.sort(values2, new MethodOrderComparator(this, value));
+ int value11;
+ for (int value12 = value11 = values2.size() - 1; value12 >= 0; value12 = value11) {
+ int value13 = value11;
+ Method[] methods6 = methods4;
+ value11--;
+ classGen.processMethod2(methods6[value13]);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/transform/MemberVisibilityTransformer.java b/src/main/java/com/allatori/transform/MemberVisibilityTransformer.java
new file mode 100644
index 0000000..fa4966c
--- /dev/null
+++ b/src/main/java/com/allatori/transform/MemberVisibilityTransformer.java
@@ -0,0 +1,202 @@
+package com.allatori.transform;
+
+import com.allatori.bytecode.MethodFactory;
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.Attribute;
+import com.allatori.lib.bcel.classfile.EnclosingMethod;
+import com.allatori.lib.bcel.classfile.ExceptionTable;
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.classfile.InnerClasses;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.classfile.MethodParameters;
+import com.allatori.lib.bcel.classfile.RuntimeVisibleParameterAnnotations;
+import com.allatori.lib.bcel.classfile.Signature;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.FieldGen;
+import com.allatori.lib.bcel.generic.MethodGen;
+import com.allatori.model.ClassStorage;
+
+public class MemberVisibilityTransformer implements ClassTransformer {
+
+ public ClassStorage classStorage;
+
+ public void processFieldGen(ClassGen classGen, MethodGen methodGen, FieldGen fieldGen) {
+ Attribute[] attributes = null;
+ if (classGen != null && methodGen == null && fieldGen == null) {
+ attributes = classGen.getAttributes();
+ }
+ if (methodGen != null) {
+ attributes = methodGen.getAttributes();
+ }
+ if (fieldGen != null) {
+ attributes = fieldGen.getAttributes();
+ }
+ if (attributes != null) {
+ int value;
+ for (int value2 = value = attributes.length - 1; value2 >= 0; value2 = --value) {
+ if (attributes[value] instanceof Signature) {
+ if (methodGen != null) {
+ methodGen.removeAttribute(attributes[value]);
+ } else if (fieldGen != null) {
+ fieldGen.removeAttribute(attributes[value]);
+ } else {
+ classGen.processAttribute2(attributes[value]);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void finish() {}
+
+ @Override
+ public void transform(ClassGen classGen) {
+ int value;
+ if (Configuration.getObfuscationOptions().matchesClassGen(this.classStorage, classGen)) {
+ this.processFieldGen(classGen, null, null);
+ int value2;
+ Method[] methods;
+ for (int value3 = value2 = (methods = classGen.getMethods()).length - 1;
+ value3 >= 0;
+ value3 = --value2) {
+ Attribute[] attributes;
+ int value4;
+ Method method;
+ if ((attributes = (method = methods[value2]).getAttributes()) != null) {
+ for (int value5 = value4 = attributes.length - 1; value5 >= 0; value5 = --value4) {
+ if (attributes[value4] instanceof Signature) {
+ MethodGen methodGen =
+ MethodFactory.createMethodGen(
+ method,
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool());
+ this.processFieldGen(null, methodGen, null);
+ classGen.replaceMethod(method, methodGen.getMethod());
+ }
+ }
+ }
+ }
+ int value6;
+ Field[] fields;
+ for (int value7 = value6 = (fields = classGen.getFields()).length - 1;
+ value7 >= 0;
+ value7 = --value6) {
+ int value8;
+ Attribute[] attributes2;
+ Field field;
+ if ((attributes2 = (field = fields[value6]).getAttributes()) != null) {
+ for (int value9 = value8 = attributes2.length - 1; value9 >= 0; value9 = --value8) {
+ if (attributes2[value8] instanceof Signature) {
+ FieldGen fieldGen = new FieldGen(field, classGen.getConstantPool());
+ this.processFieldGen(null, null, fieldGen);
+ classGen.replaceField(field, fieldGen.getField());
+ }
+ }
+ }
+ }
+ }
+ if (Configuration.getObfuscationOptions().matchesClassGen2(this.classStorage, classGen)) {
+ this.transform2(classGen);
+ }
+ int value10;
+ Method[] methods2;
+ for (int value11 = value10 = (methods2 = classGen.getMethods()).length - 1;
+ value11 >= 0;
+ value11 = --value10) {
+ Method method2 = methods2[value10];
+ int value12;
+ Attribute[] attributes3;
+ if (Configuration.getObfuscationOptions().matchesMethod(this.classStorage, classGen, method2)
+ && (attributes3 = method2.getAttributes()) != null) {
+ for (int value13 = value12 = attributes3.length - 1; value13 >= 0; value13 = --value12) {
+ if (attributes3[value12] instanceof ExceptionTable) {
+ MethodGen methodGen2 =
+ MethodFactory.createMethodGen(
+ method2,
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool());
+ methodGen2.removeExceptions();
+ classGen.replaceMethod(method2, methodGen2.getMethod());
+ break;
+ }
+ }
+ }
+ }
+ int value14;
+ Method[] methods3;
+ for (int value15 = value14 = (methods3 = classGen.getMethods()).length - 1;
+ value15 >= 0;
+ value15 = --value14) {
+ Method method3 = methods3[value14];
+ int value16;
+ value15 =
+ value16 =
+ Configuration.getRenamingOptions()
+ .getLocalVariableOptions()
+ .calculateCount(this.classStorage, classGen, method3);
+ Configuration.getRenamingOptions().getLocalVariableOptions();
+ if (value15 != 3) {
+ Configuration.getRenamingOptions().getLocalVariableOptions();
+ Attribute[] attributes4;
+ if (value16 != 5 && (attributes4 = method3.getAttributes()) != null) {
+ byte value17 = 0;
+ int value18;
+ value15 = value18 = attributes4.length - 1;
+ while (true) {
+ if (value15 < 0) {
+ value = value17;
+ break;
+ }
+ if (attributes4[value18] instanceof RuntimeVisibleParameterAnnotations) {
+ value = 1;
+ break;
+ }
+ value15 = --value18;
+ }
+ int value19;
+ if (value == 0) {
+ for (int value20 = value19 = attributes4.length - 1;
+ value20 >= 0;
+ value20 = --value19) {
+ if (attributes4[value19] instanceof MethodParameters) {
+ MethodGen methodGen3 =
+ MethodFactory.createMethodGen(
+ method3,
+ classGen.getClassName(),
+ classGen.getConstantPool(),
+ classGen.getConstantPool().getConstantPool());
+ methodGen3.removeAttribute(attributes4[value19]);
+ classGen.replaceMethod(method3, methodGen3.getMethod());
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public MemberVisibilityTransformer(ClassStorage classStorage2) {
+ super();
+ this.classStorage = classStorage2;
+ }
+
+ public void transform2(ClassGen classGen) {
+ Attribute[] attributes = null;
+ if (classGen != null) {
+ attributes = classGen.getAttributes();
+ }
+ if (attributes != null) {
+ int value;
+ for (int value2 = value = attributes.length - 1; value2 >= 0; value2 = --value) {
+ if (attributes[value] instanceof InnerClasses
+ || attributes[value] instanceof EnclosingMethod) {
+ classGen.processAttribute2(attributes[value]);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/transform/MethodAccessTransformer.java b/src/main/java/com/allatori/transform/MethodAccessTransformer.java
new file mode 100644
index 0000000..1595213
--- /dev/null
+++ b/src/main/java/com/allatori/transform/MethodAccessTransformer.java
@@ -0,0 +1,46 @@
+package com.allatori.transform;
+
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.model.ClassStorage;
+
+public class MethodAccessTransformer implements ClassTransformer {
+
+ public ClassStorage classStorage;
+
+ @Override
+ public void transform(ClassGen classGen) {
+ try {
+ int value;
+ Field[] fields;
+ for (int value2 = value = (fields = classGen.getFields()).length - 1;
+ value2 >= 0;
+ value2 = --value) {
+ Field field = fields[value];
+ if (Configuration.getSyntheticOptions().matchesField(this.classStorage, classGen, field)) {
+ field.processEnabled9(true);
+ }
+ }
+ Method[] methods;
+ for (int value3 = (methods = classGen.getMethods()).length - 1; value3 >= 0; value3--) {
+ Method method = methods[value3];
+ if (Configuration.getSyntheticOptions()
+ .matchesMethod(this.classStorage, classGen, method)) {
+ method.processEnabled9(true);
+ }
+ }
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ }
+ }
+
+ public MethodAccessTransformer(ClassStorage classStorage2) {
+ super();
+ this.classStorage = classStorage2;
+ }
+
+ @Override
+ public void finish() {}
+}
diff --git a/src/main/java/com/allatori/transform/MethodOrderComparator.java b/src/main/java/com/allatori/transform/MethodOrderComparator.java
new file mode 100644
index 0000000..dc0bef3
--- /dev/null
+++ b/src/main/java/com/allatori/transform/MethodOrderComparator.java
@@ -0,0 +1,31 @@
+package com.allatori.transform;
+
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.Method;
+import java.util.Comparator;
+
+public class MethodOrderComparator implements Comparator {
+
+ public final int count;
+
+ public final MemberReorderTransformer memberReorderTransformer;
+
+ @Override
+ public int compare(Object result, Object result2) {
+ return this.calculateCount((Method) result, (Method) result2);
+ }
+
+ public MethodOrderComparator(MemberReorderTransformer memberReorderTransformer2, int count) {
+ super();
+ this.memberReorderTransformer = memberReorderTransformer2;
+ this.count = count;
+ }
+
+ public int calculateCount(Method method, Method method2) {
+ int value = this.count;
+ Configuration.getObfuscationOptions();
+ return value == 100
+ ? method2.getText().compareTo(method.getText())
+ : method.getText().compareTo(method2.getText());
+ }
+}
diff --git a/src/main/java/com/allatori/transform/OptimizerTransformer.java b/src/main/java/com/allatori/transform/OptimizerTransformer.java
new file mode 100644
index 0000000..8f7c440
--- /dev/null
+++ b/src/main/java/com/allatori/transform/OptimizerTransformer.java
@@ -0,0 +1,27 @@
+package com.allatori.transform;
+
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.model.ClassStorage;
+import com.allatori.optimizer.MethodOptimizer;
+
+public class OptimizerTransformer implements ClassTransformer {
+
+ public ClassStorage classStorage;
+
+ @Override
+ public void finish() {
+ this.finish2();
+ }
+
+ public void finish2() {}
+
+ public OptimizerTransformer(ClassStorage classStorage2) {
+ super();
+ this.classStorage = classStorage2;
+ }
+
+ @Override
+ public void transform(ClassGen classGen) {
+ new MethodOptimizer(this.classStorage).notify(classGen);
+ }
+}
diff --git a/src/main/java/com/allatori/transform/RemoveFieldsTransformer.java b/src/main/java/com/allatori/transform/RemoveFieldsTransformer.java
new file mode 100644
index 0000000..232bb7e
--- /dev/null
+++ b/src/main/java/com/allatori/transform/RemoveFieldsTransformer.java
@@ -0,0 +1,43 @@
+package com.allatori.transform;
+
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.Field;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.model.ClassStorage;
+import com.allatori.util.Log;
+
+public class RemoveFieldsTransformer implements ClassTransformer {
+
+ public ClassStorage classStorage;
+
+ @Override
+ public void transform(ClassGen classGen) {
+ int value;
+ Field[] fields;
+ for (int value2 = value = (fields = classGen.getFields()).length - 1;
+ value2 >= 0;
+ value2 = --value) {
+ Field field = fields[value];
+ if (Configuration.getFieldRemovalOptions().matchesField(this.classStorage, classGen, field)) {
+ classGen.processField2(field);
+ String text = "" + classGen.getClassName() + "." + field.getText() + field.getText2();
+ Configuration.getFieldRemovalOptions().processText(text);
+ Log.info(
+ " [remove-fields] removed "
+ + classGen.getClassName()
+ + "."
+ + field.getText()
+ + " "
+ + field.getText2());
+ }
+ }
+ }
+
+ @Override
+ public void finish() {}
+
+ public RemoveFieldsTransformer(ClassStorage classStorage2) {
+ super();
+ this.classStorage = classStorage2;
+ }
+}
diff --git a/src/main/java/com/allatori/transform/RemoveMethodsTransformer.java b/src/main/java/com/allatori/transform/RemoveMethodsTransformer.java
new file mode 100644
index 0000000..083443e
--- /dev/null
+++ b/src/main/java/com/allatori/transform/RemoveMethodsTransformer.java
@@ -0,0 +1,46 @@
+package com.allatori.transform;
+
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.model.ClassStorage;
+import com.allatori.util.Log;
+
+public class RemoveMethodsTransformer implements ClassTransformer {
+
+ public ClassStorage classStorage;
+
+ @Override
+ public void transform(ClassGen classGen) {
+ String text = "toString";
+ String text2 = "()Ljava/lang/String;";
+ int value;
+ Method[] methods;
+ for (int value2 = value = (methods = classGen.getMethods()).length - 1;
+ value2 >= 0;
+ value2 = --value) {
+ Method method = methods[value];
+ if (Configuration.getOptimizationOptions().matchesClassGen(this.classStorage, classGen)
+ && text.equals(method.getText())
+ && text2.equals(method.getText2())) {
+ classGen.processMethod(method);
+ Log.info(" [remove-methods] removed " + classGen.getClassName() + "." + text + text2);
+ }
+ if (Configuration.getOptimizationOptions()
+ .matchesMethod(this.classStorage, classGen, method)) {
+ classGen.processMethod(method);
+ String text3 = "" + classGen.getClassName() + "." + method.getText() + method.getText2();
+ Configuration.getOptimizationOptions().processText(text3);
+ Log.info(" [remove-methods] removed " + text3);
+ }
+ }
+ }
+
+ @Override
+ public void finish() {}
+
+ public RemoveMethodsTransformer(ClassStorage classStorage2) {
+ super();
+ this.classStorage = classStorage2;
+ }
+}
diff --git a/src/main/java/com/allatori/transform/StripAttributesTransformer.java b/src/main/java/com/allatori/transform/StripAttributesTransformer.java
new file mode 100644
index 0000000..1209245
--- /dev/null
+++ b/src/main/java/com/allatori/transform/StripAttributesTransformer.java
@@ -0,0 +1,50 @@
+package com.allatori.transform;
+
+import com.allatori.config.Configuration;
+import com.allatori.lib.bcel.classfile.InnerClass;
+import com.allatori.lib.bcel.classfile.InnerClasses;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.model.ClassStorage;
+import java.util.Iterator;
+import java.util.Vector;
+
+public class StripAttributesTransformer implements ClassTransformer {
+
+ public ClassStorage classStorage;
+
+ public StripAttributesTransformer(ClassStorage classStorage2) {
+ super();
+ this.classStorage = classStorage2;
+ }
+
+ @Override
+ public void finish() {}
+
+ @Override
+ public void transform(ClassGen classGen) {
+ String text;
+ if ((text = Configuration.getMethodRemovalOptions().getTestString()) != null) {
+ ClassGen classGen2;
+ if ((classGen2 = this.classStorage.getClassGen(text)) != null) {
+ Vector vector = new Vector();
+ Iterator classesByName2 = this.classStorage.getClassesByName2();
+ String text2 = "" + text + "$";
+ while (classesByName2.hasNext()) {
+ ClassGen classGen3;
+ if ((classGen3 = (ClassGen) classesByName2.next()).getClassName().startsWith(text2)) {
+ InnerClass innerClass =
+ new InnerClass(
+ classGen2.getConstantPool().addClass(classGen3.getClassName()), 0, 0, 0);
+ vector.add(innerClass);
+ }
+ }
+ classGen2.processAttribute(
+ new InnerClasses(
+ classGen2.getConstantPool().addUtf8("InnerClasses"),
+ vector.size() * 8 + 2,
+ (InnerClass[]) vector.toArray(new InnerClass[0]),
+ classGen2.getConstantPool().getConstantPool()));
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/util/FileUtils.java b/src/main/java/com/allatori/util/FileUtils.java
new file mode 100644
index 0000000..84d1774
--- /dev/null
+++ b/src/main/java/com/allatori/util/FileUtils.java
@@ -0,0 +1,100 @@
+package com.allatori.util;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+import java.util.Vector;
+
+public class FileUtils {
+
+ public static String createText(File file, String text)
+ throws FileNotFoundException, UnsupportedEncodingException, IOException {
+ StringBuffer stringBuffer = new StringBuffer((int) file.length());
+ BufferedReader bufferedReader;
+ BufferedReader bufferedReader2 =
+ text != null
+ ? (bufferedReader =
+ new BufferedReader(new InputStreamReader(new FileInputStream(file), text)))
+ : (bufferedReader = new BufferedReader(new FileReader(file)));
+ int value;
+ while ((value = bufferedReader2.read()) != -1) {
+ bufferedReader2 = bufferedReader;
+ stringBuffer.append((char) value);
+ }
+ bufferedReader.close();
+ return stringBuffer.toString();
+ }
+
+ public static void processFile(File file, File file2) throws IOException, FileNotFoundException {
+ FileChannel fileChannel = null;
+ FileChannel fileChannel2 = null;
+ try {
+ fileChannel = new FileInputStream(file).getChannel();
+ fileChannel2 = new FileOutputStream(file2).getChannel();
+ MappedByteBuffer mappedByteBuffer =
+ fileChannel.map(MapMode.READ_ONLY, 0L, fileChannel.size());
+ fileChannel2.write(mappedByteBuffer);
+ } finally {
+ if (fileChannel != null) {
+ fileChannel.close();
+ }
+ if (fileChannel2 != null) {
+ fileChannel2.close();
+ }
+ }
+ }
+
+ public static String[] createTexts(File file, String text, boolean matches)
+ throws FileNotFoundException, UnsupportedEncodingException, IOException {
+ BufferedReader bufferedReader;
+ if (text != null) {
+ bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), text));
+ } else {
+ bufferedReader = new BufferedReader(new FileReader(file));
+ }
+ Vector vector = new Vector();
+ label25:
+ while (true) {
+ BufferedReader bufferedReader2 = bufferedReader;
+ String text2;
+ while ((text2 = bufferedReader2.readLine()) != null) {
+ if (matches) {
+ if (text2.length() <= 0) {
+ continue label25;
+ }
+ bufferedReader2 = bufferedReader;
+ vector.add(text2);
+ } else {
+ vector.add(text2);
+ bufferedReader2 = bufferedReader;
+ }
+ }
+ bufferedReader.close();
+ String[] texts = new String[vector.size()];
+ return (String[]) vector.toArray(texts);
+ }
+ }
+
+ public static void processText(File file, String text, String text2)
+ throws FileNotFoundException, UnsupportedEncodingException, IOException {
+ BufferedWriter bufferedWriter;
+ (text != null
+ ? (bufferedWriter =
+ new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), text)))
+ : (bufferedWriter = new BufferedWriter(new FileWriter(file))))
+ .write(text2);
+ bufferedWriter.close();
+ }
+}
diff --git a/src/main/java/com/allatori/util/Log.java b/src/main/java/com/allatori/util/Log.java
new file mode 100644
index 0000000..f19e689
--- /dev/null
+++ b/src/main/java/com/allatori/util/Log.java
@@ -0,0 +1,47 @@
+package com.allatori.util;
+
+import com.allatori.naming.MappingXmlWriter;
+
+public class Log {
+
+ public static boolean silent = false;
+
+ public static void error(String text) {
+ MappingXmlWriter.stringBuilder.append("[ERROR] " + text + "\n");
+ System.out.println("[ERROR] " + text);
+ }
+
+ public static void info(String text) {
+ if (!silent) {
+ MappingXmlWriter.stringBuilder.append("[INFO] " + text + "\n");
+ System.out.println("[INFO] " + text);
+ }
+ }
+
+ public static boolean isSilent() {
+ return silent;
+ }
+
+ public static void warn(String text) {
+ if (!silent) {
+ MappingXmlWriter.stringBuilder.append("[WARNING] " + text + "\n");
+ System.out.println("[WARNING] " + text);
+ }
+ }
+
+ public static void info2(String text) {
+ if (!silent) {
+ System.out.println("[INFO] " + text);
+ }
+ }
+
+ public static void setSilent(boolean matches) {
+ silent = matches;
+ }
+
+ public static void debug(String text) {
+ if (!silent) {
+ System.out.println("[DEBUG] " + text);
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/util/LookupTable.java b/src/main/java/com/allatori/util/LookupTable.java
new file mode 100644
index 0000000..c21dac7
--- /dev/null
+++ b/src/main/java/com/allatori/util/LookupTable.java
@@ -0,0 +1,33 @@
+package com.allatori.util;
+
+import java.util.Hashtable;
+import java.util.Set;
+
+public class LookupTable {
+
+ public Hashtable entries = new Hashtable();
+
+ public int getEntries() {
+ return this.entries.size();
+ }
+
+ public Set getEntries2() {
+ return this.entries.keySet();
+ }
+
+ public void processText(String text, String text2) {
+ this.entries.put(text, text2);
+ }
+
+ public boolean matchesText(String text) {
+ return this.entries.containsKey(text);
+ }
+
+ public void processText(String text) {
+ this.entries.remove(text);
+ }
+
+ public String getText(String text) {
+ return (String) this.entries.get(text);
+ }
+}
diff --git a/src/main/java/com/allatori/util/StreamUtils.java b/src/main/java/com/allatori/util/StreamUtils.java
new file mode 100644
index 0000000..3e02ad7
--- /dev/null
+++ b/src/main/java/com/allatori/util/StreamUtils.java
@@ -0,0 +1,141 @@
+package com.allatori.util;
+
+import com.allatori.config.Configuration;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+
+public class StreamUtils {
+
+ public static void processWriter(Reader reader, Writer writer) throws IOException {
+ StringBuffer stringBuffer = new StringBuffer();
+ int value;
+ while ((value = reader.read()) >= 0) {
+ char value2 = (char) value;
+ if (stringBuffer.length() == 0) {
+ if (Character.isJavaIdentifierStart(value2)) {
+ stringBuffer.append(value2);
+ } else {
+ writer.write(value2);
+ }
+ } else if (!Character.isJavaIdentifierPart(value2) && value2 != '.' && value2 != '-') {
+ processText(writer, stringBuffer.toString());
+ stringBuffer.setLength(0);
+ writer.write(value2);
+ } else {
+ stringBuffer.append(value2);
+ }
+ }
+ processText(writer, stringBuffer.toString());
+ }
+
+ public static void processText(InputStream inputStream, OutputStream outputStream, String text)
+ throws UnsupportedEncodingException, IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, text));
+ BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, text));
+ processWriter(bufferedReader, bufferedWriter);
+ bufferedWriter.flush();
+ outputStream.flush();
+ }
+
+ public static void processText(Writer writer, String text) throws IOException {
+ String text2;
+ if ((text2 = Configuration.getMappingOptions().renamingLog.lookupTable4.getText(text))
+ != null) {
+ writer.write(text2);
+ } else {
+ writer.write(text);
+ }
+ }
+
+ public static String createText(String text, String text2) {
+ String text3 = text;
+ if (text3 == null) {
+ text3 = "";
+ }
+ String text4;
+ if (text3.length() > 0) {
+ if (!text2.startsWith(text3)) {
+ return text2;
+ }
+ text4 = text2 = text2.substring(text3.length());
+ } else {
+ text4 = text2;
+ }
+ String[] texts;
+ String[] texts2 = texts = text4.split("/");
+ String text5 = texts2[texts2.length - 1];
+ String text6 = "";
+ if (text5.contains(".")) {
+ text6 = text5.substring(text5.indexOf(46));
+ text5 = text5.substring(0, text5.indexOf(46));
+ }
+ String text7 = "";
+ int value;
+ for (int value2 = value = 0; value2 < texts.length - 1; value2 = value) {
+ StringBuilder stringBuilder = new StringBuilder().insert(0, text7).append(texts[value]);
+ value++;
+ text7 = stringBuilder.append((char) '.').toString();
+ }
+ String text8 = "" + text7 + text5;
+ if (Configuration.getMappingOptions().renamingLog.lookupTable4.matchesText(text8)) {
+ return ""
+ + text3
+ + Configuration.getMappingOptions()
+ .renamingLog
+ .lookupTable4
+ .getText(text8)
+ .replace('.', '/')
+ + text6;
+ }
+ while (text5.contains("_")) {
+ text6 = "" + text5.substring(text5.lastIndexOf(95)) + text6;
+ text5 = text5.substring(0, text5.lastIndexOf(95));
+ String text9 = "" + text7 + text5;
+ if (Configuration.getMappingOptions().renamingLog.lookupTable4.matchesText(text9)) {
+ return ""
+ + text3
+ + Configuration.getMappingOptions()
+ .renamingLog
+ .lookupTable4
+ .getText(text9)
+ .replace('.', '/')
+ + text6;
+ }
+ }
+ int value3;
+ for (int value4 = value3 = texts.length - 2; value4 >= 0; value4 = --value3) {
+ String text10 = "";
+ int value5;
+ for (int value6 = value5 = 0; value6 < value3; value6 = value5) {
+ StringBuilder stringBuilder2 = new StringBuilder().insert(0, text10).append(texts[value5]);
+ value5++;
+ text10 = stringBuilder2.append((char) '.').toString();
+ }
+ String text11 = "" + text10 + texts[value3];
+ if (Configuration.getMappingOptions().lookupTable2.matchesText(text11)
+ && !text11.equals(Configuration.getMappingOptions().lookupTable2.getText(text11))) {
+ String text12 =
+ ""
+ + text3
+ + Configuration.getMappingOptions().lookupTable2.getText(text11).replace('.', '/');
+ int value7;
+ for (int value8 = value7 = value3 + 1; value8 <= texts.length - 1; value8 = value7) {
+ StringBuilder stringBuilder3 = new StringBuilder().insert(0, text12).append('/');
+ String text13 = texts[value7];
+ value7++;
+ text12 = stringBuilder3.append(text13).toString();
+ }
+ return text12;
+ }
+ }
+ return "" + text3 + text2;
+ }
+}
diff --git a/src/main/java/com/allatori/util/random/RandomGenerator.java b/src/main/java/com/allatori/util/random/RandomGenerator.java
new file mode 100644
index 0000000..7dc2107
--- /dev/null
+++ b/src/main/java/com/allatori/util/random/RandomGenerator.java
@@ -0,0 +1,77 @@
+package com.allatori.util.random;
+
+public abstract class RandomGenerator implements Cloneable {
+
+ public Double cachedGaussian;
+
+ public int nextInt(int value) {
+ return this.nextInt(1, value);
+ }
+
+ public double nextGaussian() {
+ if (this.cachedGaussian != null) {
+ double value = this.cachedGaussian;
+ this.cachedGaussian = null;
+ return value;
+ }
+ double value2;
+ double value3;
+ double value4;
+ do {
+ value2 = this.nextDouble(-1.0, 1.0);
+ value4 = this.nextDouble(-1.0, 1.0);
+ } while ((value3 = value2 * value2 + value4 * value4) >= 1.0);
+ double value5 = Math.sqrt(-2.0 * Math.log(value3) / value3);
+ this.cachedGaussian = new Double(value2 * value5);
+ return value4 * value5;
+ }
+
+ public boolean nextBoolean() {
+ return this.nextDouble() <= 0.5;
+ }
+
+ public double nextDouble(double value, double value2) {
+ return value + (value2 - value) * this.nextDouble();
+ }
+
+ public double nextGaussian(double value) {
+ return this.nextGaussian() * value;
+ }
+
+ public double nextPowerLaw(double value, double value2) {
+ return value2 * Math.pow(this.nextDouble(), 1.0 / (value + 1.0));
+ }
+
+ public void fill(double[] values) {
+ this.fill(values, values.length);
+ }
+
+ public int nextInt(int value, int value2) {
+ int value3;
+ if ((value3 = value + (int) ((value2 - value) * this.nextDouble())) > value2) {
+ value3 = value2;
+ }
+ return value3;
+ }
+
+ public void fill(double[] values, int value) {
+ int value2;
+ for (int value3 = value2 = 0; value3 < value; value3 = value2) {
+ double value4 = this.nextDouble();
+ int value5 = value2;
+ value2++;
+ values[value5] = value4;
+ }
+ }
+
+ public boolean nextBoolean(double value) {
+ return this.nextDouble() <= value;
+ }
+
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+
+ public abstract double nextDouble();
+}
diff --git a/src/main/java/com/allatori/util/random/RandomUtils.java b/src/main/java/com/allatori/util/random/RandomUtils.java
new file mode 100644
index 0000000..407cc6b
--- /dev/null
+++ b/src/main/java/com/allatori/util/random/RandomUtils.java
@@ -0,0 +1,82 @@
+package com.allatori.util.random;
+
+import com.allatori.config.Configuration;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.RandomAccess;
+
+public class RandomUtils {
+
+ public static boolean enabled = false;
+
+ public static RandomGenerator randomGenerator;
+
+ public static void processCount(List values, int value, int value2) {
+ values.set(value, values.set(value2, values.get(value)));
+ }
+
+ public static double calculateValue() {
+ if (!enabled) {
+ update();
+ }
+ return randomGenerator.nextDouble();
+ }
+
+ public static void processCount(Object[] results, int value, int value2) {
+ Object result = results[value];
+ results[value] = results[value2];
+ results[value2] = result;
+ }
+
+ public static int calculateCount(int value) {
+ if (!enabled) {
+ update();
+ }
+ int value2;
+ return (value2 = randomGenerator.nextInt(0, value)) < value ? value2 : value2 - 1;
+ }
+
+ public static void update() {
+ String text;
+ if ((text = Configuration.getObfuscationOptions().getRandomSeed()) != null
+ && text.length() != 0) {
+ randomGenerator = new RanmarRandom(text.hashCode());
+ } else {
+ randomGenerator = new RanmarRandom(System.currentTimeMillis());
+ }
+ enabled = true;
+ }
+
+ public static void processValues(List values) {
+ if (!enabled) {
+ update();
+ }
+ int value;
+ int value2;
+ if ((value = values.size()) >= 5 && !(values instanceof RandomAccess)) {
+ Object[] results = values.toArray();
+ int value3;
+ for (int value4 = value3 = value; value4 > 1; value4 = value3) {
+ int value5 = value3 - 1;
+ int value6 = value3;
+ value3--;
+ processCount(results, value5, calculateCount(value6));
+ }
+ ListIterator listIterator2 = values.listIterator();
+ int value7;
+ for (int value8 = value7 = 0; value8 < results.length; value8 = value7) {
+ listIterator2.next();
+ int value9 = value7;
+ value7++;
+ listIterator2.set(results[value9]);
+ }
+ } else {
+ for (int value10 = value2 = value; value10 > 1; value10 = value2) {
+ int value11 = value2 - 1;
+ int value12 = value2;
+ value2--;
+ processCount(values, value11, calculateCount(value12));
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/allatori/util/random/RanmarRandom.java b/src/main/java/com/allatori/util/random/RanmarRandom.java
new file mode 100644
index 0000000..f0403a8
--- /dev/null
+++ b/src/main/java/com/allatori/util/random/RanmarRandom.java
@@ -0,0 +1,136 @@
+package com.allatori.util.random;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class RanmarRandom extends SeededRandomGenerator implements Serializable {
+
+ public double carry;
+
+ public double[] savedState;
+
+ public int j97;
+
+ public double[] state;
+
+ public double carryDelta;
+
+ public int i97;
+
+ public static int DEFAULT_SEED = 54217137;
+
+ public static int SEED_MODULUS = 899999963;
+
+ public double carryModulus;
+
+ public RanmarRandom() {
+ this.initializeState(DEFAULT_SEED);
+ }
+
+ public void initializeState(int value) {
+ this.state = new double[97];
+ this.savedState = new double[97];
+ int value2 = value / 30082;
+ int value3 = value - 30082 * value2;
+ int value4 = value2 / 177 % 177 + 2;
+ int value5 = value2 % 177 + 2;
+ int value6 = value3 / 169 % 178 + 1;
+ int value7 = value3 % 169;
+ int value8;
+ for (int value9 = value8 = 0; value9 < 97; value9 = value8) {
+ double value10 = 0.0;
+ double value11 = 0.5;
+ int value12;
+ for (int value13 = value12 = 0; value13 < 24; value13 = value12) {
+ int value14 = value4 * value5 % 179 * value6 % 179;
+ value4 = value5;
+ value5 = value6;
+ value6 = value14;
+ if ((value7 = (53 * value7 + 1) % 169) * value14 % 64 >= 32) {
+ value10 += value11;
+ }
+ double value15 = value11;
+ value12++;
+ value11 = value15 * 0.5;
+ }
+ double value16 = value10;
+ int value17 = value8;
+ double[] values = this.state;
+ value8++;
+ values[value17] = value16;
+ }
+ this.carry = 0.021602869F;
+ this.carryDelta = 0.45623308F;
+ this.carryModulus = 0.9999998F;
+ this.i97 = 96;
+ this.j97 = 32;
+ }
+
+ @Override
+ public final double nextDouble() {
+ double value;
+ if ((value = this.state[this.i97] - this.state[this.j97]) < 0.0) {
+ value++;
+ }
+ this.state[this.i97] = value;
+ if (--this.i97 < 0) {
+ this.i97 = 96;
+ }
+ if (--this.j97 < 0) {
+ this.j97 = 96;
+ }
+ this.carry = this.carry - this.carryDelta;
+ if (this.carry < 0.0) {
+ this.carry = this.carry + this.carryModulus;
+ }
+ double value2;
+ if ((value2 = value - this.carry) < 0.0) {
+ value2++;
+ }
+ return value2;
+ }
+
+ public RanmarRandom(int value) {
+ super();
+ this.initializeState(Math.abs(value % SEED_MODULUS));
+ }
+
+ @Override
+ public final void fill(double[] values, int value) {
+ int value2;
+ for (int value3 = value2 = 0; value3 < value; value3 = value2) {
+ double value4;
+ if ((value4 = this.state[this.i97] - this.state[this.j97]) < 0.0) {
+ value4++;
+ }
+ this.state[this.i97] = value4;
+ if (--this.i97 < 0) {
+ this.i97 = 96;
+ }
+ if (--this.j97 < 0) {
+ this.j97 = 96;
+ }
+ this.carry = this.carry - this.carryDelta;
+ if (this.carry < 0.0) {
+ this.carry = this.carry + this.carryModulus;
+ }
+ double value5;
+ if ((value5 = value4 - this.carry) < 0.0) {
+ value5++;
+ }
+ double value6 = value5;
+ int value7 = value2;
+ value2++;
+ values[value7] = value6;
+ }
+ }
+
+ public RanmarRandom(long value) {
+ this.initializeState((int) Math.abs(value % SEED_MODULUS));
+ }
+
+ public RanmarRandom(Date date) {
+ super();
+ this.initializeState((int) calculateSeed(date) % SEED_MODULUS);
+ }
+}
diff --git a/src/main/java/com/allatori/util/random/SeededRandomGenerator.java b/src/main/java/com/allatori/util/random/SeededRandomGenerator.java
new file mode 100644
index 0000000..fc7bb0c
--- /dev/null
+++ b/src/main/java/com/allatori/util/random/SeededRandomGenerator.java
@@ -0,0 +1,14 @@
+package com.allatori.util.random;
+
+import java.util.Date;
+
+public abstract class SeededRandomGenerator extends RandomGenerator {
+
+ public static long calculateSeed(Date date) {
+ return date.getTime();
+ }
+
+ public static long calculateSeed() {
+ return calculateSeed(new Date());
+ }
+}
diff --git a/src/main/java/com/allatori/watermark/WatermarkProcessor.java b/src/main/java/com/allatori/watermark/WatermarkProcessor.java
new file mode 100644
index 0000000..9468bee
--- /dev/null
+++ b/src/main/java/com/allatori/watermark/WatermarkProcessor.java
@@ -0,0 +1,543 @@
+package com.allatori.watermark;
+
+import com.allatori.VersionInfo;
+import com.allatori.config.Configuration;
+import com.allatori.engine.ObfuscationException;
+import com.allatori.lib.bcel.classfile.Method;
+import com.allatori.lib.bcel.generic.ClassGen;
+import com.allatori.lib.bcel.generic.ICONST;
+import com.allatori.lib.bcel.generic.InstructionConstants;
+import com.allatori.lib.bcel.generic.InstructionHandle;
+import com.allatori.lib.bcel.generic.InstructionList;
+import com.allatori.lib.bcel.generic.InstructionTargeter;
+import com.allatori.lib.bcel.generic.LineNumberGen;
+import com.allatori.lib.bcel.generic.LocalVariableGen;
+import com.allatori.lib.bcel.generic.POP2;
+import com.allatori.lib.bcel.generic.SIPUSH;
+import com.allatori.lib.bcel.util.comparator.MethodComparator;
+import com.allatori.model.ClassStorage;
+import com.allatori.model.MethodContext;
+import com.allatori.util.Log;
+import com.allatori.util.random.RandomUtils;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Vector;
+
+public class WatermarkProcessor {
+
+ public ClassStorage classStorage;
+
+ public String watermarkKey;
+
+ public void processValues(Vector vector, short[] values) {
+ InstructionHandle instructionHandle;
+ int value = values.length / 4;
+ int size2 = vector.size();
+ int value2 = (value - 1) / size2 + 1;
+ int value3 = 0;
+ int value4;
+ for (int value5 = value4 = vector.size() - 1; value5 >= 0; value5 = value4) {
+ InstructionHandle instructionHandle2;
+ MethodContext methodContext;
+ InstructionList instructionList;
+ InstructionHandle instructionHandle3 =
+ instructionHandle2 =
+ (instructionList =
+ MethodContext.getMethodGen(methodContext = (MethodContext) vector.get(value4))
+ .getInstructionList())
+ .getStart();
+ while (true) {
+ if (instructionHandle3 == null) {
+ instructionHandle = instructionHandle2;
+ break;
+ }
+ if (instructionHandle2.getInstruction() instanceof ICONST
+ && this.matchesInstructionTargeters(instructionHandle2.getTargeters())
+ && instructionHandle2.getInstructionHandle2() != null) {
+ instructionHandle = instructionHandle2 = instructionHandle2.getInstructionHandle2();
+ break;
+ }
+ instructionHandle3 = instructionHandle2 = instructionHandle2.getInstructionHandle2();
+ }
+ if (instructionHandle == null) {
+ instructionHandle2 = instructionList.getStart();
+ }
+ if (Configuration.getObfuscationOptions().isEnabled()) {
+ instructionHandle2 = instructionList.getEnd();
+ }
+ int value6 = 0;
+ do {
+ InstructionHandle instructionHandle4 =
+ instructionList.createInstructionHandle(instructionHandle2, new SIPUSH(values[value3]));
+ InstructionHandle instructionHandle5 =
+ instructionList.createInstructionHandle(
+ instructionHandle2, new SIPUSH(values[++value3]));
+ InstructionHandle instructionHandle6 =
+ instructionList.createInstructionHandle(
+ instructionHandle2, new SIPUSH(values[++value3]));
+ InstructionHandle instructionHandle7 =
+ instructionList.createInstructionHandle(
+ instructionHandle2, new SIPUSH(values[++value3]));
+ value3++;
+ InstructionHandle instructionHandle8;
+ InstructionHandle instructionHandle9 =
+ instructionHandle8 =
+ instructionList.createInstructionHandle(
+ instructionHandle2, InstructionConstants.POP2);
+ instructionList.createInstructionHandle(instructionHandle2, InstructionConstants.POP2);
+ value6++;
+ instructionHandle2 = instructionList.getStart();
+ } while (value6 < value2 && value4 < value - value3 / 4);
+ MethodContext.getMethodGen(methodContext).update5();
+ ClassGen classGen = MethodContext.getClassGen(methodContext);
+ Method method = MethodContext.getMethod(methodContext);
+ MethodContext methodContext2 = methodContext;
+ value4--;
+ classGen.replaceMethod(method, MethodContext.getMethodGen(methodContext2).getMethod());
+ }
+ }
+
+ public short[] createValues(Vector vector) {
+ Vector vector2 = new Vector();
+ int value;
+ InstructionHandle instructionHandle;
+ for (int value2 = value = vector.size() - 1; value2 >= 0; value2 = --value) {
+ for (InstructionHandle instructionHandle2 =
+ instructionHandle =
+ MethodContext.getMethodGen((MethodContext) vector.get(value))
+ .getInstructionList()
+ .getStart();
+ instructionHandle2 != null;
+ instructionHandle2 = instructionHandle = instructionHandle.getInstructionHandle2()) {
+ if (this.matchesInstructionHandle(instructionHandle)) {
+ vector2.add(((SIPUSH) instructionHandle.getInstruction()).getValue());
+ vector2.add(
+ ((SIPUSH) instructionHandle.getInstructionHandle2().getInstruction()).getValue());
+ vector2.add(
+ ((SIPUSH)
+ instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstruction())
+ .getValue());
+ vector2.add(
+ ((SIPUSH)
+ instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstruction())
+ .getValue());
+ }
+ }
+ }
+ short[] values;
+ int value3;
+ for (int value4 = value3 = (values = new short[vector2.size()]).length - 1;
+ value4 >= 0;
+ value4 = value3) {
+ short value5 = ((Number) vector2.get(value3)).shortValue();
+ int value6 = value3;
+ short[] values2 = values;
+ value3--;
+ values2[value6] = value5;
+ }
+ return values;
+ }
+
+ public boolean matchesValues(Vector vector) {
+ InstructionHandle instructionHandle;
+ int value;
+ for (int value2 = value = vector.size() - 1; value2 >= 0; value2 = --value) {
+ for (InstructionHandle instructionHandle2 =
+ instructionHandle =
+ MethodContext.getMethodGen((MethodContext) vector.get(value))
+ .getInstructionList()
+ .getStart();
+ instructionHandle2 != null;
+ instructionHandle2 = instructionHandle = instructionHandle.getInstructionHandle2()) {
+ if (this.matchesInstructionHandle(instructionHandle)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public String createText(short[] values) throws Exception, UnsupportedEncodingException {
+ int value;
+ for (int value2 = value = 0; value2 < values.length; value2 = value) {
+ short value3 = values[value];
+ short value4 = values[value + 1];
+ short value5 = values[value + 2];
+ short value6 = values[value + 3];
+ values[value] = values[value + 1] = values[value + 2] = values[value + 3] = 0;
+ values[value] = (short) (values[value] | value3 ^ value5 ^ value6);
+ short[] values2;
+ if (values[value] % 2 == 0) {
+ values2 = values;
+ values[value + 1] = (short) (values[value + 1] | value3 ^ value4 ^ value6);
+ } else {
+ values2 = values;
+ values[value + 1] = (short) (values[value + 1] | value4 ^ value5 ^ values[value]);
+ }
+ short[] values3;
+ if (values2[value + 1] % 4 == 0) {
+ values3 = values;
+ values[value + 2] = (short) (values[value + 2] | value3 ^ value4 ^ value5);
+ } else if (values[value + 1] % 4 == 1) {
+ values3 = values;
+ values[value + 2] =
+ (short) (values[value + 2] | value3 ^ values[value] ^ values[value + 1]);
+ } else if (values[value + 1] % 4 == 2) {
+ values3 = values;
+ values[value + 2] = (short) (values[value + 2] | value5 ^ value6 ^ values[value + 1]);
+ } else {
+ values3 = values;
+ values[value + 2] = (short) (values[value + 2] | value4 ^ value6 ^ values[value]);
+ }
+ if (values3[value + 2] % 7 == 0) {
+ values[value + 3] = (short) (values[value + 3] | value4 ^ value5 ^ value6);
+ } else if (values[value + 2] % 7 == 1) {
+ values[value + 3] =
+ (short) (values[value + 3] | value6 ^ values[value] ^ values[value + 1]);
+ } else if (values[value + 2] % 7 == 2) {
+ values[value + 3] =
+ (short) (values[value + 3] | value5 ^ values[value] ^ values[value + 2]);
+ } else if (values[value + 2] % 7 == 3) {
+ values[value + 3] =
+ (short) (values[value + 3] | value4 ^ values[value + 1] ^ values[value + 2]);
+ } else if (values[value + 2] % 7 == 4) {
+ values[value + 3] = (short) (values[value + 3] | value3 ^ value4 ^ values[value]);
+ } else if (values[value + 2] % 7 == 5) {
+ values[value + 3] = (short) (values[value + 3] | value3 ^ value5 ^ values[value + 1]);
+ } else {
+ values[value + 3] = (short) (values[value + 3] | value3 ^ value6 ^ values[value + 2]);
+ }
+ value += 4;
+ }
+ int value7 = this.watermarkKey.hashCode();
+ short value8 = (short) ((byte) 0 | value7);
+ short value9 = (short) ((byte) 0 | value7 >> 16);
+ int value10 = -1;
+ Hashtable hashtable = new Hashtable();
+ int value11;
+ for (int value12 = value11 = 0; value12 < values.length; value12 = value11) {
+ hashtable.put(new Short(values[value11]), new Integer(value11));
+ if (values[value11] == value8 && values[value11 + 1] == value9) {
+ if (value10 != -1) {
+ throw new Exception();
+ }
+ value10 = value11;
+ }
+ value11 += 4;
+ }
+ if (value10 == -1) {
+ throw new Exception();
+ }
+ int value13;
+ int value14 = value13 = values[value10 + 3];
+ while (value14 % 4 != 0) {
+ value14 = ++value13;
+ }
+ byte[] values4;
+ Arrays.fill(values4 = new byte[value13], (byte) 0);
+ int value15 = 0;
+ int value16 = value10 + 1;
+ for (int value17 = value15; value17 < values4.length; value17 = value15) {
+ value16 = ((Number) hashtable.get(new Short(values[value16 + 1]))).shortValue();
+ int value18 = value15;
+ byte[] values5 = values4;
+ int value19 = value15;
+ byte[] values6 = values4;
+ byte[] values7 = values4;
+ byte[] values8 = values4;
+ byte[] values9 = values4;
+ value15++;
+ values6[value19] = (byte) (values5[value18] | values[value16 + 2] >> 8);
+ int value20 = value15;
+ int value21 = value15;
+ value15++;
+ values7[value21] = (byte) (values7[value20] | values[value16 + 3] >> 8);
+ int value22 = value15;
+ int value23 = value15;
+ value15++;
+ values8[value23] = (byte) (values8[value22] | values[value16 + 2]);
+ int value24 = value15;
+ int value25 = value15;
+ value15++;
+ values9[value25] = (byte) (values9[value24] | values[value16 + 3]);
+ }
+ byte[] bytes = this.watermarkKey.getBytes();
+ int value26;
+ for (int value27 = value26 = 0; value27 < values4.length; value27 = value26) {
+ byte value28 = (byte) (values4[value26] ^ bytes[value26 % bytes.length]);
+ int value29 = value26;
+ byte[] values10 = values4;
+ value26++;
+ values10[value29] = value28;
+ }
+ if (values4.length > 1) {
+ values4[1] ^= values4[0];
+ }
+ int value30;
+ for (int value31 = value30 = 2; value31 < values4.length; value31 = value30) {
+ byte value32 = (byte) (values4[value30] ^ values4[value30 - 1] ^ values4[value30 - 2]);
+ int value33 = value30;
+ byte[] values11 = values4;
+ value30++;
+ values11[value33] = value32;
+ }
+ return new String(values4, 0, values[value10 + 3], "UTF-8");
+ }
+
+ public Vector createValues() {
+ Vector vector = new Vector();
+ Iterator classesByName2 = this.classStorage.getClassesByName2();
+ while (true) {
+ Iterator iterator = classesByName2;
+ ClassGen classGen;
+ while (true) {
+ if (!iterator.hasNext()) {
+ return vector;
+ }
+ classGen = (ClassGen) classesByName2.next();
+ try {
+ if (!Configuration.getIgnoreClassesOptions()
+ .matchesClassGen(this.classStorage, classGen)) {
+ break;
+ }
+ } catch (ClassCastException classCastException) {
+ Log.error("ALLATORI INTERNAL ERROR. Class " + classGen.getClassName());
+ iterator = classesByName2;
+ continue;
+ }
+ iterator = classesByName2;
+ }
+ int value;
+ Method[] methods;
+ for (int value2 = value = (methods = classGen.getMethods()).length - 1;
+ value2 >= 0;
+ value2 = --value) {
+ Method method;
+ if ((method = methods[value]).getCode() != null) {
+ vector.add(new MethodContext(classGen, method));
+ }
+ }
+ }
+ }
+
+ public void processText(String text) throws ObfuscationException {
+ try {
+ Vector vector;
+ if (this.matchesValues(vector = this.createValues())) {
+ throw new ObfuscationException("The jar file already contains watermark.");
+ }
+ RandomUtils.processValues(vector);
+ short[] values = this.createValues(text);
+ int value;
+ for (int value2 = value = vector.size() - values.length / 4; value2 > 0; value2 = value) {
+ value--;
+ vector.remove(0);
+ }
+ this.processValues(vector, values);
+ } catch (Exception exception) {
+ System.out.println(
+ "############### EXCEPTION (" + VersionInfo.getVersion() + ") ###############");
+ exception.printStackTrace();
+ System.out.println("#################################################");
+ throw new ObfuscationException(("Watermarking error: " + exception.getMessage()));
+ }
+ }
+
+ public boolean matchesInstructionTargeters(InstructionTargeter[] instructionTargeters) {
+ if (instructionTargeters == null) {
+ return true;
+ }
+ int value;
+ for (int value2 = value = 0; value2 < instructionTargeters.length; value2 = ++value) {
+ InstructionTargeter instructionTargeter;
+ if (!((instructionTargeter = instructionTargeters[value]) instanceof LineNumberGen)
+ && !(instructionTargeter instanceof LocalVariableGen)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean matchesInstructionHandle(InstructionHandle instructionHandle) {
+ return instructionHandle.getInstruction() instanceof SIPUSH
+ && instructionHandle.getInstructionHandle2() != null
+ && instructionHandle.getInstructionHandle2().getInstruction() instanceof SIPUSH
+ && instructionHandle.getInstructionHandle2().getInstructionHandle2() != null
+ && instructionHandle.getInstructionHandle2().getInstructionHandle2().getInstruction()
+ instanceof SIPUSH
+ && instructionHandle.getInstructionHandle2().getInstructionHandle2().getInstructionHandle2()
+ != null
+ && instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstruction()
+ instanceof SIPUSH
+ && instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ != null
+ && instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstruction()
+ instanceof POP2
+ && instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ != null
+ && instructionHandle
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstructionHandle2()
+ .getInstruction()
+ instanceof POP2;
+ }
+
+ public short[] createValues(String text) throws UnsupportedEncodingException {
+ int value;
+ byte[] values;
+ int value2 = value = (values = text.getBytes("UTF-8")).length;
+ while (value2 % 4 != 0) {
+ value2 = ++value;
+ }
+ byte[] values2 = new byte[value];
+ Arrays.fill(values2, (byte) 0);
+ values2[0] = values[0];
+ if (values.length > 1) {
+ values2[1] = (byte) (values2[1] | values[1] ^ values[0]);
+ }
+ int value3;
+ for (int value4 = value3 = 2; value4 < values.length; value4 = value3) {
+ byte value5 =
+ (byte) (values2[value3] | values[value3] ^ values[value3 - 1] ^ values[value3 - 2]);
+ int value6 = value3;
+ value3++;
+ values2[value6] = value5;
+ }
+ int value7;
+ for (int value8 = value7 = values.length; value8 < value; value8 = value7) {
+ byte value9 = (byte) (values2[value7] | RandomUtils.calculateCount(256));
+ int value10 = value7;
+ value7++;
+ values2[value10] = value9;
+ }
+ byte[] bytes = this.watermarkKey.getBytes();
+ int value11;
+ for (int value12 = value11 = 0; value12 < values2.length; value12 = value11) {
+ byte value13 = (byte) (values2[value11] ^ bytes[value11 % bytes.length]);
+ int value14 = value11;
+ value11++;
+ values2[value14] = value13;
+ }
+ int value15 = value;
+ int value16;
+ value2 = value16 = (int) (value * (0.666 + RandomUtils.calculateValue() / 3.0)) + 113;
+ while (value2 % 4 != 0) {
+ value2 = ++value16;
+ }
+ short[] values3;
+ short[] values4 = values3 = new short[value15 + value16];
+ int value17 = 0;
+ Arrays.fill(values4, (short) 0);
+ for (int index = 0; value17 < values3.length; value17 = index) {
+ if (index < value15) {
+ values3[index + 2] =
+ (short) (values3[index + 2] | values2[index] << 8 | values2[index + 2] & 0xFF);
+ values3[index + 3] =
+ (short) (values3[index + 3] | values2[index + 1] << 8 | values2[index + 3] & 0xFF);
+ } else {
+ values3[index + 2] =
+ (short) (values3[index + 2] | RandomUtils.calculateCount(Integer.MAX_VALUE));
+ values3[index + 3] =
+ (short) (values3[index + 3] | RandomUtils.calculateCount(Integer.MAX_VALUE));
+ }
+ index += 4;
+ }
+ Hashtable hashtable = new Hashtable();
+ short value18 = (short) (0 | this.watermarkKey.hashCode());
+ hashtable.put(new Short(value18), "");
+ int value19 = 0;
+ for (int value20 = value19; value20 < values3.length; value20 = value19) {
+ int value21 = (short) (RandomUtils.calculateCount(65536) - 32768);
+ for (Hashtable hashtable2 = hashtable;
+ hashtable2.containsKey(new Short((short) value21));
+ hashtable2 = hashtable) {
+ value21++;
+ }
+ hashtable.put(new Short((short) value21), "");
+ values3[value19] = (short) value21;
+ if (value19 > 3) {
+ values3[value19 - 3] = (short) value21;
+ }
+ value19 += 4;
+ }
+ int value22;
+ for (int value23 = value22 = value15 + 4 * RandomUtils.calculateCount(20);
+ value23 < values3.length;
+ value23 = value22) {
+ int value24 = value22 + 1;
+ short value25 = values3[RandomUtils.calculateCount(value15 / 4) * 4];
+ short[] values5 = values3;
+ value22 += 4;
+ values5[value24] = value25;
+ }
+ int value26 = this.watermarkKey.hashCode();
+ values3[values3.length - 4] =
+ values3[values3.length - 3] = values3[values3.length - 2] = values3[values3.length - 1] = 0;
+ values3[values3.length - 4] = (short) (values3[values3.length - 4] | value26);
+ values3[values3.length - 3] = (short) (values3[values3.length - 3] | value26 >> 16);
+ values3[values3.length - 2] = (short) (values3[values3.length - 2] | values3[0]);
+ values3[values3.length - 1] = (short) (values3[values3.length - 1] | values.length);
+ int value27;
+ for (int value28 = value27 = 0; value28 < values3.length; value28 = value27) {
+ short value29 = values3[value27];
+ short value30 = values3[value27 + 1];
+ short value31 = values3[value27 + 2];
+ short value32 = values3[value27 + 3];
+ values3[value27] = values3[value27 + 1] = values3[value27 + 2] = values3[value27 + 3] = 0;
+ values3[value27] = (short) (values3[value27] | value29 ^ value30 ^ value31);
+ values3[value27 + 1] = (short) (values3[value27 + 1] | value30 ^ value31 ^ value32);
+ values3[value27 + 2] = (short) (values3[value27 + 2] | value29 ^ value31 ^ value32);
+ short value33 = (short) (values3[value27 + 3] | value29 ^ value30 ^ value32);
+ int value34 = value27 + 3;
+ short[] values6 = values3;
+ value27 += 4;
+ values6[value34] = value33;
+ }
+ return values3;
+ }
+
+ public String createText() throws ObfuscationException {
+ try {
+ return this.createText(this.createValues(this.createValues()));
+ } catch (Exception exception) {
+ throw new ObfuscationException("Cannot extract watermark.");
+ }
+ }
+
+ public WatermarkProcessor(ClassStorage classStorage2, String watermarkKey) {
+ super();
+ this.classStorage = classStorage2;
+ this.watermarkKey = watermarkKey;
+ Method.setComparator(MethodComparator.getMethodComparator());
+ }
+}
diff --git a/src/main/java/com/allatori/wtk/WTKObfuscator.java b/src/main/java/com/allatori/wtk/WTKObfuscator.java
new file mode 100644
index 0000000..30af1aa
--- /dev/null
+++ b/src/main/java/com/allatori/wtk/WTKObfuscator.java
@@ -0,0 +1,89 @@
+package com.allatori.wtk;
+
+import com.allatori.Obfuscate;
+import com.allatori.config.Configuration;
+import com.allatori.config.ConfigurationException;
+import com.allatori.engine.ObfuscationException;
+import com.allatori.util.FileUtils;
+import com.allatori.util.Log;
+import com.sun.kvem.environment.Obfuscator;
+import java.io.File;
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+public class WTKObfuscator implements Obfuscator {
+
+ public String configurationFileName;
+
+ public WTKObfuscator() {
+ super();
+ this.configurationFileName = "allatori.xml";
+ }
+
+ public void createScriptFile(File file, File file2) {}
+
+ public void run(
+ File file, String text, String text2, String text3, String text4, String text5, String text6)
+ throws IOException, ConfigurationException, ObfuscationException, ClassNotFoundException {
+ String text7;
+ if (!text4.endsWith("/") && !text4.endsWith("\\")) {
+ text7 = "" + text4 + "/" + this.configurationFileName;
+ } else {
+ text7 = "" + text4 + this.configurationFileName;
+ }
+ File file2;
+ File file3;
+ if ((file2 = new File(text7)).exists() && !file2.canWrite()) {
+ Log.info2("Using the existing configuration file.");
+ file3 = file2;
+ } else {
+ String text8 = this.createText(file, text, text2, text3, text4, text5, text6);
+ try {
+ FileUtils.processText(file2, "UTF-8", text8);
+ } catch (Exception exception) {
+ exception.printStackTrace();
+ throw new IOException();
+ }
+ file3 = file2;
+ }
+ Configuration.processText(file3.getPath());
+ Obfuscate.runObfuscation();
+ Configuration.update();
+ }
+
+ public String createText(
+ File file,
+ String text,
+ String text2,
+ String text3,
+ String text4,
+ String text5,
+ String text6) {
+ StringBuffer stringBuffer;
+ (stringBuffer = new StringBuffer()).append("\n");
+ stringBuffer.append(" \n");
+ stringBuffer.append(" \n");
+ stringBuffer.append(" \n\n");
+ stringBuffer.append(" \n");
+ StringTokenizer stringTokenizer =
+ new StringTokenizer(text5, System.getProperty("path.separator"));
+ StringTokenizer stringTokenizer2 = stringTokenizer;
+ while (stringTokenizer2.hasMoreTokens()) {
+ stringTokenizer2 = stringTokenizer;
+ String text7 = stringTokenizer.nextToken();
+ stringBuffer.append(" \n");
+ }
+ stringBuffer.append(" \n\n");
+ stringBuffer.append(" \n");
+ stringBuffer.append(
+ " \n");
+ stringBuffer.append(" \n\n");
+ stringBuffer.append(" \n");
+ stringBuffer.append(" \n");
+ stringBuffer.append(" \n");
+ stringBuffer.append(" \n");
+ stringBuffer.append(" \n");
+ stringBuffer.append("\n");
+ return stringBuffer.toString();
+ }
+}
diff --git a/src/main/resources/META-INF/MANIFEST.MF b/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..c21aa5b
--- /dev/null
+++ b/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,12 @@
+Manifest-Version: 1.0
+Implementation-Title: OpenAllatori
+Implementation-Version: 9.9
+Main-Class: com.allatori.Obfuscate
+Bundle-ManifestVersion: 2
+Bundle-Name: OpenAllatori Builder
+Bundle-SymbolicName: com.allatori.eclipse;singleton:=true
+Bundle-Version: 9.9
+Bundle-RequiredExecutionEnvironment: JavaSE-17
+Require-Bundle: org.eclipse.core.resources,org.eclipse.core.runtime,or
+ g.eclipse.core.commands,org.eclipse.jface,org.eclipse.ui,org.eclipse.
+ core.expressions,org.eclipse.jdt.core
diff --git a/src/main/resources/plugin.xml b/src/main/resources/plugin.xml
new file mode 100644
index 0000000..2360db7
--- /dev/null
+++ b/src/main/resources/plugin.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/wtkApi/java/com/sun/kvem/environment/Obfuscator.java b/src/wtkApi/java/com/sun/kvem/environment/Obfuscator.java
new file mode 100644
index 0000000..a0cf97f
--- /dev/null
+++ b/src/wtkApi/java/com/sun/kvem/environment/Obfuscator.java
@@ -0,0 +1,20 @@
+package com.sun.kvem.environment;
+
+import java.io.File;
+import java.io.IOException;
+
+/** Compile-only contract of the legacy Sun Wireless Toolkit integration. */
+public interface Obfuscator {
+
+ void createScriptFile(File outputDirectory, File inputJar) throws IOException;
+
+ void run(
+ File outputJar,
+ String projectName,
+ String className,
+ String inputJar,
+ String projectDirectory,
+ String classPath,
+ String arguments)
+ throws Exception;
+}