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