Initial revision

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@215 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent 0ec051c685
commit d267a860d3
  1. 200
      jode/test/Flow.java
  2. 145
      jode/test/LocalTypes.java

@ -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…
Cancel
Save