OSDN Git Service

* loop-invariant.c: Include tm_p.h.
[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  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 (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 (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 (char *msg);
262
263   /** check an utf8 entry, without creating a Utf8Const object */
264   bool is_attribute_name (int index, 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_AllocBytes (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)
391                                                     * pool_count) ;
392
393   /** first, we scan the constant pool, collecting tags and offsets */
394   tags[0]   = JV_CONSTANT_Undefined;
395   offsets[0] = pos;
396   for (int c = 1; c < pool_count; c++)
397     {
398       tags[c]    = read1u ();
399       offsets[c] = pos;
400
401       switch (tags[c])
402         {
403         case JV_CONSTANT_String:
404         case JV_CONSTANT_Class:
405           skip (2);
406           break;
407
408         case JV_CONSTANT_Fieldref:
409         case JV_CONSTANT_Methodref:
410         case JV_CONSTANT_InterfaceMethodref:
411         case JV_CONSTANT_NameAndType:
412         case JV_CONSTANT_Integer:
413         case JV_CONSTANT_Float:
414           skip (4);
415           break;
416
417         case JV_CONSTANT_Double:
418         case JV_CONSTANT_Long:
419           skip (8);
420           tags[++c] = JV_CONSTANT_Undefined;
421           break;
422             
423         case JV_CONSTANT_Utf8:
424           {                 
425             int len = read2u ();
426             skip (len);
427           }
428           break;
429
430         case JV_CONSTANT_Unicode:
431           throw_class_format_error ("unicode not supported");
432           break;
433
434         default:
435           throw_class_format_error ("erroneous constant pool tag");
436         }
437     }
438
439   handleConstantPool ();
440 }
441
442
443 void _Jv_ClassReader::read_fields ()
444 {
445   int fields_count = read2u ();
446   handleFieldsBegin (fields_count);
447
448   for (int i = 0; i < fields_count; i++)
449     {
450       int access_flags     = read2u ();
451       int name_index       = read2u ();
452       int descriptor_index = read2u ();
453       int attributes_count = read2u ();
454
455       check_tag (name_index, JV_CONSTANT_Utf8);
456       prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
457
458       check_tag (descriptor_index, JV_CONSTANT_Utf8);
459       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
460
461       handleField (i, access_flags, name_index, descriptor_index);
462
463       for (int j = 0; j < attributes_count; j++)
464         {
465           read_one_field_attribute (i);
466         }
467     }
468
469   handleFieldsEnd ();
470 }
471
472 bool
473 _Jv_ClassReader::is_attribute_name (int index, char *name)
474 {
475   check_tag (index, JV_CONSTANT_Utf8);
476   int len = get2u (bytes+offsets[index]);
477   if (len != (int) strlen (name))
478     return false;
479   else
480     return !memcmp (bytes+offsets[index]+2, name, len);
481 }
482
483 void _Jv_ClassReader::read_one_field_attribute (int field_index)
484 {
485   int name = read2u ();
486   int length = read4 ();
487
488   if (is_attribute_name (name, "ConstantValue"))
489     {
490       int cv = read2u ();
491
492       if (cv < pool_count 
493           && cv > 0
494           && (tags[cv] == JV_CONSTANT_Integer
495               || tags[cv] == JV_CONSTANT_Float
496               || tags[cv] == JV_CONSTANT_Long
497               || tags[cv] == JV_CONSTANT_Double
498               || tags[cv] == JV_CONSTANT_String))
499           {
500             handleConstantValueAttribute (field_index, cv);
501           }
502         else
503           {
504             throw_class_format_error ("erroneous ConstantValue attribute");
505           }
506
507         if (length != 2) 
508           throw_class_format_error ("erroneous ConstantValue attribute");
509       }
510
511     else
512       {
513         skip (length);
514       }
515 }
516
517 void _Jv_ClassReader::read_methods ()
518 {
519   int methods_count = read2u ();
520   
521   handleMethodsBegin (methods_count);
522   
523   for (int i = 0; i < methods_count; i++)
524     {
525       int access_flags     = read2u ();
526       int name_index       = read2u ();
527       int descriptor_index = read2u ();
528       int attributes_count = read2u ();
529       
530       check_tag (name_index, JV_CONSTANT_Utf8);
531       prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
532
533       check_tag (descriptor_index, JV_CONSTANT_Utf8);
534       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
535
536       handleMethod (i, access_flags, name_index,
537                     descriptor_index);
538
539       for (int j = 0; j < attributes_count; j++)
540         {
541           read_one_method_attribute (i);
542         }
543     }
544   
545   handleMethodsEnd ();
546 }
547
548 void _Jv_ClassReader::read_one_method_attribute (int method_index) 
549 {
550   int name = read2u ();
551   int length = read4 ();
552
553   if (is_attribute_name (name, "Exceptions"))
554     {
555       _Jv_Method *method = reinterpret_cast<_Jv_Method *>
556         (&def->methods[method_index]);
557       if (method->throws != NULL)
558         throw_class_format_error ("only one Exceptions attribute allowed per method");
559
560       int num_exceptions = read2u ();
561       _Jv_Utf8Const **exceptions =
562         (_Jv_Utf8Const **) _Jv_AllocBytes ((num_exceptions + 1)
563                                            * sizeof (_Jv_Utf8Const *));
564
565       int out = 0;
566       _Jv_word *pool_data = def->constants.data;
567       for (int i = 0; i < num_exceptions; ++i)
568         {
569           int ndx = read2u ();
570           // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
571           if (ndx != 0)
572             {
573               check_tag (ndx, JV_CONSTANT_Class);
574               exceptions[out++] = pool_data[ndx].utf8; 
575             }
576         }
577       exceptions[out] = NULL;
578       method->throws = exceptions;
579     }
580
581   else if (is_attribute_name (name, "Code"))
582     {
583       int start_off = pos;
584       int max_stack = read2u ();
585       int max_locals = read2u ();
586       int code_length = read4 ();
587
588       int code_start = pos;
589       skip (code_length);
590       int exception_table_length = read2u ();
591
592       handleCodeAttribute (method_index, 
593                            max_stack, max_locals,
594                            code_start, code_length,
595                            exception_table_length);
596       
597
598       for (int i = 0; i < exception_table_length; i++)
599         {
600           int start_pc   = read2u ();
601           int end_pc     = read2u ();
602           int handler_pc = read2u ();
603           int catch_type = read2u ();
604
605           if (start_pc > end_pc
606               || start_pc < 0
607               // END_PC can be equal to CODE_LENGTH.
608               // See JVM Spec 4.7.4.
609               || end_pc > code_length
610               || handler_pc >= code_length)
611             throw_class_format_error ("erroneous exception handler info");
612
613           if (! (tags[catch_type] == JV_CONSTANT_Class
614                  || tags[catch_type] == 0))
615             {
616               throw_class_format_error ("erroneous exception handler info");
617             }
618
619           handleExceptionTableEntry (method_index,
620                                      i,
621                                      start_pc,
622                                      end_pc,
623                                      handler_pc, 
624                                      catch_type);
625
626         }
627
628       int attributes_count = read2u ();
629
630       for (int i = 0; i < attributes_count; i++)
631         {
632           read_one_code_attribute (method_index);
633         }
634
635       if ((pos - start_off) != length)
636         throw_class_format_error ("code attribute too short");
637     }
638
639   else
640     {
641       /* ignore unknown attributes */
642       skip (length);
643     }
644 }
645
646 void _Jv_ClassReader::read_one_code_attribute (int method_index) 
647 {
648   int name = read2u ();
649   int length = read4 ();
650   if (is_attribute_name (name, "LineNumberTable"))
651     {
652       _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
653         (def_interp->interpreted_methods[method_index]);
654       if (method->line_table != NULL)
655         throw_class_format_error ("Method already has LineNumberTable");
656
657       int table_len = read2u ();
658       _Jv_LineTableEntry* table
659         = (_Jv_LineTableEntry *) JvAllocBytes (table_len
660                                             * sizeof (_Jv_LineTableEntry));
661       for (int i = 0; i < table_len; i++)
662        {
663          table[i].bytecode_pc = read2u ();
664          table[i].line = read2u ();
665        }
666       method->line_table_len = table_len;
667       method->line_table = table;
668     }
669   else
670     {
671       /* ignore unknown code attributes */
672       skip (length);
673     }
674 }
675
676 void _Jv_ClassReader::read_one_class_attribute () 
677 {
678   int name = read2u ();
679   int length = read4 ();
680   if (is_attribute_name (name, "SourceFile"))
681     {
682       int source_index = read2u ();
683       check_tag (source_index, JV_CONSTANT_Utf8);
684       prepare_pool_entry (source_index, JV_CONSTANT_Utf8);
685       def_interp->source_file_name = _Jv_NewStringUtf8Const
686         (def->constants.data[source_index].utf8);
687     }
688   else
689     {
690       /* Currently, we ignore most class attributes.
691          FIXME: Add inner-classes attributes support. */
692      skip (length);
693     }
694 }
695
696
697
698 \f
699 /* this section defines the semantic actions of the parser */
700
701 void _Jv_ClassReader::handleConstantPool ()
702 {
703   /** now, we actually define the class' constant pool */
704
705   // the pool is scanned explicitly by the collector
706   jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
707   _Jv_word *pool_data
708     = (_Jv_word*) _Jv_AllocBytes (pool_count * sizeof (_Jv_word));
709   
710   def->constants.tags = pool_tags;
711   def->constants.data = pool_data;
712   def->constants.size = pool_count;
713
714   // Here we make a pass to collect the strings!   We do this, because
715   // internally in the GCJ runtime, classes are encoded with .'s not /'s. 
716   // Therefore, we first collect the strings, and then translate the rest
717   // of the utf8-entries (thus not representing strings) from /-notation
718   // to .-notation.
719   for (int i = 1; i < pool_count; i++)
720     {
721       if (tags[i] == JV_CONSTANT_String)
722         {
723           unsigned char* str_data = bytes + offsets [i];
724           int utf_index = get2u (str_data);
725           check_tag (utf_index, JV_CONSTANT_Utf8);
726           unsigned char *utf_data = bytes + offsets[utf_index];
727           int len = get2u (utf_data);
728           pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
729           pool_tags[i] = JV_CONSTANT_String;
730         }
731       else
732         {
733           pool_tags[i] = JV_CONSTANT_Undefined;
734         }
735     }
736
737   // and now, we scan everything else but strings & utf8-entries.  This
738   // leaves out those utf8-entries which are not used; which will be left
739   // with a tag of JV_CONSTANT_Undefined in the class definition.
740   for (int index = 1; index < pool_count; index++)
741     {
742       switch (tags[index])
743         {
744         case JV_CONSTANT_Undefined:
745         case JV_CONSTANT_String:
746         case JV_CONSTANT_Utf8:
747           continue;
748           
749         default:
750           prepare_pool_entry (index, tags[index]);
751         }
752     }  
753   
754 }
755
756 /* this is a recursive procedure, which will prepare pool entries as needed.
757    Which is how we avoid initializing those entries which go unused. */
758 void
759 _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
760 {
761   /* these two, pool_data and pool_tags, point into the class
762      structure we are currently defining */
763
764   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
765   _Jv_word      *pool_data = def->constants.data;
766
767   /* this entry was already prepared */
768   if (pool_tags[index] == this_tag)
769     return;
770
771   /* this_data points to the constant-pool information for the current
772      constant-pool entry */
773
774   unsigned char *this_data = bytes + offsets[index];
775
776   switch (this_tag)
777     {
778     case JV_CONSTANT_Utf8: 
779       {
780         // If we came here, it is because some other tag needs this
781         // utf8-entry for type information!  Thus, we translate /'s to .'s in
782         // order to accomondate gcj's internal representation.
783
784         int len = get2u (this_data);
785         char *buffer = (char*) __builtin_alloca (len);
786         char *s = ((char*) this_data)+2;
787
788         /* FIXME: avoid using a buffer here */
789         for (int i = 0; i < len; i++)
790           {
791             if (s[i] == '/')
792               buffer[i] = '.';
793             else
794               buffer[i] = (char) s[i];
795           }
796         
797         pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
798         pool_tags[index] = JV_CONSTANT_Utf8;
799       }
800       break;
801             
802     case JV_CONSTANT_Class:      
803       {
804         int utf_index = get2u (this_data);
805         check_tag (utf_index, JV_CONSTANT_Utf8);
806         prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
807
808         if (verify)
809           verify_classname (pool_data[utf_index].utf8);
810                 
811         pool_data[index].utf8 = pool_data[utf_index].utf8;
812         pool_tags[index] = JV_CONSTANT_Class;
813       }
814       break;
815             
816     case JV_CONSTANT_String:
817       // already handled before... 
818       break;
819             
820     case JV_CONSTANT_Fieldref:
821     case JV_CONSTANT_Methodref:
822     case JV_CONSTANT_InterfaceMethodref:
823       {
824         int class_index = get2u (this_data);
825         int nat_index = get2u (this_data+2);
826
827         check_tag (class_index, JV_CONSTANT_Class);
828         prepare_pool_entry (class_index, JV_CONSTANT_Class);        
829
830         check_tag (nat_index, JV_CONSTANT_NameAndType);
831         prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
832
833         // here, verify the signature and identifier name
834         if (verify)
835         {
836           _Jv_ushort name_index, type_index;
837           _Jv_loadIndexes (&pool_data[nat_index],
838                            name_index, type_index);
839
840           if (this_tag == JV_CONSTANT_Fieldref)
841             verify_field_signature (pool_data[type_index].utf8);
842           else
843             verify_method_signature (pool_data[type_index].utf8);
844
845           _Jv_Utf8Const* name = pool_data[name_index].utf8;
846
847           if (this_tag != JV_CONSTANT_Fieldref
848               && (   _Jv_equalUtf8Consts (name, clinit_name)
849                   || _Jv_equalUtf8Consts (name, init_name)))
850             /* ignore */;
851           else
852             verify_identifier (pool_data[name_index].utf8);
853         }
854             
855         _Jv_storeIndexes (&pool_data[index], class_index, nat_index);
856         pool_tags[index] = this_tag;
857       }
858       break;
859             
860     case JV_CONSTANT_NameAndType:
861       {
862         _Jv_ushort name_index = get2u (this_data);
863         _Jv_ushort type_index = get2u (this_data+2);
864
865         check_tag (name_index, JV_CONSTANT_Utf8);
866         prepare_pool_entry (name_index, JV_CONSTANT_Utf8);          
867
868         check_tag (type_index, JV_CONSTANT_Utf8);
869         prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
870
871         _Jv_storeIndexes (&pool_data[index], name_index, type_index);
872         pool_tags[index] = JV_CONSTANT_NameAndType;
873       }
874       break;
875             
876     case JV_CONSTANT_Float:
877       {
878         jfloat f = java::lang::Float::intBitsToFloat ((jint) get4 (this_data));
879         _Jv_storeFloat (&pool_data[index], f);
880         pool_tags[index] = JV_CONSTANT_Float;
881       }
882       break;
883             
884     case JV_CONSTANT_Integer:
885       {
886         int i = get4 (this_data);
887         _Jv_storeInt (&pool_data[index], i);
888         pool_tags[index] = JV_CONSTANT_Integer;
889       }
890       break;
891             
892     case JV_CONSTANT_Double:
893       {
894         jdouble d
895           = java::lang::Double::longBitsToDouble ((jlong) get8 (this_data));
896         _Jv_storeDouble (&pool_data[index], d);
897         pool_tags[index] = JV_CONSTANT_Double;
898       }
899       break;
900             
901     case JV_CONSTANT_Long:
902       {
903         jlong i = get8 (this_data);
904         _Jv_storeLong (&pool_data[index], i);
905         pool_tags[index] = JV_CONSTANT_Long;
906       }
907       break;
908             
909     default:
910       throw_class_format_error ("erroneous constant pool tag");
911     }
912 }
913
914
915 void
916 _Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_class)
917 {
918   using namespace java::lang::reflect;
919
920   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
921   _Jv_word      *pool_data = def->constants.data;
922
923   check_tag (this_class, JV_CONSTANT_Class);
924   _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
925
926   // was ClassLoader.defineClass called with an expected class name?
927   if (def->name == 0)
928     {
929       jclass orig = def->loader->findLoadedClass(loadedName->toString());
930
931       if (orig == 0)
932         {
933           def->name = loadedName;
934         }
935       else
936         {
937           jstring msg = JvNewStringUTF ("anonymous "
938                                         "class data denotes "
939                                         "existing class ");
940           msg = msg->concat (orig->getName ());
941
942           throw_no_class_def_found_error (msg);
943         }
944     }
945
946   // assert that the loaded class has the expected name, 5.3.5
947   else if (! _Jv_equalUtf8Consts (loadedName, def->name))
948     {
949       jstring msg = JvNewStringUTF ("loaded class ");
950       msg = msg->concat (def->getName ());
951       msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
952       jstring klass_name = loadedName->toString();
953       msg = msg->concat (klass_name);
954
955       throw_no_class_def_found_error (msg);
956     }
957
958   def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
959   pool_data[this_class].clazz = def;
960   pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
961
962   if (super_class == 0)
963     {
964       // Note that this is ok if we are defining java.lang.Object.
965       // But there is no way to have this class be interpreted.
966       throw_class_format_error ("no superclass reference");
967     }
968
969   def->state = JV_STATE_PRELOADING;
970
971   // Register this class with its defining loader as well (despite the
972   // name of the function we're calling), so that super class lookups
973   // work properly.  If there is an error, our caller will unregister
974   // this class from the class loader.  Also, we don't need to hold a
975   // lock here, as our caller has acquired it.
976   _Jv_RegisterInitiatingLoader (def, def->loader);
977
978   // Note that we found a name so that unregistration can happen if
979   // needed.
980   *found_name = def->name;
981
982   if (super_class != 0)
983     {
984       // Load the superclass.
985       check_tag (super_class, JV_CONSTANT_Class);
986       _Jv_Utf8Const* super_name = pool_data[super_class].utf8; 
987
988       // Load the superclass using our defining loader.
989       jclass the_super = _Jv_FindClass (super_name, def->loader);
990
991       // This will establish that we are allowed to be a subclass,
992       // and check for class circularity error.
993       checkExtends (def, the_super);
994
995       // Note: for an interface we will find Object as the
996       // superclass.  We still check it above to ensure class file
997       // validity, but we simply assign `null' to the actual field in
998       // this case.
999       def->superclass = (((access_flags & Modifier::INTERFACE))
1000                          ? NULL : the_super);
1001       pool_data[super_class].clazz = the_super;
1002       pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
1003     }
1004
1005   // Now we've come past the circularity problem, we can 
1006   // now say that we're loading.
1007
1008   def->state = JV_STATE_LOADING;
1009   def->notifyAll ();
1010 }
1011
1012 ///// Implements the checks described in sect. 5.3.5.3
1013 void
1014 _Jv_ClassReader::checkExtends (jclass sub, jclass super)
1015 {
1016   using namespace java::lang::reflect;
1017
1018   _Jv_Linker::wait_for_state (super, JV_STATE_LOADING);
1019
1020   // Having an interface or a final class as a superclass is no good.
1021   if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
1022     {
1023       throw_incompatible_class_change_error (sub->getName ());
1024     }
1025
1026   // If the super class is not public, we need to check some more.
1027   if ((super->accflags & Modifier::PUBLIC) == 0)
1028     {
1029       // With package scope, the classes must have the same class
1030       // loader.
1031       if (   sub->loader != super->loader
1032           || !_Jv_ClassNameSamePackage (sub->name, super->name))
1033         {
1034           throw_incompatible_class_change_error (sub->getName ());
1035         }
1036     } 
1037
1038   for (; super != 0; super = super->getSuperclass ())
1039     {
1040       if (super == sub)
1041         throw_class_circularity_error (sub->getName ());
1042     }
1043 }
1044
1045
1046
1047 void _Jv_ClassReader::handleInterfacesBegin (int count)
1048 {
1049   def->interfaces = (jclass*) _Jv_AllocBytes (count*sizeof (jclass));
1050   def->interface_count = count;
1051 }
1052
1053 void _Jv_ClassReader::handleInterface (int if_number, int offset)
1054 {
1055   _Jv_word       * pool_data = def->constants.data;
1056   unsigned char  * pool_tags = (unsigned char*) def->constants.tags;
1057
1058   jclass the_interface;
1059
1060   if (pool_tags[offset] == JV_CONSTANT_Class)
1061     {
1062       _Jv_Utf8Const* name = pool_data[offset].utf8;
1063       the_interface =  _Jv_FindClass (name, def->loader);
1064     }
1065   else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
1066     {
1067       the_interface = pool_data[offset].clazz;
1068     }
1069   else
1070     {
1071       throw_no_class_def_found_error ("erroneous constant pool tag");
1072     }
1073
1074   // checks the validity of the_interface, and that we are in fact
1075   // allowed to implement that interface.
1076   checkImplements (def, the_interface);
1077   
1078   pool_data[offset].clazz = the_interface;
1079   pool_tags[offset] = JV_CONSTANT_ResolvedClass;
1080   
1081   def->interfaces[if_number] = the_interface;
1082 }
1083
1084 void
1085 _Jv_ClassReader::checkImplements (jclass sub, jclass super)
1086 {
1087   using namespace java::lang::reflect;
1088
1089   // well, it *must* be an interface
1090   if ((super->accflags & Modifier::INTERFACE) == 0)
1091     {
1092       throw_incompatible_class_change_error (sub->getName ());
1093     }
1094
1095   // if it has package scope, it must also be defined by the 
1096   // same loader.
1097   if ((super->accflags & Modifier::PUBLIC) == 0)
1098     {
1099       if (    sub->loader != super->loader
1100           || !_Jv_ClassNameSamePackage (sub->name, super->name))
1101         {
1102           throw_incompatible_class_change_error (sub->getName ());
1103         }
1104     } 
1105
1106   // FIXME: add interface circularity check here
1107   if (sub == super)
1108     {
1109       throw_class_circularity_error (sub->getName ());
1110     }           
1111 }
1112
1113 void _Jv_ClassReader::handleFieldsBegin (int count)
1114 {
1115   def->fields = (_Jv_Field*) 
1116     _Jv_AllocBytes (count * sizeof (_Jv_Field));
1117   def->field_count = count;
1118   def_interp->field_initializers = (_Jv_ushort*)
1119     _Jv_AllocBytes (count * sizeof (_Jv_ushort));
1120   for (int i = 0; i < count; i++)
1121     def_interp->field_initializers[i] = (_Jv_ushort) 0;
1122 }
1123
1124 void _Jv_ClassReader::handleField (int field_no,
1125                                    int flags,
1126                                    int name,
1127                                    int desc)
1128 {
1129   using namespace java::lang::reflect;
1130
1131   _Jv_word *pool_data = def->constants.data;
1132
1133   _Jv_Field *field = &def->fields[field_no];
1134   _Jv_Utf8Const *field_name = pool_data[name].utf8;
1135
1136   field->name      = field_name;
1137
1138   // Ignore flags we don't know about.  
1139   field->flags = flags & Modifier::ALL_FLAGS;
1140
1141   _Jv_Utf8Const* sig = pool_data[desc].utf8;
1142
1143   if (verify)
1144     {
1145       verify_identifier (field_name);
1146
1147       for (int i = 0; i < field_no; ++i)
1148         {
1149           if (_Jv_equalUtf8Consts (field_name, def->fields[i].name)
1150               && _Jv_equalUtf8Consts (sig,
1151                                       // We know the other fields are
1152                                       // unresolved.
1153                                       (_Jv_Utf8Const *) def->fields[i].type))
1154             throw_class_format_error ("duplicate field name");
1155         }
1156
1157       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1158       if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
1159                 +((field->flags & Modifier::PRIVATE) ? 1 : 0)
1160                 +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
1161         throw_class_format_error ("erroneous field access flags");
1162
1163       // FIXME: JVM spec S4.5: Verify ACC_FINAL and ACC_VOLATILE are not 
1164       // both set. Verify modifiers for interface fields.
1165       
1166     }
1167
1168   if (verify)
1169     verify_field_signature (sig);
1170
1171   // field->type is really a jclass, but while it is still
1172   // unresolved we keep an _Jv_Utf8Const* instead.
1173   field->type       = (jclass) sig;
1174   field->flags     |= _Jv_FIELD_UNRESOLVED_FLAG;
1175   field->u.boffset  = 0;
1176 }
1177
1178
1179 void _Jv_ClassReader::handleConstantValueAttribute (int field_index, 
1180                                                     int value)
1181 {
1182   using namespace java::lang::reflect;
1183
1184   _Jv_Field *field = &def->fields[field_index];
1185
1186   if ((field->flags & (Modifier::STATIC
1187                        | Modifier::FINAL
1188                        | Modifier::PRIVATE)) == 0)
1189     {
1190       // Ignore, as per vmspec #4.7.2
1191       return;
1192     }
1193
1194   // do not allow multiple constant fields!
1195   if (field->flags & _Jv_FIELD_CONSTANT_VALUE)
1196     throw_class_format_error ("field has multiple ConstantValue attributes");
1197
1198   field->flags |= _Jv_FIELD_CONSTANT_VALUE;
1199   def_interp->field_initializers[field_index] = value;
1200
1201   /* type check the initializer */
1202   
1203   if (value <= 0 || value >= pool_count)
1204     throw_class_format_error ("erroneous ConstantValue attribute");
1205
1206   /* FIXME: do the rest */
1207 }
1208
1209 void _Jv_ClassReader::handleFieldsEnd ()
1210 {
1211   using namespace java::lang::reflect;
1212
1213   // We need to reorganize the fields so that the static ones are first,
1214   // to conform to GCJ class layout.
1215
1216   int low            = 0;
1217   int high           = def->field_count-1;
1218   _Jv_Field  *fields = def->fields;
1219   _Jv_ushort *inits  = def_interp->field_initializers;
1220
1221   // this is kind of a raw version of quicksort.
1222   while (low < high)
1223     {
1224       // go forward on low, while it's a static
1225       while (low < high && (fields[low].flags & Modifier::STATIC) != 0)
1226         low++;
1227       
1228       // go backwards on high, while it's a non-static
1229       while (low < high && (fields[high].flags & Modifier::STATIC) == 0)
1230         high--;
1231
1232       if (low==high)
1233         break;
1234
1235       _Jv_Field  tmp  = fields[low];
1236       _Jv_ushort itmp = inits[low];
1237           
1238       fields[low] = fields[high];
1239       inits[low]  = inits[high];
1240           
1241       fields[high] = tmp;
1242       inits[high]  = itmp;
1243           
1244       high -= 1;
1245       low  += 1;
1246     }
1247   
1248   if ((fields[low].flags & Modifier::STATIC) != 0) 
1249     low += 1;
1250
1251   def->static_field_count = low;
1252 }
1253
1254
1255
1256 void
1257 _Jv_ClassReader::handleMethodsBegin (int count)
1258 {
1259   def->methods = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method) * count);
1260
1261   def_interp->interpreted_methods
1262     = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
1263                                           * count);
1264
1265   for (int i = 0; i < count; i++)
1266     {
1267       def_interp->interpreted_methods[i] = 0;
1268       def->methods[i].index = (_Jv_ushort) -1;
1269     }
1270
1271   def->method_count = count;
1272 }
1273
1274
1275 void _Jv_ClassReader::handleMethod 
1276     (int mth_index, int accflags, int name, int desc)
1277
1278   using namespace java::lang::reflect;
1279
1280   _Jv_word *pool_data = def->constants.data;
1281   _Jv_Method *method = &def->methods[mth_index];
1282
1283   check_tag (name, JV_CONSTANT_Utf8);
1284   prepare_pool_entry (name, JV_CONSTANT_Utf8);
1285   method->name = pool_data[name].utf8;
1286
1287   check_tag (desc, JV_CONSTANT_Utf8);
1288   prepare_pool_entry (desc, JV_CONSTANT_Utf8);
1289   method->signature = pool_data[desc].utf8;
1290
1291   // ignore unknown flags
1292   method->accflags = accflags & Modifier::ALL_FLAGS;
1293
1294   // Initialize...
1295   method->ncode = 0;
1296   method->throws = NULL;
1297   
1298   if (verify)
1299     {
1300       if (_Jv_equalUtf8Consts (method->name, clinit_name)
1301           || _Jv_equalUtf8Consts (method->name, init_name))
1302         /* ignore */;
1303       else
1304         verify_identifier (method->name);
1305
1306       verify_method_signature (method->signature);
1307
1308       for (int i = 0; i < mth_index; ++i)
1309         {
1310           if (_Jv_equalUtf8Consts (method->name, def->methods[i].name)
1311               && _Jv_equalUtf8Consts (method->signature,
1312                                       def->methods[i].signature))
1313             throw_class_format_error ("duplicate method");
1314         }
1315
1316       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1317       if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
1318                 +((method->accflags & Modifier::PRIVATE) ? 1 : 0)
1319                 +((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
1320         throw_class_format_error ("erroneous method access flags");
1321
1322       // FIXME: JVM spec S4.6: if ABSTRACT modifier is set, verify other 
1323       // flags are not set. Verify flags for interface methods.  Verify
1324       // modifiers for initializers. 
1325     }
1326 }
1327
1328 void _Jv_ClassReader::handleCodeAttribute
1329   (int method_index, int max_stack, int max_locals, 
1330    int code_start, int code_length, int exc_table_length)
1331 {
1332   int size = _Jv_InterpMethod::size (exc_table_length, code_length);
1333   _Jv_InterpMethod *method = 
1334     (_Jv_InterpMethod*) (_Jv_AllocBytes (size));
1335
1336   method->max_stack      = max_stack;
1337   method->max_locals     = max_locals;
1338   method->code_length    = code_length;
1339   method->exc_count      = exc_table_length;
1340   method->is_15          = is_15;
1341   method->defining_class = def;
1342   method->self           = &def->methods[method_index];
1343   method->prepared       = NULL;
1344   method->line_table_len = 0;
1345   method->line_table     = NULL;
1346
1347
1348   // grab the byte code!
1349   memcpy ((void*) method->bytecode (),
1350           (void*) (bytes+code_start),
1351           code_length);
1352
1353   def_interp->interpreted_methods[method_index] = method;
1354
1355   if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
1356     {
1357       // Precompute the ncode field for a static method.  This lets us
1358       // call a static method of an interpreted class from precompiled
1359       // code without first resolving the class (that will happen
1360       // during class initialization instead).
1361       method->self->ncode = method->ncode ();
1362     }
1363 }
1364
1365 void _Jv_ClassReader::handleExceptionTableEntry
1366   (int method_index, int exc_index, 
1367    int start_pc, int end_pc, int handler_pc, int catch_type)
1368 {
1369   _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1370     (def_interp->interpreted_methods[method_index]);
1371   _Jv_InterpException *exc = method->exceptions ();
1372
1373   exc[exc_index].start_pc.i     = start_pc;
1374   exc[exc_index].end_pc.i       = end_pc;
1375   exc[exc_index].handler_pc.i   = handler_pc;
1376   exc[exc_index].handler_type.i = catch_type;
1377 }
1378
1379 void _Jv_ClassReader::handleMethodsEnd ()
1380 {
1381   using namespace java::lang::reflect;
1382
1383   for (int i = 0; i < def->method_count; i++)
1384     {
1385       _Jv_Method *method = &def->methods[i];
1386       if ((method->accflags & Modifier::NATIVE) != 0)
1387         {
1388           if (def_interp->interpreted_methods[i] != 0)
1389             throw_class_format_error ("code provided for native method");
1390           else
1391             {
1392               _Jv_JNIMethod *m = (_Jv_JNIMethod *)
1393                 _Jv_AllocBytes (sizeof (_Jv_JNIMethod));
1394               m->defining_class = def;
1395               m->self = method;
1396               m->function = NULL;
1397               def_interp->interpreted_methods[i] = m;
1398
1399               if ((method->accflags & Modifier::STATIC))
1400                 {
1401                   // Precompute the ncode field for a static method.
1402                   // This lets us call a static method of an
1403                   // interpreted class from precompiled code without
1404                   // first resolving the class (that will happen
1405                   // during class initialization instead).
1406                   method->ncode = m->ncode ();
1407                 }
1408             }
1409         }
1410       else if ((method->accflags & Modifier::ABSTRACT) != 0)
1411         {
1412           if (def_interp->interpreted_methods[i] != 0)
1413             throw_class_format_error ("code provided for abstract method");
1414           method->ncode = (void *) &_Jv_ThrowAbstractMethodError;
1415         }
1416       else
1417         {
1418           if (def_interp->interpreted_methods[i] == 0)
1419             throw_class_format_error ("method with no code");
1420         }
1421     }
1422 }
1423
1424 void _Jv_ClassReader::throw_class_format_error (char *msg)
1425 {
1426   jstring str;
1427   if (def->name != NULL)
1428     {
1429       jsize mlen = strlen (msg);
1430       unsigned char* data = (unsigned char*) def->name->chars();
1431       int ulen = def->name->len();
1432       unsigned char* limit = data + ulen;
1433       jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
1434       jsize len = nlen + mlen + 3;
1435       str = JvAllocString(len);
1436       jchar *chrs = JvGetStringChars(str);
1437       while (data < limit)
1438         *chrs++ = UTF8_GET(data, limit);
1439       *chrs++ = ' ';
1440       *chrs++ = '(';
1441       for (;;)
1442         {
1443           char c = *msg++;
1444           if (c == 0)
1445             break;
1446           *chrs++ = c & 0xFFFF;
1447         }
1448       *chrs++ = ')';
1449     }
1450   else
1451     str = JvNewStringLatin1 (msg);
1452   ::throw_class_format_error (str);
1453 }
1454 \f
1455 /** Here we define the exceptions that can be thrown */
1456
1457 static void
1458 throw_no_class_def_found_error (jstring msg)
1459 {
1460   throw (msg
1461          ? new java::lang::NoClassDefFoundError (msg)
1462          : new java::lang::NoClassDefFoundError);
1463 }
1464
1465 static void
1466 throw_no_class_def_found_error (char *msg)
1467 {
1468   throw_no_class_def_found_error (JvNewStringLatin1 (msg));
1469 }
1470
1471 static void
1472 throw_class_format_error (jstring msg)
1473 {
1474   throw (msg
1475          ? new java::lang::ClassFormatError (msg)
1476          : new java::lang::ClassFormatError);
1477 }
1478
1479 static void
1480 throw_internal_error (char *msg)
1481 {
1482   throw new java::lang::InternalError (JvNewStringLatin1 (msg));
1483 }
1484
1485 static void
1486 throw_incompatible_class_change_error (jstring msg)
1487 {
1488   throw new java::lang::IncompatibleClassChangeError (msg);
1489 }
1490
1491 static void
1492 throw_class_circularity_error (jstring msg)
1493 {
1494   throw new java::lang::ClassCircularityError (msg);
1495 }
1496
1497 #endif /* INTERPRETER */
1498
1499 \f
1500
1501 /** This section takes care of verifying integrity of identifiers,
1502     signatures, field ddescriptors, and class names */
1503
1504 #define UTF8_PEEK(PTR, LIMIT) \
1505   ({ unsigned char* xxkeep = (PTR); \
1506      int xxch = UTF8_GET(PTR,LIMIT); \
1507      PTR = xxkeep; xxch; })
1508
1509 /* Verify one element of a type descriptor or signature.  */
1510 static unsigned char*
1511 _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
1512 {
1513   if (ptr >= limit)
1514     return 0;
1515
1516   int ch = UTF8_GET (ptr, limit);
1517
1518   switch (ch)
1519     {
1520     case 'V':
1521       if (! void_ok)
1522         return 0;
1523
1524     case 'S': case 'B': case 'I': case 'J':
1525     case 'Z': case 'C': case 'F': case 'D': 
1526       break;
1527
1528     case 'L':
1529       {
1530         unsigned char *start = ptr, *end;
1531         do
1532           {
1533             if (ptr > limit)
1534               return 0;
1535
1536             end = ptr;
1537
1538             if ((ch = UTF8_GET (ptr, limit)) == -1)
1539               return 0;
1540
1541           }
1542         while (ch != ';');
1543         if (! _Jv_VerifyClassName (start, (unsigned short) (end-start)))
1544           return 0;
1545       }
1546       break;
1547
1548     case '[':
1549       return _Jv_VerifyOne (ptr, limit, false);
1550       break;
1551
1552     default:
1553       return 0;
1554     }
1555
1556   return ptr;
1557 }
1558
1559 /* Verification and loading procedures.  */
1560 bool
1561 _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
1562 {
1563   unsigned char* ptr = (unsigned char*) sig->chars();
1564   unsigned char* limit = ptr + sig->len();
1565
1566   ptr = _Jv_VerifyOne (ptr, limit, false);
1567
1568   return ptr == limit;
1569 }
1570
1571 bool
1572 _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
1573 {
1574   unsigned char* ptr = (unsigned char*) sig->chars();
1575   unsigned char* limit = ptr + sig->len();
1576
1577   if (ptr == limit || UTF8_GET(ptr,limit) != '(')
1578     return false;
1579
1580   while (ptr && UTF8_PEEK (ptr, limit) != ')')
1581     ptr = _Jv_VerifyOne (ptr, limit, false);
1582
1583   if (! ptr || UTF8_GET (ptr, limit) != ')')
1584     return false;
1585
1586   // get the return type
1587   ptr = _Jv_VerifyOne (ptr, limit, true);
1588
1589   return ptr == limit;
1590 }
1591
1592 /* We try to avoid calling the Character methods all the time, in
1593    fact, they will only be called for non-standard things. */
1594 static __inline__ int 
1595 is_identifier_start (int c)
1596 {
1597   unsigned int ch = (unsigned)c;
1598
1599   if ((ch - 0x41U) < 29U)               /* A ... Z */
1600     return 1;
1601   if ((ch - 0x61U) < 29U)               /* a ... z */
1602     return 1;
1603   if (ch == 0x5FU)                      /* _ */
1604     return 1;
1605
1606   return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1607 }
1608
1609 static __inline__ int 
1610 is_identifier_part (int c)
1611 {
1612   unsigned int ch = (unsigned)c;
1613
1614   if ((ch - 0x41U) < 29U)               /* A ... Z */
1615     return 1;
1616   if ((ch - 0x61U) < 29U)               /* a ... z */
1617     return 1;
1618   if ((ch - 0x30) < 10U)                /* 0 .. 9 */
1619     return 1;
1620   if (ch == 0x5FU || ch == 0x24U)       /* _ $ */
1621     return 1;
1622
1623   return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1624 }
1625
1626 bool
1627 _Jv_VerifyIdentifier (_Jv_Utf8Const* name)
1628 {
1629   unsigned char *ptr   = (unsigned char*) name->chars();
1630   unsigned char *limit = (unsigned char*) name->limit();
1631   int ch;
1632
1633   if ((ch = UTF8_GET (ptr, limit))==-1
1634       || ! is_identifier_start (ch))
1635     return false;
1636
1637   while (ptr != limit)
1638     {
1639       if ((ch = UTF8_GET (ptr, limit))==-1
1640           || ! is_identifier_part (ch))
1641         return false;
1642     }
1643   return true;
1644 }
1645
1646 bool
1647 _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
1648 {
1649   unsigned char *limit = ptr+length;
1650   int ch;
1651
1652   if ('[' == UTF8_PEEK (ptr, limit))
1653     {
1654       unsigned char *end = _Jv_VerifyOne (++ptr, limit, false);
1655       // _Jv_VerifyOne must leave us looking at the terminating nul
1656       // byte.
1657       if (! end || *end)
1658         return false;
1659       else
1660         return true;
1661     }
1662
1663  next_level:
1664   for (;;) {
1665     if ((ch = UTF8_GET (ptr, limit))==-1)
1666       return false;
1667     if (! is_identifier_start (ch))
1668       return false;
1669     for (;;) {
1670       if (ptr == limit)
1671         return true;
1672       else if ((ch = UTF8_GET (ptr, limit))==-1)
1673         return false;
1674       else if (ch == '.')
1675         goto next_level;
1676       else if (! is_identifier_part (ch))
1677         return false;
1678     }
1679   }
1680 }
1681
1682 bool
1683 _Jv_VerifyClassName (_Jv_Utf8Const *name)
1684 {
1685   return _Jv_VerifyClassName ((unsigned char*)name->chars(), name->len());
1686 }
1687
1688 /* Returns true, if NAME1 and NAME2 represent classes in the same
1689    package.  Neither NAME2 nor NAME2 may name an array type.  */
1690 bool
1691 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
1692 {
1693   unsigned char* ptr1 = (unsigned char*) name1->chars();
1694   unsigned char* limit1 = (unsigned char*) name1->limit();
1695
1696   unsigned char* last1 = ptr1;
1697
1698   // scan name1, and find the last occurrence of '.'
1699   while (ptr1 < limit1) {
1700     int ch1 = UTF8_GET (ptr1, limit1);
1701
1702     if (ch1 == '.')
1703       last1 = ptr1;
1704
1705     else if (ch1 == -1)
1706       return false;
1707   }
1708
1709   // Now the length of NAME1's package name is LEN.
1710   int len = last1 - (unsigned char*) name1->chars();
1711
1712   // If this is longer than NAME2, then we're off.
1713   if (len > name2->len())
1714     return false;
1715
1716   // Then compare the first len bytes for equality.
1717   if (memcmp ((void*) name1->chars(), (void*) name2->chars(), len) == 0)
1718     {
1719       // Check that there are no .'s after position LEN in NAME2.
1720
1721       unsigned char* ptr2 = (unsigned char*) name2->chars() + len;
1722       unsigned char* limit2 = (unsigned char*) name2->limit();
1723
1724       while (ptr2 < limit2)
1725         {
1726           int ch2 = UTF8_GET (ptr2, limit2);
1727           if (ch2 == -1 || ch2 == '.')
1728             return false;
1729         }
1730       return true;
1731     }
1732   return false;
1733 }