git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@224 379699f6-c40d-0410-875b-85095c16579estable
parent
af4d434563
commit
a0cf5d2b52
@ -0,0 +1,65 @@ |
||||
/* |
||||
* CheckNullOperator (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.Type; |
||||
|
||||
/** |
||||
* This is a pseudo operator, which represents the check against null |
||||
* that jikes and javac generates for inner classes: |
||||
* |
||||
* <pre> |
||||
* outer.new Inner() |
||||
* </pre> |
||||
* is translated by javac to |
||||
* <pre> |
||||
* new Outer$Inner(outer ((void) DUP.getClass())); |
||||
* </pre> |
||||
* and by jikes to |
||||
* <pre> |
||||
* new Outer$Inner(outer (DUP == null ? throw null)); |
||||
* </pre> |
||||
*/ |
||||
|
||||
public class CheckNullOperator extends SimpleOperator { |
||||
|
||||
public CheckNullOperator(Type type) { |
||||
super(type, 0, 1); |
||||
operandTypes[0] = type; |
||||
} |
||||
|
||||
public int getPriority() { |
||||
return 200; |
||||
} |
||||
|
||||
public int getOperandPriority(int i) { |
||||
return 0; |
||||
} |
||||
|
||||
public String toString(String[] operands) { |
||||
/* There is no way to produce exactly the same code. |
||||
* This is a good approximation. |
||||
* op.getClass will throw a null pointer exception if operands[0] |
||||
* is null, otherwise return something not equal to null. |
||||
* The bad thing is that this isn't atomar. |
||||
*/ |
||||
return "/*CHECK NULL*/ " + |
||||
operands[0] + ".getClass() != null ? " + operands[0] + " : null"; |
||||
} |
||||
} |
@ -0,0 +1,105 @@ |
||||
/* |
||||
* CreateCheckNull (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.flow; |
||||
import jode.decompiler.*; |
||||
import jode.Type; |
||||
|
||||
public class CreateCheckNull { |
||||
|
||||
/* Situation: |
||||
* |
||||
* javac: |
||||
* DUP |
||||
* stack_0.getClass(); |
||||
* |
||||
* jikes: |
||||
* DUP |
||||
* if (!stack_0 != null) |
||||
* throw null; |
||||
*/ |
||||
|
||||
public static boolean transformJavac(InstructionContainer ic, |
||||
StructuredBlock last) { |
||||
if (!(last.outer instanceof SequentialBlock) |
||||
|| !(ic.getInstruction() instanceof ComplexExpression) |
||||
|| !(last.outer.getSubBlocks()[0] instanceof SpecialBlock)) |
||||
return false; |
||||
|
||||
SpecialBlock dup = (SpecialBlock) last.outer.getSubBlocks()[0]; |
||||
if (dup.type != SpecialBlock.DUP |
||||
|| dup.count != 1 || dup.depth != 0) |
||||
return false; |
||||
|
||||
ComplexExpression ce = (ComplexExpression) ic.getInstruction(); |
||||
|
||||
if (!(ce.getOperator() instanceof PopOperator) |
||||
|| !(ce.getSubExpressions()[0] instanceof InvokeOperator)) |
||||
return false; |
||||
|
||||
InvokeOperator getClassCall |
||||
= (InvokeOperator) ce.getSubExpressions()[0]; |
||||
if (!getClassCall.getMethodName().equals("getClass") |
||||
|| !(getClassCall.getMethodType().toString() |
||||
.equals("()Ljava/lang/Class;"))) |
||||
return false; |
||||
|
||||
ic.setInstruction(new CheckNullOperator(Type.tUObject)); |
||||
last.replace(last.outer); |
||||
return true; |
||||
} |
||||
|
||||
public static boolean transformJikes(IfThenElseBlock ifBlock, |
||||
StructuredBlock last) { |
||||
if (!(last.outer instanceof SequentialBlock) |
||||
|| !(last.outer.getSubBlocks()[0] instanceof SpecialBlock) |
||||
|| ifBlock.elseBlock != null |
||||
|| !(ifBlock.thenBlock instanceof ThrowBlock)) |
||||
return false; |
||||
System.err.println("last.outer: "+last.outer); |
||||
|
||||
SpecialBlock dup = (SpecialBlock) last.outer.getSubBlocks()[0]; |
||||
if (dup.type != SpecialBlock.DUP |
||||
|| dup.count != 1 || dup.depth != 0) |
||||
return false; |
||||
|
||||
System.err.println("tick1"); |
||||
/* negate the instruction back to its original state */ |
||||
Expression expr = ifBlock.cond.negate(); |
||||
System.err.println(expr); |
||||
if (!(expr instanceof CompareUnaryOperator) |
||||
|| expr.getOperator().getOperatorIndex() != Operator.NOTEQUALS_OP |
||||
|| !(expr.getOperator().getOperandType(0).isOfType(Type.tUObject))) |
||||
return false; |
||||
|
||||
System.err.println("tick2"); |
||||
InstructionContainer ic = |
||||
new InstructionBlock(new CheckNullOperator(Type.tUObject)); |
||||
ifBlock.flowBlock.removeSuccessor(ifBlock.thenBlock.jump); |
||||
ic.moveJump(ifBlock.jump); |
||||
if (last == ifBlock) { |
||||
ic.replace(last.outer); |
||||
last = ic; |
||||
} else { |
||||
ic.replace(ifBlock); |
||||
last.replace(last.outer); |
||||
} |
||||
return true; |
||||
} |
||||
} |
@ -0,0 +1,14 @@ |
||||
package jode.test; |
||||
|
||||
public class ClassOpTest { |
||||
static void test1() { |
||||
Class c1 = ClassOpTest.class; |
||||
Class c2 = Object.class; |
||||
Class c3 = ClassOpTest.class; |
||||
} |
||||
|
||||
void test2() { |
||||
Class c2 = Object.class; |
||||
Class c3 = ClassOpTest.class; |
||||
} |
||||
} |
Loading…
Reference in new issue