OSDN Git Service

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