source: branches/GNU/src/gcc/libjava/defineclass.cc@ 1476

Last change on this file since 1476 was 1391, checked in by bird, 22 years ago

GCC v3.3.3 sources.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 41.2 KB
Line 
1// defineclass.cc - defining a class from .class format.
2
3/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation
4
5 This file is part of libgcj.
6
7This software is copyrighted work licensed under the terms of the
8Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9details. */
10
11/*
12 Author: Kresten Krab Thorup <[email protected]>
13
14 Written using the online versions of Java Language Specification (1st
15 ed.) and The Java Virtual Machine Specification (2nd ed.).
16
17 Future work may include reading (and handling) attributes which are
18 currently being ignored ("InnerClasses", "LineNumber", etc...).
19*/
20
21#include <config.h>
22
23#include <java-interp.h>
24
25#include <stdlib.h>
26#include <java-cpool.h>
27#include <gcj/cni.h>
28
29#include <java/lang/Class.h>
30#include <java/lang/Float.h>
31#include <java/lang/Double.h>
32#include <java/lang/Character.h>
33#include <java/lang/LinkageError.h>
34#include <java/lang/InternalError.h>
35#include <java/lang/ClassFormatError.h>
36#include <java/lang/NoClassDefFoundError.h>
37#include <java/lang/ClassCircularityError.h>
38#include <java/lang/IncompatibleClassChangeError.h>
39#include <java/lang/reflect/Modifier.h>
40
41using namespace gcj;
42
43#ifdef INTERPRETER
44
45// these go in some separate functions, to avoid having _Jv_InitClass
46// inserted all over the place.
47static void throw_internal_error (char *msg)
48 __attribute__ ((__noreturn__));
49static void throw_no_class_def_found_error (jstring msg)
50 __attribute__ ((__noreturn__));
51static void throw_no_class_def_found_error (char *msg)
52 __attribute__ ((__noreturn__));
53static void throw_class_format_error (jstring msg)
54 __attribute__ ((__noreturn__));
55static void throw_incompatible_class_change_error (jstring msg)
56 __attribute__ ((__noreturn__));
57static void throw_class_circularity_error (jstring msg)
58 __attribute__ ((__noreturn__));
59
60/**
61 * We define class reading using a class. It is practical, since then
62 * the entire class-reader can be a friend of class Class (it needs to
63 * write all it's different structures); but also because this makes it
64 * easy to make class definition reentrant, and thus two threads can be
65 * defining classes at the same time. This class (_Jv_ClassReader) is
66 * never exposed outside this file, so we don't have to worry about
67 * public or private members here.
68 */
69
70struct _Jv_ClassReader {
71
72 // do verification? Currently, there is no option to disable this.
73 // This flag just controls the verificaiton done by the class loader;
74 // i.e., checking the integrity of the constant pool; and it is
75 // allways on. You always want this as far as I can see, but it also
76 // controls weither identifiers and type descriptors/signatures are
77 // verified as legal. This could be somewhat more expensive since it
78 // will call Characher.isJavaIdentifier{Start,Part} for each character
79 // in any identifier (field name or method name) it comes by. Thus,
80 // it might be useful to turn off this verification for classes that
81 // come from a trusted source. However, for GCJ, trusted classes are
82 // most likely to be linked in.
83
84 bool verify;
85
86 // input data.
87 unsigned char *bytes;
88 int len;
89
90 // current input position
91 int pos;
92
93 // the constant pool data
94 int pool_count;
95 unsigned char *tags;
96 unsigned int *offsets;
97
98 // the class to define (see java-interp.h)
99 _Jv_InterpClass *def;
100
101 /* check that the given number of input bytes are available */
102 inline void check (int num)
103 {
104 if (pos + num > len)
105 throw_class_format_error ("Premature end of data");
106 }
107
108 /* skip a given number of bytes in input */
109 inline void skip (int num)
110 {
111 check (num);
112 pos += num;
113 }
114
115 /* read an unsignend 1-byte unit */
116 inline static jint get1u (unsigned char* bytes)
117 {
118 return bytes[0];
119 }
120
121 /* read an unsigned 1-byte unit */
122 inline jint read1u ()
123 {
124 skip (1);
125 return get1u (bytes+pos-1);
126 }
127
128 /* read an unsigned 2-byte unit */
129 inline static jint get2u (unsigned char *bytes)
130 {
131 return (((jint)bytes[0]) << 8) | ((jint)bytes[1]);
132 }
133
134 /* read an unsigned 2-byte unit */
135 inline jint read2u ()
136 {
137 skip (2);
138 return get2u (bytes+pos-2);
139 }
140
141 /* read a 4-byte unit */
142 static jint get4 (unsigned char *bytes)
143 {
144 return (((jint)bytes[0]) << 24)
145 | (((jint)bytes[1]) << 16)
146 | (((jint)bytes[2]) << 8)
147 | (((jint)bytes[3]) << 0);
148 }
149
150 /* read a 4-byte unit, (we don't do that quite so often) */
151 inline jint read4 ()
152 {
153 skip (4);
154 return get4 (bytes+pos-4);
155 }
156
157 /* read a 8-byte unit */
158 static jlong get8 (unsigned char* bytes)
159 {
160 return (((jlong)bytes[0]) << 56)
161 | (((jlong)bytes[1]) << 48)
162 | (((jlong)bytes[2]) << 40)
163 | (((jlong)bytes[3]) << 32)
164 | (((jlong)bytes[4]) << 24)
165 | (((jlong)bytes[5]) << 16)
166 | (((jlong)bytes[6]) << 8)
167 | (((jlong)bytes[7]) << 0);
168 }
169
170 /* read a 8-byte unit */
171 inline jlong read8 ()
172 {
173 skip (8);
174 return get8 (bytes+pos-8);
175 }
176
177 inline void check_tag (int index, char expected_tag)
178 {
179 if (index < 0
180 || index > pool_count
181 || tags[index] != expected_tag)
182 throw_class_format_error ("erroneous constant pool tag");
183 }
184
185 inline void verify_identifier (_Jv_Utf8Const* name)
186 {
187 if (! _Jv_VerifyIdentifier (name))
188 throw_class_format_error ("erroneous identifier");
189 }
190
191 inline void verify_classname (unsigned char* ptr, _Jv_ushort length)
192 {
193 if (! _Jv_VerifyClassName (ptr, length))
194 throw_class_format_error ("erroneous class name");
195 }
196
197 inline void verify_classname (_Jv_Utf8Const *name)
198 {
199 if (! _Jv_VerifyClassName (name))
200 throw_class_format_error ("erroneous class name");
201 }
202
203 inline void verify_field_signature (_Jv_Utf8Const *sig)
204 {
205 if (! _Jv_VerifyFieldSignature (sig))
206 throw_class_format_error ("erroneous type descriptor");
207 }
208
209 inline void verify_method_signature (_Jv_Utf8Const *sig)
210 {
211 if (! _Jv_VerifyMethodSignature (sig))
212 throw_class_format_error ("erroneous type descriptor");
213 }
214
215 _Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length)
216 {
217 if (klass == 0 || length < 0 || offset+length > data->length)
218 throw_internal_error ("arguments to _Jv_DefineClass");
219
220 verify = true;
221 bytes = (unsigned char*) (elements (data)+offset);
222 len = length;
223 pos = 0;
224 def = (_Jv_InterpClass*) klass;
225 }
226
227 /** and here goes the parser members defined out-of-line */
228 void parse ();
229 void read_constpool ();
230 void prepare_pool_entry (int index, unsigned char tag);
231 void read_fields ();
232 void read_methods ();
233 void read_one_class_attribute ();
234 void read_one_method_attribute (int method);
235 void read_one_code_attribute (int method);
236 void read_one_field_attribute (int field);
237 void throw_class_format_error (char *msg);
238
239 /** check an utf8 entry, without creating a Utf8Const object */
240 bool is_attribute_name (int index, char *name);
241
242 /** here goes the class-loader members defined out-of-line */
243 void handleConstantPool ();
244 void handleClassBegin (int, int, int);
245 void handleInterfacesBegin (int);
246 void handleInterface (int, int);
247 void handleFieldsBegin (int);
248 void handleField (int, int, int, int);
249 void handleFieldsEnd ();
250 void handleConstantValueAttribute (int,int);
251 void handleMethodsBegin (int);
252 void handleMethod (int, int, int, int);
253 void handleMethodsEnd ();
254 void handleCodeAttribute (int, int, int, int, int, int);
255 void handleExceptionTableEntry (int, int, int, int, int, int);
256
257 void checkExtends (jclass sub, jclass super);
258 void checkImplements (jclass sub, jclass super);
259
260 /*
261 * FIXME: we should keep a hash table of utf8-strings, since many will
262 * be the same. It's a little tricky, however, because the hash table
263 * needs to interact gracefully with the garbage collector. Much
264 * memory is to be saved by this, however! perhaps the improvement
265 * could be implemented in prims.cc (_Jv_makeUtf8Const), since it
266 * computes the hash value anyway.
267 */
268};
269
270void
271_Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length)
272{
273 _Jv_ClassReader reader (klass, data, offset, length);
274 reader.parse();
275
276 /* that's it! */
277}
278
279
280
281/** This section defines the parsing/scanning of the class data */
282
283void
284_Jv_ClassReader::parse ()
285{
286 int magic = read4 ();
287
288 /* FIXME: Decide which range of version numbers to allow */
289
290 /* int minor_version = */ read2u ();
291 /* int major_verson = */ read2u ();
292
293 if (magic != (int) 0xCAFEBABE)
294 throw_class_format_error ("bad magic number");
295
296 pool_count = read2u ();
297
298 read_constpool ();
299
300 int access_flags = read2u ();
301 int this_class = read2u ();
302 int super_class = read2u ();
303
304 check_tag (this_class, JV_CONSTANT_Class);
305 if (super_class != 0)
306 check_tag (super_class, JV_CONSTANT_Class);
307
308 handleClassBegin (access_flags, this_class, super_class);
309
310 int interfaces_count = read2u ();
311
312 handleInterfacesBegin (interfaces_count);
313
314 for (int i = 0; i < interfaces_count; i++)
315 {
316 int iface = read2u ();
317 check_tag (iface, JV_CONSTANT_Class);
318 handleInterface (i, iface);
319 }
320
321 read_fields ();
322 read_methods ();
323
324 int attributes_count = read2u ();
325
326 for (int i = 0; i < attributes_count; i++)
327 {
328 read_one_class_attribute ();
329 }
330
331 if (pos != len)
332 throw_class_format_error ("unused data before end of file");
333
334 // tell everyone we're done.
335 def->state = JV_STATE_LOADED;
336 def->notifyAll ();
337
338}
339
340void _Jv_ClassReader::read_constpool ()
341{
342 tags = (unsigned char*) _Jv_AllocBytes (pool_count);
343 offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int)
344 * pool_count) ;
345
346 /** first, we scan the constant pool, collecting tags and offsets */
347 tags[0] = JV_CONSTANT_Undefined;
348 offsets[0] = pos;
349 for (int c = 1; c < pool_count; c++)
350 {
351 tags[c] = read1u ();
352 offsets[c] = pos;
353
354 switch (tags[c])
355 {
356 case JV_CONSTANT_String:
357 case JV_CONSTANT_Class:
358 skip (2);
359 break;
360
361 case JV_CONSTANT_Fieldref:
362 case JV_CONSTANT_Methodref:
363 case JV_CONSTANT_InterfaceMethodref:
364 case JV_CONSTANT_NameAndType:
365 case JV_CONSTANT_Integer:
366 case JV_CONSTANT_Float:
367 skip (4);
368 break;
369
370 case JV_CONSTANT_Double:
371 case JV_CONSTANT_Long:
372 skip (8);
373 tags[++c] = JV_CONSTANT_Undefined;
374 break;
375
376 case JV_CONSTANT_Utf8:
377 {
378 int len = read2u ();
379 skip (len);
380 }
381 break;
382
383 case JV_CONSTANT_Unicode:
384 throw_class_format_error ("unicode not supported");
385 break;
386
387 default:
388 throw_class_format_error ("erroneous constant pool tag");
389 }
390 }
391
392 handleConstantPool ();
393}
394
395
396void _Jv_ClassReader::read_fields ()
397{
398 int fields_count = read2u ();
399 handleFieldsBegin (fields_count);
400
401 for (int i = 0; i < fields_count; i++)
402 {
403 int access_flags = read2u ();
404 int name_index = read2u ();
405 int descriptor_index = read2u ();
406 int attributes_count = read2u ();
407
408 check_tag (name_index, JV_CONSTANT_Utf8);
409 prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
410
411 check_tag (descriptor_index, JV_CONSTANT_Utf8);
412 prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
413
414 handleField (i, access_flags, name_index, descriptor_index);
415
416 for (int j = 0; j < attributes_count; j++)
417 {
418 read_one_field_attribute (i);
419 }
420 }
421
422 handleFieldsEnd ();
423}
424
425bool
426_Jv_ClassReader::is_attribute_name (int index, char *name)
427{
428 check_tag (index, JV_CONSTANT_Utf8);
429 int len = get2u (bytes+offsets[index]);
430 if (len != (int) strlen (name))
431 return false;
432 else
433 return !memcmp (bytes+offsets[index]+2, name, len);
434}
435
436void _Jv_ClassReader::read_one_field_attribute (int field_index)
437{
438 int name = read2u ();
439 int length = read4 ();
440
441 if (is_attribute_name (name, "ConstantValue"))
442 {
443 int cv = read2u ();
444
445 if (cv < pool_count
446 && cv > 0
447 && (tags[cv] == JV_CONSTANT_Integer
448 || tags[cv] == JV_CONSTANT_Float
449 || tags[cv] == JV_CONSTANT_Long
450 || tags[cv] == JV_CONSTANT_Double
451 || tags[cv] == JV_CONSTANT_String))
452 {
453 handleConstantValueAttribute (field_index, cv);
454 }
455 else
456 {
457 throw_class_format_error ("erroneous ConstantValue attribute");
458 }
459
460 if (length != 2)
461 throw_class_format_error ("erroneous ConstantValue attribute");
462 }
463
464 else
465 {
466 skip (length);
467 }
468}
469
470void _Jv_ClassReader::read_methods ()
471{
472 int methods_count = read2u ();
473
474 handleMethodsBegin (methods_count);
475
476 for (int i = 0; i < methods_count; i++)
477 {
478 int access_flags = read2u ();
479 int name_index = read2u ();
480 int descriptor_index = read2u ();
481 int attributes_count = read2u ();
482
483 check_tag (name_index, JV_CONSTANT_Utf8);
484 prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
485
486 check_tag (name_index, JV_CONSTANT_Utf8);
487 prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
488
489 handleMethod (i, access_flags, name_index,
490 descriptor_index);
491
492 for (int j = 0; j < attributes_count; j++)
493 {
494 read_one_method_attribute (i);
495 }
496 }
497
498 handleMethodsEnd ();
499}
500
501void _Jv_ClassReader::read_one_method_attribute (int method_index)
502{
503 int name = read2u ();
504 int length = read4 ();
505
506 if (is_attribute_name (name, "Exceptions"))
507 {
508 _Jv_Method *method = reinterpret_cast<_Jv_Method *>
509 (&def->methods[method_index]);
510 if (method->throws != NULL)
511 throw_class_format_error ("only one Exceptions attribute allowed per method");
512
513 int num_exceptions = read2u ();
514 // We use malloc here because the GC won't scan the method
515 // objects. FIXME this means a memory leak if we GC a class.
516 // (Currently we never do.)
517 _Jv_Utf8Const **exceptions =
518 (_Jv_Utf8Const **) _Jv_Malloc ((num_exceptions + 1) * sizeof (_Jv_Utf8Const *));
519
520 int out = 0;
521 _Jv_word *pool_data = def->constants.data;
522 for (int i = 0; i < num_exceptions; ++i)
523 {
524 try
525 {
526 int ndx = read2u ();
527 // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
528 if (ndx != 0)
529 {
530 check_tag (ndx, JV_CONSTANT_Class);
531 exceptions[out++] = pool_data[ndx].utf8;
532 }
533 }
534 catch (java::lang::Throwable *exc)
535 {
536 _Jv_Free (exceptions);
537 throw exc;
538 }
539 }
540 exceptions[out] = NULL;
541 method->throws = exceptions;
542 }
543
544 else if (is_attribute_name (name, "Code"))
545 {
546 int start_off = pos;
547 int max_stack = read2u ();
548 int max_locals = read2u ();
549 int code_length = read4 ();
550
551 int code_start = pos;
552 skip (code_length);
553 int exception_table_length = read2u ();
554
555 handleCodeAttribute (method_index,
556 max_stack, max_locals,
557 code_start, code_length,
558 exception_table_length);
559
560
561 for (int i = 0; i < exception_table_length; i++)
562 {
563 int start_pc = read2u ();
564 int end_pc = read2u ();
565 int handler_pc = read2u ();
566 int catch_type = read2u ();
567
568 if (start_pc > end_pc
569 || start_pc < 0
570 // END_PC can be equal to CODE_LENGTH.
571 // See JVM Spec 4.7.4.
572 || end_pc > code_length
573 || handler_pc >= code_length)
574 throw_class_format_error ("erroneous exception handler info");
575
576 if (! (tags[catch_type] == JV_CONSTANT_Class
577 || tags[catch_type] == 0))
578 {
579 throw_class_format_error ("erroneous exception handler info");
580 }
581
582 handleExceptionTableEntry (method_index,
583 i,
584 start_pc,
585 end_pc,
586 handler_pc,
587 catch_type);
588
589 }
590
591 int attributes_count = read2u ();
592
593 for (int i = 0; i < attributes_count; i++)
594 {
595 read_one_code_attribute (method_index);
596 }
597
598 if ((pos - start_off) != length)
599 throw_class_format_error ("code attribute too short");
600 }
601
602 else
603 {
604 /* ignore unknown attributes */
605 skip (length);
606 }
607}
608
609void _Jv_ClassReader::read_one_code_attribute (int /*method*/)
610{
611 /* ignore for now, ... later we may want to pick up
612 line number information, for debugging purposes;
613 in fact, the whole debugger issue is open! */
614
615 /* int name = */ read2u ();
616 int length = read4 ();
617 skip (length);
618
619}
620
621void _Jv_ClassReader::read_one_class_attribute ()
622{
623 /* we also ignore the class attributes, ...
624 some day we'll add inner-classes support. */
625
626 /* int name = */ read2u ();
627 int length = read4 ();
628 skip (length);
629}
630
631
632
633
634
635/* this section defines the semantic actions of the parser */
636
637void _Jv_ClassReader::handleConstantPool ()
638{
639 /** now, we actually define the class' constant pool */
640
641 // the pool is scanned explicitly by the collector
642 jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
643 _Jv_word *pool_data
644 = (_Jv_word*) _Jv_AllocBytes (pool_count * sizeof (_Jv_word));
645
646 def->constants.tags = pool_tags;
647 def->constants.data = pool_data;
648 def->constants.size = pool_count;
649
650 // Here we make a pass to collect the strings! We do this, because
651 // internally in the GCJ runtime, classes are encoded with .'s not /'s.
652 // Therefore, we first collect the strings, and then translate the rest
653 // of the utf8-entries (thus not representing strings) from /-notation
654 // to .-notation.
655 for (int i = 1; i < pool_count; i++)
656 {
657 if (tags[i] == JV_CONSTANT_String)
658 {
659 unsigned char* str_data = bytes + offsets [i];
660 int utf_index = get2u (str_data);
661 check_tag (utf_index, JV_CONSTANT_Utf8);
662 unsigned char *utf_data = bytes + offsets[utf_index];
663 int len = get2u (utf_data);
664 pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
665 pool_tags[i] = JV_CONSTANT_String;
666 }
667 else
668 {
669 pool_tags[i] = JV_CONSTANT_Undefined;
670 }
671 }
672
673 // and now, we scan everything else but strings & utf8-entries. This
674 // leaves out those utf8-entries which are not used; which will be left
675 // with a tag of JV_CONSTANT_Undefined in the class definition.
676 for (int index = 1; index < pool_count; index++)
677 {
678 switch (tags[index])
679 {
680 case JV_CONSTANT_Undefined:
681 case JV_CONSTANT_String:
682 case JV_CONSTANT_Utf8:
683 continue;
684
685 default:
686 prepare_pool_entry (index, tags[index]);
687 }
688 }
689
690}
691
692/* this is a recursive procedure, which will prepare pool entries as needed.
693 Which is how we avoid initializing those entries which go unused. */
694void
695_Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
696{
697 /* these two, pool_data and pool_tags, point into the class
698 structure we are currently defining */
699
700 unsigned char *pool_tags = (unsigned char*) def->constants.tags;
701 _Jv_word *pool_data = def->constants.data;
702
703 /* this entry was already prepared */
704 if (pool_tags[index] == this_tag)
705 return;
706
707 /* this_data points to the constant-pool information for the current
708 constant-pool entry */
709
710 unsigned char *this_data = bytes + offsets[index];
711
712 switch (this_tag)
713 {
714 case JV_CONSTANT_Utf8:
715 {
716 // If we came here, it is because some other tag needs this
717 // utf8-entry for type information! Thus, we translate /'s to .'s in
718 // order to accomondate gcj's internal representation.
719
720 int len = get2u (this_data);
721 char *buffer = (char*) __builtin_alloca (len);
722 char *s = ((char*) this_data)+2;
723
724 /* FIXME: avoid using a buffer here */
725 for (int i = 0; i < len; i++)
726 {
727 if (s[i] == '/')
728 buffer[i] = '.';
729 else
730 buffer[i] = (char) s[i];
731 }
732
733 pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
734 pool_tags[index] = JV_CONSTANT_Utf8;
735 }
736 break;
737
738 case JV_CONSTANT_Class:
739 {
740 int utf_index = get2u (this_data);
741 check_tag (utf_index, JV_CONSTANT_Utf8);
742 prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
743
744 if (verify)
745 verify_classname (pool_data[utf_index].utf8);
746
747 pool_data[index].utf8 = pool_data[utf_index].utf8;
748 pool_tags[index] = JV_CONSTANT_Class;
749 }
750 break;
751
752 case JV_CONSTANT_String:
753 // already handled before...
754 break;
755
756 case JV_CONSTANT_Fieldref:
757 case JV_CONSTANT_Methodref:
758 case JV_CONSTANT_InterfaceMethodref:
759 {
760 int class_index = get2u (this_data);
761 int nat_index = get2u (this_data+2);
762
763 check_tag (class_index, JV_CONSTANT_Class);
764 prepare_pool_entry (class_index, JV_CONSTANT_Class);
765
766 check_tag (nat_index, JV_CONSTANT_NameAndType);
767 prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
768
769 // here, verify the signature and identifier name
770 if (verify)
771 {
772 _Jv_ushort name_index, type_index;
773 _Jv_loadIndexes (&pool_data[nat_index],
774 name_index, type_index);
775
776 if (this_tag == JV_CONSTANT_Fieldref)
777 _Jv_VerifyFieldSignature (pool_data[type_index].utf8);
778 else
779 _Jv_VerifyMethodSignature (pool_data[type_index].utf8);
780
781 _Jv_Utf8Const* name = pool_data[name_index].utf8;
782
783 if (this_tag != JV_CONSTANT_Fieldref
784 && ( _Jv_equalUtf8Consts (name, clinit_name)
785 || _Jv_equalUtf8Consts (name, init_name)))
786 /* ignore */;
787 else
788 verify_identifier (pool_data[name_index].utf8);
789 }
790
791 _Jv_storeIndexes (&pool_data[index], class_index, nat_index);
792 pool_tags[index] = this_tag;
793 }
794 break;
795
796 case JV_CONSTANT_NameAndType:
797 {
798 _Jv_ushort name_index = get2u (this_data);
799 _Jv_ushort type_index = get2u (this_data+2);
800
801 check_tag (name_index, JV_CONSTANT_Utf8);
802 prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
803
804 check_tag (type_index, JV_CONSTANT_Utf8);
805 prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
806
807 _Jv_storeIndexes (&pool_data[index], name_index, type_index);
808 pool_tags[index] = JV_CONSTANT_NameAndType;
809 }
810 break;
811
812 case JV_CONSTANT_Float:
813 {
814 jfloat f = java::lang::Float::intBitsToFloat ((jint) get4 (this_data));
815 _Jv_storeFloat (&pool_data[index], f);
816 pool_tags[index] = JV_CONSTANT_Float;
817 }
818 break;
819
820 case JV_CONSTANT_Integer:
821 {
822 int i = get4 (this_data);
823 _Jv_storeInt (&pool_data[index], i);
824 pool_tags[index] = JV_CONSTANT_Integer;
825 }
826 break;
827
828 case JV_CONSTANT_Double:
829 {
830 jdouble d
831 = java::lang::Double::longBitsToDouble ((jlong) get8 (this_data));
832 _Jv_storeDouble (&pool_data[index], d);
833 pool_tags[index] = JV_CONSTANT_Double;
834 }
835 break;
836
837 case JV_CONSTANT_Long:
838 {
839 jlong i = get8 (this_data);
840 _Jv_storeLong (&pool_data[index], i);
841 pool_tags[index] = JV_CONSTANT_Long;
842 }
843 break;
844
845 default:
846 throw_class_format_error ("erroneous constant pool tag");
847 }
848}
849
850
851void
852_Jv_ClassReader::handleClassBegin
853 (int access_flags, int this_class, int super_class)
854{
855 using namespace java::lang::reflect;
856
857 unsigned char *pool_tags = (unsigned char*) def->constants.tags;
858 _Jv_word *pool_data = def->constants.data;
859
860 check_tag (this_class, JV_CONSTANT_Class);
861 _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
862
863 // was ClassLoader.defineClass called with an expected class name?
864 if (def->name == 0)
865 {
866 jclass orig = _Jv_FindClassInCache (loadedName, def->loader);
867
868 if (orig == 0)
869 {
870 def->name = loadedName;
871 }
872 else
873 {
874 jstring msg = JvNewStringUTF ("anonymous "
875 "class data denotes "
876 "existing class ");
877 msg = msg->concat (orig->getName ());
878
879 throw_no_class_def_found_error (msg);
880 }
881 }
882
883 // assert that the loaded class has the expected name, 5.3.5
884 else if (! _Jv_equalUtf8Consts (loadedName, def->name))
885 {
886 jstring msg = JvNewStringUTF ("loaded class ");
887 msg = msg->concat (def->getName ());
888 msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
889 jstring klass_name = _Jv_NewStringUTF (loadedName->data);
890 msg = msg->concat (klass_name);
891
892 throw_no_class_def_found_error (msg);
893 }
894
895 def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
896 pool_data[this_class].clazz = def;
897 pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
898
899 if (super_class == 0 && ! (access_flags & Modifier::INTERFACE))
900 {
901 // FIXME: Consider this carefully!
902 if (! _Jv_equalUtf8Consts (def->name, java::lang::Object::class$.name))
903 throw_no_class_def_found_error ("loading java.lang.Object");
904 }
905
906 // In the pre-loading state, it can be looked up in the
907 // cache only by this thread! This allows the super-class
908 // to include references to this class.
909
910 def->state = JV_STATE_PRELOADING;
911
912 {
913 JvSynchronize sync (&java::lang::Class::class$);
914 _Jv_RegisterClass (def);
915 }
916
917 if (super_class != 0)
918 {
919 // Load the superclass.
920 check_tag (super_class, JV_CONSTANT_Class);
921 _Jv_Utf8Const* super_name = pool_data[super_class].utf8;
922
923 // Load the superclass using our defining loader.
924 jclass the_super = _Jv_FindClass (super_name,
925 def->loader);
926
927 // This will establish that we are allowed to be a subclass,
928 // and check for class circularity error.
929 checkExtends (def, the_super);
930
931 // Note: for an interface we will find Object as the
932 // superclass. We still check it above to ensure class file
933 // validity, but we simply assign `null' to the actual field in
934 // this case.
935 def->superclass = (((access_flags & Modifier::INTERFACE))
936 ? NULL : the_super);
937 pool_data[super_class].clazz = the_super;
938 pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
939 }
940
941 // Now we've come past the circularity problem, we can
942 // now say that we're loading.
943
944 def->state = JV_STATE_LOADING;
945 def->notifyAll ();
946}
947
948///// implements the checks described in sect. 5.3.5.3
949void
950_Jv_ClassReader::checkExtends (jclass sub, jclass super)
951{
952 using namespace java::lang::reflect;
953
954 // having an interface or a final class as a superclass is no good
955 if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
956 {
957 throw_incompatible_class_change_error (sub->getName ());
958 }
959
960 // if the super class is not public, we need to check some more
961 if ((super->accflags & Modifier::PUBLIC) == 0)
962 {
963 // With package scope, the classes must have the same
964 // class loader.
965 if ( sub->loader != super->loader
966 || !_Jv_ClassNameSamePackage (sub->name, super->name))
967 {
968 throw_incompatible_class_change_error (sub->getName ());
969 }
970 }
971
972 for (; super != 0; super = super->superclass)
973 {
974 if (super == sub)
975 throw_class_circularity_error (sub->getName ());
976 }
977}
978
979
980
981void _Jv_ClassReader::handleInterfacesBegin (int count)
982{
983 def->interfaces = (jclass*) _Jv_AllocBytes (count*sizeof (jclass));
984 def->interface_count = count;
985}
986
987void _Jv_ClassReader::handleInterface (int if_number, int offset)
988{
989 _Jv_word * pool_data = def->constants.data;
990 unsigned char * pool_tags = (unsigned char*) def->constants.tags;
991
992 jclass the_interface;
993
994 if (pool_tags[offset] == JV_CONSTANT_Class)
995 {
996 _Jv_Utf8Const* name = pool_data[offset].utf8;
997 the_interface = _Jv_FindClass (name, def->loader);
998 }
999 else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
1000 {
1001 the_interface = pool_data[offset].clazz;
1002 }
1003 else
1004 {
1005 throw_no_class_def_found_error ("erroneous constant pool tag");
1006 }
1007
1008 // checks the validity of the_interface, and that we are in fact
1009 // allowed to implement that interface.
1010 checkImplements (def, the_interface);
1011
1012 pool_data[offset].clazz = the_interface;
1013 pool_tags[offset] = JV_CONSTANT_ResolvedClass;
1014
1015 def->interfaces[if_number] = the_interface;
1016}
1017
1018void
1019_Jv_ClassReader::checkImplements (jclass sub, jclass super)
1020{
1021 using namespace java::lang::reflect;
1022
1023 // well, it *must* be an interface
1024 if ((super->accflags & Modifier::INTERFACE) == 0)
1025 {
1026 throw_incompatible_class_change_error (sub->getName ());
1027 }
1028
1029 // if it has package scope, it must also be defined by the
1030 // same loader.
1031 if ((super->accflags & Modifier::PUBLIC) == 0)
1032 {
1033 if ( sub->loader != super->loader
1034 || !_Jv_ClassNameSamePackage (sub->name, super->name))
1035 {
1036 throw_incompatible_class_change_error (sub->getName ());
1037 }
1038 }
1039
1040 // FIXME: add interface circularity check here
1041 if (sub == super)
1042 {
1043 throw_class_circularity_error (sub->getName ());
1044 }
1045}
1046
1047void _Jv_ClassReader::handleFieldsBegin (int count)
1048{
1049 def->fields = (_Jv_Field*)
1050 _Jv_AllocBytes (count * sizeof (_Jv_Field));
1051 def->field_count = count;
1052 def->field_initializers = (_Jv_ushort*)
1053 _Jv_AllocBytes (count * sizeof (_Jv_ushort));
1054 for (int i = 0; i < count; i++)
1055 def->field_initializers[i] = (_Jv_ushort) 0;
1056}
1057
1058void _Jv_ClassReader::handleField (int field_no,
1059 int flags,
1060 int name,
1061 int desc)
1062{
1063 using namespace java::lang::reflect;
1064
1065 _Jv_word *pool_data = def->constants.data;
1066
1067 _Jv_Field *field = &def->fields[field_no];
1068 _Jv_Utf8Const *field_name = pool_data[name].utf8;
1069
1070#ifndef COMPACT_FIELDS
1071 field->name = field_name;
1072#else
1073 field->nameIndex = name;
1074#endif
1075
1076 if (verify)
1077 verify_identifier (field_name);
1078
1079 // ignore flags we don't know about.
1080 field->flags = flags & Modifier::ALL_FLAGS;
1081
1082 if (verify)
1083 {
1084 if (field->flags & (Modifier::SYNCHRONIZED
1085 | Modifier::NATIVE
1086 | Modifier::INTERFACE
1087 | Modifier::ABSTRACT))
1088 throw_class_format_error ("erroneous field access flags");
1089
1090 if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
1091 +((field->flags & Modifier::PRIVATE) ? 1 : 0)
1092 +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
1093 throw_class_format_error ("erroneous field access flags");
1094 }
1095
1096 _Jv_Utf8Const* sig = pool_data[desc].utf8;
1097
1098 if (verify)
1099 _Jv_VerifyFieldSignature (sig);
1100
1101 // field->type is really a jclass, but while it is still
1102 // unresolved we keep an _Jv_Utf8Const* instead.
1103 field->type = (jclass) sig;
1104 field->flags |= _Jv_FIELD_UNRESOLVED_FLAG;
1105 field->u.boffset = 0;
1106}
1107
1108
1109void _Jv_ClassReader::handleConstantValueAttribute (int field_index,
1110 int value)
1111{
1112 using namespace java::lang::reflect;
1113
1114 _Jv_Field *field = &def->fields[field_index];
1115
1116 if ((field->flags & (Modifier::STATIC
1117 | Modifier::FINAL
1118 | Modifier::PRIVATE)) == 0)
1119 {
1120 // Ignore, as per vmspec #4.7.2
1121 return;
1122 }
1123
1124 // do not allow multiple constant fields!
1125 if (field->flags & _Jv_FIELD_CONSTANT_VALUE)
1126 throw_class_format_error ("field has multiple ConstantValue attributes");
1127
1128 field->flags |= _Jv_FIELD_CONSTANT_VALUE;
1129 def->field_initializers[field_index] = value;
1130
1131 /* type check the initializer */
1132
1133 if (value <= 0 || value >= pool_count)
1134 throw_class_format_error ("erroneous ConstantValue attribute");
1135
1136 /* FIXME: do the rest */
1137}
1138
1139void _Jv_ClassReader::handleFieldsEnd ()
1140{