From f1bc11a0f2e5fc3ec745043b9a4d6fc9392c941b Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 12 Feb 1999 15:21:53 +0000 Subject: [PATCH] Initial revision git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@263 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/jvm/SyntheticAnalyzer.java | 98 ++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 jode/jode/jvm/SyntheticAnalyzer.java diff --git a/jode/jode/jvm/SyntheticAnalyzer.java b/jode/jode/jvm/SyntheticAnalyzer.java new file mode 100644 index 0000000..70ce2db --- /dev/null +++ b/jode/jode/jvm/SyntheticAnalyzer.java @@ -0,0 +1,98 @@ +/* + * SyntheticAnalyzer (c) 1998 Jochen Hoenicke + * + * You may distribute under the terms of the GNU General Public License. + * + * IN NO EVENT SHALL JOCHEN HOENICKE BE LIABLE TO ANY PARTY FOR DIRECT, + * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF + * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF JOCHEN HOENICKE + * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * JOCHEN HOENICKE SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" + * BASIS, AND JOCHEN HOENICKE HAS NO OBLIGATION TO PROVIDE MAINTENANCE, + * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * $Id$ + */ + +package jode.decompiler; +import jode.Decompiler; +import jode.flow.*; +import jode.expr.*; +import jode.Type; +import jode.MethodType; + +public class SyntheticAnalyzer { + public final static int UNKNOWN = 0; + public final static int GETCLASS = 1; + public final static int GETFIELD = 2; + public final static int PUTFIELD = 3; + + int type = UNKNOWN; + MethodAnalyzer method; + + public SyntheticAnalyzer(MethodAnalyzer method) { + this.method = method; + if (method.getName().equals("class$")) + if (!checkGetClass() && Decompiler.isVerbose) + Decompiler.err.println("class$ seems to be wrong"); + } + + boolean checkGetClass() { + MethodType type = method.getType(); + if (!type.isStatic() + || !type.getReturnType().isOfType(Type.tJavaLangClass) + || type.getParameterTypes().length != 1 + || !type.getParameterTypes()[0].isOfType(Type.tString)) + return false; + + FlowBlock flow = method.getMethodHeader(); + if (!flow.hasNoJumps()) + return false; + StructuredBlock tryblock = flow.getBlock(); + if (!(tryblock instanceof TryBlock)) + return false; + StructuredBlock[] subBlocks = tryblock.getSubBlocks(); + if (subBlocks.length != 2 + || !(subBlocks[0] instanceof ReturnBlock) + || !(subBlocks[1] instanceof CatchBlock)) + return false; + + // Now check the return Block, it should be + // return Class.forName(local_0); + ReturnBlock ret = (ReturnBlock) subBlocks[0]; + Expression retExpr = ret.getInstruction(); + if (!(retExpr instanceof ComplexExpression) + || !(retExpr.getOperator() instanceof InvokeOperator)) + return false; + InvokeOperator invoke = (InvokeOperator) retExpr.getOperator(); + if (!invoke.isStatic() + || !invoke.getClassType().equals(Type.tJavaLangClass) + || !(invoke.getMethodType().getReturnType() + .equals(Type.tJavaLangClass)) + || invoke.getMethodType().getParameterTypes().length != 1 + || !(invoke.getMethodType().getParameterTypes()[0] + .equals(Type.tString)) + || !invoke.getMethodName().equals("forName")) + return false; + + Expression[] subExpr = + ((ComplexExpression) retExpr).getSubExpressions(); + if (!(subExpr[0] instanceof LocalLoadOperator) + || ((LocalLoadOperator) subExpr[0]).getLocalInfo().getSlot() != 0) + return false; + + // Now check the CatchBlock it should contain (we don't check all): + // throw new NoClassDefFoundError(exception.getMessage()); + CatchBlock catchBlock = (CatchBlock) subBlocks[1]; + StructuredBlock subBlock = catchBlock.getSubBlocks()[0]; + if (!(subBlock instanceof ThrowBlock) + || !(catchBlock.getExceptionType().equals + (Type.tClass("java.lang.ClassNotFoundException")))) + return false; + this.type = GETCLASS; + return true; + } +}