Transform inner/anonymous constructors

take care of DEBUG_CONSTRS


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@749 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent 4965eaedb1
commit 0d643c08d5
  1. 173
      jode/jode/flow/TransformConstructors.java

@ -18,9 +18,12 @@
*/ */
package jode.flow; package jode.flow;
import jode.GlobalOptions;
import jode.decompiler.Analyzer;
import jode.decompiler.ClassAnalyzer; import jode.decompiler.ClassAnalyzer;
import jode.decompiler.MethodAnalyzer; import jode.decompiler.MethodAnalyzer;
import jode.expr.*; import jode.expr.*;
import jode.bytecode.ClassInfo;
/** /**
* *
@ -28,9 +31,14 @@ import jode.expr.*;
*/ */
public class TransformConstructors { public class TransformConstructors {
public static boolean isThis(Expression thisExpr, ClassInfo clazz) {
return ((thisExpr instanceof ThisOperator)
&& (((ThisOperator)thisExpr).getClassInfo() == clazz));
}
public static void transform(ClassAnalyzer clazzAnalyzer, public static void transform(ClassAnalyzer clazzAnalyzer,
boolean isStatic, boolean isStatic, boolean isMember,
MethodAnalyzer[] cons) { boolean isAnonymous, MethodAnalyzer[] cons) {
if (cons.length == 0) if (cons.length == 0)
return; return;
@ -41,7 +49,9 @@ public class TransformConstructors {
if (header == null || !header.hasNoJumps()) if (header == null || !header.hasNoJumps())
return; return;
sb[i] = cons[i].getMethodHeader().block; sb[i] = cons[i].getMethodHeader().block;
// GlobalOptions.err.println("constr "+i+": "+sb[i]); if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("constr "+i+": "+sb[i]);
if (!isStatic) { if (!isStatic) {
InstructionBlock ib; InstructionBlock ib;
if (sb[i] instanceof InstructionBlock) if (sb[i] instanceof InstructionBlock)
@ -57,8 +67,9 @@ public class TransformConstructors {
if (!(instr instanceof ComplexExpression) if (!(instr instanceof ComplexExpression)
|| !(instr.getOperator() instanceof InvokeOperator) || !(instr.getOperator() instanceof InvokeOperator)
|| !(((ComplexExpression)instr) || !isThis(((ComplexExpression)instr)
.getSubExpressions()[0].toString().equals("this"))) .getSubExpressions()[0],
clazzAnalyzer.getClazz()))
return; return;
InvokeOperator invoke = (InvokeOperator) instr.getOperator(); InvokeOperator invoke = (InvokeOperator) instr.getOperator();
@ -69,7 +80,9 @@ public class TransformConstructors {
/* This constructor calls another constructor, so we /* This constructor calls another constructor, so we
* can skip it. * can skip it.
*/ */
// GlobalOptions.err.println("skipping this()"); if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("skipping this()");
cons[i] = cons[--constrCount]; cons[i] = cons[--constrCount];
continue; continue;
} }
@ -83,23 +96,125 @@ public class TransformConstructors {
sb[i] = sb[i].getSubBlocks()[1]; sb[i] = sb[i].getSubBlocks()[1];
else else
sb[i] = null; sb[i] = null;
// GlobalOptions.err.println("normal constructor"); if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("normal constructor");
} }
i++; i++;
} }
StructuredBlock[] start = new StructuredBlock[constrCount]; StructuredBlock[] start = new StructuredBlock[constrCount];
for (int i=0; i< constrCount; i++) for (int i=0; i< constrCount; i++)
start[i] = sb[i]; start[i] = sb[i];
if (isMember || isAnonymous) {
this_loop:
for (;;) {
StructuredBlock ib =
(sb[0] instanceof SequentialBlock)
? sb[0].getSubBlocks()[0]
: sb[0];
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("isMember: "+ib);
if (!(ib instanceof InstructionBlock))
break this_loop;
Expression instr
= ((InstructionBlock) ib).getInstruction().simplify();
if (!(instr instanceof ComplexExpression)
|| !(instr.getOperator() instanceof PutFieldOperator)
|| ((PutFieldOperator)instr.getOperator()).isStatic())
break this_loop;
PutFieldOperator pfo = (PutFieldOperator) instr.getOperator();
if (!pfo.isThis())
break this_loop;
Expression expr = ((ComplexExpression)instr)
.getSubExpressions()[isStatic ? 0 : 1];
if (isMember) {
if (!(expr instanceof ThisOperator))
break this_loop;
} else {
if (!(expr instanceof LocalLoadOperator))
break this_loop;
}
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("field "+pfo.getFieldName()
+ " = " + expr);
if (!isThis(((ComplexExpression)instr)
.getSubExpressions()[0],
clazzAnalyzer.getClazz())) {
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("not this: "+instr);
break this_loop;
}
for (int i=1; i< constrCount; i++) {
ib = (sb[i] instanceof SequentialBlock)
? sb[i].getSubBlocks()[0]
: sb[i];
if (!(ib instanceof InstructionBlock)
|| !(((InstructionBlock)ib).getInstruction().simplify()
.equals(instr))) {
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("constr "+i+" differs: "
+ib);
break this_loop;
}
}
if (!(clazzAnalyzer
.getField(pfo.getFieldName(), pfo.getFieldType())
.setSpecial(expr))) {
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("setField failed");
break this_loop;
}
for (int i=0; i< constrCount; i++) {
if (sb[i] instanceof SequentialBlock)
sb[i] = sb[i].getSubBlocks()[1];
else
sb[i] = null;
}
for (int i=0; i< constrCount; i++) {
if (sb[i] == null) {
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("constr "+i+" is over");
break this_loop;
}
}
}
}
big_loop: big_loop:
for (;;) { for (;;) {
StructuredBlock ib = StructuredBlock ib =
(sb[0] instanceof SequentialBlock) (sb[0] instanceof SequentialBlock)
? sb[0].getSubBlocks()[0] ? sb[0].getSubBlocks()[0]
: sb[0]; : sb[0];
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("fieldInit: "+ib);
if (!(ib instanceof InstructionBlock)) if (!(ib instanceof InstructionBlock))
break big_loop; break big_loop;
Expression instr = ((InstructionBlock) ib).getInstruction(); Expression instr
= ((InstructionBlock) ib).getInstruction().simplify();
if (!(instr instanceof ComplexExpression) if (!(instr instanceof ComplexExpression)
|| !(instr.getOperator() instanceof PutFieldOperator) || !(instr.getOperator() instanceof PutFieldOperator)
|| (((PutFieldOperator)instr.getOperator()).isStatic() || (((PutFieldOperator)instr.getOperator()).isStatic()
@ -112,17 +227,25 @@ public class TransformConstructors {
if (!pfo.isThis() || !expr.isConstant()) { if (!pfo.isThis() || !expr.isConstant()) {
// GlobalOptions.err.println("not constant: "+expr); if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("not constant: "+expr);
break big_loop; break big_loop;
} }
// GlobalOptions.err.println("field "+pfo.getFieldName()+ " = "+expr); if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("field "+pfo.getFieldName()+ " = "+expr);
if (!isStatic if (!isStatic) {
&& !(((ComplexExpression)instr).getSubExpressions()[0] if (!isThis(((ComplexExpression)instr)
.toString().equals("this"))) { .getSubExpressions()[0],
// GlobalOptions.err.println("not this: "+instr); clazzAnalyzer.getClazz())) {
break big_loop; if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("not this: "+instr);
break big_loop;
}
} }
for (int i=1; i< constrCount; i++) { for (int i=1; i< constrCount; i++) {
@ -130,8 +253,11 @@ public class TransformConstructors {
? sb[i].getSubBlocks()[0] ? sb[i].getSubBlocks()[0]
: sb[i]; : sb[i];
if (!(ib instanceof InstructionBlock) if (!(ib instanceof InstructionBlock)
|| !((InstructionBlock)ib).getInstruction().equals(instr)) { || !(((InstructionBlock)ib).getInstruction().simplify()
// GlobalOptions.err.println("constr "+i+" differs: "+ib); .equals(instr))) {
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("constr "+i+" differs: "+ib);
break big_loop; break big_loop;
} }
} }
@ -140,7 +266,9 @@ public class TransformConstructors {
if (!(clazzAnalyzer if (!(clazzAnalyzer
.getField(pfo.getFieldName(), pfo.getFieldType()) .getField(pfo.getFieldName(), pfo.getFieldType())
.setInitializer(expr))) { .setInitializer(expr))) {
// GlobalOptions.err.println("setField failed"); if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("setField failed");
break big_loop; break big_loop;
} }
@ -153,17 +281,22 @@ public class TransformConstructors {
} }
for (int i=0; i< constrCount; i++) for (int i=0; i< constrCount; i++)
if (sb[i] == null) { if (sb[i] == null) {
// GlobalOptions.err.println("constr "+i+" is over"); if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("constr "+i+" is over");
break big_loop; break big_loop;
} }
} }
for (int i=0; i< constrCount; i++) { for (int i=0; i< constrCount; i++) {
if (start[i] == null) if (start[i] == null)
continue; continue;
if (sb[i] == null) if (sb[i] == null)
start[i].removeBlock(); start[i].removeBlock();
else else {
sb[i].replace(start[i]); sb[i].replace(start[i]);
sb[i].simplify();
}
} }
} }
} }

Loading…
Cancel
Save