1 package gnu.bytecode; 2 3 public class PrimType extends Type { 4 5 public PrimType (String nam, String sig, int siz, Class reflectClass) { 6 super(nam, sig); 7 size = siz; 8 this.reflectClass = reflectClass; 9 Type.registerTypeForClass(reflectClass, this); 10 } 11 12 protected PrimType(PrimType type) 13 { 14 super(type.this_name, type.signature); 15 size = type.size; 16 reflectClass = type.reflectClass; 17 } 18 19 public Object coerceFromObject (Object obj) 20 { 21 if (obj.getClass() == reflectClass) 22 return obj; 23 char sig1 = (signature == null || signature.length() != 1) ? ' ' 24 : signature.charAt(0); 25 switch (sig1) 26 { 27 case 'B': return new Byte (((Number ) obj).byteValue()); 28 case 'S': return new Short (((Number ) obj).shortValue()); 29 case 'I': return new Integer (((Number ) obj).intValue()); 30 case 'J': return new Long (((Number ) obj).longValue()); 31 case 'F': return new Float (((Number ) obj).floatValue()); 32 case 'D': return new Double (((Number ) obj).doubleValue()); 33 } 34 throw new ClassCastException ("don't know how to coerce " 35 + obj.getClass().getName() + " to " 36 + getName()); 37 } 38 39 41 public char charValue (Object value) 42 { 43 return ((Character ) value).charValue(); 44 } 45 46 48 public static boolean booleanValue (Object value) 49 { 50 return ! (value instanceof Boolean ) || ((Boolean ) value).booleanValue(); 51 } 52 53 public void emitCoerceToObject (CodeAttr code) 54 { 55 char sig1 = getSignature().charAt(0); 56 ClassType clas; 57 Method method; 58 String cname; 59 Type[] args; 60 switch (sig1) 61 { 62 case 'Z': 63 clas = ClassType.make("java.lang.Boolean"); 64 code.emitIfIntNotZero(); 65 code.emitGetStatic(clas.getDeclaredField("TRUE")); 66 code.emitElse(); 67 code.emitGetStatic(clas.getDeclaredField("FALSE")); 68 code.emitFi(); 69 return; 70 case 'C': cname = "java.lang.Character"; break; 71 case 'B': cname = "java.lang.Byte"; break; 72 case 'S': cname = "java.lang.Short"; break; 73 case 'I': cname = "java.lang.Integer"; break; 74 case 'J': cname = "java.lang.Long"; break; 75 case 'F': cname = "java.lang.Float"; break; 76 case 'D': cname = "java.lang.Double"; break; 77 default: cname = null; } 79 clas = ClassType.make(cname); 80 args = new Type[1]; 81 args[0] = this; 82 method = clas.getDeclaredMethod("<init>", args); 83 code.emitNew(clas); 84 code.emitDupX(); 85 code.emitSwap(); 86 code.emitInvokeSpecial(method); 87 } 88 89 public void emitIsInstance (CodeAttr code) 90 { 91 char sig1 = (signature == null || signature.length() != 1) ? ' ' 92 : signature.charAt(0); 93 if (sig1 == 'Z') boolean_ctype.emitIsInstance(code); 95 else if (sig1 == 'V') 96 { 97 code.emitPop(1); 98 code.emitPushInt(1); 99 } 100 else 102 number_type.emitIsInstance(code); 103 } 104 105 public void emitCoerceFromObject (CodeAttr code) 106 { 107 char sig1 = (signature == null || signature.length() != 1) ? ' ' 108 : signature.charAt(0); 109 if (sig1 == 'Z') { 111 code.emitCheckcast(boolean_ctype); 112 code.emitInvokeVirtual(booleanValue_method); 113 } 114 else if (sig1 == 'V') 115 code.emitPop(1); 116 else 117 { 118 code.emitCheckcast(number_type); 119 if (sig1 == 'I' || sig1 == 'S' || sig1 == 'B') 120 code.emitInvokeVirtual(intValue_method); 121 else if (sig1 == 'J') 122 code.emitInvokeVirtual(longValue_method); 123 else if (sig1 == 'D') 124 code.emitInvokeVirtual(doubleValue_method); 125 else if (sig1 == 'F') 126 code.emitInvokeVirtual(floatValue_method); 127 else 129 super.emitCoerceFromObject(code); 130 } 131 } 132 133 public static int compare(PrimType type1, PrimType type2) 134 { 135 char sig1 = type1.signature.charAt(0); 136 char sig2 = type2.signature.charAt(0); 137 138 if (sig1 == sig2) 139 return 0; 140 141 if (sig1 == 'V') 143 return 1; 144 if (sig2 == 'V') 145 return -1; 146 147 if (sig1 == 'Z' || sig2 == 'Z') 151 return -3; 152 153 if (sig1 == 'C') 154 return type2.size > 2 ? -1 : -3; 155 if (sig2 == 'C') 156 return type1.size > 2 ? 1 : -3; 157 158 if (sig1 == 'D') 159 return 1; 160 if (sig2 == 'D') 161 return -1; 162 if (sig1 == 'F') 163 return 1; 164 if (sig2 == 'F') 165 return -1; 166 if (sig1 == 'J') 167 return 1; 168 if (sig2 == 'J') 169 return -1; 170 if (sig1 == 'I') 171 return 1; 172 if (sig2 == 'I') 173 return -1; 174 if (sig1 == 'S') 175 return 1; 176 if (sig2 == 'S') 177 return -1; 178 return -3; 180 } 181 182 public int compare(Type other) 183 { 184 if (other instanceof PrimType) 185 return compare(this, (PrimType) other); 186 if (! (other instanceof ClassType)) 187 return -3; 188 char sig1 = signature.charAt(0); 189 String otherName = other.getName(); 190 if (otherName == null) 191 return -1; 192 switch (sig1) 193 { 194 case 'V': 195 return 1; 196 case 'Z': 197 case 'C': 198 break; 199 case 'D': 200 if (otherName.equals("java.lang.Double") 201 || otherName.equals("gnu.math.DFloNum")) 202 return 0; if (otherName.equals("java.lang.Float")) 204 return 1; 205 break; 206 case 'F': 207 if (otherName.equals("java.lang.Double") 208 || otherName.equals("gnu.math.DFloNum")) 209 return -1; 210 if (otherName.equals("java.lang.Float")) 211 return 0; break; 213 case 'I': 214 if (otherName.equals("java.lang.Integer")) 215 return 0; if (otherName.equals("gnu.math.IntNum")) 217 return -1; 218 219 default: 220 if (otherName.equals("java.lang.Double") 221 || otherName.equals("java.lang.Float") 222 || otherName.equals("gnu.math.DFloNum")) 223 return -1; 224 } 225 if (otherName.equals("java.lang.Object") 226 || other == tostring_type) 227 return -1; 228 return -2; 229 } 230 } 231 | Popular Tags |