From bf4e1791de21d60e80443baa0bac64ab5b2f8011 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 28 Apr 1999 16:28:42 +0000 Subject: [PATCH] checkJikesArrayClone() git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@700 379699f6-c40d-0410-875b-85095c16579e --- jode/jode/flow/TryBlock.java | 96 ++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/jode/jode/flow/TryBlock.java b/jode/jode/flow/TryBlock.java index 13d1299..2ac7034 100644 --- a/jode/jode/flow/TryBlock.java +++ b/jode/jode/flow/TryBlock.java @@ -19,6 +19,12 @@ package jode.flow; import jode.decompiler.TabbedPrintWriter; +import jode.type.*; +import jode.expr.Expression; +import jode.expr.ComplexExpression; +import jode.expr.InvokeOperator; +import jode.expr.ConstructorOperator; +import jode.expr.LocalLoadOperator; /** * A TryBlock is created for each exception in the @@ -134,4 +140,94 @@ public class TryBlock extends StructuredBlock { } return true; } + + /** + * A special transformation for try blocks: + * jikes generate try/catch-blocks for array clone: + *
+     * try {
+     *     PUSH ARRAY.clone()
+     * } catch (CloneNotSupportedException ex) {
+     *     throw new InternalError(ex.getMessage());
+     * }
+     * 
+ * which is simply transformed to the content of the try block. + */ + public boolean checkJikesArrayClone() { + + if (subBlocks.length != 2 + || !(subBlocks[0] instanceof InstructionBlock) + || !(subBlocks[1] instanceof CatchBlock)) + return false; + + Expression instr = + ((InstructionBlock)subBlocks[0]).getInstruction(); + CatchBlock catchBlock = (CatchBlock) subBlocks[1]; + + if (instr.isVoid() + || !(instr instanceof ComplexExpression) + || !(instr.getOperator() instanceof InvokeOperator) + || !(catchBlock.catchBlock instanceof ThrowBlock) + || !(catchBlock.exceptionType.equals + (Type.tClass("java.lang.CloneNotSupportedException")))) + return false; + + + InvokeOperator arrayClone = + (InvokeOperator) instr.getOperator(); + if (!arrayClone.getMethodName().equals("clone") + || arrayClone.isStatic() + || (arrayClone.getMethodType().getParameterTypes() + .length != 0) + || (arrayClone.getMethodType().getReturnType() + != Type.tObject) + || !(((ComplexExpression) instr).getSubExpressions()[0] + .getType().isOfType(Type.tArray(Type.tUnknown)))) + return false; + + Expression throwExpr = + ((ThrowBlock) catchBlock.catchBlock).getInstruction(); + + if (!(throwExpr instanceof ComplexExpression) + || !(throwExpr.getOperator() instanceof ConstructorOperator)) + return false; + + ConstructorOperator throwOp = + (ConstructorOperator) throwExpr.getOperator(); + + if (!(throwOp.getClassType() + .equals(Type.tClass("java.lang.InternalError"))) + || throwOp.getMethodType().getParameterTypes().length != 1) + return false; + + Expression getMethodExpr = + ((ComplexExpression) throwExpr).getSubExpressions()[0]; + if (!(getMethodExpr instanceof ComplexExpression) + || !(getMethodExpr.getOperator() instanceof InvokeOperator)) + return false; + + InvokeOperator invoke = (InvokeOperator) getMethodExpr.getOperator(); + if (!invoke.getMethodName().equals("getMessage") + || invoke.isStatic() + || (invoke.getMethodType().getParameterTypes() + .length != 0) + || (invoke.getMethodType().getReturnType() + != Type.tString)) + return false; + + Expression exceptExpr = + ((ComplexExpression) getMethodExpr).getSubExpressions()[0]; + if (!(exceptExpr instanceof LocalLoadOperator) + || !(((LocalLoadOperator) exceptExpr).getLocalInfo() + .equals(catchBlock.exceptionLocal))) + return false; + subBlocks[0].replace(this); + if (flowBlock.lastModified == this) + flowBlock.lastModified = subBlocks[0]; + return true; + } + + public boolean doTransformations() { + return checkJikesArrayClone(); + } }