KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > services > classfile > ClassHolder


1 /*
2
3    Derby - Class org.apache.derby.iapi.services.classfile.ClassHolder
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.iapi.services.classfile;
23
24 import org.apache.derby.iapi.services.sanity.SanityManager;
25
26
27 import java.io.InputStream JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.util.Enumeration JavaDoc;
30
31 import java.io.IOException JavaDoc;
32 import java.util.Vector JavaDoc;
33
34 import org.apache.derby.iapi.util.ByteArray;
35 import org.apache.derby.iapi.services.classfile.VMDescriptor;
36 import org.apache.derby.iapi.services.classfile.VMDescriptor;
37
38 import java.util.Hashtable JavaDoc;
39 import java.util.Vector JavaDoc;
40 import java.util.Enumeration JavaDoc;
41
42
43 /** Based upon "THE class FILE FORMAT" chapter of "The Java Virtual Machine Specification"
44     corresponding to version 1.0.2 of the Java Virtual Machine and 1.0.2 of the
45     Java Language Specification.
46
47     ISBN 0-201-63452-X, September 1996.
48     */

49
50 public class ClassHolder {
51
52
53     /*
54     ** Constants.
55     */

56
57     /*
58     ** Fields
59     */

60
61     protected int access_flags;
62     protected int this_class;
63     protected int super_class;
64
65     // protected InterfacesArray interfaces; // can be null
66
protected int[] interfaces; //can be null
67

68     protected MemberTable field_info; // can be null
69
protected MemberTable method_info; // can be null
70
protected Attributes attribute_info; // can be null
71

72     /*
73     ** Fields for Constant Pool Table
74     */

75     protected Hashtable JavaDoc cptHashTable;
76     protected Vector JavaDoc cptEntries;
77     private int cptEstimatedSize;
78
79     /**
80         Used to search for index entries to avoid object allocation
81         in the case a referecne already exists.
82     */

83     private final CONSTANT_Index_info searchIndex = new CONSTANT_Index_info(0, 0, 0);
84
85     /*
86     ** Constructors.
87     */

88
89     protected ClassHolder(int estimatedConstantPoolCount) {
90         // Constant Pool Information
91
// 100 is the estimate of the number of entries that will be generated
92
cptEntries = new Vector JavaDoc(estimatedConstantPoolCount);
93         cptHashTable = new Hashtable JavaDoc(estimatedConstantPoolCount, (float)0.75);
94
95         // reserve the 0'th constant pool entry
96
cptEntries.setSize(1);
97     }
98
99
100     /**
101         This will not define a constructor -- it is up
102         to the caller to add at least one.
103     */

104
105     public ClassHolder(String JavaDoc fullyQualifiedName, String JavaDoc superClassName,
106         int modifiers) {
107
108         this(100);
109
110         access_flags = modifiers | /* Modifier.SUPER */ 0x0020;
111
112         this_class = addClassReference(fullyQualifiedName);
113         super_class = addClassReference(superClassName);
114         method_info = new MemberTable(0);
115     }
116
117     private void put(ClassFormatOutput out) throws IOException JavaDoc {
118
119         /* Write out the header */
120         out.putU4(VMDescriptor.JAVA_CLASS_FORMAT_MAGIC);
121         out.putU2(VMDescriptor.JAVA_CLASS_FORMAT_MINOR_VERSION);
122         out.putU2(VMDescriptor.JAVA_CLASS_FORMAT_MAJOR_VERSION);
123
124         // special case checking that the number of constant
125
// pool entries does not exceed the limit of 65535
126
// (as it is stored as a U2).
127
// Special case to allow somewhat easier debugging
128
// of the resulting failure.
129
out.putU2("constant_pool", cptEntries.size());
130         cptPut(out);
131
132         out.putU2(access_flags);
133         out.putU2(this_class);
134         out.putU2(super_class);
135
136         if (interfaces != null) {
137             int ilen = interfaces.length;
138             out.putU2(ilen);
139             for (int i = 0; i < ilen; i++) {
140                 out.putU2(interfaces[i]);
141             }
142         } else {
143             out.putU2(0);
144         }
145
146         if (field_info != null) {
147             out.putU2(field_info.size());
148             field_info.put(out);
149         } else {
150             out.putU2(0);
151         }
152
153         if (method_info != null) {
154             out.putU2(method_info.size());
155             method_info.put(out);
156         } else {
157             out.putU2(0);
158         }
159
160         if (attribute_info != null) {
161             out.putU2(attribute_info.size());
162             attribute_info.put(out);
163         } else {
164             out.putU2(0);
165         }
166
167     }
168
169
170     /*
171     ** Public methods from ClassHolder.
172     */

173
174     /**
175      * Convert the object representation of the class into
176      * its class file format.
177      * @exception IOException error writing the class
178      */

179     public ByteArray getFileFormat() throws IOException JavaDoc {
180
181         int classFileSize = 4 + (10 * 2);
182         classFileSize += cptEstimatedSize;
183
184         if (interfaces != null)
185             classFileSize += (interfaces.length * 2);
186
187         if (field_info != null)
188             classFileSize += field_info.classFileSize();
189
190         if (method_info != null)
191             classFileSize += method_info.classFileSize();
192
193         if (attribute_info != null)
194             classFileSize += attribute_info.classFileSize();
195
196     
197         ClassFormatOutput cfo = new ClassFormatOutput(classFileSize + 200);
198
199         put(cfo);
200
201         return new ByteArray(cfo.getData(), 0, cfo.size());
202
203     }
204
205     /*
206     ** Public methods from ClassMember
207     */

208
209     /** @see ClassMember
210     */

211     public int getModifier() { return access_flags; }
212
213     /** @see ClassMember
214     */

215     public String JavaDoc getName() {
216         return className(this_class).replace('/', '.');
217     }
218     /*
219     ** Public methods from ClassHolder
220     */

221
222     /** @see ClassHolder#addMember */
223     public ClassMember addMember(String JavaDoc simpleName, String JavaDoc descriptor, int modifier)
224     {
225         if (SanityManager.DEBUG)
226         {
227             if (descriptor.startsWith("(")) {
228                 if (method_info != null) {
229                     if (method_info.find(simpleName, descriptor) != null) {
230                         SanityManager.THROWASSERT("Method already exists " + simpleName + " " + descriptor);
231                     }
232                 }
233
234             } else {
235                 if (field_info != null) {
236                     if (field_info.find(simpleName, descriptor) != null) {
237                         SanityManager.THROWASSERT("Field already exists " + simpleName + " " + descriptor);
238                     }
239                 }
240             }
241         }
242
243         CONSTANT_Utf8_info utf = addUtf8Entry(simpleName);
244
245         int nameIndex = utf.getIndex();
246         int descriptorIndex = addUtf8Entry(descriptor).getIndex();
247
248         ClassMember item = new ClassMember(this, modifier, nameIndex, descriptorIndex);
249         MemberTable mt;
250         if (descriptor.startsWith("(")) {
251             mt = method_info;
252             if (mt == null)
253                 mt = method_info = new MemberTable(0);
254
255         }
256         else {
257             mt = field_info;
258             if (mt == null)
259                 mt = field_info = new MemberTable(0);
260         }
261
262         mt.addEntry(item);
263         return item;
264     }
265
266     /** @see ClassHolder#addFieldReference */
267     public int addFieldReference(String JavaDoc className, String JavaDoc simpleName, String JavaDoc descriptor) {
268         return addReference(VMDescriptor.CONSTANT_Fieldref, className, simpleName, descriptor);
269     }
270
271     public int addFieldReference(ClassMember field) {
272         return addReference(VMDescriptor.CONSTANT_Fieldref, (ClassMember) field);
273     }
274
275     /** @see ClassHolder#addMethodReference */
276     public int addMethodReference(String JavaDoc className, String JavaDoc simpleName, String JavaDoc descriptor, boolean isInterface) {
277
278         int tag = isInterface ? VMDescriptor.CONSTANT_InterfaceMethodref :
279                                 VMDescriptor.CONSTANT_Methodref;
280
281         return addReference(tag, className, simpleName, descriptor);
282     }
283
284     private int addReference(int tag, String JavaDoc className, String JavaDoc simpleName, String JavaDoc descriptor) {
285
286         int classIndex = addClassReference(className);
287         int nameTypeIndex = addNameAndType(simpleName, descriptor);
288
289         return addIndexReference(tag, classIndex, nameTypeIndex);
290     }
291
292     private int addReference(int tag, ClassMember member) {
293
294         int nameTypeIndex = addIndexReference(VMDescriptor.CONSTANT_NameAndType,
295                             member.name_index, member.descriptor_index);
296
297         return addIndexReference(tag, this_class, nameTypeIndex);
298     }
299
300     /** @see ClassHolder#addConstant */
301     public int addConstant(String JavaDoc value) {
302
303         return addString(value);
304     }
305
306     /** @see ClassHolder#addUtf8 */
307     public int addUtf8(String JavaDoc value) {
308
309         return addUtf8Entry(value).getIndex();
310     }
311
312
313     /** @see ClassHolder#addConstant */
314     public int addConstant(int value) {
315         return addDirectEntry(new CONSTANT_Integer_info(value));
316     }
317
318     /** @see ClassHolder#addConstant */
319     public int addConstant(float value) {
320         return addDirectEntry(new CONSTANT_Float_info(value));
321     }
322
323     /** @see ClassHolder#addConstant */
324     public int addConstant(long value) {
325         return addDirectEntry(new CONSTANT_Long_info(value));
326     }
327
328     /** @see ClassHolder#addConstant */
329     public int addConstant(double value) {
330         return addDirectEntry(new CONSTANT_Double_info(value));
331     }
332
333
334     /** @see ClassMember
335     */

336     public int getConstantPoolIndex() { return this_class; }
337
338     public void addAttribute(String JavaDoc attributeName, ClassFormatOutput info) {
339
340         if (attribute_info == null)
341             attribute_info = new Attributes(1);
342
343
344         CONSTANT_Utf8_info autf = addUtf8Entry(attributeName);
345
346         int index = autf.getIndex();
347
348         attribute_info.addEntry(new AttributeEntry(index, info));
349     }
350
351
352     public String JavaDoc getSuperClassName() {
353         if (super_class == 0)
354             return null;
355         else
356             return className(super_class).replace('/', '.');
357     }
358
359
360 /*
361     public ClassMember getMemberReference(String fullyQualifiedClassName, String simpleName, String descriptor) {
362
363         int classIndex;
364
365         if (fullyQualifiedClassName == null)
366              classIndex = this_class;
367         else
368             classIndex = constantPool.findClass(fullyQualifiedClassName);
369
370         if (classIndex < 0)
371             return null;
372
373         int nameAndTypeIndex = constantPool.findNameAndType(simpleName, descriptor);
374         if (nameAndTypeIndex < 0)
375             return null;
376
377         return constantPool.findReference(classIndex, nameAndTypeIndex);
378     }
379 */

380     /*
381     ** Public methods from ClassRead
382     */

383
384
385
386     /*
387     ** Implementation specific methods.
388     */

389
390     /*
391     ** Methods related to Constant Pool Table
392     */

393     /**
394         Generic add entry to constant pool. Includes the logic
395         for an entry to occupy more than one slot (e.g. long).
396
397         @return The number of slots occupied by the entry.
398 .
399     */

400     protected int addEntry(Object JavaDoc key, ConstantPoolEntry item) {
401
402         item.setIndex(cptEntries.size());
403         if (key != null)
404             cptHashTable.put(key, item);
405         cptEntries.addElement(item);
406
407         cptEstimatedSize += item.classFileSize();
408
409         if (item.doubleSlot()) {
410             cptEntries.addElement(null);
411             return 2;
412         } else {
413             return 1;
414         }
415     }
416     
417     /**
418         Add an entry, but only if it doesn't exist.
419
420         @return the constant pool index of the added
421         or existing item.
422     */

423     private int addDirectEntry(ConstantPoolEntry item) {
424         ConstantPoolEntry existingItem = findMatchingEntry(item);
425         if (existingItem != null) {
426             item = existingItem;
427             //foundCount++;
428
}
429         else {
430             addEntry(item.getKey(), item);
431         }
432         return item.getIndex();
433     }
434
435     /**
436         Add an index reference.
437     */

438     private int addIndexReference(int tag, int i1, int i2) {
439
440         // search for the item using the pre-allocated object
441
searchIndex.set(tag, i1, i2);
442
443         ConstantPoolEntry item = findMatchingEntry(searchIndex);
444
445         if (item == null) {
446             item = new CONSTANT_Index_info(tag, i1, i2);
447             addEntry(item.getKey(), item);
448         }
449
450         return item.getIndex();
451     }
452
453     /**
454         Add a class entry to the pool.
455     */

456     public int addClassReference(String JavaDoc fullyQualifiedName) {
457         if (ClassHolder.isExternalClassName(fullyQualifiedName)) {
458             fullyQualifiedName = ClassHolder.convertToInternalClassName(fullyQualifiedName);
459             // System.out.println("addClassReference " + fullyQualifiedName);
460
}
461
462         int name_index = addUtf8Entry(fullyQualifiedName).getIndex();
463
464         return addIndexReference(VMDescriptor.CONSTANT_Class, name_index, 0);
465     }
466
467     /**
468         Add a name and type entry
469     */

470     private int addNameAndType(String JavaDoc name, String JavaDoc descriptor) {
471         int nameIndex = addUtf8Entry(name).getIndex();
472
473         int descriptorIndex = addUtf8Entry(descriptor).getIndex();
474
475         return addIndexReference(VMDescriptor.CONSTANT_NameAndType, nameIndex, descriptorIndex);
476     }
477
478     /**
479         Add a UTF8 into the pool and return the index to it.
480     */

481     private CONSTANT_Utf8_info addUtf8Entry(String JavaDoc value) {
482
483         CONSTANT_Utf8_info item = (CONSTANT_Utf8_info) findMatchingEntry(value);
484
485         if (item == null) {
486
487             item = new CONSTANT_Utf8_info(value);
488             addEntry(value, item);
489         }
490         return item;
491     }
492     /**
493         Add an extra UTF8 into the pool
494     */

495     private CONSTANT_Utf8_info addExtraUtf8(String JavaDoc value) {
496
497         CONSTANT_Utf8_info item = new CONSTANT_Utf8_info(value);
498         addEntry(null, item);
499
500         return item;
501     }
502
503     /**
504         Add a string entry
505     */

506     private int addString(String JavaDoc value) {
507         CONSTANT_Utf8_info sutf = addUtf8Entry(value);
508         int valueIndex = sutf.setAsString();
509         if (valueIndex == 0) {
510             // string is already being used as code
511
valueIndex = addExtraUtf8(value).getIndex();
512             sutf.setAlternative(valueIndex);
513         }
514
515         return addIndexReference(VMDescriptor.CONSTANT_String, valueIndex, 0);
516     }
517
518     /**
519         Add a string entry
520     */

521     private int addCodeUtf8(String JavaDoc value) {
522         CONSTANT_Utf8_info sutf = addUtf8Entry(value);
523         int index = sutf.setAsCode();
524         if (index == 0) {
525             // code string is already being used as string
526
CONSTANT_Utf8_info eutf = addExtraUtf8(value);
527             eutf.setAsCode(); // ensure the replace will happen
528
index = eutf.getIndex();
529             sutf.setAlternative(index);
530         }
531
532         return index;
533     }
534     protected void cptPut(ClassFormatOutput out) throws IOException JavaDoc {
535
536         for (Enumeration JavaDoc e = cptEntries.elements(); e.hasMoreElements(); ) {
537             ConstantPoolEntry item = (ConstantPoolEntry) e.nextElement();
538             if (item == null) {
539                 continue;
540             }
541
542             item.put(out);
543         }
544     }
545
546     /*
547     ** Methods to convert indexes to constant pool entries and vice-versa.
548     */

549
550     public ConstantPoolEntry getEntry(int index) {
551         return (ConstantPoolEntry) cptEntries.elementAt(index);
552     }
553
554     /**
555         Return the class name for an index to a CONSTANT_Class_info.
556     */

557
558     protected String JavaDoc className(int classIndex) {
559         CONSTANT_Index_info ci = (CONSTANT_Index_info) getEntry(classIndex);
560
561         return nameIndexToString(ci.getI1()).replace('/', '.');
562
563     }
564
565     /*
566     ** Methods to find specific types of constant pool entries.
567        In these methods we try to avoid using the ConstantPoolEntry.matchValue()
568        as that requires creating a new object for the search. The matchValue()
569        call is really intended for when objects are being added to the constant pool.
570     */

571
572     /**
573         Return the index of a UTF entry or -1 if it doesn't exist.
574     */

575     int findUtf8(String JavaDoc value) {
576
577         ConstantPoolEntry item = findMatchingEntry(value);
578         if (item == null)
579             return -1;
580
581         return item.getIndex();
582     }
583
584     /**
585         Find a class descriptor (section 4.4.1) and return its
586         index, returns -1 if not found.
587     */

588     public int findClass(String JavaDoc fullyQualifiedName) {
589         String JavaDoc internalName = ClassHolder.convertToInternalClassName(fullyQualifiedName);
590         int utf_index = findUtf8(internalName);
591         if (utf_index < 0)
592             return -1;
593
594         return findIndexIndex(VMDescriptor.CONSTANT_Class,
595             utf_index, 0);
596     }
597
598
599     /**
600         Find a name and type descriptor (section 4.4.6) and
601         return it's index.
602         <p>
603         returns -1 if not found.
604     */

605     public int findNameAndType(String JavaDoc name, String JavaDoc descriptor) {
606
607         int name_index = findUtf8(name);
608         if (name_index < 0)
609             return -1;
610         int descriptor_index = findUtf8(descriptor);
611         if (descriptor_index < 0)
612             return -1;
613
614         return findIndexIndex(VMDescriptor.CONSTANT_NameAndType,
615             name_index, descriptor_index);
616     }
617 /*
618     public ClassMember findReference(int classIndex, int nameAndTypeIndex) {
619
620         CONSTANT_Index_info item = findIndexEntry(VMDescriptor.CONSTANT_Methodref,
621                 classIndex, nameAndTypeIndex);
622
623         if (item == null) {
624
625             item = findIndexEntry(VMDescriptor.CONSTANT_InterfaceMethodref,
626                 classIndex, nameAndTypeIndex);
627
628             if (item == null) {
629                 item = findIndexEntry(VMDescriptor.CONSTANT_Fieldref,
630                     classIndex, nameAndTypeIndex);
631
632                 if (item == null)
633                     return null;
634
635             }
636         }
637
638         return new ReferenceMember(this, item);
639     }
640 */

641     protected CONSTANT_Index_info findIndexEntry(int tag, int i1, int i2) {
642         // search for the item using the pre-allocated object
643
searchIndex.set(tag, i1, i2);
644
645         return (CONSTANT_Index_info) findMatchingEntry(searchIndex);
646     }
647
648     protected int findIndexIndex(int tag, int i1, int i2) {
649         CONSTANT_Index_info item = findIndexEntry(tag, i1, i2);
650         if (item == null)
651             return -1;
652
653         return item.getIndex();
654     }
655
656     protected ConstantPoolEntry findMatchingEntry(Object JavaDoc key) {
657         return (ConstantPoolEntry) cptHashTable.get(key);
658     }
659
660     /** get a string (UTF) given a name_index into the constant pool
661        */

662     String JavaDoc nameIndexToString(int index) {
663
664         return getEntry(index).toString();
665     }
666
667     /** get the class name of a Class given the index of its CONSTANT_Class_info
668         entry in the Constant Pool.
669         */

670
671     protected String JavaDoc getClassName(int index) {
672
673         if (index == 0)
674             return ""; // must be the super class of java.lang.Object, ie. nothing.
675

676         return nameIndexToString(getEntry(index).getI1());
677     }
678
679     /*
680      * Determine whether the class descriptor string is
681      * in external format or not. Assumes that to be in external
682      * format means it must have a '.' or end in an ']'.
683      *
684      * @param className the name of the class to check
685      *
686      * @return true/false
687      */

688     public static boolean isExternalClassName(String JavaDoc className)
689     {
690         int len;
691         if (className.indexOf('.') != -1)
692         {
693             return true;
694         }
695         else if ((len = className.length()) == 0)
696         {
697             return false;
698         }
699         return (className.charAt(len - 1) == ']');
700     }
701
702     /*
703      * Convert a class name to the internal VM class name format.
704        See sections 4.3.2, 4.4.1 of the vm spec.
705      * The normal leading 'L' and trailing ';' are left
706      * off of objects. This is intended primarily for
707      * the class manager.
708      * <p>
709      * An example of a conversion would be java.lang.Double[]
710      * to "[Ljava/lang/Double;".
711      <BR>
712        java.lang.Double would be converted to "java/lang/Double"
713
714     <BR>
715     Note that for array types the result of convertToInternalClassName()
716     and convertToInternalDescriptor() are identical.
717
718      *
719      * @param the external name (cannot be null)
720      *
721      * @return the internal string
722      */

723     public static String JavaDoc convertToInternalClassName(String JavaDoc externalName)
724     {
725         return convertToInternal(externalName, false);
726     }
727
728     /*
729      * Convert a class name to internal JVM descriptor format.
730        See sections 4.3.2 of the vm spec.
731      * <p>
732      * An example of a conversion would be "java.lang.Double[]"
733      * to "[Ljava/lang/Double;".
734      *
735      <BR>
736        java.lang.Double would be converted to "Ljava/lang/Double;"
737
738     <BR>
739     Note that for array types the result of convertToInternalClassName()
740     and convertToInternalDescriptor() are identical.
741
742      * @param the external name (cannot be null)
743      *
744      * @return the internal string
745      */

746     public static String JavaDoc convertToInternalDescriptor(String JavaDoc externalName)
747     {
748         return convertToInternal(externalName, true);
749     }
750
751     /*
752     ** Workhorse method. Convert to internal format.
753
754         @param descriptor True if converting to descriptor format, false if
755         converting to class name format.
756     **
757     ** Lifted from BCClass.java.
758     **
759     ** Returns the result string.
760     */

761     private static String JavaDoc convertToInternal(String JavaDoc externalName, boolean descriptor)
762     {
763         if (SanityManager.DEBUG)
764         {
765             SanityManager.ASSERT(externalName != null, "unexpected null");
766         }
767
768         int len = externalName.length();
769
770         String JavaDoc internalName;
771         String JavaDoc retVal = null;
772         int origLen = len;
773         int arity = 0;
774
775         // first walk through all array-ness
776
if (externalName.charAt(len-1) == ']')
777         {
778             while (len > 0
779                 && externalName.charAt(len-1) == ']'
780                 && externalName.charAt(len-2) == '[')
781             {
782                 len -= 2;
783                 arity++;
784             }
785         }
786         if (SanityManager.DEBUG) {
787             SanityManager.ASSERT(len > 0);
788         }
789
790         internalName = (origLen == len)?
791                           externalName
792                         : externalName.substring(0,len);
793
794         // then check for primitive types ...
795
// in length by expected frequency order
796

797         switch (len) {
798             case 7 :
799                 if ("boolean".equals(internalName)) {
800                     retVal = makeDesc(VMDescriptor.C_BOOLEAN, arity);
801                 }
802                 break;
803             case 4 :
804                 if ("void".equals(internalName)) {
805                     retVal = makeDesc(VMDescriptor.C_VOID, arity);
806                 }
807                 else if ("long".equals(internalName)) {
808                     retVal = makeDesc(VMDescriptor.C_LONG, arity);
809                 }
810                 else if ("byte".equals(internalName)) {
811                     retVal = makeDesc(VMDescriptor.C_BYTE, arity);
812                 }
813                 else if ("char".equals(internalName)) {
814                     retVal = makeDesc(VMDescriptor.C_CHAR, arity);
815                 }
816                 break;
817             case 3 :
818                 if ("int".equals(internalName)) {
819                     retVal = makeDesc(VMDescriptor.C_INT, arity);
820                 }
821                 break;
822             case 6 :
823                 if ("double".equals(internalName)) {
824                     retVal = makeDesc(VMDescriptor.C_DOUBLE, arity);
825                 }
826                 break;
827             case 5 :
828                 if ("short".equals(internalName)) {
829                     retVal = makeDesc(VMDescriptor.C_SHORT, arity);
830                 }
831                 else if ("float".equals(internalName)) {
832                     retVal = makeDesc(VMDescriptor.C_FLOAT, arity);
833                 }
834                 break;
835         }
836
837         // then it must be a Java class
838
if (retVal == null)
839             retVal = makeDesc(internalName, arity, descriptor);
840
841         return retVal;
842     }
843
844     /**
845         A helper to build a type description based on a built-in type
846         and an array arity.
847      */

848     static private String JavaDoc makeDesc (char builtin, int arity) {
849         if (arity == 0)
850             switch (builtin) {
851                 case VMDescriptor.C_BYTE : return VMDescriptor.BYTE;
852                 case VMDescriptor.C_CHAR : return VMDescriptor.CHAR;
853                 case VMDescriptor.C_DOUBLE : return VMDescriptor.DOUBLE;
854                 case VMDescriptor.C_FLOAT : return VMDescriptor.FLOAT;
855                 case VMDescriptor.C_INT : return VMDescriptor.INT;
856                 case VMDescriptor.C_LONG : return VMDescriptor.LONG;
857                 case VMDescriptor.C_SHORT : return VMDescriptor.SHORT;
858                 case VMDescriptor.C_BOOLEAN : return VMDescriptor.BOOLEAN;
859                 case VMDescriptor.C_VOID : return VMDescriptor.VOID;
860                 default:
861                     if (SanityManager.DEBUG)
862                         SanityManager.THROWASSERT("No type match");
863                     return null;
864             }
865         else {
866             StringBuffer JavaDoc desc = new StringBuffer JavaDoc(arity+3);
867
868             for (int i=0;i<arity;i++)
869                 desc.append(VMDescriptor.C_ARRAY);
870
871             desc.append(ClassHolder.makeDesc(builtin, 0));
872
873             return desc.toString();
874         }
875     }
876
877     /**
878         A helper to build a type description based on a Java class
879         and an array arity.
880
881         If descriptor is true create a descriptor according to
882         section 4.3.2 of the vm spec. If false create a class name
883         according to sections 4.3.2 and 4.4.1 of the vm spec.
884     
885      */

886     static private String JavaDoc makeDesc (String JavaDoc className, int arity, boolean descriptor) {
887
888         if (!descriptor && (arity == 0)) {
889             return className.replace('.','/');
890         }
891
892         StringBuffer JavaDoc desc = new StringBuffer JavaDoc(arity+2+className.length());
893
894         for (int i=0;i<arity;i++)
895             desc.append(VMDescriptor.C_ARRAY);
896
897         desc.append(VMDescriptor.C_CLASS);
898
899         desc.append(className.replace('.','/'));
900
901         desc.append(VMDescriptor.C_ENDCLASS);
902
903         return desc.toString();
904     }
905
906
907 }
908
Popular Tags