OSDN Git Service

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