OSDN Git Service

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