KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gov > nasa > jpf > jvm > Types


1 //
2
// Copyright (C) 2005 United States Government as represented by the
3
// Administrator of the National Aeronautics and Space Administration
4
// (NASA). All Rights Reserved.
5
//
6
// This software is distributed under the NASA Open Source Agreement
7
// (NOSA), version 1.3. The NOSA has been approved by the Open Source
8
// Initiative. See the file NOSA-1.3-JPF at the top of the distribution
9
// directory tree for the complete NOSA document.
10
//
11
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
12
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
13
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
14
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
15
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
16
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
17
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
18
//
19
package gov.nasa.jpf.jvm;
20
21 import gov.nasa.jpf.JPFException;
22
23 import java.lang.reflect.Method JavaDoc;
24
25 import org.apache.bcel.Constants;
26
27
28 /**
29  * various type mangling/demangling routines
30  */

31 public class Types implements Constants {
32   public static byte[] getArgumentTypes (String JavaDoc signature) {
33     int i;
34     int j;
35     int nArgs;
36
37     for (i = 1, nArgs = 0; signature.charAt(i) != ')'; nArgs++) {
38       i += getTypeLength(signature, i);
39     }
40
41     byte[] args = new byte[nArgs];
42
43     for (i = 1, j = 0; j < nArgs; j++) {
44       int end = i + getTypeLength(signature, i);
45       String JavaDoc arg = signature.substring(i, end);
46       i = end;
47
48       args[j] = getBaseType(arg);
49     }
50
51     return args;
52   }
53
54   /**
55    * get size in stack slots (ints), excluding this
56    */

57   public static int getArgumentsSize (String JavaDoc signature) {
58     int i;
59     int n;
60     char c;
61
62     for (i = 1, n = 0; (c = signature.charAt(i)) != ')'; n++) {
63       switch (c) {
64       case 'L':
65
66         for (i++; signature.charAt(i) != ';'; i++) {
67           ;
68         }
69
70         break;
71
72       case '[':
73
74         while ((c = signature.charAt(++i)) == '[') {
75           ;
76         }
77
78         if (c == 'L') {
79           for (i++; signature.charAt(i) != ';'; i++) {
80             ;
81           }
82         }
83
84         break;
85
86       case 'J':
87       case 'D':
88
89         // the two-slot types
90
n++;
91
92         break;
93
94       default:
95
96         // just one slot entry
97
}
98
99       i++;
100     }
101
102     return n;
103   }
104
105   public static String JavaDoc getArrayElementType (String JavaDoc type) {
106     if (type.charAt(0) != '[') {
107       throw new JPFException("not an array type");
108     }
109
110     return type.substring(1);
111   }
112
113   public static byte getBaseType (String JavaDoc type) {
114     switch (type.charAt(0)) {
115     case 'B':
116       return T_BYTE;
117
118     case 'C':
119       return T_CHAR;
120
121     case 'D':
122       return T_DOUBLE;
123
124     case 'F':
125       return T_FLOAT;
126
127     case 'I':
128       return T_INT;
129
130     case 'J':
131       return T_LONG;
132
133     case 'L':
134       return T_OBJECT; // T_REFERENCE is deprecated
135

136     case 'S':
137       return T_SHORT;
138
139     case 'V':
140       return T_VOID;
141
142     case 'Z':
143       return T_BOOLEAN;
144
145     case '[':
146       return T_ARRAY;
147     }
148
149     throw new JPFException("invalid type string: " + type);
150   }
151
152   /**
153    * get the argument type part of the signature out of a
154    * JNI mangled method name.
155    * Note this is not the complete signature, since we don't have a
156    * return type (which is superfluous since it's not overloading,
157    * but unfortunately part of the signature in the class file)
158    */

159   public static String JavaDoc getJNIArgSignature (String JavaDoc mangledName) {
160     int i = mangledName.indexOf("__");
161     String JavaDoc sig = null;
162
163     if (i > 0) {
164       int len = mangledName.length();
165       char[] buf = new char[len + 1];
166       int j;
167       int k = 0;
168
169       buf[k++] = '(';
170
171       for (j = i + 2; j < len; j++) {
172         char c = mangledName.charAt(j);
173
174         if (c == '_') {
175           j++;
176
177           if (j < len) {
178             c = mangledName.charAt(j);
179
180             switch (c) {
181             case '1':
182               buf[k++] = '_';
183
184               break;
185
186             case '2':
187               buf[k++] = ';';
188
189               break;
190
191             case '3':
192               buf[k++] = '[';
193
194               break;
195
196             default:
197               buf[k++] = '/';
198               buf[k++] = c;
199             }
200           } else {
201             buf[k++] = '/';
202           }
203         } else {
204           buf[k++] = c;
205         }
206       }
207
208       buf[k++] = ')';
209       sig = new String JavaDoc(buf, 0, k);
210     }
211
212     return sig;
213   }
214
215   public static String JavaDoc getJNIMangledMethodName (Method JavaDoc m) {
216     String JavaDoc name = m.getName();
217     Class JavaDoc[] pt = m.getParameterTypes();
218     StringBuffer JavaDoc s = new StringBuffer JavaDoc(name.length() + (pt.length * 16));
219
220     s.append(name);
221     s.append("__");
222
223     // <2do> not very efficient, but we don't care for now
224
for (int i = 0; i < pt.length; i++) {
225       s.append(getJNITypeCode(pt[i].getName()));
226     }
227
228     return s.toString();
229   }
230
231   public static String JavaDoc getJNIMangledMethodName (String JavaDoc cls, String JavaDoc name,
232                                                 String JavaDoc signature) {
233     StringBuffer JavaDoc s = new StringBuffer JavaDoc(signature.length() + 10);
234     int i;
235     char c;
236
237     if (cls != null) {
238       s.append(cls.replace('.', '_'));
239     }
240
241     s.append(name);
242     s.append("__");
243
244     // as defined in the JNI specs
245
for (i = 1; (c = signature.charAt(i)) != ')'; i++) {
246       switch (c) {
247       case '/':
248         s.append("_");
249
250         break;
251
252       case '_':
253         s.append("_1");
254
255         break;
256
257       case ';':
258         s.append("_2");
259
260         break;
261
262       case '[':
263         s.append("_3");
264
265         break;
266
267       default:
268         s.append(c);
269       }
270     }
271
272     return s.toString();
273   }
274
275   /**
276    * return the name part of a JNI mangled method name (which is of
277    * course not completely safe - you should only use it if you know
278    * this is a JNI name)
279    */

280   public static String JavaDoc getJNIMethodName (String JavaDoc mangledName) {
281     int i = mangledName.indexOf("__");
282
283     if (i > 0) {
284       return mangledName.substring(0, i);
285     } else {
286       return mangledName;
287     }
288   }
289
290   public static String JavaDoc getJNITypeCode (String JavaDoc type) {
291     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(32);
292     int l = type.length() - 1;
293
294     for (; type.charAt(l) == ']'; l -= 2) {
295       sb.append("_3");
296     }
297
298     type = type.substring(0, l + 1);
299
300     if (type.equals("int")) {
301       sb.append('I');
302     } else if (type.equals("long")) {
303       sb.append('J');
304     } else if (type.equals("boolean")) {
305       sb.append('Z');
306     } else if (type.equals("char")) {
307       sb.append('C');
308     } else if (type.equals("byte")) {
309       sb.append('B');
310     } else if (type.equals("short")) {
311       sb.append('S');
312     } else if (type.equals("double")) {
313       sb.append('D');
314     } else if (type.equals("float")) {
315       sb.append('F');
316     } else {
317       sb.append('L');
318
319       for (int i = 0; i < type.length(); i++) {
320         char c = type.charAt(i);
321
322         switch (c) {
323         case '.':
324           sb.append('_');
325
326           break;
327
328         case '_':
329           sb.append("_1");
330
331           break;
332
333         default:
334           sb.append(c);
335         }
336       }
337
338       sb.append("_2");
339     }
340
341     return sb.toString();
342   }
343
344   public static int getNumberOfArguments (String JavaDoc signature) {
345     int i;
346     int n;
347     char c;
348
349     for (i = 1, n = 0; (c = signature.charAt(i)) != ')'; n++) {
350       switch (c) {
351       case 'L':
352
353         for (i++; signature.charAt(i) != ';'; i++) {
354           ;
355         }
356
357         break;
358
359       case '[':
360
361         while ((c = signature.charAt(++i)) == '[') {
362           ;
363         }
364
365         if (c == 'L') {
366           for (i++; signature.charAt(i) != ';'; i++) {
367             ;
368           }
369         }
370
371         break;
372
373       default:
374
375         // just a single type char
376
}
377
378       i++;
379     }
380
381     return n;
382   }
383
384   public static boolean isReference (String JavaDoc type) {
385     int t = getBaseType(type);
386
387     return (t == T_ARRAY) || (t == T_REFERENCE);
388   }
389
390   public static byte getReturnType (String JavaDoc signature) {
391     int i = signature.indexOf(')');
392
393     return getBaseType(signature.substring(i + 1));
394   }
395
396   public static String JavaDoc getTypeCode (String JavaDoc type) {
397     String JavaDoc t = null;
398     boolean isArray = type.endsWith("[]");
399
400     if (isArray) {
401       type = type.substring(0, type.length() - 2);
402     }
403
404     if (type.equals("byte")) {
405       t = "B";
406     } else if (type.equals("char")) {
407       t = "C";
408     } else if (type.equals("short")) {
409       t = "S";
410     } else if (type.equals("int")) {
411       t = "I";
412     } else if (type.equals("float")) {
413       t = "F";
414     } else if (type.equals("long")) {
415       t = "J";
416     } else if (type.equals("double")) {
417       t = "D";
418     } else if (type.equals("boolean")) {
419       t = "Z";
420     } else if (type.equals("void")) {
421       t = "V";
422     }
423
424     if (t != null) {
425       if (isArray) {
426         t = "[" + t;
427       }
428     } else {
429       t = "L";
430
431       if (isArray) {
432         t += '[';
433       }
434
435       t += type.replace('.', '/');
436       t += ';';
437     }
438
439     return t;
440   }
441
442   public static boolean isTypeCode (String JavaDoc t) {
443     char c = t.charAt(0);
444
445     if (c == '[') {
446       return true;
447     }
448
449     if ((t.length() == 1) &&
450             ((c == 'B') || (c == 'I') || (c == 'S') || (c == 'C') ||
451               (c == 'F') || (c == 'J') || (c == 'D') || (c == 'Z'))) {
452       return true;
453     }
454
455     if (t.endsWith(";")) {
456       return true;
457     }
458
459     return false;
460   }
461
462   public static String JavaDoc getTypeName (String JavaDoc type) {
463     int len = type.length();
464     char c = type.charAt(0);
465
466     if (len == 1) {
467       switch (c) {
468       case 'B':
469         return "byte";
470
471       case 'C':
472         return "char";
473
474       case 'D':
475         return "double";
476
477       case 'F':
478         return "float";
479
480       case 'I':
481         return "int";
482
483       case 'J':
484         return "long";
485
486       case 'S':
487         return "short";
488
489       case 'V':
490         return "void";
491
492       case 'Z':
493         return "boolean";
494       }
495     }
496
497     if (c == '[') {
498       return getTypeName(type.substring(1)) + "[]";
499     }
500
501     if (type.charAt(len - 1) == ';') {
502       return type.substring(1, type.indexOf(';')).replace('/', '.');
503     }
504
505     throw new JPFException("invalid type string: " + type);
506   }
507
508   /**
509    * what would be the info size in bytes, not words
510    * (we ignore 64bit machines for now)
511    */

512   public static int getTypeSizeInBytes (String JavaDoc type) {
513     switch (type.charAt(0)) {
514       case 'V':
515         return 0;
516         
517       case 'Z': // that's a stretch, but we assume boolean uses the smallest addressable size
518
case 'B':
519         return 1;
520         
521       case 'S':
522       case 'C':
523         return 2;
524         
525       case 'L':
526       case '[':
527       case 'F':
528       case 'I':
529         return 4;
530         
531       case 'D':
532       case 'J':
533         return 8;
534     }
535
536     throw new JPFException("invalid type string: " + type);
537   }
538   
539   public static int getTypeSize (String JavaDoc type) {
540     switch (type.charAt(0)) {
541     case 'V':
542       return 0;
543
544     case 'B':
545     case 'C':
546     case 'F':
547     case 'I':
548     case 'L':
549     case 'S':
550     case 'Z':
551     case '[':
552       return 1;
553
554     case 'D':
555     case 'J':
556       return 2;
557     }
558
559     throw new JPFException("invalid type string: " + type);
560   }
561
562   public static String JavaDoc asTypeName (String JavaDoc type) {
563     if (type.startsWith("[") || type.endsWith(";")) {
564       return getTypeName(type);
565     }
566
567     return type;
568   }
569
570   public static int booleanToInt (boolean b) {
571     return b ? 1 : 0;
572   }
573
574   public static long doubleToLong (double d) {
575     return Double.doubleToLongBits(d);
576   }
577
578   public static int floatToInt (float f) {
579     return Float.floatToIntBits(f);
580   }
581
582   public static int hiDouble (double d) {
583     return hiLong(Double.doubleToLongBits(d));
584   }
585
586   public static int hiLong (long l) {
587     return (int) (l >> 32);
588   }
589
590   public static boolean instanceOf (String JavaDoc type, String JavaDoc ofType) {
591     int bType = getBaseType(type);
592
593     if ((bType == T_ARRAY) && ofType.equals("Ljava/lang/Object;")) {
594       return true;
595     }
596
597     int bOfType = getBaseType(ofType);
598
599     if (bType != bOfType) {
600       return false;
601     }
602
603     switch (bType) {
604     case T_ARRAY:
605       return instanceOf(type.substring(1), ofType.substring(1));
606
607     case T_REFERENCE:
608       return ClassInfo.getClassInfo(getTypeName(type))
609                       .instanceOf(getTypeName(ofType));
610
611     default:
612       return true;
613     }
614   }
615
616   public static boolean intToBoolean (int i) {
617     return i != 0;
618   }
619
620   public static float intToFloat (int i) {
621     return Float.intBitsToFloat(i);
622   }
623
624   public static double intsToDouble (int l, int h) {
625     return longToDouble(intsToLong(l, h));
626   }
627
628   public static long intsToLong (int l, int h) {
629     return ((long) h << 32) | ((long) l & 0xFFFFFFFFL);
630   }
631
632   public static int loDouble (double d) {
633     return loLong(Double.doubleToLongBits(d));
634   }
635
636   public static int loLong (long l) {
637     return (int) (l & 0xFFFFFFFFL);
638   }
639
640   public static double longToDouble (long l) {
641     return Double.longBitsToDouble(l);
642   }
643
644   private static int getTypeLength (String JavaDoc signature, int idx) {
645     switch (signature.charAt(idx)) {
646     case 'B':
647     case 'C':
648     case 'D':
649     case 'F':
650     case 'I':
651     case 'J':
652     case 'S':
653     case 'V':
654     case 'Z':
655       return 1;
656
657     case '[':
658       return 1 + getTypeLength(signature, idx + 1);
659
660     case 'L':
661
662       int semicolon = signature.indexOf(';', idx);
663
664       if (semicolon == -1) {
665         throw new JPFException("invalid type signature: " +
666                                          signature);
667       }
668
669       return semicolon - idx + 1;
670     }
671
672     throw new JPFException("invalid type signature");
673   }
674 }
675
Popular Tags