OSDN Git Service

/cp
[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_pc = read2u ();
1013           table[i].length = read2u ();
1014           pool_Utf8_to_char_arr (read2u (), &table[i].name);
1015           pool_Utf8_to_char_arr (read2u (), &table[i].descriptor);
1016           table[i].slot = read2u ();
1017           
1018           if (table[i].slot > method->max_locals || table[i].slot < 0)
1019             throw_class_format_error ("Malformed Local Variable Table: Invalid Slot");
1020         }
1021             
1022       method->local_var_table_len = table_len;
1023       method->local_var_table = table;
1024     }
1025   else
1026     {
1027       /* ignore unknown code attributes */
1028       skip (length);
1029     }
1030 }
1031
1032 void _Jv_ClassReader::read_one_class_attribute () 
1033 {
1034   int name = read2u ();
1035   int length = read4 ();
1036   if (is_attribute_name (name, "SourceFile"))
1037     {
1038       int source_index = read2u ();
1039       check_tag (source_index, JV_CONSTANT_Utf8);
1040       prepare_pool_entry (source_index, JV_CONSTANT_Utf8, false);
1041       def_interp->source_file_name = _Jv_NewStringUtf8Const
1042         (def->constants.data[source_index].utf8);
1043     }
1044   else if (is_attribute_name (name, "Signature"))
1045     handleGenericSignature(JV_CLASS_ATTR, 0, length);
1046   else if (is_attribute_name (name, "EnclosingMethod"))
1047     handleEnclosingMethod(length);
1048   else if (is_attribute_name (name, "RuntimeVisibleAnnotations"))
1049     handleMemberAnnotations(JV_CLASS_ATTR, 0, length);
1050   else if (is_attribute_name (name, "InnerClasses"))
1051     {
1052       ::java::io::DataOutputStream *stream = get_reflection_stream ();
1053       stream->writeByte(JV_CLASS_ATTR);
1054       stream->writeInt(length + 1);
1055       stream->writeByte(JV_INNER_CLASSES_KIND);
1056       stream->write(input_data, input_offset + pos, length);
1057       skip (length);
1058     }
1059   else
1060     {
1061       /* Currently, we ignore most class attributes. */
1062      skip (length);
1063     }
1064 }
1065
1066
1067
1068 \f
1069 /* this section defines the semantic actions of the parser */
1070
1071 void _Jv_ClassReader::handleConstantPool ()
1072 {
1073   /** now, we actually define the class' constant pool */
1074
1075   jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
1076   _Jv_word *pool_data
1077     = (_Jv_word*) _Jv_AllocRawObj (pool_count * sizeof (_Jv_word));
1078
1079   def->constants.tags = pool_tags;
1080   def->constants.data = pool_data;
1081   def->constants.size = pool_count;
1082
1083   // Here we make a pass to collect the strings!   We do this, because
1084   // internally in the GCJ runtime, classes are encoded with .'s not /'s. 
1085   // Therefore, we first collect the strings, and then translate the rest
1086   // of the utf8-entries (thus not representing strings) from /-notation
1087   // to .-notation.
1088   for (int i = 1; i < pool_count; i++)
1089     {
1090       if (tags[i] == JV_CONSTANT_String)
1091         {
1092           unsigned char* str_data = bytes + offsets [i];
1093           int utf_index = get2u (str_data);
1094           check_tag (utf_index, JV_CONSTANT_Utf8);
1095           unsigned char *utf_data = bytes + offsets[utf_index];
1096           int len = get2u (utf_data);
1097           pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
1098           pool_tags[i] = JV_CONSTANT_String;
1099         }
1100       else
1101         {
1102           pool_tags[i] = JV_CONSTANT_Undefined;
1103         }
1104     }
1105
1106   // and now, we scan everything else but strings & utf8-entries.  This
1107   // leaves out those utf8-entries which are not used; which will be left
1108   // with a tag of JV_CONSTANT_Undefined in the class definition.
1109   for (int index = 1; index < pool_count; index++)
1110     {
1111       switch (tags[index])
1112         {
1113         case JV_CONSTANT_Undefined:
1114         case JV_CONSTANT_String:
1115         case JV_CONSTANT_Utf8:
1116           continue;
1117           
1118         default:
1119           prepare_pool_entry (index, tags[index]);
1120         }
1121     }  
1122   
1123 }
1124
1125 /* this is a recursive procedure, which will prepare pool entries as needed.
1126    Which is how we avoid initializing those entries which go unused. 
1127    
1128    REWRITE is true iff this pool entry is the Utf8 representation of a
1129    class name or a signature.
1130 */
1131
1132 void
1133 _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag,
1134                                      bool rewrite)
1135 {
1136   /* these two, pool_data and pool_tags, point into the class
1137      structure we are currently defining */
1138
1139   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
1140   _Jv_word      *pool_data = def->constants.data;
1141
1142   /* this entry was already prepared */
1143   if (pool_tags[index] == this_tag)
1144     return;
1145
1146   /* this_data points to the constant-pool information for the current
1147      constant-pool entry */
1148
1149   unsigned char *this_data = bytes + offsets[index];
1150
1151   switch (this_tag)
1152     {
1153     case JV_CONSTANT_Utf8: 
1154       {
1155         int len = get2u (this_data);
1156         char *s = ((char*) this_data)+2;
1157         pool_tags[index] = JV_CONSTANT_Utf8;
1158
1159         if (! rewrite)
1160           {
1161             pool_data[index].utf8 = _Jv_makeUtf8Const (s, len);
1162             break;
1163           }
1164
1165         // If REWRITE is set, it is because some other tag needs this
1166         // utf8-entry for type information: it is a class or a
1167         // signature.  Thus, we translate /'s to .'s in order to
1168         // accomondate gcj's internal representation.
1169         char *buffer = (char*) __builtin_alloca (len);
1170         for (int i = 0; i < len; i++)
1171           {
1172             if (s[i] == '/')
1173               buffer[i] = '.';
1174             else
1175               buffer[i] = s[i];
1176           }
1177         pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
1178       }
1179       break;
1180             
1181     case JV_CONSTANT_Class:      
1182       {
1183         int utf_index = get2u (this_data);
1184         check_tag (utf_index, JV_CONSTANT_Utf8);
1185         prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
1186
1187         if (verify)
1188           verify_classname (pool_data[utf_index].utf8);
1189                 
1190         pool_data[index].utf8 = pool_data[utf_index].utf8;
1191         pool_tags[index] = JV_CONSTANT_Class;
1192       }
1193       break;
1194             
1195     case JV_CONSTANT_String:
1196       // already handled before... 
1197       break;
1198             
1199     case JV_CONSTANT_Fieldref:
1200     case JV_CONSTANT_Methodref:
1201     case JV_CONSTANT_InterfaceMethodref:
1202       {
1203         int class_index = get2u (this_data);
1204         int nat_index = get2u (this_data+2);
1205
1206         check_tag (class_index, JV_CONSTANT_Class);
1207         prepare_pool_entry (class_index, JV_CONSTANT_Class);        
1208
1209         check_tag (nat_index, JV_CONSTANT_NameAndType);
1210         prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
1211
1212         // here, verify the signature and identifier name
1213         if (verify)
1214         {
1215           _Jv_ushort name_index, type_index;
1216           _Jv_loadIndexes (&pool_data[nat_index],
1217                            name_index, type_index);
1218
1219           if (this_tag == JV_CONSTANT_Fieldref)
1220             verify_field_signature (pool_data[type_index].utf8);
1221           else
1222             verify_method_signature (pool_data[type_index].utf8);
1223
1224           _Jv_Utf8Const* name = pool_data[name_index].utf8;
1225
1226           if (this_tag != JV_CONSTANT_Fieldref
1227               && (   _Jv_equalUtf8Consts (name, clinit_name)
1228                   || _Jv_equalUtf8Consts (name, init_name)))
1229             /* ignore */;
1230           else
1231             verify_identifier (pool_data[name_index].utf8);
1232         }
1233             
1234         _Jv_storeIndexes (&pool_data[index], class_index, nat_index);
1235         pool_tags[index] = this_tag;
1236       }
1237       break;
1238             
1239     case JV_CONSTANT_NameAndType:
1240       {
1241         _Jv_ushort name_index = get2u (this_data);
1242         _Jv_ushort type_index = get2u (this_data+2);
1243
1244         check_tag (name_index, JV_CONSTANT_Utf8);
1245         prepare_pool_entry (name_index, JV_CONSTANT_Utf8, false);
1246         check_tag (type_index, JV_CONSTANT_Utf8);
1247         prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
1248
1249         _Jv_storeIndexes (&pool_data[index], name_index, type_index);
1250         pool_tags[index] = JV_CONSTANT_NameAndType;
1251       }
1252       break;
1253             
1254     case JV_CONSTANT_Float:
1255       {
1256         jfloat f = java::lang::Float::intBitsToFloat ((jint) get4 (this_data));
1257         _Jv_storeFloat (&pool_data[index], f);
1258         pool_tags[index] = JV_CONSTANT_Float;
1259       }
1260       break;
1261             
1262     case JV_CONSTANT_Integer:
1263       {
1264         int i = get4 (this_data);
1265         _Jv_storeInt (&pool_data[index], i);
1266         pool_tags[index] = JV_CONSTANT_Integer;
1267       }
1268       break;
1269             
1270     case JV_CONSTANT_Double:
1271       {
1272         jdouble d
1273           = java::lang::Double::longBitsToDouble ((jlong) get8 (this_data));
1274         _Jv_storeDouble (&pool_data[index], d);
1275         pool_tags[index] = JV_CONSTANT_Double;
1276       }
1277       break;
1278             
1279     case JV_CONSTANT_Long:
1280       {
1281         jlong i = get8 (this_data);
1282         _Jv_storeLong (&pool_data[index], i);
1283         pool_tags[index] = JV_CONSTANT_Long;
1284       }
1285       break;
1286             
1287     default:
1288       throw_class_format_error ("erroneous constant pool tag");
1289     }
1290 }
1291
1292
1293 void
1294 _Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_class)
1295 {
1296   using namespace java::lang::reflect;
1297
1298   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
1299   _Jv_word      *pool_data = def->constants.data;
1300
1301   check_tag (this_class, JV_CONSTANT_Class);
1302   _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
1303
1304   // was ClassLoader.defineClass called with an expected class name?
1305   if (def->name == 0)
1306     {
1307       jclass orig = def->loader->findLoadedClass(loadedName->toString());
1308
1309       if (orig == 0)
1310         {
1311           def->name = loadedName;
1312         }
1313       else
1314         {
1315           jstring msg = JvNewStringUTF ("anonymous "
1316                                         "class data denotes "
1317                                         "existing class ");
1318           msg = msg->concat (orig->getName ());
1319
1320           throw_no_class_def_found_error (msg);
1321         }
1322     }
1323
1324   // assert that the loaded class has the expected name, 5.3.5
1325   else if (! _Jv_equalUtf8Consts (loadedName, def->name))
1326     {
1327       jstring msg = JvNewStringUTF ("loaded class ");
1328       msg = msg->concat (def->getName ());
1329       msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
1330       jstring klass_name = loadedName->toString();
1331       msg = msg->concat (klass_name);
1332
1333       throw_no_class_def_found_error (msg);
1334     }
1335
1336   def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
1337   pool_data[this_class].clazz = def;
1338   pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
1339
1340   if (super_class == 0)
1341     {
1342       // Note that this is ok if we are defining java.lang.Object.
1343       // But there is no way to have this class be interpreted.
1344       throw_class_format_error ("no superclass reference");
1345     }
1346
1347   def->state = JV_STATE_PRELOADING;
1348
1349   // Register this class with its defining loader as well (despite the
1350   // name of the function we're calling), so that super class lookups
1351   // work properly.  If there is an error, our caller will unregister
1352   // this class from the class loader.  Also, we don't need to hold a
1353   // lock here, as our caller has acquired it.
1354   _Jv_RegisterInitiatingLoader (def, def->loader);
1355
1356   // Note that we found a name so that unregistration can happen if
1357   // needed.
1358   *found_name = def->name;
1359
1360   if (super_class != 0)
1361     {
1362       // Load the superclass.
1363       check_tag (super_class, JV_CONSTANT_Class);
1364       _Jv_Utf8Const* super_name = pool_data[super_class].utf8; 
1365
1366       // Load the superclass using our defining loader.
1367       jclass the_super = _Jv_FindClass (super_name, def->loader);
1368
1369       // This will establish that we are allowed to be a subclass,
1370       // and check for class circularity error.
1371       checkExtends (def, the_super);
1372
1373       // Note: for an interface we will find Object as the
1374       // superclass.  We still check it above to ensure class file
1375       // validity, but we simply assign `null' to the actual field in
1376       // this case.
1377       def->superclass = (((access_flags & Modifier::INTERFACE))
1378                          ? NULL : the_super);
1379       pool_data[super_class].clazz = the_super;
1380       pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
1381     }
1382
1383   // Now we've come past the circularity problem, we can 
1384   // now say that we're loading.
1385
1386   def->state = JV_STATE_LOADING;
1387   def->notifyAll ();
1388 }
1389
1390 ///// Implements the checks described in sect. 5.3.5.3
1391 void
1392 _Jv_ClassReader::checkExtends (jclass sub, jclass super)
1393 {
1394   using namespace java::lang::reflect;
1395
1396   _Jv_Linker::wait_for_state (super, JV_STATE_LOADING);
1397
1398   // Having an interface or a final class as a superclass is no good.
1399   if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
1400     {
1401       throw_incompatible_class_change_error (sub->getName ());
1402     }
1403
1404   // If the super class is not public, we need to check some more.
1405   if ((super->accflags & Modifier::PUBLIC) == 0)
1406     {
1407       // With package scope, the classes must have the same class
1408       // loader.
1409       if (   sub->loader != super->loader
1410           || !_Jv_ClassNameSamePackage (sub->name, super->name))
1411         {
1412           throw_incompatible_class_change_error (sub->getName ());
1413         }
1414     } 
1415
1416   for (; super != 0; super = super->getSuperclass ())
1417     {
1418       if (super == sub)
1419         throw_class_circularity_error (sub->getName ());
1420     }
1421 }
1422
1423
1424
1425 void _Jv_ClassReader::handleInterfacesBegin (int count)
1426 {
1427   def->interfaces = (jclass*) _Jv_AllocRawObj (count*sizeof (jclass));
1428   def->interface_count = count;
1429 }
1430
1431 void _Jv_ClassReader::handleInterface (int if_number, int offset)
1432 {
1433   _Jv_word       * pool_data = def->constants.data;
1434   unsigned char  * pool_tags = (unsigned char*) def->constants.tags;
1435
1436   jclass the_interface;
1437
1438   if (pool_tags[offset] == JV_CONSTANT_Class)
1439     {
1440       _Jv_Utf8Const* name = pool_data[offset].utf8;
1441       the_interface =  _Jv_FindClass (name, def->loader);
1442     }
1443   else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
1444     {
1445       the_interface = pool_data[offset].clazz;
1446     }
1447   else
1448     {
1449       throw_no_class_def_found_error ("erroneous constant pool tag");
1450     }
1451
1452   // checks the validity of the_interface, and that we are in fact
1453   // allowed to implement that interface.
1454   checkImplements (def, the_interface);
1455   
1456   pool_data[offset].clazz = the_interface;
1457   pool_tags[offset] = JV_CONSTANT_ResolvedClass;
1458   
1459   def->interfaces[if_number] = the_interface;
1460 }
1461
1462 void
1463 _Jv_ClassReader::checkImplements (jclass sub, jclass super)
1464 {
1465   using namespace java::lang::reflect;
1466
1467   // well, it *must* be an interface
1468   if ((super->accflags & Modifier::INTERFACE) == 0)
1469     {
1470       throw_incompatible_class_change_error (sub->getName ());
1471     }
1472
1473   // if it has package scope, it must also be defined by the 
1474   // same loader.
1475   if ((super->accflags & Modifier::PUBLIC) == 0)
1476     {
1477       if (    sub->loader != super->loader
1478           || !_Jv_ClassNameSamePackage (sub->name, super->name))
1479         {
1480           throw_incompatible_class_change_error (sub->getName ());
1481         }
1482     } 
1483
1484   // FIXME: add interface circularity check here
1485   if (sub == super)
1486     {
1487       throw_class_circularity_error (sub->getName ());
1488     }           
1489 }
1490
1491 void _Jv_ClassReader::handleFieldsBegin (int count)
1492 {
1493   def->fields = (_Jv_Field*) _Jv_AllocRawObj (count * sizeof (_Jv_Field));
1494   def->field_count = count;
1495   def_interp->field_initializers
1496     = (_Jv_ushort*) _Jv_AllocRawObj (count * sizeof (_Jv_ushort));
1497   for (int i = 0; i < count; i++)
1498     def_interp->field_initializers[i] = (_Jv_ushort) 0;
1499 }
1500
1501 void _Jv_ClassReader::handleField (int field_no,
1502                                    int flags,
1503                                    int name,
1504                                    int desc,
1505                                    int *fieldmap)
1506 {
1507   using namespace java::lang::reflect;
1508
1509   _Jv_word *pool_data = def->constants.data;
1510
1511   _Jv_Field *field = &def->fields[fieldmap[field_no]];
1512   _Jv_Utf8Const *field_name = pool_data[name].utf8;
1513
1514   field->name      = field_name;
1515
1516   // Ignore flags we don't know about.  
1517   field->flags = flags & (Field::FIELD_MODIFIERS
1518                           | Modifier::SYNTHETIC
1519                           | Modifier::ENUM);
1520
1521   _Jv_Utf8Const* sig = pool_data[desc].utf8;
1522
1523   if (verify)
1524     {
1525       verify_identifier (field_name);
1526
1527       for (int i = 0; i < field_no; ++i)
1528         {
1529           if (_Jv_equalUtf8Consts (field_name, def->fields[fieldmap[i]].name)
1530               && _Jv_equalUtf8Consts (sig,
1531                                       // We know the other fields are
1532                                       // unresolved.
1533                                       (_Jv_Utf8Const *) def->fields[i].type))
1534             throw_class_format_error ("duplicate field name");
1535         }
1536
1537       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1538       if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
1539                 +((field->flags & Modifier::PRIVATE) ? 1 : 0)
1540                 +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
1541         throw_class_format_error ("erroneous field access flags");
1542
1543       // FIXME: JVM spec S4.5: Verify ACC_FINAL and ACC_VOLATILE are not 
1544       // both set. Verify modifiers for interface fields.
1545       
1546     }
1547
1548   if (verify)
1549     verify_field_signature (sig);
1550
1551   // field->type is really a jclass, but while it is still
1552   // unresolved we keep an _Jv_Utf8Const* instead.
1553   field->type       = (jclass) sig;
1554   field->flags     |= _Jv_FIELD_UNRESOLVED_FLAG;
1555   field->u.boffset  = 0;
1556 }
1557
1558
1559 void _Jv_ClassReader::handleConstantValueAttribute (int field_index, 
1560                                                     int value,
1561                                                     bool *found_value)
1562 {
1563   using namespace java::lang::reflect;
1564
1565   _Jv_Field *field = &def->fields[field_index];
1566
1567   if ((field->flags & (Modifier::STATIC
1568                        | Modifier::FINAL
1569                        | Modifier::PRIVATE)) == 0)
1570     {
1571       // Ignore, as per vmspec #4.7.2
1572       return;
1573     }
1574
1575   // do not allow multiple constant fields!
1576   if (*found_value)
1577     throw_class_format_error ("field has multiple ConstantValue attributes");
1578
1579   *found_value = true;
1580   def_interp->field_initializers[field_index] = value;
1581
1582   /* type check the initializer */
1583   
1584   if (value <= 0 || value >= pool_count)
1585     throw_class_format_error ("erroneous ConstantValue attribute");
1586
1587   /* FIXME: do the rest */
1588 }
1589
1590 void
1591 _Jv_ClassReader::handleMethodsBegin (int count)
1592 {
1593   def->methods = (_Jv_Method *) _Jv_AllocRawObj (sizeof (_Jv_Method) * count);
1594
1595   def_interp->interpreted_methods
1596     = (_Jv_MethodBase **) _Jv_AllocRawObj (sizeof (_Jv_MethodBase *)
1597                                            * count);
1598
1599   for (int i = 0; i < count; i++)
1600     {
1601       def_interp->interpreted_methods[i] = 0;
1602       def->methods[i].index = (_Jv_ushort) -1;
1603     }
1604
1605   def->method_count = count;
1606 }
1607
1608
1609 void _Jv_ClassReader::handleMethod 
1610     (int mth_index, int accflags, int name, int desc)
1611
1612   using namespace java::lang::reflect;
1613
1614   _Jv_word *pool_data = def->constants.data;
1615   _Jv_Method *method = &def->methods[mth_index];
1616
1617   check_tag (name, JV_CONSTANT_Utf8);
1618   prepare_pool_entry (name, JV_CONSTANT_Utf8, false);
1619   method->name = pool_data[name].utf8;
1620
1621   check_tag (desc, JV_CONSTANT_Utf8);
1622   prepare_pool_entry (desc, JV_CONSTANT_Utf8);
1623   method->signature = pool_data[desc].utf8;
1624
1625   // ignore unknown flags
1626   method->accflags = accflags & (Method::METHOD_MODIFIERS
1627                                  | Modifier::BRIDGE
1628                                  | Modifier::SYNTHETIC
1629                                  | Modifier::VARARGS);
1630
1631   // Initialize...
1632   method->ncode = 0;
1633   method->throws = NULL;
1634   
1635   if (verify)
1636     {
1637       if (_Jv_equalUtf8Consts (method->name, clinit_name)
1638           || _Jv_equalUtf8Consts (method->name, init_name))
1639         /* ignore */;
1640       else
1641         verify_identifier (method->name);
1642
1643       verify_method_signature (method->signature);
1644
1645       for (int i = 0; i < mth_index; ++i)
1646         {
1647           if (_Jv_equalUtf8Consts (method->name, def->methods[i].name)
1648               && _Jv_equalUtf8Consts (method->signature,
1649                                       def->methods[i].signature))
1650             throw_class_format_error ("duplicate method");
1651         }
1652
1653       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1654       if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
1655                 +((method->accflags & Modifier::PRIVATE) ? 1 : 0)
1656                 +((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
1657         throw_class_format_error ("erroneous method access flags");
1658
1659       // FIXME: JVM spec S4.6: if ABSTRACT modifier is set, verify other 
1660       // flags are not set. Verify flags for interface methods.  Verify
1661       // modifiers for initializers. 
1662     }
1663 }
1664
1665 void _Jv_ClassReader::handleCodeAttribute
1666   (int method_index, int max_stack, int max_locals, 
1667    int code_start, int code_length, int exc_table_length)
1668 {
1669   int size = _Jv_InterpMethod::size (exc_table_length, code_length);
1670   _Jv_InterpMethod *method = 
1671     (_Jv_InterpMethod*) (_Jv_AllocRawObj (size));
1672
1673   method->max_stack      = max_stack;
1674   method->max_locals     = max_locals;
1675   method->code_length    = code_length;
1676   method->exc_count      = exc_table_length;
1677   method->is_15          = is_15;
1678   method->defining_class = def;
1679   method->self           = &def->methods[method_index];
1680   method->prepared       = NULL;
1681   method->line_table_len = 0;
1682   method->line_table     = NULL;
1683
1684
1685   // grab the byte code!
1686   memcpy ((void*) method->bytecode (),
1687           (void*) (bytes+code_start),
1688           code_length);
1689
1690   def_interp->interpreted_methods[method_index] = method;
1691
1692   if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
1693     {
1694       // Precompute the ncode field for a static method.  This lets us
1695       // call a static method of an interpreted class from precompiled
1696       // code without first resolving the class (that will happen
1697       // during class initialization instead).
1698       method->self->ncode = method->ncode (def);
1699     }
1700 }
1701
1702 void _Jv_ClassReader::handleExceptionTableEntry
1703   (int method_index, int exc_index, 
1704    int start_pc, int end_pc, int handler_pc, int catch_type)
1705 {
1706   _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1707     (def_interp->interpreted_methods[method_index]);
1708   _Jv_InterpException *exc = method->exceptions ();
1709
1710   exc[exc_index].start_pc.i     = start_pc;
1711   exc[exc_index].end_pc.i       = end_pc;
1712   exc[exc_index].handler_pc.i   = handler_pc;
1713   exc[exc_index].handler_type.i = catch_type;
1714 }
1715
1716 void _Jv_ClassReader::handleMethodsEnd ()
1717 {
1718   using namespace java::lang::reflect;
1719
1720   for (int i = 0; i < def->method_count; i++)
1721     {
1722       _Jv_Method *method = &def->methods[i];
1723       if ((method->accflags & Modifier::NATIVE) != 0)
1724         {
1725           if (def_interp->interpreted_methods[i] != 0)
1726             throw_class_format_error ("code provided for native method");
1727           else
1728             {
1729               _Jv_JNIMethod *m = (_Jv_JNIMethod *)
1730                 _Jv_AllocRawObj (sizeof (_Jv_JNIMethod));
1731               m->defining_class = def;
1732               m->self = method;
1733               m->function = NULL;
1734               def_interp->interpreted_methods[i] = m;
1735
1736               if ((method->accflags & Modifier::STATIC))
1737                 {
1738                   // Precompute the ncode field for a static method.
1739                   // This lets us call a static method of an
1740                   // interpreted class from precompiled code without
1741                   // first resolving the class (that will happen
1742                   // during class initialization instead).
1743                   method->ncode = m->ncode (def);
1744                 }
1745             }
1746         }
1747       else if ((method->accflags & Modifier::ABSTRACT) != 0)
1748         {
1749           if (def_interp->interpreted_methods[i] != 0)
1750             throw_class_format_error ("code provided for abstract method");
1751           method->ncode = (void *) &_Jv_ThrowAbstractMethodError;
1752         }
1753       else
1754         {
1755           if (def_interp->interpreted_methods[i] == 0)
1756             throw_class_format_error ("method with no code");
1757         }
1758     }
1759 }
1760
1761 void _Jv_ClassReader::throw_class_format_error (const char *msg)
1762 {
1763   jstring str;
1764   if (def->name != NULL)
1765     {
1766       jsize mlen = strlen (msg);
1767       unsigned char* data = (unsigned char*) def->name->chars();
1768       int ulen = def->name->len();
1769       unsigned char* limit = data + ulen;
1770       jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
1771       jsize len = nlen + mlen + 3;
1772       str = JvAllocString(len);
1773       jchar *chrs = JvGetStringChars(str);
1774       while (data < limit)
1775         *chrs++ = UTF8_GET(data, limit);
1776       *chrs++ = ' ';
1777       *chrs++ = '(';
1778       for (;;)
1779         {
1780           char c = *msg++;
1781           if (c == 0)
1782             break;
1783           *chrs++ = c & 0xFFFF;
1784         }
1785       *chrs++ = ')';
1786     }
1787   else
1788     str = JvNewStringLatin1 (msg);
1789   ::throw_class_format_error (str);
1790 }
1791 \f
1792 /** Here we define the exceptions that can be thrown */
1793
1794 static void
1795 throw_no_class_def_found_error (jstring msg)
1796 {
1797   throw (msg
1798          ? new java::lang::NoClassDefFoundError (msg)
1799          : new java::lang::NoClassDefFoundError);
1800 }
1801
1802 static void
1803 throw_no_class_def_found_error (const char *msg)
1804 {
1805   throw_no_class_def_found_error (JvNewStringLatin1 (msg));
1806 }
1807
1808 static void
1809 throw_class_format_error (jstring msg)
1810 {
1811   throw (msg
1812          ? new java::lang::ClassFormatError (msg)
1813          : new java::lang::ClassFormatError);
1814 }
1815
1816 static void
1817 throw_internal_error (const char *msg)
1818 {
1819   throw new java::lang::InternalError (JvNewStringLatin1 (msg));
1820 }
1821
1822 static void
1823 throw_incompatible_class_change_error (jstring msg)
1824 {
1825   throw new java::lang::IncompatibleClassChangeError (msg);
1826 }
1827
1828 static void
1829 throw_class_circularity_error (jstring msg)
1830 {
1831   throw new java::lang::ClassCircularityError (msg);
1832 }
1833
1834 #endif /* INTERPRETER */
1835
1836 \f
1837
1838 /** This section takes care of verifying integrity of identifiers,
1839     signatures, field ddescriptors, and class names */
1840
1841 #define UTF8_PEEK(PTR, LIMIT) \
1842   ({ unsigned char* xxkeep = (PTR); \
1843      int xxch = UTF8_GET(PTR,LIMIT); \
1844      PTR = xxkeep; xxch; })
1845
1846 /* Verify one element of a type descriptor or signature.  */
1847 static unsigned char*
1848 _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
1849 {
1850   if (ptr >= limit)
1851     return 0;
1852
1853   int ch = UTF8_GET (ptr, limit);
1854
1855   switch (ch)
1856     {
1857     case 'V':
1858       if (! void_ok)
1859         return 0;
1860
1861     case 'S': case 'B': case 'I': case 'J':
1862     case 'Z': case 'C': case 'F': case 'D': 
1863       break;
1864
1865     case 'L':
1866       {
1867         unsigned char *start = ptr, *end;
1868         do
1869           {
1870             if (ptr > limit)
1871               return 0;
1872
1873             end = ptr;
1874
1875             if ((ch = UTF8_GET (ptr, limit)) == -1)
1876               return 0;
1877
1878           }
1879         while (ch != ';');
1880         if (! _Jv_VerifyClassName (start, (unsigned short) (end-start)))
1881           return 0;
1882       }
1883       break;
1884
1885     case '[':
1886       return _Jv_VerifyOne (ptr, limit, false);
1887       break;
1888
1889     default:
1890       return 0;
1891     }
1892
1893   return ptr;
1894 }
1895
1896 /* Verification and loading procedures.  */
1897 bool
1898 _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
1899 {
1900   unsigned char* ptr = (unsigned char*) sig->chars();
1901   unsigned char* limit = ptr + sig->len();
1902
1903   ptr = _Jv_VerifyOne (ptr, limit, false);
1904
1905   return ptr == limit;
1906 }
1907
1908 bool
1909 _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
1910 {
1911   unsigned char* ptr = (unsigned char*) sig->chars();
1912   unsigned char* limit = ptr + sig->len();
1913
1914   if (ptr == limit || UTF8_GET(ptr,limit) != '(')
1915     return false;
1916
1917   while (ptr && UTF8_PEEK (ptr, limit) != ')')
1918     ptr = _Jv_VerifyOne (ptr, limit, false);
1919
1920   if (! ptr || UTF8_GET (ptr, limit) != ')')
1921     return false;
1922
1923   // get the return type
1924   ptr = _Jv_VerifyOne (ptr, limit, true);
1925
1926   return ptr == limit;
1927 }
1928
1929 /* We try to avoid calling the Character methods all the time, in
1930    fact, they will only be called for non-standard things. */
1931 static __inline__ int 
1932 is_identifier_start (int c)
1933 {
1934   unsigned int ch = (unsigned)c;
1935
1936   if ((ch - 0x41U) < 29U)               /* A ... Z */
1937     return 1;
1938   if ((ch - 0x61U) < 29U)               /* a ... z */
1939     return 1;
1940   if (ch == 0x5FU)                      /* _ */
1941     return 1;
1942
1943   return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1944 }
1945
1946 static __inline__ int 
1947 is_identifier_part (int c)
1948 {
1949   unsigned int ch = (unsigned)c;
1950
1951   if ((ch - 0x41U) < 29U)               /* A ... Z */
1952     return 1;
1953   if ((ch - 0x61U) < 29U)               /* a ... z */
1954     return 1;
1955   if ((ch - 0x30) < 10U)                /* 0 .. 9 */
1956     return 1;
1957   if (ch == 0x5FU || ch == 0x24U)       /* _ $ */
1958     return 1;
1959
1960   return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1961 }
1962
1963 bool
1964 _Jv_VerifyIdentifier (_Jv_Utf8Const* name)
1965 {
1966   unsigned char *ptr   = (unsigned char*) name->chars();
1967   unsigned char *limit = (unsigned char*) name->limit();
1968   int ch;
1969
1970   if ((ch = UTF8_GET (ptr, limit))==-1
1971       || ! is_identifier_start (ch))
1972     return false;
1973
1974   while (ptr != limit)
1975     {
1976       if ((ch = UTF8_GET (ptr, limit))==-1
1977           || ! is_identifier_part (ch))
1978         return false;
1979     }
1980   return true;
1981 }
1982
1983 bool
1984 _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
1985 {
1986   unsigned char *limit = ptr+length;
1987   int ch;
1988
1989   if ('[' == UTF8_PEEK (ptr, limit))
1990     {
1991       unsigned char *end = _Jv_VerifyOne (++ptr, limit, false);
1992       // _Jv_VerifyOne must leave us looking at the terminating nul
1993       // byte.
1994       if (! end || *end)
1995         return false;
1996       else
1997         return true;
1998     }
1999
2000  next_level:
2001   for (;;) {
2002     if ((ch = UTF8_GET (ptr, limit))==-1)
2003       return false;
2004     if (! is_identifier_start (ch))
2005       return false;
2006     for (;;) {
2007       if (ptr == limit)
2008         return true;
2009       else if ((ch = UTF8_GET (ptr, limit))==-1)
2010         return false;
2011       else if (ch == '.')
2012         goto next_level;
2013       else if (! is_identifier_part (ch))
2014         return false;
2015     }
2016   }
2017 }
2018
2019 bool
2020 _Jv_VerifyClassName (_Jv_Utf8Const *name)
2021 {
2022   return _Jv_VerifyClassName ((unsigned char*)name->chars(), name->len());
2023 }
2024
2025 /* Returns true, if NAME1 and NAME2 represent classes in the same
2026    package.  Neither NAME2 nor NAME2 may name an array type.  */
2027 bool
2028 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
2029 {
2030   unsigned char* ptr1 = (unsigned char*) name1->chars();
2031   unsigned char* limit1 = (unsigned char*) name1->limit();
2032
2033   unsigned char* last1 = ptr1;
2034
2035   // scan name1, and find the last occurrence of '.'
2036   while (ptr1 < limit1) {
2037     int ch1 = UTF8_GET (ptr1, limit1);
2038
2039     if (ch1 == '.')
2040       last1 = ptr1;
2041
2042     else if (ch1 == -1)
2043       return false;
2044   }
2045
2046   // Now the length of NAME1's package name is LEN.
2047   int len = last1 - (unsigned char*) name1->chars();
2048
2049   // If this is longer than NAME2, then we're off.
2050   if (len > name2->len())
2051     return false;
2052
2053   // Then compare the first len bytes for equality.
2054   if (memcmp ((void*) name1->chars(), (void*) name2->chars(), len) == 0)
2055     {
2056       // Check that there are no .'s after position LEN in NAME2.
2057
2058       unsigned char* ptr2 = (unsigned char*) name2->chars() + len;
2059       unsigned char* limit2 = (unsigned char*) name2->limit();
2060
2061       while (ptr2 < limit2)
2062         {
2063           int ch2 = UTF8_GET (ptr2, limit2);
2064           if (ch2 == -1 || ch2 == '.')
2065             return false;
2066         }
2067       return true;
2068     }
2069   return false;
2070 }