OSDN Git Service

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