KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > bytecode > PrimType


1 package gnu.bytecode;
2
3 public class PrimType extends Type {
4
5   public PrimType (String JavaDoc nam, String JavaDoc sig, int siz, Class JavaDoc 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 JavaDoc coerceFromObject (Object JavaDoc 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 JavaDoc(((Number JavaDoc) obj).byteValue());
28       case 'S': return new Short JavaDoc(((Number JavaDoc) obj).shortValue());
29       case 'I': return new Integer JavaDoc(((Number JavaDoc) obj).intValue());
30       case 'J': return new Long JavaDoc(((Number JavaDoc) obj).longValue());
31       case 'F': return new Float JavaDoc(((Number JavaDoc) obj).floatValue());
32       case 'D': return new Double JavaDoc(((Number JavaDoc) obj).doubleValue());
33       }
34     throw new ClassCastException JavaDoc("don't know how to coerce "
35                  + obj.getClass().getName() + " to "
36                  + getName());
37   }
38
39   /** Coerce value to a char.
40    * Only defined if getSignature() is "C". */

41   public char charValue (Object JavaDoc value)
42   {
43     return ((Character JavaDoc) value).charValue();
44   }
45
46   /** Coerce value to a boolean.
47    * Only defined if getSignature() is "Z". */

48   public static boolean booleanValue (Object JavaDoc value)
49   {
50     return ! (value instanceof Boolean JavaDoc) || ((Boolean JavaDoc) 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 JavaDoc 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; // Should never happen.
78
}
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
94
boolean_ctype.emitIsInstance(code);
95     else if (sig1 == 'V')
96       {
97     code.emitPop(1);
98     code.emitPushInt(1);
99       }
100     // Have left out Character -> char, since not used by Kawa.
101
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') // boolean
110
{
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     // Have left out Character -> char, since not used by Kawa.
128
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     // Anything can be converted to void, but not vice versa.
142
if (sig1 == 'V')
143       return 1;
144     if (sig2 == 'V')
145       return -1;
146
147     // In Java, no other type can be converted to/from boolean.
148
// Other languages, including C and Scheme are different:
149
// "everything" can be converted to a boolean.
150
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     // Can we get here?
179
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 JavaDoc 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; // Or maybe 1?
203
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; // Or maybe 1?
212
break;
213       case 'I':
214         if (otherName.equals("java.lang.Integer"))
215           return 0; // Or maybe 1?
216
if (otherName.equals("gnu.math.IntNum"))
217           return -1;
218         /* fall through */
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