git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@215 379699f6-c40d-0410-875b-85095c16579estable
parent
0ec051c685
commit
d267a860d3
@ -0,0 +1,200 @@ |
|||||||
|
package jode.test; |
||||||
|
|
||||||
|
public abstract class Flow { |
||||||
|
int g; |
||||||
|
int[] ain; |
||||||
|
|
||||||
|
void skip() { |
||||||
|
for (int i=0; i<3; i++) { |
||||||
|
if (g > 5) { |
||||||
|
for (int j=0; j<5; j++) { |
||||||
|
g++; |
||||||
|
} |
||||||
|
} |
||||||
|
i--; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* This tests the while in a switch problem. |
||||||
|
*/ |
||||||
|
public void switchWhileTest() { |
||||||
|
int dir = g; |
||||||
|
int x = 0; |
||||||
|
int y = 0; |
||||||
|
boolean done = false; |
||||||
|
g = 5; |
||||||
|
switch (dir) { |
||||||
|
case 1: |
||||||
|
while (!done) { |
||||||
|
done = true; |
||||||
|
if (g > 7) |
||||||
|
g = g - 4; |
||||||
|
x = g; |
||||||
|
y = g; |
||||||
|
if (x > 7) |
||||||
|
x = x - 4; |
||||||
|
for (int i=0; i<4; i++) { |
||||||
|
for (int j=0; j<5; j++) { |
||||||
|
if (ain[j] == x + i && ain[j] == y) |
||||||
|
done = false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
for (int i=0; i<5; i++) { |
||||||
|
ain[g] = x + i; |
||||||
|
ain[g] = y; |
||||||
|
g += 1; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 2: |
||||||
|
while (!done) { |
||||||
|
done = true; |
||||||
|
x = g; |
||||||
|
y = g; |
||||||
|
if (y > 7) |
||||||
|
y = y - 4; |
||||||
|
for (int i=0; i<4; i++) { |
||||||
|
for (int j=0; j<4; j++) { |
||||||
|
if (ain[j] == x && ain[j] == y + i) |
||||||
|
done = false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
for (int i = 0; i<4; i++) { |
||||||
|
ain[g] = x; |
||||||
|
ain[g] = y + i; |
||||||
|
g += 1; |
||||||
|
} |
||||||
|
break; |
||||||
|
case 3: // Same code as case 2 slightly optimized
|
||||||
|
big: |
||||||
|
for (;;) { |
||||||
|
x = g; |
||||||
|
y = g; |
||||||
|
if (y > 7) |
||||||
|
y = y - 4; |
||||||
|
for (int i=0; i<4; i++) { |
||||||
|
for (int j=0; j<4; j++) { |
||||||
|
if (ain[j] == x && ain[j] == y + i) |
||||||
|
continue big; |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
for (int i = 0; i<4; i++) { |
||||||
|
ain[g] = x; |
||||||
|
ain[g] = y + i; |
||||||
|
g += 1; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This was an example where our flow analysis didn't find an |
||||||
|
* elegant solution. The reason is, that we try to make |
||||||
|
* while(true)-loops as small as possible (you can't see the real |
||||||
|
* end of the loop, if it is breaked there like here). |
||||||
|
* |
||||||
|
* Look at the assembler code and you know why my Decompiler had |
||||||
|
* problems with this. But the decompiler did produce compilable |
||||||
|
* code which produces the same assembler code. |
||||||
|
* |
||||||
|
* The solution was, to make switches as big as possible, the whole |
||||||
|
* analyze methods were overworked. |
||||||
|
*/ |
||||||
|
void WhileTrueSwitch() { |
||||||
|
int i = 1; |
||||||
|
while (true) { |
||||||
|
switch (i) { |
||||||
|
case 0: |
||||||
|
return; |
||||||
|
case 1: |
||||||
|
i = 5; |
||||||
|
continue; |
||||||
|
case 2: |
||||||
|
i = 6; |
||||||
|
continue; |
||||||
|
case 3: |
||||||
|
throw new RuntimeException(); |
||||||
|
default: |
||||||
|
i = 7; |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
abstract int test(); |
||||||
|
|
||||||
|
/** |
||||||
|
* This tests shorts and empty ifs. Especially the no op ifs can |
||||||
|
* be optimized to very unusual code. |
||||||
|
*/ |
||||||
|
public void shortIf() { |
||||||
|
while(g != 7) { |
||||||
|
if (g == 5) |
||||||
|
return; |
||||||
|
else if (g != 4) |
||||||
|
break; |
||||||
|
else if (g == 2) |
||||||
|
shortIf(); |
||||||
|
else |
||||||
|
return; |
||||||
|
|
||||||
|
if (g!= 7) |
||||||
|
shortIf(); |
||||||
|
else { |
||||||
|
shortIf(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (g != 1) |
||||||
|
break; |
||||||
|
else if (g == 3) |
||||||
|
shortIf(); |
||||||
|
else |
||||||
|
break; |
||||||
|
|
||||||
|
// javac optimizes this instruction to
|
||||||
|
// test();
|
||||||
|
// jikes reproduces this statement as one would expect
|
||||||
|
if (g + 5 == test()) { |
||||||
|
} |
||||||
|
|
||||||
|
// javac -O optimizes this to the following weired statements
|
||||||
|
// PUSH g;
|
||||||
|
// PUSH test();
|
||||||
|
// POP2;
|
||||||
|
// This cannot be decompiled correctly, since the == is lost.
|
||||||
|
if (g == test()) |
||||||
|
continue; |
||||||
|
} |
||||||
|
while(g == 3) { |
||||||
|
// javac:
|
||||||
|
// PUSH test() == 4 || test() == 3 && test() == 2;
|
||||||
|
// POP;
|
||||||
|
if (test() == 4 || test() == 3 && test() == 2); |
||||||
|
// javac -O:
|
||||||
|
// if (test() != 4 && test() == 3) {
|
||||||
|
// PUSH test()+test() - test();
|
||||||
|
// PUSH g-4;
|
||||||
|
// POP2;
|
||||||
|
// }
|
||||||
|
if (test() == 4 || test() == 3 && test() == 2) |
||||||
|
continue; |
||||||
|
} |
||||||
|
while (g==2) { |
||||||
|
// javac:
|
||||||
|
// test();
|
||||||
|
// test();
|
||||||
|
// test();
|
||||||
|
if ((long) (test() + test() - test()) == (long)(g-4)); |
||||||
|
// javac -O:
|
||||||
|
// PUSH (long)(test() + test() - test()) <=> (long)(g-4)
|
||||||
|
// POP;
|
||||||
|
if ((long) (test() + test() - test()) == (long)(g-4)) |
||||||
|
continue; |
||||||
|
} |
||||||
|
System.err.println("Hallo"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,145 @@ |
|||||||
|
package jode.test; |
||||||
|
|
||||||
|
class A { |
||||||
|
} |
||||||
|
|
||||||
|
interface I1 { |
||||||
|
} |
||||||
|
|
||||||
|
interface I2 { |
||||||
|
} |
||||||
|
|
||||||
|
interface I12 extends I1, I2 { |
||||||
|
} |
||||||
|
|
||||||
|
class B extends A implements I1 { |
||||||
|
} |
||||||
|
|
||||||
|
class C extends B implements I2, I12 { |
||||||
|
} |
||||||
|
|
||||||
|
class D extends A implements I12 { |
||||||
|
} |
||||||
|
|
||||||
|
class E extends A implements I2 { |
||||||
|
} |
||||||
|
|
||||||
|
public class LocalTypes { |
||||||
|
A a; |
||||||
|
B b; |
||||||
|
C c; |
||||||
|
D d; |
||||||
|
E e; |
||||||
|
|
||||||
|
I1 i1; |
||||||
|
I2 i2; |
||||||
|
I12 i12; |
||||||
|
|
||||||
|
boolean g_bo; |
||||||
|
byte g_by; |
||||||
|
short g_sh; |
||||||
|
int g_in; |
||||||
|
|
||||||
|
int z; |
||||||
|
int[]ain; |
||||||
|
|
||||||
|
public void arithTest() { |
||||||
|
int a=1,b=2; |
||||||
|
boolean x = true,y = false; |
||||||
|
int c=0; |
||||||
|
arithTest(); |
||||||
|
if (x & y) { |
||||||
|
c = 5; |
||||||
|
arithTest(); |
||||||
|
x &= y; |
||||||
|
arithTest(); |
||||||
|
x = x | y; |
||||||
|
arithTest(); |
||||||
|
x ^= y; |
||||||
|
arithTest(); |
||||||
|
x = x && y; |
||||||
|
arithTest(); |
||||||
|
b <<= a; |
||||||
|
b <<= c; |
||||||
|
} |
||||||
|
a&=b; |
||||||
|
} |
||||||
|
|
||||||
|
public void intTypeTest() { |
||||||
|
boolean b = false; |
||||||
|
boolean abo[] = null; |
||||||
|
byte aby[] = null; |
||||||
|
byte by; |
||||||
|
int in; |
||||||
|
short sh; |
||||||
|
b = g_bo; |
||||||
|
in = g_sh; |
||||||
|
sh = (short)g_in; |
||||||
|
by = (byte)sh; |
||||||
|
sh = by; |
||||||
|
in = by; |
||||||
|
abo[0] = g_bo; |
||||||
|
abo[1] = false; |
||||||
|
abo[2] = true; |
||||||
|
aby[0] = g_by; |
||||||
|
aby[1] = 0; |
||||||
|
aby[2] = 1; |
||||||
|
} |
||||||
|
|
||||||
|
native void arrFunc(B[] b); |
||||||
|
|
||||||
|
/** |
||||||
|
* This is an example where it is really hard to know, which type |
||||||
|
* each local has. |
||||||
|
*/ |
||||||
|
void DifficultType () { |
||||||
|
B myB = c; |
||||||
|
C myC = c; |
||||||
|
I2 myI2 = c; |
||||||
|
I12 myI12 = c; |
||||||
|
boolean bool = true; |
||||||
|
B[] aB = new C[3]; |
||||||
|
arrFunc(new C[3]); |
||||||
|
|
||||||
|
while (bool) { |
||||||
|
if (bool) { |
||||||
|
i1 = myB; |
||||||
|
i2 = myC; |
||||||
|
i1 = aB[0]; |
||||||
|
} else if (bool) { |
||||||
|
i1 = myI12; |
||||||
|
i2 = myI2; |
||||||
|
} else { |
||||||
|
i1 = myC; |
||||||
|
i2 = myI12; |
||||||
|
} |
||||||
|
myB = b; |
||||||
|
if (bool) |
||||||
|
myI2 = i12; |
||||||
|
else { |
||||||
|
myI12 = d; |
||||||
|
myI2 = e; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This is an example where it is really hard to know, which type |
||||||
|
* each local has. |
||||||
|
*/ |
||||||
|
void DifficultArrayType () { |
||||||
|
boolean bool = true; |
||||||
|
B[] aB = new C[3]; |
||||||
|
arrFunc(new C[3]); |
||||||
|
C[][][][][] x = new C[4][3][4][][]; |
||||||
|
int[][][][][] y = new int[1][2][][][]; |
||||||
|
|
||||||
|
while (bool) { |
||||||
|
if (bool) { |
||||||
|
i1 = aB[0]; |
||||||
|
aB[0] = b; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
Loading…
Reference in new issue