1 // $Id: class.cpp,v 1.16 2004/09/14 05:49:05 elliott-oss Exp $
2 //
3 // This software is subject to the terms of the IBM Jikes Compiler
4 // License Agreement available at the following URL:
5 // http://ibm.com/developerworks/opensource/jikes.
6 // Copyright (C) 1996, 2004 IBM Corporation and others.  All Rights Reserved.
7 // You must accept the terms of that agreement to use this software.
8 //
9 
10 #include "class.h"
11 #include "code.h"
12 #include "control.h"
13 #include "op.h"
14 #include "option.h"
15 #include "semantic.h"
16 #include "zip.h"
17 
18 #ifdef HAVE_JIKES_NAMESPACE
19 namespace Jikes { // Open namespace Jikes block
20 #endif // HAVE_JIKES_NAMESPACE
21 
22 
SetNext(CPInfo * constant)23 void ConstantPool::SetNext(CPInfo* constant)
24 {
25     Next() = constant;
26     if (constant -> Large())
27         Next() = NULL; // entries following Long or Double are unused
28 }
29 
Check() const30 bool ConstantPool::Check() const
31 {
32     for (unsigned i = 1; i < top; i++)
33     {
34         CPInfo* entry = Tuple<CPInfo*>::operator[](i);
35         if (entry && ! entry -> Check(*this))
36             return false;
37     }
38     return true;
39 }
40 
41 
AllocateCPInfo(ClassFile & buffer)42 CPInfo* CPInfo::AllocateCPInfo(ClassFile& buffer)
43 {
44     u1 tag = buffer.GetU1();
45     switch (tag)
46     {
47     case CONSTANT_Utf8:
48         return new CPUtf8Info(buffer);
49     case CONSTANT_Integer:
50         return new CPIntegerInfo(buffer);
51     case CONSTANT_Float:
52         return new CPFloatInfo(buffer);
53     case CONSTANT_Long:
54         return new CPLongInfo(buffer);
55     case CONSTANT_Double:
56         return new CPDoubleInfo(buffer);
57     case CONSTANT_Class:
58         return new CPClassInfo(buffer);
59     case CONSTANT_String:
60         return new CPStringInfo(buffer);
61     case CONSTANT_Fieldref:
62     case CONSTANT_Methodref:
63     case CONSTANT_InterfaceMethodref:
64         return new CPMemberInfo((ConstantPoolTag) tag, buffer);
65     case CONSTANT_NameAndType:
66         return new CPNameAndTypeInfo(buffer);
67     default:
68         return new CPInfo((ConstantPoolTag) tag);
69     }
70 }
71 
72 
CPClassInfo(ClassFile & buffer)73 CPClassInfo::CPClassInfo(ClassFile& buffer)
74     : CPInfo(CONSTANT_Class)
75     , name_index(buffer.GetU2())
76     , type(NULL)
77 {}
78 
79 
CPMemberInfo(ConstantPoolTag _tag,ClassFile & buffer)80 CPMemberInfo::CPMemberInfo(ConstantPoolTag _tag, ClassFile& buffer)
81     : CPInfo(_tag)
82     , class_index(buffer.GetU2())
83     , name_and_type_index(buffer.GetU2())
84 {}
85 
86 
CPStringInfo(ClassFile & buffer)87 CPStringInfo::CPStringInfo(ClassFile& buffer)
88     : CPInfo(CONSTANT_String)
89     , string_index(buffer.GetU2())
90 {}
91 
92 
CPIntegerInfo(ClassFile & buffer)93 CPIntegerInfo::CPIntegerInfo(ClassFile& buffer)
94     : CPInfo(CONSTANT_Integer)
95     , bytes(buffer.GetU4())
96 {}
97 
98 
CPFloatInfo(ClassFile & buffer)99 CPFloatInfo::CPFloatInfo(ClassFile& buffer)
100     : CPInfo(CONSTANT_Float)
101     , value(buffer.GetU4())
102 {}
103 
104 
CPLongInfo(ClassFile & buffer)105 CPLongInfo::CPLongInfo(ClassFile& buffer)
106     : CPInfo(CONSTANT_Long)
107     , value(buffer.GetU8())
108 {}
109 
110 
CPDoubleInfo(ClassFile & buffer)111 CPDoubleInfo::CPDoubleInfo(ClassFile& buffer)
112     : CPInfo(CONSTANT_Double)
113     , value(buffer.GetU8())
114 {}
115 
116 
CPNameAndTypeInfo(ClassFile & buffer)117 CPNameAndTypeInfo::CPNameAndTypeInfo(ClassFile& buffer)
118     : CPInfo(CONSTANT_NameAndType)
119     , name_index(buffer.GetU2())
120     , descriptor_index(buffer.GetU2())
121 {}
122 
123 
CPUtf8Info(ClassFile & buffer)124 CPUtf8Info::CPUtf8Info(ClassFile& buffer)
125     : CPInfo(CONSTANT_Utf8)
126     , len(buffer.GetU2())
127     , valid(true)
128 {
129     u2 size = (u2) buffer.GetN(bytes, len);
130     if (size != len)
131         valid = false;
132     Init(size);
133     if (! valid)
134         buffer.MarkInvalid("bad CPUtf8Info");
135 }
136 
Init(u2 size)137 void CPUtf8Info::Init(u2 size)
138 {
139 #ifdef JIKES_DEBUG
140     const char* tmp;
141 #endif // JIKES_DEBUG
142     for (u2 i = 0; i < size; i++)
143     {
144         switch (bytes[i])
145         {
146         case 0x00:
147         case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5:
148         case 0xf6: case 0xf7: case 0xf8: case 0xf9: case 0xfa: case 0xfb:
149         case 0xfc: case 0xfd: case 0xfe: case 0xff: // invalid
150             valid = false;
151 #ifdef JIKES_DEBUG
152             contents.Next() = '\\';
153             contents.Next() = 'x';
154             tmp = IntToString(bytes[i], 2).String();
155             contents.Next() = tmp[0];
156             contents.Next() = tmp[1];
157 #endif // JIKES_DEBUG
158             break;
159 #ifdef JIKES_DEBUG
160         case 0x09:
161             contents.Next() = '\\';
162             contents.Next() = 't';
163             break;
164         case 0x0a:
165             contents.Next() = '\\';
166             contents.Next() = 'n';
167             break;
168         case 0x0d:
169             contents.Next() = '\\';
170             contents.Next() = 'r';
171             break;
172         case 0x22:
173             contents.Next() = '\\';
174             contents.Next() = '"';
175             break;
176         case 0x5c:
177             contents.Next() = '\\';
178             contents.Next() = '\\';
179             break;
180         case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06:
181         case 0x07: case 0x08: case 0x0b: case 0x0c: case 0x0e: case 0x0f:
182         case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15:
183         case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b:
184         case 0x1c: case 0x1d: case 0x1e: case 0x1f: case 0x7f:
185             // non-printing ASCII
186             contents.Next() = '\\';
187             contents.Next() = 'u';
188             tmp = IntToString(bytes[i], 4).String();
189             contents.Next() = tmp[0];
190             contents.Next() = tmp[1];
191             contents.Next() = tmp[2];
192             contents.Next() = tmp[3];
193             break;
194 #endif // JIKES_DEBUG
195         default:
196             if (bytes[i] <= 0x7f) // 1-byte (printing ASCII, if JIKES_DEBUG)
197             {
198 #ifdef JIKES_DEBUG
199                 contents.Next() = bytes[i];
200 #endif // JIKES_DEBUG
201             }
202             else if (bytes[i] <= 0xdf) // 2-byte source
203             {
204                 if (i + 1 == size || (bytes[i + 1] & 0xc0) != 0x80)
205                 {
206                     valid = false;
207 #ifdef JIKES_DEBUG
208                     contents.Next() = '\\';
209                     contents.Next() = 'x';
210                     tmp = IntToString(bytes[i], 2).String();
211                     contents.Next() = tmp[0];
212                     contents.Next() = tmp[1];
213 #endif // JIKES_DEBUG
214                     break;
215                 }
216                 ++i;
217 #ifdef JIKES_DEBUG
218                 u2 value = (bytes[i - 1] & 0x1f) << 6;
219                 value |= bytes[i] & 0x3f;
220                 contents.Next() = '\\';
221                 contents.Next() = 'u';
222                 tmp = IntToString(value, 4).String();
223                 contents.Next() = tmp[0];
224                 contents.Next() = tmp[1];
225                 contents.Next() = tmp[2];
226                 contents.Next() = tmp[3];
227 #endif // JIKES_DEBUG
228             }
229             else // 3-byte source
230             {
231                 assert((bytes[i] & 0xf0) == 0xe0);
232                 if (i + 2 >= size ||
233                     (bytes[i + 1] & 0xc0) != 0x80 ||
234                     (bytes[i + 2] & 0xc0) != 0x80)
235                 {
236                     valid = false;
237 #ifdef JIKES_DEBUG
238                     contents.Next() = '\\';
239                     contents.Next() = 'x';
240                     tmp = IntToString(bytes[i], 2).String();
241                     contents.Next() = tmp[0];
242                     contents.Next() = tmp[1];
243 #endif // JIKES_DEBUG
244                     break;
245                 }
246                 i += 2;
247 #ifdef JIKES_DEBUG
248                 u2 value = (bytes[i - 2] & 0x0f) << 12;
249                 value |= (bytes[i - 1] & 0x3f) << 6;
250                 value |= bytes[i] & 0x3f;
251                 contents.Next() = '\\';
252                 contents.Next() = 'u';
253                 tmp = IntToString(value, 4).String();
254                 contents.Next() = tmp[0];
255                 contents.Next() = tmp[1];
256                 contents.Next() = tmp[2];
257                 contents.Next() = tmp[3];
258 #endif // JIKES_DEBUG
259             }
260         }
261     }
262 #ifdef JIKES_DEBUG
263     if (! valid)
264     {
265         contents.Next() = '\\';
266         contents.Next() = 'i';
267         contents.Next() = 'n';
268         contents.Next() = 'v';
269         contents.Next() = 'a';
270         contents.Next() = 'l';
271         contents.Next() = 'i';
272         contents.Next() = 'd';
273         contents.Next() = '\\';
274     }
275     contents.Next() = 0;
276 #endif // JIKES_DEBUG
277 }
278 
279 
FieldInfo(ClassFile & buffer)280 FieldInfo::FieldInfo(ClassFile& buffer)
281     : AccessFlags(buffer.GetU2())
282     , name_index(buffer.GetU2())
283     , descriptor_index(buffer.GetU2())
284     , attr_synthetic(NULL)
285     , attr_deprecated(NULL)
286     , attr_signature(NULL)
287     , attr_constantvalue(NULL)
288     , attr_visible_annotations(NULL)
289     , attr_invisible_annotations(NULL)
290 {
291     unsigned count = buffer.GetU2();
292     while (count--)
293     {
294         AttributeInfo* attr = AttributeInfo::AllocateAttributeInfo(buffer);
295         attributes.Next() = attr;
296         switch (attr -> Tag())
297         {
298         case AttributeInfo::ATTRIBUTE_Synthetic:
299             if (attr_synthetic)
300                 buffer.MarkInvalid("duplicate synthetic attribute");
301             attr_synthetic = (SyntheticAttribute*) attr;
302             SetACC_SYNTHETIC();
303             break;
304         case AttributeInfo::ATTRIBUTE_Deprecated:
305             if (attr_deprecated)
306                 buffer.MarkInvalid("duplicate deprecated attribute");
307             attr_deprecated = (DeprecatedAttribute*) attr;
308             break;
309         case AttributeInfo::ATTRIBUTE_ConstantValue:
310             if (attr_constantvalue)
311                 buffer.MarkInvalid("duplicate ConstantValue attribute");
312             if (! ACC_FINAL())
313                 buffer.MarkInvalid("ConstantValue attribute without final");
314             attr_constantvalue = (ConstantValueAttribute*) attr;
315             break;
316         case AttributeInfo::ATTRIBUTE_Signature:
317             if (attr_signature)
318                 buffer.MarkInvalid("duplicate signature attribute");
319             attr_signature = (SignatureAttribute*) attr;
320             break;
321         case AttributeInfo::ATTRIBUTE_RuntimeVisibleAnnotations:
322             if (attr_visible_annotations)
323                 buffer.MarkInvalid("duplicate signature attribute");
324             attr_visible_annotations = (AnnotationsAttribute*) attr;
325             break;
326         case AttributeInfo::ATTRIBUTE_RuntimeInvisibleAnnotations:
327             if (attr_invisible_annotations)
328                 buffer.MarkInvalid("duplicate invisible attribute");
329             attr_invisible_annotations = (AnnotationsAttribute*) attr;
330             break;
331         case AttributeInfo::ATTRIBUTE_Generic:
332             // ignore
333             break;
334         default:
335             // invalid field attribute
336             buffer.MarkInvalid("invalid field attribute");
337         }
338     }
339 }
340 
Signature(const ConstantPool & pool,const Control &) const341 const char* FieldInfo::Signature(const ConstantPool& pool,
342                                  const Control& /*control*/) const
343 {
344     assert(pool[descriptor_index] -> Tag() == CPInfo::CONSTANT_Utf8);
345     const CPUtf8Info* sig =
346         /*(control.option.source >= JikesOption::SDK1_5 && attr_signature)
347         ? attr_signature -> Signature(pool)
348         :*/ (const CPUtf8Info*) pool[descriptor_index];
349     return sig -> Bytes();
350 }
351 
SignatureLength(const ConstantPool & pool,const Control &) const352 u2 FieldInfo::SignatureLength(const ConstantPool& pool,
353                               const Control& /*control*/) const
354 {
355     assert(pool[descriptor_index] -> Tag() == CPInfo::CONSTANT_Utf8);
356     const CPUtf8Info* sig =
357         /*(control.option.source >= JikesOption::SDK1_5 && attr_signature)
358         ? attr_signature -> Signature(pool)
359         :*/ (const CPUtf8Info*) pool[descriptor_index];
360     return sig -> Length();
361 }
362 
363 
MethodInfo(ClassFile & buffer)364 MethodInfo::MethodInfo(ClassFile& buffer)
365     : AccessFlags(buffer.GetU2())
366     , name_index(buffer.GetU2())
367     , descriptor_index(buffer.GetU2())
368     , attr_synthetic(NULL)
369     , attr_deprecated(NULL)
370     , attr_signature(NULL)
371     , attr_bridge(NULL)
372     , attr_code(NULL)
373     , attr_exceptions(NULL)
374     , attr_visible_annotations(NULL)
375     , attr_invisible_annotations(NULL)
376     , attr_param_visible_annotations(NULL)
377     , attr_param_invisible_annotations(NULL)
378     , attr_annotation_default(NULL)
379 {
380     unsigned count = buffer.GetU2();
381     while (count--)
382     {
383         AttributeInfo* attr = AttributeInfo::AllocateAttributeInfo(buffer);
384         attributes.Next() = attr;
385         switch (attr -> Tag())
386         {
387         case AttributeInfo::ATTRIBUTE_Synthetic:
388             if (attr_synthetic)
389                 buffer.MarkInvalid("duplicate synthetic attribute");
390             attr_synthetic = (SyntheticAttribute*) attr;
391             SetACC_SYNTHETIC();
392             break;
393         case AttributeInfo::ATTRIBUTE_Deprecated:
394             if (attr_deprecated)
395                 buffer.MarkInvalid("duplicate deprecated attribute");
396             attr_deprecated = (DeprecatedAttribute*) attr;
397             break;
398         case AttributeInfo::ATTRIBUTE_Code:
399             if (attr_code)
400                 buffer.MarkInvalid("duplicate code attribute");
401             if (ACC_NATIVE() || ACC_ABSTRACT())
402                 buffer.MarkInvalid("code for native or abstract method");
403             attr_code = (CodeAttribute*) attr;
404             break;
405         case AttributeInfo::ATTRIBUTE_Signature:
406             if (attr_signature)
407                 buffer.MarkInvalid("duplicate signature attribute");
408             attr_signature = (SignatureAttribute*) attr;
409             break;
410         case AttributeInfo::ATTRIBUTE_Bridge:
411             if (attr_bridge)
412                 buffer.MarkInvalid("duplicate bridge attribute");
413             attr_bridge = (BridgeAttribute*) attr;
414             break;
415         case AttributeInfo::ATTRIBUTE_Exceptions:
416             if (attr_exceptions)
417                 buffer.MarkInvalid("duplicate exceptions attribute");
418             attr_exceptions = (ExceptionsAttribute*) attr;
419             break;
420         case AttributeInfo::ATTRIBUTE_RuntimeVisibleAnnotations:
421             if (attr_visible_annotations)
422                 buffer.MarkInvalid("duplicate visible attribute");
423             attr_visible_annotations = (AnnotationsAttribute*) attr;
424             break;
425         case AttributeInfo::ATTRIBUTE_RuntimeInvisibleAnnotations:
426             if (attr_invisible_annotations)
427                 buffer.MarkInvalid("duplicate invisible attribute");
428             attr_invisible_annotations = (AnnotationsAttribute*) attr;
429             break;
430         case AttributeInfo::ATTRIBUTE_RuntimeVisibleParameterAnnotations:
431             if (attr_param_visible_annotations)
432                 buffer.MarkInvalid("duplicate param visible attribute");
433             attr_param_visible_annotations =
434                 (ParameterAnnotationsAttribute*) attr;
435             break;
436         case AttributeInfo::ATTRIBUTE_RuntimeInvisibleParameterAnnotations:
437             if (attr_param_invisible_annotations)
438                 buffer.MarkInvalid("duplicate param invisible attribute");
439             attr_param_invisible_annotations =
440                 (ParameterAnnotationsAttribute*) attr;
441             break;
442         case AttributeInfo::ATTRIBUTE_AnnotationDefault:
443             if (attr_annotation_default)
444                 buffer.MarkInvalid("duplicate annotation default attribute");
445             if (! ACC_ABSTRACT() || ! ACC_PUBLIC())
446                 buffer.MarkInvalid("annotation default on non-abstract or non-public method");
447             attr_annotation_default = (AnnotationDefaultAttribute*) attr;
448             break;
449         case AttributeInfo::ATTRIBUTE_Generic:
450             // ignore
451             break;
452         default:
453             // invalid method attribute
454             buffer.MarkInvalid("invalid method attribute");
455         }
456     }
457     if (! ACC_NATIVE() && ! ACC_ABSTRACT() && ! attr_code)
458         buffer.MarkInvalid("no code for non-native, non-abstract method");
459 }
460 
Signature(const ConstantPool & pool,const Control &) const461 const char* MethodInfo::Signature(const ConstantPool& pool,
462                                   const Control& /*control*/) const
463 {
464     assert(pool[descriptor_index] -> Tag() == CPInfo::CONSTANT_Utf8);
465     const CPUtf8Info* sig =
466         /*(control.option.source >= JikesOption::SDK1_5 && attr_signature)
467         ? attr_signature -> Signature(pool)
468         :*/ (const CPUtf8Info*) pool[descriptor_index];
469     return sig -> Bytes();
470 }
471 
SignatureLength(const ConstantPool & pool,const Control &) const472 u2 MethodInfo::SignatureLength(const ConstantPool& pool,
473                                const Control& /*control*/) const
474 {
475     assert(pool[descriptor_index] -> Tag() == CPInfo::CONSTANT_Utf8);
476     const CPUtf8Info* sig =
477         /*(control.option.source >= JikesOption::SDK1_5 && attr_signature)
478         ? attr_signature -> Signature(pool)
479         :*/ (const CPUtf8Info*) pool[descriptor_index];
480     return sig -> Length();
481 }
482 
483 
AttributeInfo(AttributeInfoTag _tag,ClassFile & buffer)484 AttributeInfo::AttributeInfo(AttributeInfoTag _tag, ClassFile& buffer)
485     : tag(_tag)
486     , attribute_name_index(buffer.GetU2())
487     , attribute_length(buffer.GetU4())
488 {}
489 
Tag(const CPUtf8Info * name)490 AttributeInfo::AttributeInfoTag AttributeInfo::Tag(const CPUtf8Info* name)
491 {
492     switch (name -> Length())
493     {
494     case 4:
495         if (! strcmp(name -> Bytes(), StringConstant::U8S_Code))
496             return ATTRIBUTE_Code;
497         break;
498     case 8:
499         if (! strcmp(name -> Bytes(), StringConstant::U8S_StackMap))
500             return ATTRIBUTE_StackMap;
501         break;
502     case 9:
503         if (! strcmp(name -> Bytes(), StringConstant::U8S_Signature))
504             return ATTRIBUTE_Signature;
505         if (! strcmp(name -> Bytes(), StringConstant::U8S_Synthetic))
506             return ATTRIBUTE_Synthetic;
507         break;
508     case 10:
509         if (! strcmp(name -> Bytes(), StringConstant::U8S_Deprecated))
510             return ATTRIBUTE_Deprecated;
511         if (! strcmp(name -> Bytes(), StringConstant::U8S_Exceptions))
512             return ATTRIBUTE_Exceptions;
513         if (! strcmp(name -> Bytes(), StringConstant::U8S_SourceFile))
514             return ATTRIBUTE_SourceFile;
515         break;
516     case 12:
517         if (! strcmp(name -> Bytes(), StringConstant::U8S_InnerClasses))
518             return ATTRIBUTE_InnerClasses;
519         break;
520     case 13:
521         if (! strcmp(name -> Bytes(), StringConstant::U8S_ConstantValue))
522             return ATTRIBUTE_ConstantValue;
523         break;
524     case 15:
525         if (! strcmp(name -> Bytes(), StringConstant::U8S_LineNumberTable))
526             return ATTRIBUTE_LineNumberTable;
527         if (! strcmp(name -> Bytes(), StringConstant::U8S_EnclosingMethod))
528             return ATTRIBUTE_EnclosingMethod;
529         break;
530     case 17:
531         if (! strcmp(name -> Bytes(), StringConstant::U8S_AnnotationDefault))
532             return ATTRIBUTE_AnnotationDefault;
533         break;
534     case 18:
535         if (! strcmp(name -> Bytes(), StringConstant::U8S_LocalVariableTable))
536             return ATTRIBUTE_LocalVariableTable;
537         break;
538     case 22:
539         if (! strcmp(name -> Bytes(),
540                      StringConstant::U8S_LocalVariableTypeTable))
541             return ATTRIBUTE_LocalVariableTypeTable;
542         break;
543     case 25:
544         if (! strcmp(name -> Bytes(),
545                      StringConstant::U8S_RuntimeVisibleAnnotations))
546             return ATTRIBUTE_RuntimeVisibleAnnotations;
547         break;
548     case 27:
549         if (! strcmp(name -> Bytes(),
550                      StringConstant::U8S_RuntimeInvisibleAnnotations))
551             return ATTRIBUTE_RuntimeInvisibleAnnotations;
552         break;
553     case 34:
554         if (! strcmp(name -> Bytes(),
555                      StringConstant::U8S_RuntimeVisibleParameterAnnotations))
556             return ATTRIBUTE_RuntimeVisibleParameterAnnotations;
557         break;
558     case 36:
559         if (! strcmp(name -> Bytes(),
560                      StringConstant::U8S_RuntimeInvisibleParameterAnnotations))
561             return ATTRIBUTE_RuntimeInvisibleParameterAnnotations;
562     }
563     return ATTRIBUTE_Generic;
564 }
565 
AllocateAttributeInfo(ClassFile & buffer)566 AttributeInfo* AttributeInfo::AllocateAttributeInfo(ClassFile& buffer)
567 {
568     u2 index = buffer.PeekU2();
569     if (buffer.Pool()[index] -> Tag() != CPInfo::CONSTANT_Utf8)
570     {
571         buffer.MarkInvalid("attribute name not utf8 constant");
572         return new UnknownAttribute(buffer);
573     }
574     switch (Tag((CPUtf8Info*) buffer.Pool()[index]))
575     {
576     case ATTRIBUTE_ConstantValue:
577         return new ConstantValueAttribute(buffer);
578     case ATTRIBUTE_Code:
579         return new CodeAttribute(buffer);
580     case ATTRIBUTE_Exceptions:
581         return new ExceptionsAttribute(buffer);
582     case ATTRIBUTE_InnerClasses:
583         return new InnerClassesAttribute(buffer);
584     case ATTRIBUTE_SourceFile:
585         return new SourceFileAttribute(buffer);
586     case ATTRIBUTE_Synthetic:
587         return new SyntheticAttribute(buffer);
588     case ATTRIBUTE_LineNumberTable:
589         return new LineNumberTableAttribute(buffer);
590     case ATTRIBUTE_LocalVariableTable:
591         return new LocalVariableTableAttribute(buffer, false);
592     case ATTRIBUTE_Deprecated:
593         return new DeprecatedAttribute(buffer);
594     case ATTRIBUTE_Signature:
595         return new SignatureAttribute(buffer);
596     case ATTRIBUTE_Bridge:
597         return new BridgeAttribute(buffer);
598     case ATTRIBUTE_EnclosingMethod:
599         return new EnclosingMethodAttribute(buffer);
600     case ATTRIBUTE_LocalVariableTypeTable:
601         return new LocalVariableTableAttribute(buffer, true);
602     case ATTRIBUTE_StackMap:
603         return new StackMapAttribute(buffer);
604     case ATTRIBUTE_RuntimeVisibleAnnotations:
605         return new AnnotationsAttribute(buffer, true);
606     case ATTRIBUTE_RuntimeInvisibleAnnotations:
607         return new AnnotationsAttribute(buffer, false);
608     case ATTRIBUTE_RuntimeVisibleParameterAnnotations:
609         return new ParameterAnnotationsAttribute(buffer, true);
610     case ATTRIBUTE_RuntimeInvisibleParameterAnnotations:
611         return new ParameterAnnotationsAttribute(buffer, false);
612     case ATTRIBUTE_AnnotationDefault:
613         return new AnnotationDefaultAttribute(buffer);
614     default:
615         return new UnknownAttribute(buffer);
616     }
617 }
618 
619 
UnknownAttribute(ClassFile & buffer)620 UnknownAttribute::UnknownAttribute(ClassFile& buffer)
621     : AttributeInfo(ATTRIBUTE_Generic, buffer)
622 {
623     info_length = buffer.GetN(info, attribute_length);
624 }
625 
626 
ConstantValueAttribute(ClassFile & buffer)627 ConstantValueAttribute::ConstantValueAttribute(ClassFile& buffer)
628     : AttributeInfo(ATTRIBUTE_ConstantValue, buffer)
629     , constantvalue_index(buffer.GetU2())
630 {
631     if (attribute_length != 2)
632         buffer.MarkInvalid("bad constant value attribute length");
633     if (! buffer.Pool()[constantvalue_index] -> Constant())
634         buffer.MarkInvalid("bad constant value attribute type");
635 }
636 
637 
CodeAttribute(ClassFile & buffer)638 CodeAttribute::CodeAttribute(ClassFile& buffer)
639     : AttributeInfo(ATTRIBUTE_Code, buffer)
640     , max_stack(buffer.GetU2())
641     , max_locals(buffer.GetU2())
642     , code(8, 4)
643     , exception_table(6, 16)
644     , attributes(6, 16)
645     , attr_linenumbers(NULL)
646     , attr_locals(NULL)
647     , attr_stackmap(NULL)
648 {
649     unsigned remaining = attribute_length - 12;
650     // +2 for max_stack, +2 for max_locals, +4 for code_length,
651     // +2 for exception_table_length, +2 for attributes_count
652     u4 code_length = buffer.GetU4();
653     remaining -= code_length;
654     buffer.SkipN(code_length);
655 
656     u2 exception_table_length = buffer.GetU2();
657     remaining -= exception_table_length * 8;
658     while (exception_table_length--)
659     {
660         ExceptionElement& entry = exception_table.Next();
661         entry.start_pc = buffer.GetU2();
662         entry.end_pc = buffer.GetU2();
663         entry.handler_pc = buffer.GetU2();
664         entry.catch_type = buffer.GetU2();
665         if (entry.catch_type &&
666             buffer.Pool()[entry.catch_type] -> Tag() != CPInfo::CONSTANT_Class)
667         {
668             buffer.MarkInvalid("bad type for exception table catch type");
669         }
670     }
671 
672     u2 attributes_count = buffer.GetU2();
673     while (attributes_count--)
674     {
675         AttributeInfo* attr = AllocateAttributeInfo(buffer);
676         remaining -= 6 + attr -> AttributeLength();
677         attributes.Next() = attr;
678         switch (attr -> Tag())
679         {
680         case AttributeInfo::ATTRIBUTE_LineNumberTable:
681             if (attr_linenumbers)
682                 buffer.MarkInvalid("duplicate line number table");
683             attr_linenumbers = (LineNumberTableAttribute*) attr;
684             break;
685         case AttributeInfo::ATTRIBUTE_LocalVariableTable:
686             if (attr_locals)
687                 buffer.MarkInvalid("duplicate local variable table");
688             attr_locals = (LocalVariableTableAttribute*) attr;
689             break;
690         case AttributeInfo::ATTRIBUTE_LocalVariableTypeTable:
691             if (attr_local_types)
692                 buffer.MarkInvalid("duplicate local variable type table");
693             attr_local_types = (LocalVariableTableAttribute*) attr;
694             break;
695         case AttributeInfo::ATTRIBUTE_StackMap:
696             if (attr_stackmap)
697                 buffer.MarkInvalid("duplicate stack map");
698             attr_stackmap = (StackMapAttribute*) attr;
699             break;
700         case AttributeInfo::ATTRIBUTE_Generic:
701             // ignore
702             break;
703         default:
704             buffer.MarkInvalid("invalid code attribute");
705         }
706     }
707     if (remaining)
708         buffer.MarkInvalid("bytes remaining at end of code attribute");
709 }
710 
711 
712 #ifdef JIKES_DEBUG
Print(const ConstantPool & constant_pool,int fill) const713 void CodeAttribute::Print(const ConstantPool& constant_pool, int fill) const
714 {
715     assert(! fill);
716     PrintPrefix("Code", constant_pool, 0);
717     Coutput << endl << " max_stack: " << (unsigned) max_stack
718             << ", max_locals: " << (unsigned) max_locals
719             << ", code_length: " << (unsigned) code.Length() << endl;
720     Operators::OpDmp(constant_pool, code);
721     Coutput << " exception_table_length: "
722             << (unsigned) exception_table.Length() << endl;
723     for (unsigned i = 0; i < exception_table.Length(); i++)
724     {
725         Coutput << "  start " << (unsigned) exception_table[i].start_pc
726                 << ", end " << (unsigned) exception_table[i].end_pc
727                 << ", handler " << (unsigned) exception_table[i].handler_pc
728                 << ", catch_type " << (unsigned) exception_table[i].catch_type;
729         if (! exception_table[i].catch_type)
730             Coutput << " (all)";
731         else if (constant_pool[exception_table[i].catch_type] -> Tag() ==
732                  CPInfo::CONSTANT_Class)
733         {
734             Coutput << '=';
735             constant_pool[exception_table[i].catch_type] ->
736                 Describe(constant_pool);
737         }
738         else Coutput << "(invalid)";
739         Coutput << endl;
740     }
741     Coutput << " attribute_count: " << (unsigned) attributes.Length() << endl;
742     for (unsigned j = 0; j < attributes.Length(); j++)
743         attributes[j] -> Print(constant_pool, 2);
744 }
745 #endif // JIKES_DEBUG
746 
747 
ExceptionsAttribute(ClassFile & buffer)748 ExceptionsAttribute::ExceptionsAttribute(ClassFile& buffer)
749     : AttributeInfo(ATTRIBUTE_Exceptions, buffer)
750     , exception_index_table(6, 16)
751 {
752     unsigned count = buffer.GetU2();
753     if (attribute_length != count * 2 + 2)
754         buffer.MarkInvalid("bad exceptions attribute length");
755     while (count--)
756     {
757         u2 index = buffer.GetU2();
758         exception_index_table.Next() = index;
759         if (buffer.Pool()[index] -> Tag() != CPInfo::CONSTANT_Class)
760             buffer.MarkInvalid("bad type for exceptions attribute entry");
761     }
762 }
763 
764 
InnerClassesAttribute(ClassFile & buffer)765 InnerClassesAttribute::InnerClassesAttribute(ClassFile& buffer)
766     : AttributeInfo(ATTRIBUTE_InnerClasses, buffer)
767     , classes(6, 16)
768 {
769     unsigned count = buffer.GetU2();
770     if (attribute_length != count * 8 + 2)
771         buffer.MarkInvalid("bad inner classes attribute length");
772     while (count--)
773     {
774         InnerClassesElement& entry = classes.Next();
775         entry.inner_class_info_index = buffer.GetU2();
776         entry.outer_class_info_index = buffer.GetU2();
777         entry.inner_name_index = buffer.GetU2();
778         entry.inner_class_access_flags.SetFlags(buffer.GetU2());
779         if ((buffer.Pool()[entry.inner_class_info_index] -> Tag() !=
780              CPInfo::CONSTANT_Class) ||
781             (entry.outer_class_info_index &&
782              (buffer.Pool()[entry.outer_class_info_index] -> Tag() !=
783               CPInfo::CONSTANT_Class)) ||
784             (entry.inner_name_index &&
785              (buffer.Pool()[entry.inner_name_index] -> Tag() !=
786               CPInfo::CONSTANT_Utf8)) ||
787             ! entry.inner_class_access_flags.LegalAccess())
788         {
789             buffer.MarkInvalid("bad type in inner classes attribute");
790         }
791     }
792 }
793 
794 
SyntheticAttribute(ClassFile & buffer)795 SyntheticAttribute::SyntheticAttribute(ClassFile& buffer)
796     : AttributeInfo(ATTRIBUTE_Synthetic, buffer)
797 {
798     if (attribute_length)
799         buffer.MarkInvalid("bad synthetic attribute length");
800 }
801 
802 
SourceFileAttribute(ClassFile & buffer)803 SourceFileAttribute::SourceFileAttribute(ClassFile& buffer)
804     : AttributeInfo(ATTRIBUTE_SourceFile, buffer)
805     , sourcefile_index(buffer.GetU2())
806 {
807     if (attribute_length != 2)
808         buffer.MarkInvalid("bad source file attribute length");
809     if (buffer.Pool()[sourcefile_index] -> Tag() != CPInfo::CONSTANT_Utf8)
810         buffer.MarkInvalid("bad type for source file attribute");
811 }
812 
813 
LineNumberTableAttribute(ClassFile & buffer)814 LineNumberTableAttribute::LineNumberTableAttribute(ClassFile& buffer)
815     : AttributeInfo(ATTRIBUTE_LineNumberTable, buffer)
816     , line_number_table(6, 16)
817 {
818     unsigned count = buffer.GetU2();
819     if(attribute_length != count * 4 + 2)
820         buffer.MarkInvalid("bad line number table length");
821     while (count--)
822     {
823         LineNumberElement& entry = line_number_table.Next();
824         entry.start_pc = buffer.GetU2();
825         entry.line_number = buffer.GetU2();
826     }
827 }
828 
829 
LocalVariableTableAttribute(ClassFile & buffer,bool generic)830 LocalVariableTableAttribute::LocalVariableTableAttribute(ClassFile& buffer,
831                                                          bool generic)
832     : AttributeInfo(generic ? ATTRIBUTE_LocalVariableTypeTable
833                     : ATTRIBUTE_LocalVariableTable, buffer)
834     , local_variable_table(6, 16)
835 {
836     unsigned count = buffer.GetU2();
837     if (attribute_length != count * 10 + 2)
838         buffer.MarkInvalid("bad local variable table length");
839     while (count--)
840     {
841         LocalVariableElement& entry = local_variable_table.Next();
842         entry.start_pc = buffer.GetU2();
843         entry.length = buffer.GetU2();
844         entry.name_index = buffer.GetU2();
845         entry.descriptor_index = buffer.GetU2();
846         entry.index = buffer.GetU2();
847         if ((buffer.Pool()[entry.name_index] -> Tag() !=
848              CPInfo::CONSTANT_Utf8) ||
849             (buffer.Pool()[entry.descriptor_index] -> Tag() !=
850              CPInfo::CONSTANT_Utf8))
851         {
852             buffer.MarkInvalid("bad type for local variable table entry");
853         }
854     }
855 }
856 
857 
DeprecatedAttribute(ClassFile & buffer)858 DeprecatedAttribute::DeprecatedAttribute(ClassFile& buffer)
859     : AttributeInfo(ATTRIBUTE_Deprecated, buffer)
860 {
861     if (attribute_length)
862         buffer.MarkInvalid("bad deprecated attribute length");
863 }
864 
865 
SignatureAttribute(ClassFile & buffer)866 SignatureAttribute::SignatureAttribute(ClassFile& buffer)
867     : AttributeInfo(ATTRIBUTE_Signature, buffer)
868     , signature_index(buffer.GetU2())
869 {
870     if (attribute_length != 2)
871         buffer.MarkInvalid("bad signature attribute length");
872     if (buffer.Pool()[signature_index] -> Tag() != CPInfo::CONSTANT_Utf8)
873         buffer.MarkInvalid("bad type for signature attribute");
874 }
875 
876 
BridgeAttribute(ClassFile & buffer)877 BridgeAttribute::BridgeAttribute(ClassFile& buffer)
878     : AttributeInfo(ATTRIBUTE_Bridge, buffer)
879 {
880     if (attribute_length)
881         buffer.MarkInvalid("bad bridge attribute length");
882 }
883 
884 
Read(ClassFile & buffer)885 void StackMapAttribute::StackMapFrame::VerificationTypeInfo::Read(ClassFile& buffer)
886 {
887     int type = buffer.GetU1();
888     tag = (VerificationTypeInfoTag) type;
889     if (type < TYPE_Top || type > TYPE_Uninitialized)
890     {
891         type = TYPE_Top;
892         buffer.MarkInvalid("bad stack map type");
893     }
894     if (type >= TYPE_Object)
895     {
896         info = buffer.GetU2();
897         if (type == TYPE_Object &&
898             buffer.Pool()[info] -> Tag() != CPInfo::CONSTANT_Class)
899         {
900             buffer.MarkInvalid("bad stack map info");
901         }
902     }
903 }
904 
StackMapFrame(ClassFile & buffer)905 StackMapAttribute::StackMapFrame::StackMapFrame(ClassFile& buffer)
906     : offset(buffer.GetU2())
907     , locals(6, 16)
908     , stack(6, 16)
909     , frame_size(6)
910     // +2 for offset, +2 for locals_size, +2 for stack_size
911 {
912     unsigned count = buffer.GetU2();
913     while (count--)
914     {
915         unsigned index = locals.NextIndex();
916         locals[index].Read(buffer);
917         frame_size += locals[index].Size();
918     }
919     count = buffer.GetU2();
920     while (count--)
921     {
922         unsigned index = stack.NextIndex();
923         stack[index].Read(buffer);
924         frame_size += stack[index].Size();
925     }
926 }
927 
StackMapAttribute(ClassFile & buffer)928 StackMapAttribute::StackMapAttribute(ClassFile& buffer)
929     : AttributeInfo(ATTRIBUTE_StackMap, buffer)
930     , frames(6, 16)
931 {
932     unsigned remaining = attribute_length - 2; // -2 for frame_count
933     unsigned count = buffer.GetU2();
934     while (count--)
935     {
936         unsigned index = frames.NextIndex();
937         frames[index] = new StackMapFrame(buffer);
938         remaining -= frames[index] -> FrameSize();
939     }
940     if (remaining)
941         buffer.MarkInvalid("bytes remaining at end of stack map attribute");
942 }
943 
944 
AllocateAnnotationComponentValue(ClassFile & buffer)945 AnnotationComponentValue* AnnotationComponentValue::AllocateAnnotationComponentValue(ClassFile& buffer)
946 {
947     AnnotationComponentValueTag tag =
948         (AnnotationComponentValueTag) buffer.GetU1();
949     switch (tag)
950     {
951     case COMPONENT_boolean: case COMPONENT_byte: case COMPONENT_char:
952     case COMPONENT_short: case COMPONENT_int: case COMPONENT_long:
953     case COMPONENT_float: case COMPONENT_double: case COMPONENT_string:
954     case COMPONENT_class:
955         return new AnnotationComponentConstant(buffer, tag);
956     case COMPONENT_enum:
957         return new AnnotationComponentEnum(buffer);
958     case COMPONENT_annotation:
959         return new AnnotationComponentAnnotation(buffer);
960     case COMPONENT_array:
961         return new AnnotationComponentArray(buffer);
962     default:
963         buffer.MarkInvalid("unknown annotation component value");
964         return new AnnotationComponentValue(tag);
965     }
966 }
967 
968 
AnnotationComponentConstant(ClassFile & buffer,AnnotationComponentValueTag _tag)969 AnnotationComponentConstant::AnnotationComponentConstant(ClassFile& buffer,
970                                                          AnnotationComponentValueTag _tag)
971     : AnnotationComponentValue(_tag)
972     , index(buffer.GetU2())
973 {
974     switch (tag)
975     {
976     case COMPONENT_boolean: case COMPONENT_byte: case COMPONENT_char:
977     case COMPONENT_short: case COMPONENT_int:
978         if (buffer.Pool()[index] -> Tag() != CPInfo::CONSTANT_Integer)
979             buffer.MarkInvalid("bad int-like annotation constant");
980         break;
981     case COMPONENT_long:
982         if (buffer.Pool()[index] -> Tag() != CPInfo::CONSTANT_Long)
983             buffer.MarkInvalid("bad long annotation constant");
984         break;
985     case COMPONENT_float:
986         if (buffer.Pool()[index] -> Tag() != CPInfo::CONSTANT_Float)
987             buffer.MarkInvalid("bad float annotation constant");
988         break;
989     case COMPONENT_double:
990         if (buffer.Pool()[index] -> Tag() != CPInfo::CONSTANT_Double)
991             buffer.MarkInvalid("bad double annotation constant");
992         break;
993     case COMPONENT_string:
994         if (buffer.Pool()[index] -> Tag() != CPInfo::CONSTANT_String)
995             buffer.MarkInvalid("bad string annotation constant");
996         break;
997     case COMPONENT_class:
998         if (buffer.Pool()[index] -> Tag() != CPInfo::CONSTANT_Class)
999             buffer.MarkInvalid("bad class annotation constant");
1000         break;
1001     default:
1002         assert(false && "invalid annotation constant");
1003     }
1004 }
1005 
1006 
AnnotationComponentEnum(ClassFile & buffer)1007 AnnotationComponentEnum::AnnotationComponentEnum(ClassFile& buffer)
1008     : AnnotationComponentValue(COMPONENT_enum)
1009     , type_name_index(buffer.GetU2())
1010     , const_name_index(buffer.GetU2())
1011 {
1012     if (buffer.Pool()[type_name_index] -> Tag() != CPInfo::CONSTANT_Class ||
1013         buffer.Pool()[const_name_index] -> Tag() != CPInfo::CONSTANT_Utf8)
1014     {
1015         buffer.MarkInvalid("bad type for annotation component enum");
1016     }
1017 }
1018 
1019 
AnnotationComponentAnnotation(ClassFile & buffer)1020 AnnotationComponentAnnotation::AnnotationComponentAnnotation(ClassFile& buffer)
1021     : AnnotationComponentValue(COMPONENT_annotation)
1022 {
1023     attr_value = new Annotation(buffer);
1024 }
1025 
~AnnotationComponentAnnotation()1026 AnnotationComponentAnnotation::~AnnotationComponentAnnotation()
1027 {
1028     delete attr_value;
1029 }
1030 
Length() const1031 u2 AnnotationComponentAnnotation::Length() const
1032 {
1033     return 1 + attr_value -> Length(); // +1 tag
1034 }
1035 
Put(OutputBuffer & out) const1036 void AnnotationComponentAnnotation::Put(OutputBuffer& out) const
1037 {
1038     AnnotationComponentValue::Put(out);
1039     attr_value -> Put(out);
1040 }
1041 
1042 #ifdef JIKES_DEBUG
Print(const ConstantPool & pool) const1043 void AnnotationComponentAnnotation::Print(const ConstantPool& pool) const
1044 {
1045     attr_value -> Print(pool);
1046 }
1047 #endif // JIKES_DEBUG
1048 
1049 
AnnotationComponentArray(ClassFile & buffer)1050 AnnotationComponentArray::AnnotationComponentArray(ClassFile& buffer)
1051     : AnnotationComponentValue(COMPONENT_array)
1052     , values(6, 16)
1053     , len(3) // +1 tag, +2 num_values
1054 {
1055     unsigned count = buffer.GetU2();
1056     while (count--)
1057         AddValue(AllocateAnnotationComponentValue(buffer));
1058 }
1059 
1060 
Annotation(ClassFile & buffer)1061 Annotation::Annotation(ClassFile& buffer)
1062     : type_index(buffer.GetU2())
1063     , components(6, 16)
1064 {
1065     if (buffer.Pool()[type_index] -> Tag() != CPInfo::CONSTANT_Utf8)
1066         buffer.MarkInvalid("bad type for annotation");
1067     unsigned i = buffer.GetU2();
1068     while (i--)
1069     {
1070         Component& component = components.Next();
1071         u2 index = buffer.GetU2();
1072         component.component_name_index = index;
1073         if (buffer.Pool()[index] -> Tag() != CPInfo::CONSTANT_Utf8)
1074             buffer.MarkInvalid("bad type for annotation component name");
1075         component.component_value =
1076             AnnotationComponentValue::AllocateAnnotationComponentValue(buffer);
1077     }
1078 }
1079 
1080 
AnnotationsAttribute(ClassFile & buffer,bool visible)1081 AnnotationsAttribute::AnnotationsAttribute(ClassFile& buffer, bool visible)
1082     : AttributeInfo((visible ? ATTRIBUTE_RuntimeVisibleAnnotations
1083                      : ATTRIBUTE_RuntimeInvisibleAnnotations), buffer)
1084     , annotations(6, 16)
1085 {
1086     unsigned count = buffer.GetU2();
1087     unsigned length = 2; // +2 num_annotations
1088     while (count--)
1089     {
1090         Annotation* value = new Annotation(buffer);
1091         annotations.Next() = value;
1092         length += value -> Length();
1093     }
1094     if (length != attribute_length)
1095         buffer.MarkInvalid("bad annotations attribute length");
1096 }
1097 
1098 
ParameterAnnotationsAttribute(ClassFile & buffer,bool visible)1099 ParameterAnnotationsAttribute::ParameterAnnotationsAttribute(ClassFile& buffer,
1100                                                              bool visible)
1101     : AttributeInfo((visible ? ATTRIBUTE_RuntimeVisibleParameterAnnotations
1102                      : ATTRIBUTE_RuntimeInvisibleParameterAnnotations), buffer)
1103     , num_parameters(buffer.GetU1())
1104     , parameters(NULL)
1105 {
1106     unsigned length = 1 + 2 * num_parameters;
1107     // +1 num_parameters, +2 num_annotations * num_parameters
1108     if (num_parameters)
1109         parameters = new Tuple<Annotation*>[num_parameters];
1110     for (unsigned i = 0; i < num_parameters; i++)
1111     {
1112         unsigned count = buffer.GetU2();
1113         while (count--)
1114         {
1115             Annotation* value = new Annotation(buffer);
1116             parameters[i].Next() = value;
1117             length += value -> Length();
1118         }
1119     }
1120     if (length != attribute_length)
1121         buffer.MarkInvalid("bad parameter annotations attribute length");
1122 }
1123 
1124 
AnnotationDefaultAttribute(ClassFile & buffer)1125 AnnotationDefaultAttribute::AnnotationDefaultAttribute(ClassFile& buffer)
1126     : AttributeInfo(ATTRIBUTE_AnnotationDefault, buffer)
1127 {
1128     default_value =
1129         AnnotationComponentValue::AllocateAnnotationComponentValue(buffer);
1130     if (default_value -> Length() != attribute_length)
1131         buffer.MarkInvalid("bad annotation default attribute length");
1132 }
1133 
1134 
EnclosingMethodAttribute(ClassFile & buffer)1135 EnclosingMethodAttribute::EnclosingMethodAttribute(ClassFile& buffer)
1136     : AttributeInfo(ATTRIBUTE_EnclosingMethod, buffer)
1137     , class_index(buffer.GetU2())
1138     , name_and_type_index(buffer.GetU2())
1139 {
1140     if (attribute_length != 4)
1141         buffer.MarkInvalid("bad enclosing method attribute length");
1142     if (buffer.Pool()[class_index] -> Tag() != CPInfo::CONSTANT_Class ||
1143         (name_and_type_index &&
1144          (buffer.Pool()[name_and_type_index] -> Tag() !=
1145           CPInfo::CONSTANT_NameAndType)))
1146     {
1147         buffer.MarkInvalid("bad type for enclosing method attribute");
1148     }
1149 }
1150 
1151 
ClassFile(const char * buf,unsigned buf_size)1152 ClassFile::ClassFile(const char* buf, unsigned buf_size)
1153     : problem(NULL)
1154     , buffer(buf)
1155     , buffer_tail(buf + buf_size)
1156     , magic(GetU4())
1157     , minor_version(GetU2())
1158     , major_version(GetU2())
1159     , constant_pool(8, 4)
1160     , interfaces(6, 16)
1161     , fields(6, 16)
1162     , methods(6, 16)
1163     , attributes(6, 16)
1164     , attr_synthetic(NULL)
1165     , attr_deprecated(NULL)
1166     , attr_signature(NULL)
1167     , attr_sourcefile(NULL)
1168     , attr_innerclasses(NULL)
1169     , attr_visible_annotations(NULL)
1170     , attr_invisible_annotations(NULL)
1171     , attr_enclosing_method(NULL)
1172 {
1173     if (magic != MAGIC || major_version < 45)
1174         MarkInvalid("unknown class format");
1175     u2 count = GetU2();
1176     if (! count)
1177         MarkInvalid("empty constant pool");
1178     else
1179     {
1180         while (--count) // skip entry 0
1181         {
1182             CPInfo* entry = CPInfo::AllocateCPInfo(*this);
1183             if (entry -> Large())
1184                 count--; // skip next entry for eight-byte constants
1185             constant_pool.SetNext(entry);
1186         }
1187     }
1188     if (! constant_pool.Check())
1189         MarkInvalid("invalid constant pool");
1190     access_flags = GetU2();
1191     if (! LegalAccess())
1192         MarkInvalid("illegal access");
1193     this_class = GetU2();
1194     if (constant_pool[this_class] -> Tag() != CPInfo::CONSTANT_Class)
1195         MarkInvalid("illegal this class");
1196     super_class = GetU2();
1197     if (super_class &&
1198         constant_pool[super_class] -> Tag() != CPInfo::CONSTANT_Class)
1199     {
1200         MarkInvalid("illegal super class");
1201     }
1202     count = GetU2();
1203     while (count--)
1204     {
1205         u2 inter = GetU2();
1206         if (constant_pool[inter] -> Tag() != CPInfo::CONSTANT_Class)
1207             MarkInvalid("illegal interface");
1208         interfaces.Next() = inter;
1209     }
1210 
1211     count = GetU2();
1212     while (count--)
1213         fields.Next() = new FieldInfo(*this);
1214     count = GetU2();
1215     while (count--)
1216         methods.Next() = new MethodInfo(*this);
1217     count = GetU2();
1218     while (count--)
1219     {
1220         AttributeInfo* attr = AttributeInfo::AllocateAttributeInfo(*this);
1221         attributes.Next() = attr;
1222         switch (attr -> Tag())
1223         {
1224         case AttributeInfo::ATTRIBUTE_Synthetic:
1225             if (attr_synthetic)
1226                 MarkInvalid("duplicate synthetic attribute");
1227             attr_synthetic = (SyntheticAttribute*) attr;
1228             SetACC_SYNTHETIC();
1229             break;
1230         case AttributeInfo::ATTRIBUTE_Deprecated:
1231             if (attr_deprecated)
1232                 MarkInvalid("duplicate deprecated attribute");
1233             attr_deprecated = (DeprecatedAttribute*) attr;
1234             break;
1235         case AttributeInfo::ATTRIBUTE_Signature:
1236             if (attr_signature)
1237                 MarkInvalid("duplicate signature attribute");
1238             attr_signature = (SignatureAttribute*) attr;
1239             break;
1240         case AttributeInfo::ATTRIBUTE_SourceFile:
1241             if (attr_sourcefile)
1242                 MarkInvalid("duplicate source file attribute");
1243             attr_sourcefile = (SourceFileAttribute*) attr;
1244             break;
1245         case AttributeInfo::ATTRIBUTE_InnerClasses:
1246             if (attr_innerclasses)
1247                 MarkInvalid("duplicate inner classes attribute");
1248             attr_innerclasses = (InnerClassesAttribute*) attr;
1249             break;
1250         case AttributeInfo::ATTRIBUTE_RuntimeVisibleAnnotations:
1251             if (attr_visible_annotations)
1252                 MarkInvalid("duplicate visible annotations attribute");
1253             attr_visible_annotations = (AnnotationsAttribute*) attr;
1254             break;
1255         case AttributeInfo::ATTRIBUTE_RuntimeInvisibleAnnotations:
1256             if (attr_invisible_annotations)
1257                 MarkInvalid("duplicate invisible annotations attribute");
1258             attr_invisible_annotations = (AnnotationsAttribute*) attr;
1259             break;
1260         case AttributeInfo::ATTRIBUTE_EnclosingMethod:
1261             if (attr_enclosing_method)
1262                 MarkInvalid("duplicate enclosing method attribute");
1263             attr_enclosing_method = (EnclosingMethodAttribute*) attr;
1264             break;
1265         case AttributeInfo::ATTRIBUTE_Generic:
1266             // ignore
1267             break;
1268         default:
1269             MarkInvalid("invalid method attribute");
1270         }
1271     }
1272 }
1273 
Write(TypeSymbol * unit_type) const1274 void ClassFile::Write(TypeSymbol* unit_type) const
1275 {
1276     Semantic* sem = unit_type -> semantic_environment -> sem;
1277     Control& control = sem -> control;
1278     OutputBuffer output_buffer;
1279 
1280     const char* class_file_name = unit_type -> ClassName();
1281     if (control.option.verbose)
1282         Coutput << "[write " << class_file_name << "]" << endl;
1283     assert (Valid());
1284     if (control.option.nowrite)
1285         return;
1286 
1287     unsigned i;
1288     output_buffer.PutU4(MAGIC);
1289     output_buffer.PutU2(minor_version);
1290     output_buffer.PutU2(major_version);
1291 
1292     output_buffer.PutU2(constant_pool.Length());
1293     assert(constant_pool.Check());
1294     for (i = 1; i < constant_pool.Length(); i++)
1295     {
1296         constant_pool[i] -> Put(output_buffer);
1297         if (constant_pool[i] -> Large())
1298             i++; // skip the next entry for eight-byte constants
1299     }
1300 
1301     output_buffer.PutU2(access_flags);
1302     output_buffer.PutU2(this_class);
1303     output_buffer.PutU2(super_class);
1304     output_buffer.PutU2(interfaces.Length());
1305     for (i = 0; i < interfaces.Length(); i++)
1306         output_buffer.PutU2(interfaces[i]);
1307     output_buffer.PutU2(fields.Length());
1308     for (i = 0; i < fields.Length(); i++)
1309         fields[i] -> Put(output_buffer);
1310     output_buffer.PutU2(methods.Length());
1311     for (i = 0; i < methods.Length(); i++)
1312         methods[i] -> Put(output_buffer);
1313     output_buffer.PutU2(attributes.Length());
1314     for (i = 0; i < attributes.Length(); i++)
1315         attributes[i] -> Put(output_buffer);
1316 
1317     // Now output to file
1318     if (! output_buffer.WriteToFile(class_file_name))
1319     {
1320         int length = strlen(class_file_name);
1321         wchar_t* name = new wchar_t[length + 1];
1322         for (int j = 0; j < length; j++)
1323             name[j] = class_file_name[j];
1324         name[length] = U_NULL;
1325 
1326         sem -> ReportSemError(SemanticError::CANNOT_WRITE_FILE,
1327                               unit_type -> declaration, name);
1328         delete [] name;
1329     }
1330 }
1331 
1332 
1333 //
1334 // This processes a descriptor, and returns the associated type, or else
1335 // control.no_type if the descriptor is bad. Signature is assumed to be null
1336 // terminated, and this adjusts the pointer to the spot just after the type
1337 // parsed.
1338 //
ProcessSignature(TypeSymbol * base_type,const char * & signature,TokenIndex tok)1339 TypeSymbol* Semantic::ProcessSignature(TypeSymbol* base_type,
1340                                        const char*& signature, TokenIndex tok)
1341 {
1342     TypeSymbol* type;
1343     int num_dimensions = 0;
1344     for ( ; *signature == U_LEFT_BRACKET; signature++)
1345         num_dimensions++;
1346     switch (*signature++)
1347     {
1348     case U_B:
1349         type = control.byte_type;
1350         break;
1351     case U_C:
1352         type = control.char_type;
1353         break;
1354     case U_D:
1355         type = control.double_type;
1356         break;
1357     case U_F:
1358         type = control.float_type;
1359         break;
1360     case U_I:
1361         type = control.int_type;
1362         break;
1363     case U_J:
1364         type = control.long_type;
1365         break;
1366     case U_S:
1367         type = control.short_type;
1368         break;
1369     case U_Z:
1370         type = control.boolean_type;
1371         break;
1372     case U_V:
1373         if (num_dimensions)
1374             return control.no_type;
1375         type = control.void_type;
1376         break;
1377     case U_L:
1378         {
1379             const char* str = signature;
1380             while (*str && *str != U_SEMICOLON)
1381                 str++;
1382             if (! *str)
1383             {
1384                 signature = str;
1385                 return control.no_type;
1386             }
1387             type = ReadTypeFromSignature(base_type, signature,
1388                                          str - signature, tok);
1389             signature = str + 1;
1390         }
1391         break;
1392     case U_T:
1393         assert(false && "generics not implemented yet");
1394     case U_NULL: // oops, already exceeded string
1395         signature--;
1396         // fallthrough
1397     default:
1398         return control.no_type;
1399     }
1400     return type -> GetArrayType(this, num_dimensions);
1401 }
1402 
1403 //
1404 // This returns the type associated with a CONSTANT_Class entry, or
1405 // control.no_type if there was an error. Unless the type is bad, it is
1406 // necessarily a subtype of java.lang.Object.
1407 //
GetType(TypeSymbol * base_type,CPClassInfo * class_info,const ConstantPool & constant_pool,TokenIndex tok)1408 TypeSymbol* Semantic::GetType(TypeSymbol* base_type, CPClassInfo* class_info,
1409                               const ConstantPool& constant_pool,
1410                               TokenIndex tok)
1411 {
1412     if (! class_info -> Type())
1413     {
1414         const char* str = class_info -> TypeName(constant_pool);
1415         if (*str == U_LEFT_BRACKET)
1416             class_info -> SetType(ProcessSignature(base_type, str, tok));
1417         else
1418         {
1419             u2 length = class_info -> TypeNameLength(constant_pool);
1420             class_info -> SetType(ReadTypeFromSignature(base_type, str,
1421                                                         length, tok));
1422         }
1423     }
1424     return class_info -> Type();
1425 }
1426 
1427 //
1428 // Searches for a nested type with the simple name name_symbol located within
1429 // base_type, when base_type was loaded from a .class file.
1430 //
ProcessNestedType(TypeSymbol * base_type,NameSymbol * name_symbol,TokenIndex tok)1431 TypeSymbol* Semantic::ProcessNestedType(TypeSymbol* base_type,
1432                                         NameSymbol* name_symbol,
1433                                         TokenIndex tok)
1434 {
1435     TypeSymbol* inner_type = base_type -> FindTypeSymbol(name_symbol);
1436     if (! inner_type)
1437     {
1438         int length = base_type -> ExternalNameLength() + 1 +
1439             name_symbol -> NameLength(); // +1 for $,... +1 for $
1440         wchar_t* external_name = new wchar_t[length + 1]; // +1 for '\0';
1441         wcscpy(external_name, base_type -> ExternalName());
1442         wcscat(external_name, StringConstant::US_DS);
1443         wcscat(external_name, name_symbol -> Name());
1444         NameSymbol* external_name_symbol =
1445             control.FindOrInsertName(external_name, length);
1446 
1447         delete [] external_name;
1448 
1449         inner_type = base_type -> InsertNestedTypeSymbol(name_symbol);
1450         inner_type -> outermost_type = base_type -> outermost_type;
1451         inner_type -> supertypes_closure = new SymbolSet;
1452         inner_type -> subtypes = new SymbolSet;
1453         inner_type -> SetExternalIdentity(external_name_symbol);
1454         inner_type -> SetOwner(base_type);
1455         inner_type -> SetSignature(control);
1456 
1457         FileSymbol* file_symbol =
1458             Control::GetFile(control, base_type -> ContainingPackage(),
1459                              external_name_symbol);
1460         if (file_symbol)
1461         {
1462             inner_type -> file_symbol = file_symbol;
1463             inner_type -> SetLocation();
1464 
1465             ReadClassFile(inner_type, tok);
1466         }
1467         else
1468         {
1469             // this symbol table will only contain a default constructor
1470             inner_type -> SetSymbolTable(1);
1471             inner_type -> super = control.Object();
1472             inner_type -> MarkBad();
1473             AddDefaultConstructor(inner_type);
1474             ReportSemError(SemanticError::TYPE_NOT_FOUND, tok,
1475                            inner_type -> ContainingPackageName(),
1476                            inner_type -> ExternalName());
1477         }
1478     }
1479 
1480     return inner_type;
1481 }
1482 
1483 //
1484 // Retrieves the innermost nested type from a signature containing '$' as
1485 // the type nesting separator.
1486 //
RetrieveNestedTypes(TypeSymbol * base_type,wchar_t * signature,TokenIndex tok)1487 TypeSymbol* Semantic::RetrieveNestedTypes(TypeSymbol* base_type,
1488                                           wchar_t* signature, TokenIndex tok)
1489 {
1490     int len;
1491     for (len = 0;
1492          signature[len] != U_NULL && signature[len] != U_DOLLAR; len++)
1493         ;
1494     NameSymbol* name_symbol = control.FindOrInsertName(signature, len);
1495     TypeSymbol* inner_type = ProcessNestedType(base_type, name_symbol, tok);
1496 
1497     return (signature[len] == U_DOLLAR
1498             ? RetrieveNestedTypes(inner_type, &signature[len + 1], tok)
1499             : inner_type);
1500 }
1501 
1502 //
1503 // Given a UTF8 signature, this finds the type that it refers to, loading
1504 // the type into memory or causing a type not found error.
1505 //
ReadTypeFromSignature(TypeSymbol * base_type,const char * utf8_signature,int length,TokenIndex tok)1506 TypeSymbol* Semantic::ReadTypeFromSignature(TypeSymbol* base_type,
1507                                             const char* utf8_signature,
1508                                             int length, TokenIndex tok)
1509 {
1510     TypeSymbol* type = control.type_table.FindType(utf8_signature, length);
1511 
1512     if (type)
1513     {
1514         if (type -> SourcePending())
1515             control.ProcessHeaders(type -> file_symbol);
1516     }
1517     else
1518     {
1519         wchar_t* signature = new wchar_t[length + 1];
1520         Control::ConvertUtf8ToUnicode(signature, utf8_signature, length);
1521 
1522         int total_length;
1523         for (total_length = 0;
1524              signature[total_length] != U_NULL &&
1525                  signature[total_length] != U_DOLLAR; total_length++)
1526             ;
1527 
1528         if (signature[total_length] != U_NULL &&
1529             Code::IsDecimalDigit(signature[total_length + 1]))
1530         {
1531             // an anonymous or a local type?
1532             for (total_length += 2;
1533                  Code::IsDecimalDigit(signature[total_length]); total_length++)
1534                 // will stop at next '$' or '\0' !!!
1535                 ;
1536             if (signature[total_length] != U_NULL)
1537             {
1538                 // not an anonymous type? then scan local type name
1539                 for (total_length++;
1540                      signature[total_length] != U_NULL &&
1541                          signature[total_length] != U_DOLLAR; total_length++)
1542                     ;
1543             }
1544         }
1545 
1546         int len;
1547         for (len = total_length - 1;
1548              len >= 0 && signature[len] != U_SLASH; len--)
1549             ;
1550 
1551         wchar_t* name = &(signature[len + 1]);
1552 
1553         //
1554         // When a package name is specified in the signature, we look for the
1555         // type in question in that package, i.e., we redefine package.
1556         // Otherwise, we search for the type in the unnamed package.
1557         //
1558         PackageSymbol* package = NULL;
1559 
1560         //
1561         // Which package?
1562         //
1563         if (len >= 0)
1564         {
1565             wchar_t* package_name = new wchar_t[len + 1];
1566             for (int i = 0; i < len; i++)
1567                 package_name[i] = signature[i];
1568             package_name[len] = U_NULL;
1569             package = control.ProcessPackage(package_name);
1570 
1571             if (package -> directory.Length() == 0)
1572             {
1573                 ReportSemError(SemanticError::PACKAGE_NOT_FOUND, tok,
1574                                package -> PackageName());
1575             }
1576             delete [] package_name;
1577         }
1578         else package = control.UnnamedPackage();
1579 
1580         //
1581         // Process type
1582         //
1583         NameSymbol* name_symbol =
1584             control.FindOrInsertName(name, total_length - (len + 1));
1585         type = package -> FindTypeSymbol(name_symbol);
1586         if (type)
1587         {
1588             if (type -> SourcePending())
1589                 control.ProcessHeaders(type -> file_symbol);
1590         }
1591         else
1592         {
1593             FileSymbol* file_symbol = Control::GetFile(control, package,
1594                                                        name_symbol);
1595             //
1596             // If a file_symbol was not found, ReadType will issue an error
1597             // message
1598             //
1599             type = ReadType(file_symbol, package, name_symbol, tok);
1600 
1601             //
1602             // If we have to do a full check and we have a case where a
1603             // ".class" file depends on a ".java" file then we should signal
1604             // that the ".java" file associated with the ".class" file should
1605             // be recompiled.
1606             //
1607             if (control.option.full_check && ! control.option.depend &&
1608                 file_symbol && file_symbol -> IsJava() &&
1609                 ! file_symbol -> IsZip())
1610             {
1611                 control.recompilation_file_set.AddElement(file_symbol);
1612                 if (! control.option.incremental && control.option.pedantic)
1613                 {
1614                     ReportSemError(SemanticError::RECOMPILATION, tok,
1615                                    base_type -> ContainingPackageName(),
1616                                    base_type -> ExternalName(),
1617                                    type -> ContainingPackageName(),
1618                                    type -> ExternalName());
1619                 }
1620             }
1621         }
1622 
1623         if (signature[total_length] == U_DOLLAR)
1624             type = RetrieveNestedTypes(type, &signature[total_length + 1],
1625                                        tok);
1626 
1627         delete [] signature;
1628     }
1629 
1630     //
1631     // Establish a dependence from base_type (read from a class file) to type.
1632     //
1633     AddDependence(base_type, type);
1634 
1635     return type;
1636 }
1637 
1638 //
1639 // This is called when a type needs to be read from a .class file. It reads
1640 // the file and fills in the symbol table of type.
1641 //
ReadClassFile(TypeSymbol * type,TokenIndex tok)1642 void Semantic::ReadClassFile(TypeSymbol* type, TokenIndex tok)
1643 {
1644 #ifdef JIKES_DEBUG
1645     control.class_files_read++;
1646 #endif // JIKES_DEBUG
1647 
1648     FileSymbol* file_symbol = type -> file_symbol;
1649 
1650     if (control.option.verbose)  {
1651         Coutput << "[read "
1652                 << file_symbol -> FileName()
1653                 << "]" << endl;
1654     }
1655 
1656     if (file_symbol -> IsZip())
1657     {
1658         ZipFile* zipfile = new ZipFile(file_symbol);
1659 
1660         if (zipfile -> Buffer() == NULL)
1661         {
1662             // this symbol table will only contain a default constructor
1663             type -> SetSymbolTable(1);
1664             if (type != control.Object())
1665                 type -> super = (type == control.Throwable()
1666                                  ? control.Object() : control.Throwable());
1667             type -> MarkBad();
1668             AddDefaultConstructor(type);
1669 
1670             ReportSemError(SemanticError::COMPRESSED_ZIP_FILE, tok,
1671                            file_symbol -> PathSym() -> Name(),
1672                            type -> ContainingPackageName(),
1673                            type -> ExternalName());
1674         }
1675         else ProcessClassFile(type, zipfile -> Buffer(),
1676                               file_symbol -> uncompressed_size, tok);
1677         delete zipfile;
1678     }
1679     else
1680     {
1681         // Get a ReadObject from the API that contains the file's data.
1682         JikesAPI::FileReader* classFile =
1683             JikesAPI::getInstance() -> read(file_symbol -> FileName());
1684         if (classFile == NULL)
1685         {
1686             // this symbol table will only contain a default constructor
1687             type -> SetSymbolTable(1);
1688             if (type != control.Object())
1689                 type -> super = (type == control.Throwable()
1690                                  ? control.Object() : control.Throwable());
1691             type -> MarkBad();
1692             AddDefaultConstructor(type);
1693 
1694             ReportSemError(SemanticError::CANNOT_OPEN_CLASS_FILE, tok,
1695                            type -> ContainingPackageName(),
1696                            type -> ExternalName());
1697         }
1698 
1699         else
1700         {
1701             // Process the file data.
1702             unsigned size = classFile -> getBufferSize();
1703 
1704 #if defined(WIN32_FILE_SYSTEM)
1705             size = ((0xFFFFFFFF && GetLastError()) != NO_ERROR) ? 0 : size;
1706 #endif
1707             ProcessClassFile(type, classFile -> getBuffer(), size, tok);
1708             delete classFile;
1709         }
1710     }
1711 }
1712 
1713 //
1714 // Attempts to read in a type from a buffer representing a .class file.
1715 //
ProcessClassFile(TypeSymbol * type,const char * buffer,unsigned buffer_size,TokenIndex tok)1716 void Semantic::ProcessClassFile(TypeSymbol* type, const char* buffer,
1717                                 unsigned buffer_size, TokenIndex tok)
1718 {
1719     assert(! type -> HeaderProcessed());
1720     ClassFile* class_data = new ClassFile(buffer, buffer_size);
1721     if (! class_data -> Valid())
1722     {
1723         const char* problem = class_data -> DescribeProblem();
1724         int length = strlen(problem);
1725         wchar_t* unicode_problem = new wchar_t[length + 1];
1726         Control::ConvertUtf8ToUnicode(unicode_problem, problem, length);
1727 
1728         ReportSemError(SemanticError::INVALID_CLASS_FILE, tok,
1729                        type -> ExternalName(),
1730                        type -> file_symbol -> PathSym() -> Name(),
1731                        type -> ContainingPackageName(),
1732                        unicode_problem);
1733         type -> MarkBad();
1734         delete class_data;
1735         delete unicode_problem;
1736         return;
1737     }
1738 
1739     //
1740     // See if we read the expected type.
1741     //
1742     const ConstantPool& pool = class_data -> Pool();
1743     CPClassInfo* class_info = class_data -> ThisClass();
1744     if (strcmp(type -> fully_qualified_name -> value,
1745                class_info -> TypeName(pool)))
1746     {
1747         wchar_t* str = new wchar_t[class_info -> TypeNameLength(pool) + 1];
1748         control.ConvertUtf8ToUnicode(str, class_info -> TypeName(pool),
1749                                      class_info -> TypeNameLength(pool));
1750         // Passing NULL as the filename allows the error format to use the
1751         // platform dependent directory delimiter.
1752         ReportSemError(SemanticError::WRONG_TYPE_IN_CLASSFILE, tok,
1753                        type -> ExternalName(),
1754                        type -> file_symbol -> PathSym() -> Name(),
1755                        NULL, str);
1756         type -> MarkBad();
1757         delete [] str;
1758         delete class_data;
1759         return;
1760     }
1761 
1762     type -> MarkHeaderProcessed();
1763     type -> MarkConstructorMembersProcessed();
1764     type -> MarkMethodMembersProcessed();
1765     type -> MarkFieldMembersProcessed();
1766     type -> MarkLocalClassProcessingCompleted();
1767     type -> MarkSourceNoLongerPending();
1768 
1769     //
1770     // Since the unnamed packages includes all directories on the CLASSPATH,
1771     // check that types are not duplicated between directories.
1772     //
1773     if (! type -> IsNested() &&
1774         type -> ContainingPackage() == control.UnnamedPackage())
1775     {
1776         TypeSymbol* old_type = (TypeSymbol*)
1777             control.unnamed_package_types.Image(type -> Identity());
1778         if (! old_type)
1779             control.unnamed_package_types.AddElement(type);
1780         else
1781         {
1782             ReportSemError(SemanticError::DUPLICATE_TYPE_DECLARATION,
1783                            tok, type -> Name(), old_type -> FileLoc());
1784         }
1785     }
1786 
1787     //
1788     // On systems such as NT and Win-95 that are not case-sensitive,
1789     // we need to confirm that the type name specified matches the name
1790     // in the class file.
1791     // TODO: Is this necessary, or did the previous check filter this?
1792 //      assert(type_name_length - (n + 1) == type -> ExternalNameLength());
1793 //      int i;
1794 //      for (i = 0; i < type -> ExternalNameLength(); i++)
1795 //      {
1796 //          if (type_name[n + 1 + i] != type -> ExternalName()[i])
1797 //              break;
1798 //      }
1799 //      if (i < type -> ExternalNameLength())
1800 //      {
1801 //          wchar_t* name = new wchar_t[type_name_length + 1];
1802 //          for (int k = 0; k < type_name_length; k++)
1803 //              name[k] = type_name[k];
1804 //          name[type_name_length] = U_NULL;
1805 //          ReportSemError(SemanticError::TYPE_NAME_MISMATCH, tok,
1806 //                         type -> ContainingPackageName(),
1807 //                         type -> ExternalName(), name);
1808 //          delete [] name;
1809 //      }
1810 
1811     //
1812     // We now have enough information to make a good estimate for the
1813     // size of the symbol table we need for this class.
1814     //
1815     int i;
1816     const InnerClassesAttribute* inner_classes = class_data -> InnerClasses();
1817     type -> SetSymbolTable(class_data -> FieldsCount() +
1818                            class_data -> MethodsCount() +
1819                            (inner_classes
1820                             ? inner_classes -> InnerClassesLength() : 0));
1821 
1822     //
1823     // Read the attributes. We do this now to learn about inner classes and
1824     // type parameterization, since this information may be needed when
1825     // processing supertypes, field signatures, and method signatures. Also,
1826     // we learn the access flags of this type.
1827     //
1828     type -> SetFlags(class_data -> Flags());
1829     type -> ResetACC_SUPER();
1830     if (class_data -> Deprecated())
1831         type -> MarkDeprecated();
1832     if (inner_classes)
1833     {
1834         for (i = inner_classes -> InnerClassesLength() - 1; i >= 0; i--)
1835         {
1836             const CPClassInfo* inner = inner_classes -> Inner(i, pool);
1837             const CPClassInfo* outer = inner_classes -> Outer(i, pool);
1838             if (inner == class_info)
1839             {
1840                 type -> SetFlags(inner_classes -> Flags(i));
1841                 if (! outer)
1842                 {
1843                     //
1844                     // This type is local or anonymous, so we shouldn't be
1845                     // reading it from the .class file. Marking it anonymous
1846                     // is our clue to report an error for trying to use the
1847                     // type by qualified name.
1848                     //
1849                     type -> MarkAnonymous();
1850                 }
1851             }
1852             else if (outer == class_info && inner_classes -> Name(i, pool) &&
1853                      inner_classes -> NameLength(i, pool))
1854             {
1855                 //
1856                 // Some idiot compilers give anonymous classes the name "" and
1857                 // an outer class, rather than obeying JVMS 4.7.5.  For
1858                 // example, mail.jar in Sun's javamail 1.3.1 includes
1859                 // javax.mail.Service with this property. The check for
1860                 // NameLength above skips those invalid entries.
1861                 //
1862                 type -> AddNestedTypeSignature((inner_classes ->
1863                                                 Name(i, pool)),
1864                                                (inner_classes ->
1865                                                 NameLength(i, pool)));
1866             }
1867         }
1868     }
1869     if (control.option.full_check &&
1870         (control.option.unzip || ! type -> file_symbol -> IsZip()))
1871     {
1872         type -> ProcessNestedTypeSignatures(this, tok);
1873     }
1874 
1875     //
1876     // Tie this type to its supertypes.
1877     // FIXME: for sdk1_5, read attr_signature
1878     //
1879     class_info = class_data -> SuperClass();
1880     if ((type == control.Object()) != (class_info == NULL))
1881         type -> MarkBad();
1882     if (class_info)
1883     {
1884         type -> super = GetType(type, class_info, pool, tok);
1885         if (type -> super -> ACC_INTERFACE() || type -> super -> IsArray() ||
1886             type -> super -> Bad())
1887         {
1888             type -> MarkBad();
1889         }
1890         else
1891         {
1892             type -> supertypes_closure -> AddElement(type -> super);
1893             type -> supertypes_closure -> Union(*type -> super ->
1894                                                 supertypes_closure);
1895         }
1896     }
1897     for (i = class_data -> InterfacesCount() - 1; i >= 0; i--)
1898     {
1899         class_info = class_data -> Interface(i);
1900         assert(class_info);
1901         TypeSymbol* interf = GetType(type, class_info, pool, tok);
1902         type -> AddInterface(interf);
1903         type -> supertypes_closure -> AddElement(interf);
1904         type -> supertypes_closure -> Union(*interf -> supertypes_closure);
1905         if (! interf -> ACC_INTERFACE())
1906             type -> MarkBad();
1907     }
1908 
1909     //
1910     // Read the fields.
1911     //
1912     for (i = class_data -> FieldsCount() - 1; i >= 0; i--)
1913     {
1914         const FieldInfo* field = class_data -> Field(i);
1915         if (field -> ACC_SYNTHETIC())
1916             continue; // No point reading these - the user can't access them.
1917         NameSymbol* name_symbol =
1918             control.ConvertUtf8ToUnicode(field -> Name(pool),
1919                                          field -> NameLength(pool));
1920         VariableSymbol* symbol = new VariableSymbol(name_symbol);
1921         symbol -> SetOwner(type);
1922         symbol -> MarkComplete();
1923         symbol -> MarkInitialized();
1924         symbol -> SetFlags(field -> Flags());
1925         symbol -> SetSignatureString(field -> Signature(pool, control),
1926                                      field -> SignatureLength(pool, control));
1927         if (field -> Deprecated())
1928             symbol -> MarkDeprecated();
1929         const CPInfo* value = field -> ConstantValue(pool);
1930         if (value)
1931         {
1932             switch (value -> Tag())
1933             {
1934             case CPInfo::CONSTANT_Integer:
1935                 symbol -> initial_value = control.int_pool.
1936                     FindOrInsert(((CPIntegerInfo*) value) -> Value());
1937                 break;
1938             case CPInfo::CONSTANT_Long:
1939                 symbol -> initial_value = control.long_pool.
1940                     FindOrInsert(((CPLongInfo*) value) -> Value());
1941                 break;
1942             case CPInfo::CONSTANT_Float:
1943                 symbol -> initial_value = control.float_pool.
1944                     FindOrInsert(((CPFloatInfo*) value) -> Value());
1945                 break;
1946             case CPInfo::CONSTANT_Double:
1947                 symbol -> initial_value = control.double_pool.
1948                     FindOrInsert(((CPDoubleInfo*) value) -> Value());
1949                 break;
1950             case CPInfo::CONSTANT_String:
1951                 {
1952                     CPStringInfo* str_value = (CPStringInfo*) value;
1953                     symbol -> initial_value = control.Utf8_pool.
1954                         FindOrInsert(str_value -> Bytes(pool),
1955                                      str_value -> Length(pool));
1956                 }
1957                 break;
1958             default:
1959                 assert(false && "unexpected constant pool entry");
1960             }
1961         }
1962         type -> InsertVariableSymbol(symbol);
1963         if (control.option.full_check &&
1964             (control.option.unzip || ! type -> file_symbol -> IsZip()))
1965         {
1966             symbol -> ProcessVariableSignature(this, tok);
1967         }
1968     }
1969 
1970     //
1971     // Read the methods.
1972     //
1973     for (i = class_data -> MethodsCount() - 1; i >= 0; i--)
1974     {
1975         const MethodInfo* method = class_data -> Method(i);
1976         NameSymbol* name_symbol =
1977             control.ConvertUtf8ToUnicode(method -> Name(pool),
1978                                          method -> NameLength(pool));
1979         if (method -> ACC_SYNTHETIC() ||
1980             name_symbol == control.clinit_name_symbol)
1981         {
1982             continue; // No point reading these - the user can't access them.
1983         }
1984         MethodSymbol* symbol = new MethodSymbol(name_symbol);
1985         symbol -> SetContainingType(type);
1986         symbol -> SetFlags(method -> Flags());
1987         Utf8LiteralValue* sig = control.Utf8_pool.
1988             FindOrInsert(method -> Signature(pool, control),
1989                          method -> SignatureLength(pool, control));
1990         symbol -> SetSignature(sig);
1991         if (method -> Deprecated())
1992             symbol -> MarkDeprecated();
1993         const ExceptionsAttribute* throws_clause = method -> Exceptions();
1994         if (throws_clause)
1995         {
1996             for (int j = throws_clause -> NumberOfExceptions() - 1;
1997                  j >= 0; j--)
1998             {
1999                 const CPClassInfo* exception =
2000                     throws_clause -> Exception(j, pool);
2001                 symbol ->
2002                     AddThrowsSignature(exception -> TypeName(pool),
2003                                        exception -> TypeNameLength(pool));
2004             }
2005         }
2006 
2007         type -> InsertMethodSymbol(symbol);
2008         if (control.option.full_check &&
2009             (control.option.unzip || ! type -> file_symbol -> IsZip()))
2010         {
2011             symbol -> ProcessMethodSignature(this, tok);
2012         }
2013     }
2014 
2015     //
2016     // If requested by +F, suck in all types referred to in the constant pool
2017     // (both in CONSTANT_Class and in descriptors of CONSTANT_NameAndType).
2018     //
2019     if (control.option.full_check &&
2020         (control.option.unzip || ! type -> file_symbol -> IsZip()))
2021     {
2022         for (i = pool.Length() - 1; i > 0; i--)
2023         {
2024             if (pool[i] -> Tag() == CPInfo::CONSTANT_Class)
2025                 GetType(type, (CPClassInfo*) pool[i], pool, tok);
2026             else if (pool[i] -> Tag() == CPInfo::CONSTANT_NameAndType)
2027             {
2028                 const char* signature =
2029                     ((CPNameAndTypeInfo*) pool[i]) -> Signature(pool);
2030                 if (*signature != U_LEFT_PARENTHESIS)
2031                     // no '(' indicates a field descriptor
2032                     ProcessSignature(type, signature, tok);
2033                 else // a method descriptor
2034                 {
2035                     while (*signature && *signature++ != U_RIGHT_PARENTHESIS);
2036                     ProcessSignature(type, signature, tok);
2037                 }
2038             }
2039         }
2040     }
2041 
2042     delete class_data;
2043     type -> CompressSpace();
2044 }
2045 
2046 
2047 #ifdef HAVE_JIKES_NAMESPACE
2048 } // Close namespace Jikes block
2049 #endif
2050