OSDN Git Service

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