OSDN Git Service

2007-06-07 Matthias Klose <doko@ubuntu.com>
[pf3gnuchains/gcc-fork.git] / libjava / defineclass.cc
1 // defineclass.cc - defining a class from .class format.
2
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4    Free Software Foundation
5
6    This file is part of libgcj.
7
8 This software is copyrighted work licensed under the terms of the
9 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
10 details.  */
11
12 /* 
13    Author: Kresten Krab Thorup <krab@gnu.org> 
14
15    Written using the online versions of Java Language Specification (1st
16    ed.) and The Java Virtual Machine Specification (2nd ed.). 
17
18    Future work may include reading (and handling) attributes which are
19    currently being ignored ("InnerClasses", "LineNumber", etc...).  
20 */
21
22 #include <config.h>
23
24 #include <java-interp.h>
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <java-cpool.h>
29 #include <gcj/cni.h>
30 #include <execution.h>
31
32 #include <java/lang/Class.h>
33 #include <java/lang/Float.h>
34 #include <java/lang/Double.h>
35 #include <java/lang/Character.h>
36 #include <java/lang/LinkageError.h>
37 #include <java/lang/InternalError.h>
38 #include <java/lang/ClassFormatError.h>
39 #include <java/lang/NoClassDefFoundError.h>
40 #include <java/lang/ClassCircularityError.h>
41 #include <java/lang/IncompatibleClassChangeError.h>
42 #include <java/lang/reflect/Modifier.h>
43 #include <java/lang/reflect/Field.h>
44 #include <java/lang/reflect/Method.h>
45 #include <java/security/ProtectionDomain.h>
46 #include <java/io/DataOutputStream.h>
47 #include <java/io/ByteArrayOutputStream.h>
48
49 using namespace gcj;
50
51 #ifdef INTERPRETER
52
53 // these go in some separate functions, to avoid having _Jv_InitClass
54 // inserted all over the place.
55 static void throw_internal_error (const char *msg)
56         __attribute__ ((__noreturn__));
57 static void throw_no_class_def_found_error (jstring msg)
58         __attribute__ ((__noreturn__));
59 static void throw_no_class_def_found_error (const char *msg)
60         __attribute__ ((__noreturn__));
61 static void throw_class_format_error (jstring msg)
62         __attribute__ ((__noreturn__));
63 static void throw_incompatible_class_change_error (jstring msg)
64         __attribute__ ((__noreturn__));
65 static void throw_class_circularity_error (jstring msg)
66         __attribute__ ((__noreturn__));
67
68 /**
69  * We define class reading using a class.  It is practical, since then
70  * the entire class-reader can be a friend of class Class (it needs to
71  * write all it's different structures); but also because this makes it
72  * easy to make class definition reentrant, and thus two threads can be
73  * defining classes at the same time.   This class (_Jv_ClassReader) is
74  * never exposed outside this file, so we don't have to worry about
75  * public or private members here.
76  */
77
78 struct _Jv_ClassReader
79 {
80
81   // do verification?  Currently, there is no option to disable this.
82   // This flag just controls the verificaiton done by the class loader;
83   // i.e., checking the integrity of the constant pool; and it is
84   // allways on.  You always want this as far as I can see, but it also
85   // controls weither identifiers and type descriptors/signatures are
86   // verified as legal.  This could be somewhat more expensive since it
87   // will call Character.isJavaIdentifier{Start,Part} for each character
88   // in any identifier (field name or method name) it comes by.  Thus,
89   // it might be useful to turn off this verification for classes that
90   // come from a trusted source.  However, for GCJ, trusted classes are
91   // most likely to be linked in.
92
93   bool verify;
94
95   // original input data.
96   jbyteArray input_data;
97   jint input_offset;
98
99   // input data.
100   unsigned char     *bytes;
101   int                len;
102
103   // current input position
104   int                pos;
105
106   // the constant pool data
107   int pool_count;
108   unsigned char     *tags;
109   unsigned int      *offsets;
110
111   // the class to define (see java-interp.h)
112   jclass           def;
113
114   // the classes associated interpreter data.
115   _Jv_InterpClass  *def_interp;
116
117   // The name we found.
118   _Jv_Utf8Const **found_name;
119
120   // True if this is a 1.5 class file.
121   bool             is_15;
122
123   // Buffer holding extra reflection data.
124   ::java::io::ByteArrayOutputStream *reflection_data;
125   ::java::io::DataOutputStream *data_stream;
126
127
128   /* check that the given number of input bytes are available */
129   inline void check (int num)
130   {
131     if (pos + num > len)
132       throw_class_format_error ("Premature end of data");
133   }
134
135   /* skip a given number of bytes in input */
136   inline void skip (int num)
137   {
138     check (num);
139     pos += num;
140   }
141   
142   /* read an unsigned 1-byte unit */
143   inline static jint get1u (unsigned char* bytes)
144   {
145     return bytes[0];
146   }
147   
148   /* read an unsigned 1-byte unit */
149   inline jint read1u ()
150   {
151     skip (1);
152     return get1u (bytes+pos-1);
153   }
154   
155   /* read an unsigned 2-byte unit */
156   inline static jint get2u (unsigned char *bytes)
157   {
158     return (((jint)bytes[0]) << 8) | ((jint)bytes[1]);
159   }
160   
161   /* read an unsigned 2-byte unit */
162   inline jint read2u ()
163   {
164     skip (2);  
165     return get2u (bytes+pos-2);
166   }
167   
168   /* read a 4-byte unit */
169   static jint get4 (unsigned char *bytes)
170   {
171     return (((jint)bytes[0]) << 24)
172          | (((jint)bytes[1]) << 16)
173          | (((jint)bytes[2]) << 8)
174          | (((jint)bytes[3]) << 0);
175   }
176
177   /* read a 4-byte unit, (we don't do that quite so often) */
178   inline jint read4 ()
179   {
180     skip (4);  
181     return get4 (bytes+pos-4);
182   }
183
184   /* read a 8-byte unit */
185   static jlong get8 (unsigned char* bytes)
186   {
187     return (((jlong)bytes[0]) << 56)
188          | (((jlong)bytes[1]) << 48)
189          | (((jlong)bytes[2]) << 40)
190          | (((jlong)bytes[3]) << 32) 
191          | (((jlong)bytes[4]) << 24)
192          | (((jlong)bytes[5]) << 16)
193          | (((jlong)bytes[6]) << 8)
194          | (((jlong)bytes[7]) << 0);
195   }
196
197   /* read a 8-byte unit */
198   inline jlong read8 ()
199   {
200     skip (8);  
201     return get8 (bytes+pos-8);
202   }
203
204   inline void check_tag (int index, char expected_tag)
205   {
206     if (index < 0
207         || index > pool_count
208         || tags[index] != expected_tag)
209       throw_class_format_error ("erroneous constant pool tag");
210   }
211
212   inline void verify_identifier (_Jv_Utf8Const* name)
213   {
214     if (! _Jv_VerifyIdentifier (name))
215       throw_class_format_error ("erroneous identifier");
216   }
217
218   inline void verify_classname (unsigned char* ptr, _Jv_ushort length)
219   {
220     if (! _Jv_VerifyClassName (ptr, length))
221       throw_class_format_error ("erroneous class name");
222   }
223
224   inline void verify_classname (_Jv_Utf8Const *name)
225   {
226     if (! _Jv_VerifyClassName (name))
227       throw_class_format_error ("erroneous class name");
228   }
229
230   inline void verify_field_signature (_Jv_Utf8Const *sig)
231   {
232     if (! _Jv_VerifyFieldSignature (sig))
233       throw_class_format_error ("erroneous type descriptor");
234   }
235
236   inline void verify_method_signature (_Jv_Utf8Const *sig)
237   {
238     if (! _Jv_VerifyMethodSignature (sig))
239       throw_class_format_error ("erroneous type descriptor");
240   }
241
242   ::java::io::DataOutputStream *get_reflection_stream ()
243   {
244     if (reflection_data == NULL)
245       {
246         reflection_data = new ::java::io::ByteArrayOutputStream();
247         data_stream = new ::java::io::DataOutputStream(reflection_data);
248       }
249     return data_stream;
250   }
251
252   _Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length,
253                    java::security::ProtectionDomain *pd,
254                    _Jv_Utf8Const **name_result)
255   {
256     if (klass == 0 || length < 0 || offset+length > data->length)
257       throw_internal_error ("arguments to _Jv_DefineClass");
258
259     verify = true;
260     input_data = data;
261     input_offset = offset;
262     bytes  = (unsigned char*) (elements (data)+offset);
263     len    = length;
264     pos    = 0;
265     is_15  = false;
266
267     def    = klass;
268     found_name = name_result;
269     reflection_data = NULL;
270     data_stream = NULL;
271
272     def->size_in_bytes = -1;
273     def->vtable_method_count = -1;
274     def->engine = &_Jv_soleInterpreterEngine;
275     def->protectionDomain = pd;
276   }
277
278   /** and here goes the parser members defined out-of-line */
279   void parse ();
280   void read_constpool ();
281   void prepare_pool_entry (int index, unsigned char tag,
282                            bool rewrite = true);
283   void read_fields ();
284   void read_methods ();
285   void read_one_class_attribute ();
286   void read_one_method_attribute (int method);
287   void read_one_code_attribute (int method);
288   void read_one_field_attribute (int field, bool *);
289   void throw_class_format_error (const char *msg);
290
291   void handleEnclosingMethod(int);
292   void handleGenericSignature(jv_attr_type, unsigned short, int);
293   void handleAnnotationElement();
294   void handleAnnotation();
295   void handleAnnotations();
296   void handleMemberAnnotations(jv_attr_type, int, int);
297   void handleAnnotationDefault(int, int);
298   void handleParameterAnnotations(int, int);
299   void finish_reflection_data ();
300
301   /** check an utf8 entry, without creating a Utf8Const object */
302   bool is_attribute_name (int index, const char *name);
303   
304   /** return the value of a utf8 entry in the passed array */
305   int pool_Utf8_to_char_arr (int index, char **entry);
306
307   /** here goes the class-loader members defined out-of-line */
308   void handleConstantPool ();
309   void handleClassBegin (int, int, int);
310   void handleInterfacesBegin (int);
311   void handleInterface (int, int);
312   void handleFieldsBegin (int);
313   void handleField (int, int, int, int, int *);
314   void handleConstantValueAttribute (int, int, bool *);
315   void handleMethodsBegin (int);
316   void handleMethod (int, int, int, int);
317   void handleMethodsEnd ();
318   void handleCodeAttribute (int, int, int, int, int, int);
319   void handleExceptionTableEntry (int, int, int, int, int, int);
320
321   void checkExtends (jclass sub, jclass super);
322   void checkImplements (jclass sub, jclass super);
323
324   /*
325    * FIXME: we should keep a hash table of utf8-strings, since many will
326    * be the same.  It's a little tricky, however, because the hash table
327    * needs to interact gracefully with the garbage collector.  Much
328    * memory is to be saved by this, however!  perhaps the improvement
329    * could be implemented in prims.cc (_Jv_makeUtf8Const), since it
330    * computes the hash value anyway.
331    */
332 };
333
334 // Note that *NAME_RESULT will only be set if the class is registered
335 // with the class loader.  This is how the caller can know whether
336 // unregistration is require.
337 void
338 _Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length,
339                  java::security::ProtectionDomain *pd,
340                  _Jv_Utf8Const **name_result)
341 {
342   _Jv_ClassReader reader (klass, data, offset, length, pd, name_result);
343   reader.parse();
344
345   /* that's it! */
346 }
347
348 \f
349 /** This section defines the parsing/scanning of the class data */
350
351 // Major and minor version numbers for various releases.
352 #define MAJOR_1_1 45
353 #define MINOR_1_1  3
354 #define MAJOR_1_2 46
355 #define MINOR_1_2  0
356 #define MAJOR_1_3 47
357 #define MINOR_1_3  0
358 #define MAJOR_1_4 48
359 #define MINOR_1_4  0
360 #define MAJOR_1_5 49
361 #define MINOR_1_5  0
362
363 void
364 _Jv_ClassReader::parse ()
365 {
366   int magic = read4 ();
367   if (magic != (int) 0xCAFEBABE)
368     throw_class_format_error ("bad magic number");
369
370   int minor_version = read2u ();
371   int major_version = read2u ();
372   if (major_version < MAJOR_1_1 || major_version > MAJOR_1_5
373       || (major_version == MAJOR_1_5 && minor_version > MINOR_1_5))
374     throw_class_format_error ("unrecognized class file version");
375   is_15 = (major_version == MAJOR_1_5);
376
377   pool_count = read2u ();
378
379   read_constpool ();
380
381   int access_flags = read2u ();
382   int this_class = read2u ();
383   int super_class = read2u ();
384
385   check_tag (this_class, JV_CONSTANT_Class);
386   if (super_class != 0) 
387     check_tag (super_class, JV_CONSTANT_Class);
388
389   handleClassBegin (access_flags, this_class, super_class);
390
391   // Allocate our aux_info here, after the name is set, to fulfill our
392   // contract with the collector interface.
393   def->aux_info = (void *) _Jv_AllocRawObj (sizeof (_Jv_InterpClass));
394   def_interp = (_Jv_InterpClass *) def->aux_info;
395
396   int interfaces_count = read2u (); 
397
398   handleInterfacesBegin (interfaces_count);
399
400   for (int i = 0; i < interfaces_count; i++)
401     {
402       int iface = read2u ();
403       check_tag (iface, JV_CONSTANT_Class);
404       handleInterface (i, iface);
405     }
406   
407   read_fields ();
408   read_methods ();
409   
410   int attributes_count = read2u ();
411   
412   for (int i = 0; i < attributes_count; i++)
413     {
414       read_one_class_attribute ();
415     }
416
417   if (pos != len)
418     throw_class_format_error ("unused data before end of file");
419
420   finish_reflection_data ();
421
422   // Tell everyone we're done.
423   def->state = JV_STATE_READ;
424   if (gcj::verbose_class_flag)
425     _Jv_Linker::print_class_loaded (def);
426   ++gcj::loadedClasses;
427   def->notifyAll ();
428 }
429
430 void
431 _Jv_ClassReader::finish_reflection_data ()
432 {
433   if (data_stream == NULL)
434     return;
435   data_stream->writeByte(JV_DONE_ATTR);
436   data_stream->flush();
437   int nbytes = reflection_data->count;
438   unsigned char *new_bytes = (unsigned char *) _Jv_AllocBytes (nbytes);
439   memcpy (new_bytes, elements (reflection_data->buf), nbytes);
440   def->reflection_data = new_bytes;
441 }
442
443 void
444 _Jv_ClassReader::handleEnclosingMethod (int len)
445 {
446   if (len != 4)
447     throw_class_format_error ("invalid EnclosingMethod attribute");
448   // FIXME: only allow one...
449
450   int class_index = read2u();
451   check_tag (class_index, JV_CONSTANT_Class);
452   prepare_pool_entry (class_index, JV_CONSTANT_Class);
453
454   int method_index = read2u();
455   // Zero is ok and means no enclosing method.
456   if (method_index != 0)
457     {
458       check_tag (method_index, JV_CONSTANT_NameAndType);
459       prepare_pool_entry (method_index, JV_CONSTANT_NameAndType);
460     }
461
462   ::java::io::DataOutputStream *stream = get_reflection_stream ();
463   stream->writeByte(JV_CLASS_ATTR);
464   stream->writeInt(5);
465   stream->writeByte(JV_ENCLOSING_METHOD_KIND);
466   stream->writeShort(class_index);
467   stream->writeShort(method_index);
468 }
469
470 void
471 _Jv_ClassReader::handleGenericSignature (jv_attr_type type,
472                                          unsigned short index,
473                                          int len)
474 {
475   if (len != 2)
476     throw_class_format_error ("invalid Signature attribute");
477
478   int cpool_idx = read2u();
479   check_tag (cpool_idx, JV_CONSTANT_Utf8);
480   prepare_pool_entry (cpool_idx, JV_CONSTANT_Utf8, false);
481
482   ::java::io::DataOutputStream *stream = get_reflection_stream ();
483   stream->writeByte(type);
484   int attrlen = 3;
485   if (type != JV_CLASS_ATTR)
486     attrlen += 2;
487   stream->writeInt(attrlen);
488   if (type != JV_CLASS_ATTR)
489     stream->writeShort(index);
490   stream->writeByte(JV_SIGNATURE_KIND);
491   stream->writeShort(cpool_idx);
492 }
493
494 void
495 _Jv_ClassReader::handleAnnotationElement()
496 {
497   int tag = read1u();
498   switch (tag)
499     {
500     case 'B':
501     case 'C':
502     case 'S':
503     case 'Z':
504     case 'I':
505       {
506         int index = read2u();
507         check_tag (index, JV_CONSTANT_Integer);
508         prepare_pool_entry (index, JV_CONSTANT_Integer);
509       }
510       break;
511     case 'D':
512       {
513         int index = read2u();
514         check_tag (index, JV_CONSTANT_Double);
515         prepare_pool_entry (index, JV_CONSTANT_Double);
516       }
517       break;
518     case 'F':
519       {
520         int index = read2u();
521         check_tag (index, JV_CONSTANT_Float);
522         prepare_pool_entry (index, JV_CONSTANT_Float);
523       }
524       break;
525     case 'J':
526       {
527         int index = read2u();
528         check_tag (index, JV_CONSTANT_Long);
529         prepare_pool_entry (index, JV_CONSTANT_Long);
530       }
531       break;
532     case 's':
533       {
534         int index = read2u();
535         // Despite what the JVM spec says, compilers generate a Utf8
536         // constant here, not a String.
537         check_tag (index, JV_CONSTANT_Utf8);
538         prepare_pool_entry (index, JV_CONSTANT_Utf8, false);
539       }
540       break;
541
542     case 'e':
543       {
544         int type_name_index = read2u();
545         int const_name_index = read2u ();
546         check_tag (type_name_index, JV_CONSTANT_Utf8);
547         prepare_pool_entry (type_name_index, JV_CONSTANT_Utf8);
548         check_tag (const_name_index, JV_CONSTANT_Utf8);
549         prepare_pool_entry (const_name_index, JV_CONSTANT_Utf8, false);
550       }
551       break;
552     case 'c':
553       {
554         int index = read2u();
555         check_tag (index, JV_CONSTANT_Utf8);
556         prepare_pool_entry (index, JV_CONSTANT_Utf8);
557       }
558       break;
559     case '@':
560       handleAnnotation();
561       break;
562     case '[':
563       {
564         int n_array_elts = read2u ();
565         for (int i = 0; i < n_array_elts; ++i)
566           handleAnnotationElement();
567       }
568       break;
569     default:
570       throw_class_format_error ("invalid annotation element");
571     }
572 }
573
574 void
575 _Jv_ClassReader::handleAnnotation()
576 {
577   int type_index = read2u();
578   check_tag (type_index, JV_CONSTANT_Utf8);
579   prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
580
581   int npairs = read2u();
582   for (int i = 0; i < npairs; ++i)
583     {
584       int name_index = read2u();
585       check_tag (name_index, JV_CONSTANT_Utf8);
586       prepare_pool_entry (name_index, JV_CONSTANT_Utf8, false);
587       handleAnnotationElement();
588     }
589 }
590
591 void
592 _Jv_ClassReader::handleAnnotations()
593 {
594   int num = read2u();
595   while (num--)
596     handleAnnotation();
597 }
598
599 void
600 _Jv_ClassReader::handleMemberAnnotations(jv_attr_type member_type,
601                                          int member_index,
602                                          int len)
603 {
604   // We're going to copy the bytes in verbatim.  But first we want to
605   // make sure the attribute is well-formed, and we want to prepare
606   // the constant pool.  So, we save our starting point.
607   int orig_pos = pos;
608
609   handleAnnotations();
610   // FIXME: check that we read all LEN bytes?
611
612   ::java::io::DataOutputStream *stream = get_reflection_stream ();
613   stream->writeByte(member_type);
614   int newLen = len + 1;
615   if (member_type != JV_CLASS_ATTR)
616     newLen += 2;
617   stream->writeInt(newLen);
618   stream->writeByte(JV_ANNOTATIONS_KIND);
619   if (member_type != JV_CLASS_ATTR)
620     stream->writeShort(member_index);
621   // Write the data as-is.
622   stream->write(input_data, input_offset + orig_pos, len);
623 }
624
625 void
626 _Jv_ClassReader::handleAnnotationDefault(int member_index, int len)
627 {
628   int orig_pos = pos;
629   handleAnnotationElement();
630
631   ::java::io::DataOutputStream *stream = get_reflection_stream ();
632   stream->writeByte(JV_METHOD_ATTR);
633   stream->writeInt(len + 3);
634   stream->writeByte(JV_ANNOTATION_DEFAULT_KIND);
635   stream->writeShort(member_index);
636   stream->write(input_data, input_offset + orig_pos, len);
637 }
638
639 void
640 _Jv_ClassReader::handleParameterAnnotations(int member_index, int len)
641 {
642   int orig_pos = pos;
643
644   int n_params = read1u();
645   for (int i = 0; i < n_params; ++i)
646     handleAnnotations();
647
648   ::java::io::DataOutputStream *stream = get_reflection_stream ();
649   stream->writeByte(JV_METHOD_ATTR);
650   stream->writeInt(len + 3);
651   stream->writeByte(JV_PARAMETER_ANNOTATIONS_KIND);
652   stream->writeShort(member_index);
653   stream->write(input_data, input_offset + orig_pos, len);
654 }
655
656 void _Jv_ClassReader::read_constpool ()
657 {
658   tags    = (unsigned char*) _Jv_AllocBytes (pool_count);
659   offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int) * pool_count) ;
660
661   /** first, we scan the constant pool, collecting tags and offsets */
662   tags[0]   = JV_CONSTANT_Undefined;
663   offsets[0] = pos;
664   for (int c = 1; c < pool_count; c++)
665     {
666       tags[c]    = read1u ();
667       offsets[c] = pos;
668
669       switch (tags[c])
670         {
671         case JV_CONSTANT_String:
672         case JV_CONSTANT_Class:
673           skip (2);
674           break;
675
676         case JV_CONSTANT_Fieldref:
677         case JV_CONSTANT_Methodref:
678         case JV_CONSTANT_InterfaceMethodref:
679         case JV_CONSTANT_NameAndType:
680         case JV_CONSTANT_Integer:
681         case JV_CONSTANT_Float:
682           skip (4);
683           break;
684
685         case JV_CONSTANT_Double:
686         case JV_CONSTANT_Long:
687           skip (8);
688           tags[++c] = JV_CONSTANT_Undefined;
689           break;
690             
691         case JV_CONSTANT_Utf8:
692           {                 
693             int len = read2u ();
694             skip (len);
695           }
696           break;
697
698         case JV_CONSTANT_Unicode:
699           throw_class_format_error ("unicode not supported");
700           break;
701
702         default:
703           throw_class_format_error ("erroneous constant pool tag");
704         }
705     }
706
707   handleConstantPool ();
708 }
709
710
711 void _Jv_ClassReader::read_fields ()
712 {
713   int fields_count = read2u ();
714   handleFieldsBegin (fields_count);
715
716   // We want to sort the fields so that static fields come first,
717   // followed by instance fields.  We do this before parsing the
718   // fields so that we can have the new indices available when
719   // creating the annotation data structures.
720
721   // Allocate this on the heap in case there are a large number of
722   // fields.
723   int *fieldmap = (int *) _Jv_AllocBytes (fields_count * sizeof (int));
724   int save_pos = pos;
725   int static_count = 0, instance_count = -1;
726   for (int i = 0; i < fields_count; ++i)
727     {
728       using namespace java::lang::reflect;
729
730       int access_flags = read2u ();
731       skip (4);
732       int attributes_count = read2u ();
733
734       if ((access_flags & Modifier::STATIC) != 0) 
735         fieldmap[i] = static_count++;
736       else
737         fieldmap[i] = instance_count--;
738
739       for (int j = 0; j < attributes_count; ++j)
740         {
741           skip (2);
742           int length = read4 ();
743           skip (length);
744         }
745     }
746   pos = save_pos;
747
748   // In the loop above, instance fields are represented by negative
749   // numbers.  Here we rewrite these to be proper offsets.
750   for (int i = 0; i < fields_count; ++i)
751     {
752       if (fieldmap[i] < 0)
753         fieldmap[i] = static_count - 1 - fieldmap[i];
754     }
755   def->static_field_count = static_count;
756
757   for (int i = 0; i < fields_count; i++)
758     {
759       int access_flags     = read2u ();
760       int name_index       = read2u ();
761       int descriptor_index = read2u ();
762       int attributes_count = read2u ();
763
764       check_tag (name_index, JV_CONSTANT_Utf8);
765       prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
766
767       check_tag (descriptor_index, JV_CONSTANT_Utf8);
768       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
769
770       handleField (i, access_flags, name_index, descriptor_index, fieldmap);
771
772       bool found_value = false;
773       for (int j = 0; j < attributes_count; j++)
774         {
775           read_one_field_attribute (fieldmap[i], &found_value);
776         }
777     }
778 }
779
780 bool
781 _Jv_ClassReader::is_attribute_name (int index, const char *name)
782 {
783   check_tag (index, JV_CONSTANT_Utf8);
784   int len = get2u (bytes+offsets[index]);
785   if (len != (int) strlen (name))
786     return false;
787   else
788     return !memcmp (bytes+offsets[index]+2, name, len);
789 }
790
791 // Get a UTF8 value from the constant pool and turn it into a garbage
792 // collected char array.
793 int _Jv_ClassReader::pool_Utf8_to_char_arr (int index, char** entry)
794 {
795   check_tag (index, JV_CONSTANT_Utf8);
796   int len = get2u (bytes + offsets[index]);
797   *entry = reinterpret_cast<char *> (_Jv_AllocBytes (len + 1));
798   (*entry)[len] = '\0';
799   memcpy (*entry, bytes + offsets[index] + 2, len);
800   return len + 1;
801 }
802
803 void _Jv_ClassReader::read_one_field_attribute (int field_index,
804                                                 bool *found_value)
805 {
806   int name = read2u ();
807   int length = read4 ();
808
809   if (is_attribute_name (name, "ConstantValue"))
810     {
811       int cv = read2u ();
812
813       if (cv < pool_count 
814           && cv > 0
815           && (tags[cv] == JV_CONSTANT_Integer
816               || tags[cv] == JV_CONSTANT_Float
817               || tags[cv] == JV_CONSTANT_Long
818               || tags[cv] == JV_CONSTANT_Double
819               || tags[cv] == JV_CONSTANT_String))
820         {
821           handleConstantValueAttribute (field_index, cv, found_value);
822         }
823       else
824         {
825           throw_class_format_error ("erroneous ConstantValue attribute");
826         }
827
828       if (length != 2) 
829         throw_class_format_error ("erroneous ConstantValue attribute");
830     }
831   else if (is_attribute_name (name, "Signature"))
832     handleGenericSignature(JV_FIELD_ATTR, field_index, length);
833   else if (is_attribute_name (name, "RuntimeVisibleAnnotations"))
834     handleMemberAnnotations(JV_FIELD_ATTR, field_index, length);
835   else
836     skip (length);
837 }
838
839 void _Jv_ClassReader::read_methods ()
840 {
841   int methods_count = read2u ();
842   
843   handleMethodsBegin (methods_count);
844   
845   for (int i = 0; i < methods_count; i++)
846     {
847       int access_flags     = read2u ();
848       int name_index       = read2u ();
849       int descriptor_index = read2u ();
850       int attributes_count = read2u ();
851       
852       check_tag (name_index, JV_CONSTANT_Utf8);
853       prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
854
855       check_tag (descriptor_index, JV_CONSTANT_Utf8);
856       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
857
858       handleMethod (i, access_flags, name_index,
859                     descriptor_index);
860
861       for (int j = 0; j < attributes_count; j++)
862         {
863           read_one_method_attribute (i);
864         }
865     }
866   
867   handleMethodsEnd ();
868 }
869
870 void _Jv_ClassReader::read_one_method_attribute (int method_index) 
871 {
872   int name = read2u ();
873   int length = read4 ();
874
875   if (is_attribute_name (name, "Exceptions"))
876     {
877       _Jv_Method *method = reinterpret_cast<_Jv_Method *>
878         (&def->methods[method_index]);
879       if (method->throws != NULL)
880         throw_class_format_error ("only one Exceptions attribute allowed per method");
881
882       int num_exceptions = read2u ();
883       _Jv_Utf8Const **exceptions =
884         (_Jv_Utf8Const **) _Jv_AllocBytes ((num_exceptions + 1)
885                                            * sizeof (_Jv_Utf8Const *));
886
887       int out = 0;
888       _Jv_word *pool_data = def->constants.data;
889       for (int i = 0; i < num_exceptions; ++i)
890         {
891           int ndx = read2u ();
892           // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
893           if (ndx != 0)
894             {
895               check_tag (ndx, JV_CONSTANT_Class);
896               exceptions[out++] = pool_data[ndx].utf8; 
897             }
898         }
899       exceptions[out] = NULL;
900       method->throws = exceptions;
901     }
902
903   else if (is_attribute_name (name, "Code"))
904     {
905       int start_off = pos;
906       int max_stack = read2u ();
907       int max_locals = read2u ();
908       int code_length = read4 ();
909
910       int code_start = pos;
911       skip (code_length);
912       int exception_table_length = read2u ();
913
914       handleCodeAttribute (method_index, 
915                            max_stack, max_locals,
916                            code_start, code_length,
917                            exception_table_length);
918       
919
920       for (int i = 0; i < exception_table_length; i++)
921         {
922           int start_pc   = read2u ();
923           int end_pc     = read2u ();
924           int handler_pc = read2u ();
925           int catch_type = read2u ();
926
927           if (start_pc > end_pc
928               || start_pc < 0
929               // END_PC can be equal to CODE_LENGTH.
930               // See JVM Spec 4.7.4.
931               || end_pc > code_length
932               || handler_pc >= code_length)
933             throw_class_format_error ("erroneous exception handler info");
934
935           if (! (tags[catch_type] == JV_CONSTANT_Class
936                  || tags[catch_type] == 0))
937             {
938               throw_class_format_error ("erroneous exception handler info");
939             }
940
941           handleExceptionTableEntry (method_index,
942                                      i,
943                                      start_pc,
944                                      end_pc,
945                                      handler_pc, 
946                                      catch_type);
947
948         }
949
950       int attributes_count = read2u ();
951
952       for (int i = 0; i < attributes_count; i++)
953         {
954           read_one_code_attribute (method_index);
955         }
956
957       if ((pos - start_off) != length)
958         throw_class_format_error ("code attribute too short");
959     }
960   else if (is_attribute_name (name, "Signature"))
961     handleGenericSignature(JV_METHOD_ATTR, method_index, length);
962   else if (is_attribute_name (name, "RuntimeVisibleAnnotations"))
963     handleMemberAnnotations(JV_METHOD_ATTR, method_index, length);
964   else if (is_attribute_name (name, "RuntimeVisibleParameterAnnotations"))
965     handleParameterAnnotations(method_index, length);
966   else if (is_attribute_name (name, "AnnotationDefault"))
967     handleAnnotationDefault(method_index, length);
968   else
969     {
970       /* ignore unknown attributes */
971       skip (length);
972     }
973 }
974
975 void _Jv_ClassReader::read_one_code_attribute (int method_index) 
976 {
977   int name = read2u ();
978   int length = read4 ();
979   if (is_attribute_name (name, "LineNumberTable"))
980     {
981       _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
982         (def_interp->interpreted_methods[method_index]);
983       if (method->line_table != NULL)
984         throw_class_format_error ("Method already has LineNumberTable");
985
986       int table_len = read2u ();
987       _Jv_LineTableEntry* table
988         = (_Jv_LineTableEntry *) _Jv_AllocBytes (table_len
989                                                  * sizeof (_Jv_LineTableEntry));
990       for (int i = 0; i < table_len; i++)
991        {
992          table[i].bytecode_pc = read2u ();
993          table[i].line = read2u ();
994        }
995       method->line_table_len = table_len;
996       method->line_table = table;
997     }
998   else if (is_attribute_name (name, "LocalVariableTable"))
999     {
1000       _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1001                                (def_interp->interpreted_methods[method_index]);
1002       if (method->local_var_table != NULL)
1003         throw_class_format_error ("Method already has LocalVariableTable");
1004         
1005       int table_len = read2u ();
1006       _Jv_LocalVarTableEntry *table 
1007         = reinterpret_cast<_Jv_LocalVarTableEntry *>
1008             (_Jv_AllocRawObj (table_len * sizeof (_Jv_LocalVarTableEntry)));
1009                                
1010       for (int i = 0; i < table_len; i++)
1011         {
1012           table[i].bytecode_start_pc = read2u ();
1013           table[i].length = read2u ();
1014           int len;
1015           len = pool_Utf8_to_char_arr (read2u (), &table[i].name);
1016           len = pool_Utf8_to_char_arr (read2u (), &table[i].descriptor);
1017           table[i].slot = read2u ();
1018           
1019           if (table[i].slot > method->max_locals || table[i].slot < 0)
1020             throw_class_format_error ("Malformed Local Variable Table: Invalid Slot");
1021         }
1022             
1023       method->local_var_table_len = table_len;
1024       method->local_var_table = table;
1025     }
1026   else
1027     {
1028       /* ignore unknown code attributes */
1029       skip (length);
1030     }
1031 }
1032
1033 void _Jv_ClassReader::read_one_class_attribute () 
1034 {
1035   int name = read2u ();
1036   int length = read4 ();
1037   if (is_attribute_name (name, "SourceFile"))
1038     {
1039       int source_index = read2u ();
1040       check_tag (source_index, JV_CONSTANT_Utf8);
1041       prepare_pool_entry (source_index, JV_CONSTANT_Utf8, false);
1042       def_interp->source_file_name = _Jv_NewStringUtf8Const
1043         (def->constants.data[source_index].utf8);
1044     }
1045   else if (is_attribute_name (name, "Signature"))
1046     handleGenericSignature(JV_CLASS_ATTR, 0, length);
1047   else if (is_attribute_name (name, "EnclosingMethod"))
1048     handleEnclosingMethod(length);
1049   else if (is_attribute_name (name, "RuntimeVisibleAnnotations"))
1050     handleMemberAnnotations(JV_CLASS_ATTR, 0, length);
1051   else if (is_attribute_name (name, "InnerClasses"))
1052     {
1053       ::java::io::DataOutputStream *stream = get_reflection_stream ();
1054       stream->writeByte(JV_CLASS_ATTR);
1055       stream->writeInt(length + 1);
1056       stream->writeByte(JV_INNER_CLASSES_KIND);
1057       stream->write(input_data, input_offset + pos, length);
1058       skip (length);
1059     }
1060   else
1061     {
1062       /* Currently, we ignore most class attributes. */
1063      skip (length);
1064     }
1065 }
1066
1067
1068
1069 \f
1070 /* this section defines the semantic actions of the parser */
1071
1072 void _Jv_ClassReader::handleConstantPool ()
1073 {
1074   /** now, we actually define the class' constant pool */
1075
1076   jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
1077   _Jv_word *pool_data
1078     = (_Jv_word*) _Jv_AllocRawObj (pool_count * sizeof (_Jv_word));
1079
1080   def->constants.tags = pool_tags;
1081   def->constants.data = pool_data;
1082   def->constants.size = pool_count;
1083
1084   // Here we make a pass to collect the strings!   We do this, because
1085   // internally in the GCJ runtime, classes are encoded with .'s not /'s. 
1086   // Therefore, we first collect the strings, and then translate the rest
1087   // of the utf8-entries (thus not representing strings) from /-notation
1088   // to .-notation.
1089   for (int i = 1; i < pool_count; i++)
1090     {
1091       if (tags[i] == JV_CONSTANT_String)
1092         {
1093           unsigned char* str_data = bytes + offsets [i];
1094           int utf_index = get2u (str_data);
1095           check_tag (utf_index, JV_CONSTANT_Utf8);
1096           unsigned char *utf_data = bytes + offsets[utf_index];
1097           int len = get2u (utf_data);
1098           pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
1099           pool_tags[i] = JV_CONSTANT_String;
1100         }
1101       else
1102         {
1103           pool_tags[i] = JV_CONSTANT_Undefined;
1104         }
1105     }
1106
1107   // and now, we scan everything else but strings & utf8-entries.  This
1108   // leaves out those utf8-entries which are not used; which will be left
1109   // with a tag of JV_CONSTANT_Undefined in the class definition.
1110   for (int index = 1; index < pool_count; index++)
1111     {
1112       switch (tags[index])
1113         {
1114         case JV_CONSTANT_Undefined:
1115         case JV_CONSTANT_String:
1116         case JV_CONSTANT_Utf8:
1117           continue;
1118           
1119         default:
1120           prepare_pool_entry (index, tags[index]);
1121         }
1122     }  
1123   
1124 }
1125
1126 /* this is a recursive procedure, which will prepare pool entries as needed.
1127    Which is how we avoid initializing those entries which go unused. 
1128    
1129    REWRITE is true iff this pool entry is the Utf8 representation of a
1130    class name or a signature.
1131 */
1132
1133 void
1134 _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag,
1135                                      bool rewrite)
1136 {
1137   /* these two, pool_data and pool_tags, point into the class
1138      structure we are currently defining */
1139
1140   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
1141   _Jv_word      *pool_data = def->constants.data;
1142
1143   /* this entry was already prepared */
1144   if (pool_tags[index] == this_tag)
1145     return;
1146
1147   /* this_data points to the constant-pool information for the current
1148      constant-pool entry */
1149
1150   unsigned char *this_data = bytes + offsets[index];
1151
1152   switch (this_tag)
1153     {
1154     case JV_CONSTANT_Utf8: 
1155       {
1156         int len = get2u (this_data);
1157         char *s = ((char*) this_data)+2;
1158         pool_tags[index] = JV_CONSTANT_Utf8;
1159
1160         if (! rewrite)
1161           {
1162             pool_data[index].utf8 = _Jv_makeUtf8Const (s, len);
1163             break;
1164           }
1165
1166         // If REWRITE is set, it is because some other tag needs this
1167         // utf8-entry for type information: it is a class or a
1168         // signature.  Thus, we translate /'s to .'s in order to
1169         // accomondate gcj's internal representation.
1170         char *buffer = (char*) __builtin_alloca (len);
1171         for (int i = 0; i < len; i++)
1172           {
1173             if (s[i] == '/')
1174               buffer[i] = '.';
1175             else
1176               buffer[i] = s[i];
1177           }
1178         pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
1179       }
1180       break;
1181             
1182     case JV_CONSTANT_Class:      
1183       {
1184         int utf_index = get2u (this_data);
1185         check_tag (utf_index, JV_CONSTANT_Utf8);
1186         prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
1187
1188         if (verify)
1189           verify_classname (pool_data[utf_index].utf8);
1190                 
1191         pool_data[index].utf8 = pool_data[utf_index].utf8;
1192         pool_tags[index] = JV_CONSTANT_Class;
1193       }
1194       break;
1195             
1196     case JV_CONSTANT_String:
1197       // already handled before... 
1198       break;
1199             
1200     case JV_CONSTANT_Fieldref:
1201     case JV_CONSTANT_Methodref:
1202     case JV_CONSTANT_InterfaceMethodref:
1203       {
1204         int class_index = get2u (this_data);
1205         int nat_index = get2u (this_data+2);
1206
1207         check_tag (class_index, JV_CONSTANT_Class);
1208         prepare_pool_entry (class_index, JV_CONSTANT_Class);        
1209
1210         check_tag (nat_index, JV_CONSTANT_NameAndType);
1211         prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
1212
1213         // here, verify the signature and identifier name
1214         if (verify)
1215         {
1216           _Jv_ushort name_index, type_index;
1217           _Jv_loadIndexes (&pool_data[nat_index],
1218                            name_index, type_index);
1219
1220           if (this_tag == JV_CONSTANT_Fieldref)
1221             verify_field_signature (pool_data[type_index].utf8);
1222           else
1223             verify_method_signature (pool_data[type_index].utf8);
1224
1225           _Jv_Utf8Const* name = pool_data[name_index].utf8;
1226
1227           if (this_tag != JV_CONSTANT_Fieldref
1228               && (   _Jv_equalUtf8Consts (name, clinit_name)
1229                   || _Jv_equalUtf8Consts (name, init_name)))
1230             /* ignore */;
1231           else
1232             verify_identifier (pool_data[name_index].utf8);
1233         }
1234             
1235         _Jv_storeIndexes (&pool_data[index], class_index, nat_index);
1236         pool_tags[index] = this_tag;
1237       }
1238       break;
1239             
1240     case JV_CONSTANT_NameAndType:
1241       {
1242         _Jv_ushort name_index = get2u (this_data);
1243         _Jv_ushort type_index = get2u (this_data+2);
1244
1245         check_tag (name_index, JV_CONSTANT_Utf8);
1246         prepare_pool_entry (name_index, JV_CONSTANT_Utf8, false);
1247         check_tag (type_index, JV_CONSTANT_Utf8);
1248         prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
1249
1250         _Jv_storeIndexes (&pool_data[index], name_index, type_index);
1251         pool_tags[index] = JV_CONSTANT_NameAndType;
1252       }
1253       break;
1254             
1255     case JV_CONSTANT_Float:
1256       {
1257         jfloat f = java::lang::Float::intBitsToFloat ((jint) get4 (this_data));
1258         _Jv_storeFloat (&pool_data[index], f);
1259         pool_tags[index] = JV_CONSTANT_Float;
1260       }
1261       break;
1262             
1263     case JV_CONSTANT_Integer:
1264       {
1265         int i = get4 (this_data);
1266         _Jv_storeInt (&pool_data[index], i);
1267         pool_tags[index] = JV_CONSTANT_Integer;
1268       }
1269       break;
1270             
1271     case JV_CONSTANT_Double:
1272       {
1273         jdouble d
1274           = java::lang::Double::longBitsToDouble ((jlong) get8 (this_data));
1275         _Jv_storeDouble (&pool_data[index], d);
1276         pool_tags[index] = JV_CONSTANT_Double;
1277       }
1278       break;
1279             
1280     case JV_CONSTANT_Long:
1281       {
1282         jlong i = get8 (this_data);
1283         _Jv_storeLong (&pool_data[index], i);
1284         pool_tags[index] = JV_CONSTANT_Long;
1285       }
1286       break;
1287             
1288     default:
1289       throw_class_format_error ("erroneous constant pool tag");
1290     }
1291 }
1292
1293
1294 void
1295 _Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_class)
1296 {
1297   using namespace java::lang::reflect;
1298
1299   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
1300   _Jv_word      *pool_data = def->constants.data;
1301
1302   check_tag (this_class, JV_CONSTANT_Class);
1303   _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
1304
1305   // was ClassLoader.defineClass called with an expected class name?
1306   if (def->name == 0)
1307     {
1308       jclass orig = def->loader->findLoadedClass(loadedName->toString());
1309
1310       if (orig == 0)
1311         {
1312           def->name = loadedName;
1313         }
1314       else
1315         {
1316           jstring msg = JvNewStringUTF ("anonymous "
1317                                         "class data denotes "
1318                                         "existing class ");
1319           msg = msg->concat (orig->getName ());
1320
1321           throw_no_class_def_found_error (msg);
1322         }
1323     }
1324
1325   // assert that the loaded class has the expected name, 5.3.5
1326   else if (! _Jv_equalUtf8Consts (loadedName, def->name))
1327     {
1328       jstring msg = JvNewStringUTF ("loaded class ");
1329       msg = msg->concat (def->getName ());
1330       msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
1331       jstring klass_name = loadedName->toString();
1332       msg = msg->concat (klass_name);
1333
1334       throw_no_class_def_found_error (msg);
1335     }
1336
1337   def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
1338   pool_data[this_class].clazz = def;
1339   pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
1340
1341   if (super_class == 0)
1342     {
1343       // Note that this is ok if we are defining java.lang.Object.
1344       // But there is no way to have this class be interpreted.
1345       throw_class_format_error ("no superclass reference");
1346     }
1347
1348   def->state = JV_STATE_PRELOADING;
1349
1350   // Register this class with its defining loader as well (despite the
1351   // name of the function we're calling), so that super class lookups
1352   // work properly.  If there is an error, our caller will unregister
1353   // this class from the class loader.  Also, we don't need to hold a
1354   // lock here, as our caller has acquired it.
1355   _Jv_RegisterInitiatingLoader (def, def->loader);
1356
1357   // Note that we found a name so that unregistration can happen if
1358   // needed.
1359   *found_name = def->name;
1360
1361   if (super_class != 0)
1362     {
1363       // Load the superclass.
1364       check_tag (super_class, JV_CONSTANT_Class);
1365       _Jv_Utf8Const* super_name = pool_data[super_class].utf8; 
1366
1367       // Load the superclass using our defining loader.
1368       jclass the_super = _Jv_FindClass (super_name, def->loader);
1369
1370       // This will establish that we are allowed to be a subclass,
1371       // and check for class circularity error.
1372       checkExtends (def, the_super);
1373
1374       // Note: for an interface we will find Object as the
1375       // superclass.  We still check it above to ensure class file
1376       // validity, but we simply assign `null' to the actual field in
1377       // this case.
1378       def->superclass = (((access_flags & Modifier::INTERFACE))
1379                          ? NULL : the_super);
1380       pool_data[super_class].clazz = the_super;
1381       pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
1382     }
1383
1384   // Now we've come past the circularity problem, we can 
1385   // now say that we're loading.
1386
1387   def->state = JV_STATE_LOADING;
1388   def->notifyAll ();
1389 }
1390
1391 ///// Implements the checks described in sect. 5.3.5.3
1392 void
1393 _Jv_ClassReader::checkExtends (jclass sub, jclass super)
1394 {
1395   using namespace java::lang::reflect;
1396
1397   _Jv_Linker::wait_for_state (super, JV_STATE_LOADING);
1398
1399   // Having an interface or a final class as a superclass is no good.
1400   if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
1401     {
1402       throw_incompatible_class_change_error (sub->getName ());
1403     }
1404
1405   // If the super class is not public, we need to check some more.
1406   if ((super->accflags & Modifier::PUBLIC) == 0)
1407     {
1408       // With package scope, the classes must have the same class
1409       // loader.
1410       if (   sub->loader != super->loader
1411           || !_Jv_ClassNameSamePackage (sub->name, super->name))
1412         {
1413           throw_incompatible_class_change_error (sub->getName ());
1414         }
1415     } 
1416
1417   for (; super != 0; super = super->getSuperclass ())
1418     {
1419       if (super == sub)
1420         throw_class_circularity_error (sub->getName ());
1421     }
1422 }
1423
1424
1425
1426 void _Jv_ClassReader::handleInterfacesBegin (int count)
1427 {
1428   def->interfaces = (jclass*) _Jv_AllocRawObj (count*sizeof (jclass));
1429   def->interface_count = count;
1430 }
1431
1432 void _Jv_ClassReader::handleInterface (int if_number, int offset)
1433 {
1434   _Jv_word       * pool_data = def->constants.data;
1435   unsigned char  * pool_tags = (unsigned char*) def->constants.tags;
1436
1437   jclass the_interface;
1438
1439   if (pool_tags[offset] == JV_CONSTANT_Class)
1440     {
1441       _Jv_Utf8Const* name = pool_data[offset].utf8;
1442       the_interface =  _Jv_FindClass (name, def->loader);
1443     }
1444   else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
1445     {
1446       the_interface = pool_data[offset].clazz;
1447     }
1448   else
1449     {
1450       throw_no_class_def_found_error ("erroneous constant pool tag");
1451     }
1452
1453   // checks the validity of the_interface, and that we are in fact
1454   // allowed to implement that interface.
1455   checkImplements (def, the_interface);
1456   
1457   pool_data[offset].clazz = the_interface;
1458   pool_tags[offset] = JV_CONSTANT_ResolvedClass;
1459   
1460   def->interfaces[if_number] = the_interface;
1461 }
1462
1463 void
1464 _Jv_ClassReader::checkImplements (jclass sub, jclass super)
1465 {
1466   using namespace java::lang::reflect;
1467
1468   // well, it *must* be an interface
1469   if ((super->accflags & Modifier::INTERFACE) == 0)
1470     {
1471       throw_incompatible_class_change_error (sub->getName ());
1472     }
1473
1474   // if it has package scope, it must also be defined by the 
1475   // same loader.
1476   if ((super->accflags & Modifier::PUBLIC) == 0)
1477     {
1478       if (    sub->loader != super->loader
1479           || !_Jv_ClassNameSamePackage (sub->name, super->name))
1480         {
1481           throw_incompatible_class_change_error (sub->getName ());
1482         }
1483     } 
1484
1485   // FIXME: add interface circularity check here
1486   if (sub == super)
1487     {
1488       throw_class_circularity_error (sub->getName ());
1489     }           
1490 }
1491
1492 void _Jv_ClassReader::handleFieldsBegin (int count)
1493 {
1494   def->fields = (_Jv_Field*) _Jv_AllocRawObj (count * sizeof (_Jv_Field));
1495   def->field_count = count;
1496   def_interp->field_initializers
1497     = (_Jv_ushort*) _Jv_AllocRawObj (count * sizeof (_Jv_ushort));
1498   for (int i = 0; i < count; i++)
1499     def_interp->field_initializers[i] = (_Jv_ushort) 0;
1500 }
1501
1502 void _Jv_ClassReader::handleField (int field_no,
1503                                    int flags,
1504                                    int name,
1505                                    int desc,
1506                                    int *fieldmap)
1507 {
1508   using namespace java::lang::reflect;
1509
1510   _Jv_word *pool_data = def->constants.data;
1511
1512   _Jv_Field *field = &def->fields[fieldmap[field_no]];
1513   _Jv_Utf8Const *field_name = pool_data[name].utf8;
1514
1515   field->name      = field_name;
1516
1517   // Ignore flags we don't know about.  
1518   field->flags = flags & (Field::FIELD_MODIFIERS
1519                           | Modifier::SYNTHETIC
1520                           | Modifier::ENUM);
1521
1522   _Jv_Utf8Const* sig = pool_data[desc].utf8;
1523
1524   if (verify)
1525     {
1526       verify_identifier (field_name);
1527
1528       for (int i = 0; i < field_no; ++i)
1529         {
1530           if (_Jv_equalUtf8Consts (field_name, def->fields[fieldmap[i]].name)
1531               && _Jv_equalUtf8Consts (sig,
1532                                       // We know the other fields are
1533                                       // unresolved.
1534                                       (_Jv_Utf8Const *) def->fields[i].type))
1535             throw_class_format_error ("duplicate field name");
1536         }
1537
1538       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1539       if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
1540                 +((field->flags & Modifier::PRIVATE) ? 1 : 0)
1541                 +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
1542         throw_class_format_error ("erroneous field access flags");
1543
1544       // FIXME: JVM spec S4.5: Verify ACC_FINAL and ACC_VOLATILE are not 
1545       // both set. Verify modifiers for interface fields.
1546       
1547     }
1548
1549   if (verify)
1550     verify_field_signature (sig);
1551
1552   // field->type is really a jclass, but while it is still
1553   // unresolved we keep an _Jv_Utf8Const* instead.
1554   field->type       = (jclass) sig;
1555   field->flags     |= _Jv_FIELD_UNRESOLVED_FLAG;
1556   field->u.boffset  = 0;
1557 }
1558
1559
1560 void _Jv_ClassReader::handleConstantValueAttribute (int field_index, 
1561                                                     int value,
1562                                                     bool *found_value)
1563 {
1564   using namespace java::lang::reflect;
1565
1566   _Jv_Field *field = &def->fields[field_index];
1567
1568   if ((field->flags & (Modifier::STATIC
1569                        | Modifier::FINAL
1570                        | Modifier::PRIVATE)) == 0)
1571     {
1572       // Ignore, as per vmspec #4.7.2
1573       return;
1574     }
1575
1576   // do not allow multiple constant fields!
1577   if (*found_value)
1578     throw_class_format_error ("field has multiple ConstantValue attributes");
1579
1580   *found_value = true;
1581   def_interp->field_initializers[field_index] = value;
1582
1583   /* type check the initializer */
1584   
1585   if (value <= 0 || value >= pool_count)
1586     throw_class_format_error ("erroneous ConstantValue attribute");
1587
1588   /* FIXME: do the rest */
1589 }
1590
1591 void
1592 _Jv_ClassReader::handleMethodsBegin (int count)
1593 {
1594   def->methods = (_Jv_Method *) _Jv_AllocRawObj (sizeof (_Jv_Method) * count);
1595
1596   def_interp->interpreted_methods
1597     = (_Jv_MethodBase **) _Jv_AllocRawObj (sizeof (_Jv_MethodBase *)
1598                                            * count);
1599
1600   for (int i = 0; i < count; i++)
1601     {
1602       def_interp->interpreted_methods[i] = 0;
1603       def->methods[i].index = (_Jv_ushort) -1;
1604     }
1605
1606   def->method_count = count;
1607 }
1608
1609
1610 void _Jv_ClassReader::handleMethod 
1611     (int mth_index, int accflags, int name, int desc)
1612
1613   using namespace java::lang::reflect;
1614
1615   _Jv_word *pool_data = def->constants.data;
1616   _Jv_Method *method = &def->methods[mth_index];
1617
1618   check_tag (name, JV_CONSTANT_Utf8);
1619   prepare_pool_entry (name, JV_CONSTANT_Utf8, false);
1620   method->name = pool_data[name].utf8;
1621
1622   check_tag (desc, JV_CONSTANT_Utf8);
1623   prepare_pool_entry (desc, JV_CONSTANT_Utf8);
1624   method->signature = pool_data[desc].utf8;
1625
1626   // ignore unknown flags
1627   method->accflags = accflags & (Method::METHOD_MODIFIERS
1628                                  | Modifier::BRIDGE
1629                                  | Modifier::SYNTHETIC
1630                                  | Modifier::VARARGS);
1631
1632   // Initialize...
1633   method->ncode = 0;
1634   method->throws = NULL;
1635   
1636   if (verify)
1637     {
1638       if (_Jv_equalUtf8Consts (method->name, clinit_name)
1639           || _Jv_equalUtf8Consts (method->name, init_name))
1640         /* ignore */;
1641       else
1642         verify_identifier (method->name);
1643
1644       verify_method_signature (method->signature);
1645
1646       for (int i = 0; i < mth_index; ++i)
1647         {
1648           if (_Jv_equalUtf8Consts (method->name, def->methods[i].name)
1649               && _Jv_equalUtf8Consts (method->signature,
1650                                       def->methods[i].signature))
1651             throw_class_format_error ("duplicate method");
1652         }
1653
1654       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1655       if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
1656                 +((method->accflags & Modifier::PRIVATE) ? 1 : 0)
1657                 +((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
1658         throw_class_format_error ("erroneous method access flags");
1659
1660       // FIXME: JVM spec S4.6: if ABSTRACT modifier is set, verify other 
1661       // flags are not set. Verify flags for interface methods.  Verify
1662       // modifiers for initializers. 
1663     }
1664 }
1665
1666 void _Jv_ClassReader::handleCodeAttribute
1667   (int method_index, int max_stack, int max_locals, 
1668    int code_start, int code_length, int exc_table_length)
1669 {
1670   int size = _Jv_InterpMethod::size (exc_table_length, code_length);
1671   _Jv_InterpMethod *method = 
1672     (_Jv_InterpMethod*) (_Jv_AllocRawObj (size));
1673
1674   method->max_stack      = max_stack;
1675   method->max_locals     = max_locals;
1676   method->code_length    = code_length;
1677   method->exc_count      = exc_table_length;
1678   method->is_15          = is_15;
1679   method->defining_class = def;
1680   method->self           = &def->methods[method_index];
1681   method->prepared       = NULL;
1682   method->line_table_len = 0;
1683   method->line_table     = NULL;
1684
1685
1686   // grab the byte code!
1687   memcpy ((void*) method->bytecode (),
1688           (void*) (bytes+code_start),
1689           code_length);
1690
1691   def_interp->interpreted_methods[method_index] = method;
1692
1693   if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
1694     {
1695       // Precompute the ncode field for a static method.  This lets us
1696       // call a static method of an interpreted class from precompiled
1697       // code without first resolving the class (that will happen
1698       // during class initialization instead).
1699       method->self->ncode = method->ncode (def);
1700     }
1701 }
1702
1703 void _Jv_ClassReader::handleExceptionTableEntry
1704   (int method_index, int exc_index, 
1705    int start_pc, int end_pc, int handler_pc, int catch_type)
1706 {
1707   _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1708     (def_interp->interpreted_methods[method_index]);
1709   _Jv_InterpException *exc = method->exceptions ();
1710
1711   exc[exc_index].start_pc.i     = start_pc;
1712   exc[exc_index].end_pc.i       = end_pc;
1713   exc[exc_index].handler_pc.i   = handler_pc;
1714   exc[exc_index].handler_type.i = catch_type;
1715 }
1716
1717 void _Jv_ClassReader::handleMethodsEnd ()
1718 {
1719   using namespace java::lang::reflect;
1720
1721   for (int i = 0; i < def->method_count; i++)
1722     {
1723       _Jv_Method *method = &def->methods[i];
1724       if ((method->accflags & Modifier::NATIVE) != 0)
1725         {
1726           if (def_interp->interpreted_methods[i] != 0)
1727             throw_class_format_error ("code provided for native method");
1728           else
1729             {
1730               _Jv_JNIMethod *m = (_Jv_JNIMethod *)
1731                 _Jv_AllocRawObj (sizeof (_Jv_JNIMethod));
1732               m->defining_class = def;
1733               m->self = method;
1734               m->function = NULL;
1735               def_interp->interpreted_methods[i] = m;
1736
1737               if ((method->accflags & Modifier::STATIC))
1738                 {
1739                   // Precompute the ncode field for a static method.
1740                   // This lets us call a static method of an
1741                   // interpreted class from precompiled code without
1742                   // first resolving the class (that will happen
1743                   // during class initialization instead).
1744                   method->ncode = m->ncode (def);
1745                 }
1746             }
1747         }
1748       else if ((method->accflags & Modifier::ABSTRACT) != 0)
1749         {
1750           if (def_interp->interpreted_methods[i] != 0)
1751             throw_class_format_error ("code provided for abstract method");
1752           method->ncode = (void *) &_Jv_ThrowAbstractMethodError;
1753         }
1754       else
1755         {
1756           if (def_interp->interpreted_methods[i] == 0)
1757             throw_class_format_error ("method with no code");
1758         }
1759     }
1760 }
1761
1762 void _Jv_ClassReader::throw_class_format_error (const char *msg)
1763 {
1764   jstring str;
1765   if (def->name != NULL)
1766     {
1767       jsize mlen = strlen (msg);
1768       unsigned char* data = (unsigned char*) def->name->chars();
1769       int ulen = def->name->len();
1770       unsigned char* limit = data + ulen;
1771       jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
1772       jsize len = nlen + mlen + 3;
1773       str = JvAllocString(len);
1774       jchar *chrs = JvGetStringChars(str);
1775       while (data < limit)
1776         *chrs++ = UTF8_GET(data, limit);
1777       *chrs++ = ' ';
1778       *chrs++ = '(';
1779       for (;;)
1780         {
1781           char c = *msg++;
1782           if (c == 0)
1783             break;
1784           *chrs++ = c & 0xFFFF;
1785         }
1786       *chrs++ = ')';
1787     }
1788   else
1789     str = JvNewStringLatin1 (msg);
1790   ::throw_class_format_error (str);
1791 }
1792 \f
1793 /** Here we define the exceptions that can be thrown */
1794
1795 static void
1796 throw_no_class_def_found_error (jstring msg)
1797 {
1798   throw (msg
1799          ? new java::lang::NoClassDefFoundError (msg)
1800          : new java::lang::NoClassDefFoundError);
1801 }
1802
1803 static void
1804 throw_no_class_def_found_error (const char *msg)
1805 {
1806   throw_no_class_def_found_error (JvNewStringLatin1 (msg));
1807 }
1808
1809 static void
1810 throw_class_format_error (jstring msg)
1811 {
1812   throw (msg
1813          ? new java::lang::ClassFormatError (msg)
1814          : new java::lang::ClassFormatError);
1815 }
1816
1817 static void
1818 throw_internal_error (const char *msg)
1819 {
1820   throw new java::lang::InternalError (JvNewStringLatin1 (msg));
1821 }
1822
1823 static void
1824 throw_incompatible_class_change_error (jstring msg)
1825 {
1826   throw new java::lang::IncompatibleClassChangeError (msg);
1827 }
1828
1829 static void
1830 throw_class_circularity_error (jstring msg)
1831 {
1832   throw new java::lang::ClassCircularityError (msg);
1833 }
1834
1835 #endif /* INTERPRETER */
1836
1837 \f
1838
1839 /** This section takes care of verifying integrity of identifiers,
1840     signatures, field ddescriptors, and class names */
1841
1842 #define UTF8_PEEK(PTR, LIMIT) \
1843   ({ unsigned char* xxkeep = (PTR); \
1844      int xxch = UTF8_GET(PTR,LIMIT); \
1845      PTR = xxkeep; xxch; })
1846
1847 /* Verify one element of a type descriptor or signature.  */
1848 static unsigned char*
1849 _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
1850 {
1851   if (ptr >= limit)
1852     return 0;
1853
1854   int ch = UTF8_GET (ptr, limit);
1855
1856   switch (ch)
1857     {
1858     case 'V':
1859       if (! void_ok)
1860         return 0;
1861
1862     case 'S': case 'B': case 'I': case 'J':
1863     case 'Z': case 'C': case 'F': case 'D': 
1864       break;
1865
1866     case 'L':
1867       {
1868         unsigned char *start = ptr, *end;
1869         do
1870           {
1871             if (ptr > limit)
1872               return 0;
1873
1874             end = ptr;
1875
1876             if ((ch = UTF8_GET (ptr, limit)) == -1)
1877               return 0;
1878
1879           }
1880         while (ch != ';');
1881         if (! _Jv_VerifyClassName (start, (unsigned short) (end-start)))
1882           return 0;
1883       }
1884       break;
1885
1886     case '[':
1887       return _Jv_VerifyOne (ptr, limit, false);
1888       break;
1889
1890     default:
1891       return 0;
1892     }
1893
1894   return ptr;
1895 }
1896
1897 /* Verification and loading procedures.  */
1898 bool
1899 _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
1900 {
1901   unsigned char* ptr = (unsigned char*) sig->chars();
1902   unsigned char* limit = ptr + sig->len();
1903
1904   ptr = _Jv_VerifyOne (ptr, limit, false);
1905
1906   return ptr == limit;
1907 }
1908
1909 bool
1910 _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
1911 {
1912   unsigned char* ptr = (unsigned char*) sig->chars();
1913   unsigned char* limit = ptr + sig->len();
1914
1915   if (ptr == limit || UTF8_GET(ptr,limit) != '(')
1916     return false;
1917
1918   while (ptr && UTF8_PEEK (ptr, limit) != ')')
1919     ptr = _Jv_VerifyOne (ptr, limit, false);
1920
1921   if (! ptr || UTF8_GET (ptr, limit) != ')')
1922     return false;
1923
1924   // get the return type
1925   ptr = _Jv_VerifyOne (ptr, limit, true);
1926
1927   return ptr == limit;
1928 }
1929
1930 /* We try to avoid calling the Character methods all the time, in
1931    fact, they will only be called for non-standard things. */
1932 static __inline__ int 
1933 is_identifier_start (int c)
1934 {
1935   unsigned int ch = (unsigned)c;
1936
1937   if ((ch - 0x41U) < 29U)               /* A ... Z */
1938     return 1;
1939   if ((ch - 0x61U) < 29U)               /* a ... z */
1940     return 1;
1941   if (ch == 0x5FU)                      /* _ */
1942     return 1;
1943
1944   return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1945 }
1946
1947 static __inline__ int 
1948 is_identifier_part (int c)
1949 {
1950   unsigned int ch = (unsigned)c;
1951
1952   if ((ch - 0x41U) < 29U)               /* A ... Z */
1953     return 1;
1954   if ((ch - 0x61U) < 29U)               /* a ... z */
1955     return 1;
1956   if ((ch - 0x30) < 10U)                /* 0 .. 9 */
1957     return 1;
1958   if (ch == 0x5FU || ch == 0x24U)       /* _ $ */
1959     return 1;
1960
1961   return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1962 }
1963
1964 bool
1965 _Jv_VerifyIdentifier (_Jv_Utf8Const* name)
1966 {
1967   unsigned char *ptr   = (unsigned char*) name->chars();
1968   unsigned char *limit = (unsigned char*) name->limit();
1969   int ch;
1970
1971   if ((ch = UTF8_GET (ptr, limit))==-1
1972       || ! is_identifier_start (ch))
1973     return false;
1974
1975   while (ptr != limit)
1976     {
1977       if ((ch = UTF8_GET (ptr, limit))==-1
1978           || ! is_identifier_part (ch))
1979         return false;
1980     }
1981   return true;
1982 }
1983
1984 bool
1985 _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
1986 {
1987   unsigned char *limit = ptr+length;
1988   int ch;
1989
1990   if ('[' == UTF8_PEEK (ptr, limit))
1991     {
1992       unsigned char *end = _Jv_VerifyOne (++ptr, limit, false);
1993       // _Jv_VerifyOne must leave us looking at the terminating nul
1994       // byte.
1995       if (! end || *end)
1996         return false;
1997       else
1998         return true;
1999     }
2000
2001  next_level:
2002   for (;;) {
2003     if ((ch = UTF8_GET (ptr, limit))==-1)
2004       return false;
2005     if (! is_identifier_start (ch))
2006       return false;
2007     for (;;) {
2008       if (ptr == limit)
2009         return true;
2010       else if ((ch = UTF8_GET (ptr, limit))==-1)
2011         return false;
2012       else if (ch == '.')
2013         goto next_level;
2014       else if (! is_identifier_part (ch))
2015         return false;
2016     }
2017   }
2018 }
2019
2020 bool
2021 _Jv_VerifyClassName (_Jv_Utf8Const *name)
2022 {
2023   return _Jv_VerifyClassName ((unsigned char*)name->chars(), name->len());
2024 }
2025
2026 /* Returns true, if NAME1 and NAME2 represent classes in the same
2027    package.  Neither NAME2 nor NAME2 may name an array type.  */
2028 bool
2029 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
2030 {
2031   unsigned char* ptr1 = (unsigned char*) name1->chars();
2032   unsigned char* limit1 = (unsigned char*) name1->limit();
2033
2034   unsigned char* last1 = ptr1;
2035
2036   // scan name1, and find the last occurrence of '.'
2037   while (ptr1 < limit1) {
2038     int ch1 = UTF8_GET (ptr1, limit1);
2039
2040     if (ch1 == '.')
2041       last1 = ptr1;
2042
2043     else if (ch1 == -1)
2044       return false;
2045   }
2046
2047   // Now the length of NAME1's package name is LEN.
2048   int len = last1 - (unsigned char*) name1->chars();
2049
2050   // If this is longer than NAME2, then we're off.
2051   if (len > name2->len())
2052     return false;
2053
2054   // Then compare the first len bytes for equality.
2055   if (memcmp ((void*) name1->chars(), (void*) name2->chars(), len) == 0)
2056     {
2057       // Check that there are no .'s after position LEN in NAME2.
2058
2059       unsigned char* ptr2 = (unsigned char*) name2->chars() + len;
2060       unsigned char* limit2 = (unsigned char*) name2->limit();
2061
2062       while (ptr2 < limit2)
2063         {
2064           int ch2 = UTF8_GET (ptr2, limit2);
2065           if (ch2 == -1 || ch2 == '.')
2066             return false;
2067         }
2068       return true;
2069     }
2070   return false;
2071 }