00001 package gov.nasa.arc.ase.jpf.jvm; 00002 00003 import de.fub.bytecode.Constants; 00004 import gov.nasa.arc.ase.jpf.InternalErrorException; 00005 00006 public class Types implements Constants { 00007 public static int booleanToInt(boolean b) { return b ? 1 : 0; } 00008 public static long doubleToLong(double d) { return Double.doubleToLongBits(d); } 00009 public static int floatToInt(float f) { return Float.floatToIntBits(f); } 00010 public static int getArgumentsSize(String signature) { 00011 String[] args = getArgumentsTypes(signature); 00012 00013 int length = args.length; 00014 int size = 0; 00015 00016 for(int i = 0; i < length; i++) 00017 size += getTypeSize(args[i]); 00018 00019 return size; 00020 } 00021 public static String[] getArgumentsTypes(String signature) { 00022 if(signature.charAt(0) != '(') 00023 throw new InternalErrorException("not a method signature"); 00024 00025 int idx = 1; 00026 int size = 0; 00027 00028 while(signature.charAt(idx) != ')') { 00029 idx += getTypeLength(signature, idx); 00030 size++; 00031 } 00032 00033 String[] args = new String[size]; 00034 00035 int i = 0; 00036 idx = 1; 00037 while(signature.charAt(idx) != ')') { 00038 int end = idx + getTypeLength(signature, idx); 00039 args[i++] = signature.substring(idx, end); 00040 idx = end; 00041 } 00042 00043 return args; 00044 } 00045 public static String getArrayElementType(String type) { 00046 if(type.charAt(0) != '[') 00047 throw new InternalErrorException("not an array type"); 00048 00049 return type.substring(1); 00050 } 00051 public static int getBaseType(String type) { 00052 switch(type.charAt(0)) { 00053 case 'B': return T_BYTE; 00054 case 'C': return T_CHAR; 00055 case 'D': return T_DOUBLE; 00056 case 'F': return T_FLOAT; 00057 case 'I': return T_INT; 00058 case 'J': return T_LONG; 00059 case 'L': return T_REFERENCE; 00060 case 'S': return T_SHORT; 00061 case 'V': return T_VOID; 00062 case 'Z': return T_BOOLEAN; 00063 case '[': return T_ARRAY; 00064 } 00065 00066 throw new InternalErrorException("invalid type string: " + type); 00067 } 00068 private static int getTypeLength(String signature, int idx) { 00069 switch(signature.charAt(idx)) { 00070 case 'B': 00071 case 'C': 00072 case 'D': 00073 case 'F': 00074 case 'I': 00075 case 'J': 00076 case 'S': 00077 case 'V': 00078 case 'Z': 00079 return 1; 00080 00081 case '[': 00082 return 1 + getTypeLength(signature, idx+1); 00083 00084 case 'L': 00085 int semicolon = signature.indexOf(';', idx); 00086 00087 if(semicolon == -1) 00088 throw new InternalErrorException("invalid type signature: " + signature); 00089 00090 return semicolon - idx + 1; 00091 } 00092 00093 throw new InternalErrorException("invalid type signature"); 00094 } 00095 public static String getTypeName(String type) { 00096 switch(type.charAt(0)) { 00097 case 'B': return "byte"; 00098 case 'C': return "char"; 00099 case 'D': return "double"; 00100 case 'F': return "float"; 00101 case 'I': return "int"; 00102 case 'J': return "long"; 00103 case 'L': return type.substring(1, type.indexOf(';')).replace('/', '.'); 00104 case 'S': return "short"; 00105 case 'V': return "void"; 00106 case 'Z': return "boolean"; 00107 case '[': return getTypeName(type.substring(1)) + "[]"; 00108 } 00109 00110 throw new InternalErrorException("invalid type string: " + type); 00111 } 00112 public static int getTypeSize(String type) { 00113 switch(type.charAt(0)) { 00114 case 'V': return 0; 00115 00116 case 'B': 00117 case 'C': 00118 case 'F': 00119 case 'I': 00120 case 'L': 00121 case 'S': 00122 case 'Z': 00123 case '[': return 1; 00124 00125 case 'D': 00126 case 'J': return 2; 00127 } 00128 00129 throw new InternalErrorException("invalid type string: " + type); 00130 } 00131 public static int hiDouble(double d) { return hiLong(Double.doubleToLongBits(d)); } 00132 public static int hiLong(long l) { return (int)(l >> 32); } 00133 public static boolean instanceOf(String type, String ofType) { 00134 int bType = getBaseType(type); 00135 00136 if(bType == T_ARRAY && ofType.equals("Ljava/lang/Object;")) 00137 return true; 00138 00139 int bOfType = getBaseType(ofType); 00140 00141 if(bType != bOfType) return false; 00142 00143 switch(bType) { 00144 case T_ARRAY: 00145 return instanceOf(type.substring(1), ofType.substring(1)); 00146 00147 case T_REFERENCE: 00148 return ClassInfo.getClassInfo(getTypeName(type)).instanceOf( 00149 getTypeName(ofType)); 00150 00151 default: 00152 return true; 00153 } 00154 } 00155 public static double intsToDouble(int l, int h) { return longToDouble(intsToLong(l, h)); } 00156 public static long intsToLong(int l, int h) { return (((long)h) << 32) | ((long)l & 0xFFFFFFFFL); } 00157 public static boolean intToBoolean(int i) { return i != 0; } 00158 public static float intToFloat(int i) { return Float.intBitsToFloat(i); } 00159 public static boolean isReference(String type) { 00160 int t = getBaseType(type); 00161 00162 return t == T_ARRAY || t == T_REFERENCE; 00163 } 00164 public static int loDouble(double d) { return loLong(Double.doubleToLongBits(d)); } 00165 public static int loLong(long l) { return (int)(l & 0xFFFFFFFFL); } 00166 public static double longToDouble(long l) { return Double.longBitsToDouble(l); } 00167 }