OSDN Git Service

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