hint types implemented

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@902 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 25 years ago
parent 0a34c2eaaa
commit 12f0205840
  1. 143
      jode/jode/type/IntegerType.java

@ -28,87 +28,106 @@ import jode.GlobalOptions;
* ints whose value is in byte resp. short range. They may be * ints whose value is in byte resp. short range. They may be
* converted to B resp. S, but sometimes need an explicit cast. * converted to B resp. S, but sometimes need an explicit cast.
* *
* @author Jochen Hoenicke */ * @author Jochen Hoenicke
*/
public class IntegerType extends Type { public class IntegerType extends Type {
public static final int IT_I = 0x01; /* Order does matter:
public static final int IT_C = 0x02; * First type that is possible (and hinted) will be taken.
public static final int IT_S = 0x04; */
public static final int IT_B = 0x08; public static final int IT_Z = 0x01;
public static final int IT_Z = 0x10; public static final int IT_I = 0x02;
public static final int IT_C = 0x04;
public static final int IT_S = 0x08;
public static final int IT_B = 0x10;
public static final int IT_cS = 0x20; public static final int IT_cS = 0x20;
public static final int IT_cB = 0x40; public static final int IT_cB = 0x40;
private static final int NUM_TYPES = 7; private static final int NUM_TYPES = 7;
private static final int[] subTypes = { private static final int[] subTypes = {
/*Z*/ IT_Z,
/*I*/ IT_I|IT_C|IT_S|IT_B/*|IT_cS|IT_cB*/, /*C*/ IT_C, /*I*/ IT_I|IT_C|IT_S|IT_B/*|IT_cS|IT_cB*/, /*C*/ IT_C,
/*S*/ IT_S|IT_B/*|IT_cS|IT_cB*/, /*B*/ IT_B/*|IT_cB*/, /*S*/ IT_S|IT_B/*|IT_cS|IT_cB*/, /*B*/ IT_B/*|IT_cB*/,
/*Z*/ IT_Z,
/*cS*/IT_cS|IT_cB, /*cB*/IT_cB /*cS*/IT_cS|IT_cB, /*cB*/IT_cB
}; };
private static final int[] superTypes = { private static final int[] superTypes = {
/*Z*/ IT_Z,
/*I*/ IT_I, /*C*/ IT_I|IT_C, /*I*/ IT_I, /*C*/ IT_I|IT_C,
/*S*/ IT_I|IT_S, /*B*/ IT_I|IT_S|IT_B, /*S*/ IT_I|IT_S, /*B*/ IT_I|IT_S|IT_B,
/*Z*/ IT_Z,
/*cS*/IT_I|IT_C|IT_S|IT_cS, /*cB*/IT_I|IT_C|IT_S|IT_B|IT_cS|IT_cB /*cS*/IT_I|IT_C|IT_S|IT_cS, /*cB*/IT_I|IT_C|IT_S|IT_B|IT_cS|IT_cB
}; };
private static final Type[] simpleTypes = { private static final Type[] simpleTypes = {
new IntegerType(IT_Z),
new IntegerType(IT_I), new IntegerType(IT_C), new IntegerType(IT_I), new IntegerType(IT_C),
new IntegerType(IT_S), new IntegerType(IT_B), new IntegerType(IT_S), new IntegerType(IT_B),
new IntegerType(IT_Z),
new IntegerType(IT_cS), new IntegerType(IT_cB) new IntegerType(IT_cS), new IntegerType(IT_cB)
}; };
private static final String[] typeNames = { private static final String[] typeNames = {
"I","C","S","B","Z","cS","cB" "Z","I","C","S","B","s","b"
}; };
int possTypes; int possTypes;
int strongHint = 0; int hintTypes;
int weakHint = 0;
/** /**
* Create a new type with the given type. * Create a new type with the given type.
*/ */
public IntegerType(int types) { public IntegerType(int types) {
this(types, types);
}
public IntegerType(int types, int hints) {
super(TC_INTEGER); super(TC_INTEGER);
possTypes = types; possTypes = types;
hintTypes = hints;
} }
public Type getHint() { public Type getHint() {
int hint = ((possTypes & IT_Z) != 0 ? IT_Z int hint = possTypes & hintTypes;
: strongHint != 0 ? strongHint if (hint == 0)
: weakHint != 0 ? weakHint hint = possTypes;
: possTypes);
int i = 0; int i = 0;
for (int it = 0x1; (it & hint) == 0; it <<= 1) while ((hint & 1) == 0) {
hint >>= 1;
i++; i++;
}
return simpleTypes[i]; return simpleTypes[i];
} }
private int getSubTypes() { public Type getCanonic() {
int types = possTypes;
int i = 0;
while ((types >>= 1) != 0) {
i++;
}
return simpleTypes[i];
}
private static int getSubTypes(int types) {
int result = 0; int result = 0;
for (int i=0; i < NUM_TYPES; i++) { for (int i=0; i < NUM_TYPES; i++) {
if (((1<<i) & possTypes) != 0) if (((1<<i) & types) != 0)
result |= subTypes[i]; result |= subTypes[i];
} }
return result; return result;
} }
private int getSuperTypes() { private static int getSuperTypes(int types) {
int result = 0; int result = 0;
for (int i=0; i < NUM_TYPES; i++) { for (int i=0; i < NUM_TYPES; i++) {
if (((1<<i) & possTypes) != 0) if (((1<<i) & types) != 0)
result |= superTypes[i]; result |= superTypes[i];
} }
return result; return result;
} }
public Type getSubType() { public Type getSubType() {
return new IntegerType(getSubTypes()); return new IntegerType(getSubTypes(possTypes),
getSubTypes(hintTypes));
} }
public Type getSuperType() { public Type getSuperType() {
return new IntegerType(getSuperTypes()); /* Don't upgrade hints */
return new IntegerType(getSuperTypes(possTypes), hintTypes);
} }
/** /**
@ -181,28 +200,34 @@ public class IntegerType extends Type {
} }
public String toString() { public String toString() {
switch (possTypes) { if (possTypes == hintTypes) {
case IT_Z: switch (possTypes) {
return "boolean"; case IT_Z:
case IT_C: return "boolean";
return "char"; case IT_C:
case IT_B: return "char";
return "byte"; case IT_B:
case IT_S: return "byte";
return "short"; case IT_S:
case IT_I: return "short";
return "int"; case IT_I:
default: return "int";
StringBuffer sb = new StringBuffer("{"); }
String comma = ""; }
for (int i=0; i< NUM_TYPES; i++) StringBuffer sb = new StringBuffer("{");
if (((1<<i) & possTypes) != 0) { for (int i=0; i< NUM_TYPES; i++) {
sb.append(comma).append(typeNames[i]); if (((1<<i) & possTypes) != 0)
comma = ","; sb.append(typeNames[i]);
} }
sb.append("}"); if (possTypes != hintTypes) {
return sb.toString(); sb.append(":");
} for (int i=0; i< NUM_TYPES; i++) {
if (((1<<i) & hintTypes) != 0)
sb.append(typeNames[i]);
}
}
sb.append("}");
return sb.toString();
} }
/** /**
@ -217,21 +242,26 @@ public class IntegerType extends Type {
return this; return this;
int mergeTypes; int mergeTypes;
int mergeHints = 0;
if (type.typecode != TC_INTEGER) if (type.typecode != TC_INTEGER)
mergeTypes = 0; mergeTypes = 0;
else { else {
IntegerType other = (IntegerType) type; IntegerType other = (IntegerType) type;
mergeTypes = possTypes & other.possTypes; mergeTypes = possTypes & other.possTypes;
/* HINTING XXX */ mergeHints = hintTypes & other.hintTypes;
if (mergeTypes == possTypes)
if (mergeTypes == possTypes
&& mergeHints == hintTypes)
return this; return this;
if (mergeTypes == other.possTypes) if (mergeTypes == other.possTypes
&& mergeHints == other.hintTypes)
return other; return other;
} }
Type result = mergeTypes == 0 ? tError : new IntegerType(mergeTypes); Type result = mergeTypes == 0
? tError : new IntegerType(mergeTypes, mergeHints);
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_TYPES) != 0) { if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_TYPES) != 0) {
GlobalOptions.err.println("intersecting "+ this +" and "+ type + GlobalOptions.err.println("intersecting "+ this +" and "+ type +
" to " + result); " to " + result);
} }
return result; return result;
} }
@ -239,8 +269,11 @@ public class IntegerType extends Type {
public boolean equals(Object o) { public boolean equals(Object o) {
if (o == this) if (o == this)
return true; return true;
if (o instanceof IntegerType) if (o instanceof IntegerType) {
return ((IntegerType)o).possTypes == possTypes; IntegerType other = (IntegerType)o;
return other.possTypes == possTypes
&& other.hintTypes == hintTypes;
}
return false; return false;
} }
} }

Loading…
Cancel
Save