OSDN Git Service

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