OSDN Git Service

Mon Aug 9 18:33:38 1999 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
[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   _Jv_word *pool_data
618     = (_Jv_word*) _Jv_AllocBytesChecked (pool_count * sizeof (_Jv_word));
619   
620   def->constants.tags = pool_tags;
621   def->constants.data = pool_data;
622   def->constants.size = pool_count;
623
624   // Here we make a pass to collect the strings!   We do this, because
625   // internally in the GCJ runtime, classes are encoded with .'s not /'s. 
626   // Therefore, we first collect the strings, and then translate the rest
627   // of the utf8-entries (thus not representing strings) from /-notation
628   // to .-notation.
629   for (int i = 1; i < pool_count; i++)
630     {
631       if (tags[i] == JV_CONSTANT_String)
632         {
633           unsigned char* str_data = bytes + offsets [i];
634           int utf_index = get2u (str_data);
635           check_tag (utf_index, JV_CONSTANT_Utf8);
636           unsigned char *utf_data = bytes + offsets[utf_index];
637           int len = get2u (utf_data);
638           pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
639           pool_tags[i] = JV_CONSTANT_String;
640         }
641       else
642         {
643           pool_tags[i] = JV_CONSTANT_Undefined;
644         }
645     }
646
647   // and now, we scan everything else but strings & utf8-entries.  This
648   // leaves out those utf8-entries which are not used; which will be left
649   // with a tag of JV_CONSTANT_Undefined in the class definition.
650   for (int index = 1; index < pool_count; index++)
651     {
652       switch (tags[index])
653         {
654         case JV_CONSTANT_Undefined:
655         case JV_CONSTANT_String:
656         case JV_CONSTANT_Utf8:
657           continue;
658           
659         default:
660           prepare_pool_entry (index, tags[index]);
661         }
662     }  
663   
664 }
665
666 /* this is a recursive procedure, which will prepare pool entries as needed.
667    Which is how we avoid initializing those entries which go unused. */
668 void
669 _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
670 {
671   /* these two, pool_data and pool_tags, point into the class
672      structure we are currently defining */
673
674   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
675   _Jv_word      *pool_data = def->constants.data;
676
677   /* this entry was already prepared */
678   if (pool_tags[index] == this_tag)
679     return;
680
681   /* this_data points to the constant-pool information for the current
682      constant-pool entry */
683
684   unsigned char *this_data = bytes + offsets[index];
685
686   switch (this_tag)
687     {
688     case JV_CONSTANT_Utf8: 
689       {
690         // If we came here, it is because some other tag needs this
691         // utf8-entry for type information!  Thus, we translate /'s to .'s in
692         // order to accomondate gcj's internal representation.
693
694         int len = get2u (this_data);
695         char *buffer = (char*) alloca (len);
696         char *s = ((char*) this_data)+2;
697
698         /* FIXME: avoid using a buffer here */
699         for (int i = 0; i < len; i++)
700           {
701             if (s[i] == '/')
702               buffer[i] = '.';
703             else
704               buffer[i] = (char) s[i];
705           }
706         
707         pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
708         pool_tags[index] = JV_CONSTANT_Utf8;
709       }
710       break;
711             
712     case JV_CONSTANT_Class:      
713       {
714         int utf_index = get2u (this_data);
715         check_tag (utf_index, JV_CONSTANT_Utf8);
716         prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
717
718         if (verify)
719           _Jv_VerifyClassName (pool_data[utf_index].utf8);
720                 
721         pool_data[index].utf8 = pool_data[utf_index].utf8;
722         pool_tags[index] = JV_CONSTANT_Class;
723       }
724       break;
725             
726     case JV_CONSTANT_String:
727       // already handled before... 
728       break;
729             
730     case JV_CONSTANT_Fieldref:
731     case JV_CONSTANT_Methodref:
732     case JV_CONSTANT_InterfaceMethodref:
733       {
734         int class_index = get2u (this_data);
735         int nat_index = get2u (this_data+2);
736
737         check_tag (class_index, JV_CONSTANT_Class);
738         prepare_pool_entry (class_index, JV_CONSTANT_Class);        
739
740         check_tag (nat_index, JV_CONSTANT_NameAndType);
741         prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
742
743         // here, verify the signature and identifier name
744         if (verify)
745         {
746           _Jv_ushort name_index, type_index;
747           _Jv_loadIndexes (&pool_data[nat_index],
748                            name_index, type_index);
749
750           if (this_tag == JV_CONSTANT_Fieldref)
751             _Jv_VerifyFieldSignature (pool_data[type_index].utf8);
752           else
753             _Jv_VerifyMethodSignature (pool_data[type_index].utf8);
754
755           _Jv_Utf8Const* name = pool_data[name_index].utf8;
756
757           if (this_tag != JV_CONSTANT_Fieldref
758               && (   _Jv_equalUtf8Consts (name, clinit_name)
759                   || _Jv_equalUtf8Consts (name, init_name)))
760             /* ignore */;
761           else
762             _Jv_VerifyIdentifier (pool_data[name_index].utf8);
763         }
764             
765         _Jv_storeIndexes (&pool_data[index], class_index, nat_index);
766         pool_tags[index] = this_tag;
767       }
768       break;
769             
770     case JV_CONSTANT_NameAndType:
771       {
772         _Jv_ushort name_index = get2u (this_data);
773         _Jv_ushort type_index = get2u (this_data+2);
774
775         check_tag (name_index, JV_CONSTANT_Utf8);
776         prepare_pool_entry (name_index, JV_CONSTANT_Utf8);          
777
778         check_tag (type_index, JV_CONSTANT_Utf8);
779         prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
780
781         _Jv_storeIndexes (&pool_data[index], name_index, type_index);
782         pool_tags[index] = JV_CONSTANT_NameAndType;
783       }
784       break;
785             
786     case JV_CONSTANT_Float:
787       {
788         jfloat f = int_bits_to_float ((jint) get4 (this_data));
789         _Jv_storeFloat (&pool_data[index], f);
790         pool_tags[index] = JV_CONSTANT_Float;
791       }
792       break;
793             
794     case JV_CONSTANT_Integer:
795       {
796         int i = get4 (this_data);
797         _Jv_storeInt (&pool_data[index], i);
798         pool_tags[index] = JV_CONSTANT_Integer;
799       }
800       break;
801             
802     case JV_CONSTANT_Double:
803       {
804         jdouble d = long_bits_to_double ((jlong) get8 (this_data));
805         _Jv_storeDouble (&pool_data[index], d);
806         pool_tags[index] = JV_CONSTANT_Double;
807       }
808       break;
809             
810     case JV_CONSTANT_Long:
811       {
812         jlong i = get8 (this_data);
813         _Jv_storeLong (&pool_data[index], i);
814         pool_tags[index] = JV_CONSTANT_Long;
815       }
816       break;
817             
818     default:
819       throw_class_format_error ("erroneous constant pool tag");
820     }
821 }
822
823
824 void
825 _Jv_ClassReader::handleClassBegin
826   (int access_flags, int this_class, int super_class)
827 {
828   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
829   _Jv_word      *pool_data = def->constants.data;
830
831   check_tag (this_class, JV_CONSTANT_Class);
832   _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
833
834   // was ClassLoader.defineClass called with an expected class name?
835   if (def->name == 0)
836     {
837       jclass orig = _Jv_FindClassInCache (loadedName, def->loader);
838
839       if (orig == 0)
840         {
841           def->name = loadedName;
842         }
843       else
844         {
845           jstring msg = JvNewStringUTF ("anonymous "
846                                         "class data denotes "
847                                         "existing class ");
848           msg = msg->concat (orig->getName ());
849
850           throw_no_class_def_found_error (msg);
851         }
852     }
853
854   // assert that the loaded class has the expected name, 5.3.5
855   else if (! _Jv_equalUtf8Consts (loadedName, def->name))
856     {
857       jstring msg = JvNewStringUTF ("loaded class ");
858       msg = msg->concat (def->getName ());
859       msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
860       jstring klass_name = _Jv_NewStringUTF (loadedName->data);
861       msg = msg->concat (klass_name);
862
863       throw_no_class_def_found_error (msg);
864     }
865
866   def->accflags = access_flags;
867   pool_data[this_class].clazz = def;
868   pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
869
870   if (super_class == 0)
871     {
872       // interfaces have java.lang.Object as super.
873       if (access_flags & INTERFACE)
874         {
875           def->superclass = (jclass)&ClassObject;
876         }
877
878       // FIXME: Consider this carefully!  
879       else if (!_Jv_equalUtf8Consts (def->name, ClassObject.name))
880         {
881           throw_no_class_def_found_error ("loading java.lang.Object");
882         }
883     }
884
885   // In the pre-loading state, it can be looked up in the
886   // cache only by this thread!  This allows the super-class
887   // to include references to this class.
888
889   def->state = JV_STATE_PRELOADING;
890   _Jv_RegisterClass (def);
891
892   if (super_class != 0)
893     {
894       // load the super class
895       check_tag (super_class, JV_CONSTANT_Class);
896       _Jv_Utf8Const* super_name = pool_data[super_class].utf8; 
897
898       // load the super class using our defining loader
899       jclass the_super = _Jv_FindClass (super_name,
900                                         def->loader);
901
902       // This will establish that we are allowed to be a subclass,
903       // and check for class circularity error
904       checkExtends (def, the_super);
905
906       def->superclass = the_super;
907       pool_data[super_class].clazz = the_super;
908       pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
909     }
910             
911   // now we've come past the circularity problem, we can 
912   // now say that we're loading...
913
914   def->state = JV_STATE_LOADING;
915   def->notifyAll ();
916 }
917
918 ///// implements the checks described in sect. 5.3.5.3
919 void
920 _Jv_ClassReader::checkExtends (jclass sub, jclass super)
921 {
922   // having an interface or a final class as a superclass is no good
923   if ((super->accflags & (INTERFACE | FINAL)) != 0)
924     {
925       throw_incompatible_class_change_error (sub->getName ());
926     }
927
928   // if the super class is not public, we need to check some more
929   if ((super->accflags & PUBLIC) == 0)
930     {
931       // With package scope, the classes must have the same
932       // class loader.
933       if (   sub->loader != super->loader
934           || !_Jv_ClassNameSamePackage (sub->name, super->name))
935         {
936           throw_incompatible_class_change_error (sub->getName ());
937         }
938     } 
939
940   for (; super != 0; super = super->superclass)
941     {
942       if (super == sub)
943         throw_class_circularity_error (sub->getName ());
944     }
945 }
946
947
948
949 void _Jv_ClassReader::handleInterfacesBegin (int count)
950 {
951   def->interfaces = (jclass*) _Jv_AllocBytesChecked (count*sizeof (jclass));
952   def->interface_count = count;
953 }
954
955 void _Jv_ClassReader::handleInterface (int if_number, int offset)
956 {
957   _Jv_word       * pool_data = def->constants.data;
958   unsigned char  * pool_tags = (unsigned char*) def->constants.tags;
959
960   jclass the_interface;
961
962   if (pool_tags[offset] == JV_CONSTANT_Class)
963     {
964       _Jv_Utf8Const* name = pool_data[offset].utf8;
965       the_interface =  _Jv_FindClass (name, def->loader);
966     }
967   else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
968     {
969       the_interface = pool_data[offset].clazz;
970     }
971   else
972     {
973       throw_no_class_def_found_error ("erroneous constant pool tag");
974     }
975
976   // checks the validity of the_interface, and that we are in fact
977   // allowed to implement that interface.
978   checkImplements (def, the_interface);
979   
980   pool_data[offset].clazz = the_interface;
981   pool_tags[offset] = JV_CONSTANT_ResolvedClass;
982   
983   def->interfaces[if_number] = the_interface;
984 }
985
986 void
987 _Jv_ClassReader::checkImplements (jclass sub, jclass super)
988 {
989   // well, it *must* be an interface
990   if ((super->accflags & INTERFACE) == 0)
991     {
992       throw_incompatible_class_change_error (sub->getName ());
993     }
994
995   // if it has package scope, it must also be defined by the 
996   // same loader.
997   if ((super->accflags & PUBLIC) == 0)
998     {
999       if (    sub->loader != super->loader
1000           || !_Jv_ClassNameSamePackage (sub->name, super->name))
1001         {
1002           throw_incompatible_class_change_error (sub->getName ());
1003         }
1004     } 
1005
1006   // FIXME: add interface circularity check here
1007   if (sub == super)
1008     {
1009       throw_class_circularity_error (sub->getName ());
1010     }           
1011 }
1012
1013 void _Jv_ClassReader::handleFieldsBegin (int count)
1014 {
1015   def->fields = (_Jv_Field*) 
1016     _Jv_AllocBytesChecked (count * sizeof (_Jv_Field));
1017   def->field_count = count;
1018   def->field_initializers = (_Jv_ushort*)
1019     _Jv_AllocBytesChecked (count * sizeof (_Jv_ushort));
1020   for (int i = 0; i < count; i++)
1021     def->field_initializers[i] = (_Jv_ushort) 0;
1022 }
1023
1024 void _Jv_ClassReader::handleField (int field_no,
1025                                    int flags,
1026                                    int name,
1027                                    int desc)
1028 {
1029   _Jv_word *pool_data = def->constants.data;
1030
1031   _Jv_Field *field = &def->fields[field_no];
1032   _Jv_Utf8Const *field_name = pool_data[name].utf8;
1033
1034 #ifndef COMPACT_FIELDS
1035   field->name      = field_name;
1036 #else
1037   field->nameIndex = name;
1038 #endif
1039
1040   if (verify)
1041     _Jv_VerifyIdentifier (field_name);
1042
1043   // ignore flags we don't know about.  
1044   field->flags = flags & ALL_FLAGS;
1045
1046   if (verify)
1047     {
1048       if (field->flags & (SYNCHRONIZED|NATIVE|INTERFACE|ABSTRACT))
1049         throw_class_format_error ("erroneous field access flags");
1050       
1051       if (1 < ( ((field->flags & PUBLIC) ? 1 : 0)
1052                 +((field->flags & PRIVATE) ? 1 : 0)
1053                 +((field->flags & 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   _Jv_Field *field = &def->fields[field_index];
1074
1075   if ((field->flags & (STATIC|FINAL|PRIVATE)) == 0)
1076     {
1077       // Ignore, as per vmspec #4.7.2
1078       return;
1079     }
1080
1081   // do not allow multiple constant fields!
1082   if (field->flags & _Jv_FIELD_CONSTANT_VALUE)
1083     throw_class_format_error ("field has multiple ConstantValue attributes");
1084
1085   field->flags |= _Jv_FIELD_CONSTANT_VALUE;
1086   def->field_initializers[field_index] = value;
1087
1088   /* type check the initializer */
1089   
1090   if (value <= 0 || value >= pool_count)
1091     throw_class_format_error ("erroneous ConstantValue attribute");
1092
1093   /* FIXME: do the rest */
1094 }
1095
1096 void _Jv_ClassReader::handleFieldsEnd ()
1097 {
1098   // We need to reorganize the fields so that the static ones are first,
1099   // to conform to GCJ class layout.
1100
1101   int low            = 0;
1102   int high           = def->field_count-1;
1103   _Jv_Field  *fields = def->fields;
1104   _Jv_ushort *inits  = def->field_initializers;
1105
1106   // this is kind of a raw version of quicksort.
1107   while (low < high)
1108     {
1109       // go forward on low, while it's a static
1110       while (low < high && (fields[low].flags & STATIC) != 0)
1111         low++;
1112       
1113       // go backwards on high, while it's a non-static
1114       while (low < high && (fields[high].flags & STATIC) == 0)
1115         high--;
1116
1117       if (low==high)
1118         break;
1119
1120       _Jv_Field  tmp  = fields[low];
1121       _Jv_ushort itmp = inits[low];
1122           
1123       fields[low] = fields[high];
1124       inits[low]  = inits[high];
1125           
1126       fields[high] = tmp;
1127       inits[high]  = itmp;
1128           
1129       high -= 1;
1130       low  += 1;
1131     }
1132   
1133   if ((fields[low].flags & STATIC) != 0) 
1134     low += 1;
1135
1136   def->static_field_count = low;
1137 }
1138
1139
1140
1141 void _Jv_ClassReader::handleMethodsBegin (int count)
1142 {
1143   def->methods = (_Jv_Method*)
1144     _Jv_AllocBytesChecked (sizeof (_Jv_Method)*count);
1145
1146   def->interpreted_methods = (_Jv_InterpMethod**)
1147     _Jv_AllocBytesChecked (sizeof (_Jv_InterpMethod*) * count);
1148
1149   for (int i = 0; i < count; i++)
1150     def->interpreted_methods[i] = 0;
1151
1152   def->method_count = count;
1153 }
1154
1155
1156 void _Jv_ClassReader::handleMethod 
1157     (int mth_index, int accflags, int name, int desc)
1158
1159   _Jv_word *pool_data = def->constants.data;
1160   _Jv_Method *method = &def->methods[mth_index];
1161
1162   check_tag (name, JV_CONSTANT_Utf8);
1163   prepare_pool_entry (name, JV_CONSTANT_Utf8);
1164   method->name = pool_data[name].utf8;
1165
1166   check_tag (desc, JV_CONSTANT_Utf8);
1167   prepare_pool_entry (desc, JV_CONSTANT_Utf8);
1168   method->signature = pool_data[desc].utf8;
1169
1170   // ignore unknown flags
1171   method->accflags = accflags & ALL_FLAGS;
1172
1173   // intialize...
1174   method->ncode = 0;
1175   
1176   if (verify)
1177     {
1178       if (_Jv_equalUtf8Consts (method->name, clinit_name)
1179           || _Jv_equalUtf8Consts (method->name, init_name))
1180         /* ignore */;
1181       else
1182         _Jv_VerifyIdentifier (method->name);
1183
1184       _Jv_VerifyMethodSignature (method->signature);
1185
1186       if (method->accflags & (VOLATILE|TRANSIENT|INTERFACE))
1187         throw_class_format_error ("erroneous method access flags");
1188       
1189       if (1 < ( ((method->accflags & PUBLIC) ? 1 : 0)
1190                 +((method->accflags & PRIVATE) ? 1 : 0)
1191                 +((method->accflags & PROTECTED) ? 1 : 0)))
1192         throw_class_format_error ("erroneous method access flags");
1193     }
1194 }
1195
1196 void _Jv_ClassReader::handleCodeAttribute
1197   (int method_index, int max_stack, int max_locals, 
1198    int code_start, int code_length, int exc_table_length)
1199 {
1200   int size = _Jv_InterpMethod::size (exc_table_length, code_length);
1201   _Jv_InterpMethod *method = 
1202     (_Jv_InterpMethod*) (_Jv_AllocBytesChecked (size));
1203
1204   method->max_stack      = max_stack;
1205   method->max_locals     = max_locals;
1206   method->code_length    = code_length;
1207   method->exc_count      = exc_table_length;
1208   method->defining_class = def;
1209   method->self           = &def->methods[method_index];
1210
1211   // grab the byte code!
1212   memcpy ((void*) method->bytecode (),
1213           (void*) (bytes+code_start),
1214           code_length);
1215   
1216   def->interpreted_methods[method_index] = method;
1217
1218   /* that's all we do for now */
1219 }
1220
1221 void _Jv_ClassReader::handleExceptionTableEntry 
1222   (int method_index, int exc_index, 
1223    int start_pc, int end_pc, int handler_pc, int catch_type)
1224 {
1225   _Jv_InterpMethod *method = def->interpreted_methods[method_index];
1226   _Jv_InterpException *exc = method->exceptions ();
1227
1228   exc[exc_index].start_pc     = start_pc;
1229   exc[exc_index].end_pc       = end_pc;
1230   exc[exc_index].handler_pc   = handler_pc;
1231   exc[exc_index].handler_type = catch_type;
1232 }
1233
1234 void _Jv_ClassReader::handleMethodsEnd ()
1235 {
1236   for (int i = 0; i < def->method_count; i++)
1237     {
1238       _Jv_Method *method = &def->methods[i];
1239       if (method->accflags & (NATIVE|ABSTRACT))
1240         {
1241           if (def->interpreted_methods[i] != 0)
1242             throw_class_format_error ("code provided "
1243                                       "for abstract or native method");
1244         }
1245       else
1246         {
1247           if (def->interpreted_methods[i] == 0)
1248             throw_class_format_error ("abstract or native method "
1249                                       "with no code");
1250         }
1251     }
1252
1253 }
1254
1255 \f
1256 /** This section takes care of verifying integrity of identifiers,
1257     signatures, field ddescriptors, and class names */
1258
1259 #define UTF8_PEEK(PTR, LIMIT) \
1260   ({ unsigned char* xxkeep = (PTR); \
1261      int xxch = UTF8_GET(PTR,LIMIT); \
1262      PTR = xxkeep; xxch; })
1263
1264 /* verify one element of a type descriptor or signature */
1265 static unsigned char*
1266 _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
1267 {
1268   if (ptr >= limit)
1269     return 0;
1270
1271   int ch = UTF8_GET (ptr, limit);
1272
1273   switch (ch)
1274     {
1275     case 'V':
1276       if (! void_ok) return 0;
1277
1278     case 'S': case 'B': case 'I': case 'J':
1279     case 'Z': case 'C': case 'F': case 'D': 
1280       break;
1281
1282     case 'L':
1283       {
1284         unsigned char *start = ptr, *end;
1285         do {
1286           if (ptr > limit)
1287             return 0;
1288                 
1289           end = ptr;
1290                 
1291           if ((ch = UTF8_GET (ptr, limit)) == -1)
1292             return 0;
1293                 
1294         } while (ch != ';');
1295         _Jv_VerifyClassName (start, (unsigned short) (end-start));
1296       }
1297       break;
1298
1299     case '[':
1300       return _Jv_VerifyOne (ptr, limit, false);
1301       break;
1302         
1303     default:
1304       return 0;
1305     }
1306
1307   return ptr;
1308     
1309 }
1310
1311
1312 /** verification and loading procedures **/
1313
1314 void
1315 _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
1316 {
1317   unsigned char* ptr = (unsigned char*) sig->data;
1318   unsigned char* limit = ptr + sig->length;
1319
1320   ptr = _Jv_VerifyOne (ptr, limit, false);
1321
1322   if (ptr != limit)
1323     throw_class_format_error ("erroneous type descriptor");
1324 }
1325
1326 void
1327 _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
1328 {
1329   unsigned char* ptr = (unsigned char*) sig->data;
1330   unsigned char* limit = ptr + sig->length;
1331
1332   if (ptr == limit)
1333     throw_class_format_error ("erroneous type descriptor");
1334
1335   if (UTF8_GET(ptr,limit) != '(')
1336     throw_class_format_error ("erroneous type descriptor");
1337
1338   while (ptr && UTF8_PEEK (ptr, limit) != ')')
1339     ptr = _Jv_VerifyOne (ptr, limit, false);
1340     
1341   if (UTF8_GET (ptr, limit) != ')')
1342     throw_class_format_error ("erroneous type descriptor");
1343
1344   // get the return type
1345   ptr = _Jv_VerifyOne (ptr, limit, true);
1346
1347   if (ptr != limit)
1348     throw_class_format_error ("erroneous type descriptor");
1349
1350   return;
1351
1352 }
1353
1354 /* we try to avoid calling the Character methods all the time, 
1355    in fact, they will only be called for non-standard things */
1356
1357 static __inline__ int 
1358 is_identifier_start (int c)
1359 {
1360   unsigned int ch = (unsigned)c;
1361
1362   if ((ch - 0x41U) < 29U)               /* A ... Z */
1363     return 1;
1364   if ((ch - 0x61U) < 29U)               /* a ... z */
1365     return 1;
1366   if (ch == 0x5FU)                      /* _ */
1367     return 1;
1368
1369   return character->isJavaIdentifierStart ((jchar) ch);
1370 }
1371
1372 static __inline__ int 
1373 is_identifier_part (int c)
1374 {
1375   unsigned int ch = (unsigned)c;
1376
1377   if ((ch - 0x41U) < 29U)               /* A ... Z */
1378     return 1;
1379   if ((ch - 0x61U) < 29U)               /* a ... z */
1380     return 1;
1381   if ((ch - 0x30) < 10U)                /* 0 .. 9 */
1382     return 1;
1383   if (ch == 0x5FU || ch == 0x24U)       /* _ $ */
1384     return 1;
1385
1386   return character->isJavaIdentifierStart ((jchar) ch);
1387 }
1388
1389 void 
1390 _Jv_VerifyIdentifier (_Jv_Utf8Const* name)
1391 {
1392   unsigned char *ptr   = (unsigned char*) name->data;
1393   unsigned char *limit = ptr + name->length;
1394   int ch;
1395
1396   if ((ch = UTF8_GET (ptr, limit))==-1
1397       || ! is_identifier_start (ch))
1398     throw_class_format_error ("erroneous identifier");
1399
1400   while (ptr != limit)
1401     {
1402       if ((ch = UTF8_GET (ptr, limit))==-1
1403           || ! is_identifier_part (ch))
1404         throw_class_format_error ("erroneous identifier");
1405     }
1406 }
1407
1408
1409 void
1410 _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
1411 {
1412   unsigned char *limit = ptr+length;
1413   int ch;
1414
1415   if ('[' == UTF8_PEEK (ptr, limit))
1416     {
1417       if (! _Jv_VerifyOne (++ptr, limit, false))
1418         throw_class_format_error ("erroneous class name");
1419       else
1420         return;
1421     }
1422
1423  next_level:
1424   do {
1425     if ((ch = UTF8_GET (ptr, limit))==-1)
1426       throw_class_format_error ("erroneous class name");
1427     if (! is_identifier_start (ch))
1428       throw_class_format_error ("erroneous class name");
1429     do {
1430       if (ptr == limit)
1431         return;
1432       else if ((ch = UTF8_GET (ptr, limit))==-1)
1433         throw_class_format_error ("erroneous class name");
1434       else if (ch == '.')
1435         goto next_level;
1436       else if (! is_identifier_part (ch))
1437         throw_class_format_error ("erroneous class name");
1438     } while (true);
1439   } while (true);
1440
1441 }
1442
1443 void
1444 _Jv_VerifyClassName (_Jv_Utf8Const *name)
1445 {
1446     _Jv_VerifyClassName ((unsigned char*)&name->data[0],
1447                          (_Jv_ushort) name->length);
1448 }
1449
1450
1451 /** returns true, if name1 and name2 represents classes in the same
1452     package. */
1453     
1454 bool
1455 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
1456 {
1457   unsigned char* ptr1 = (unsigned char*) name1->data;
1458   unsigned char* limit1 = ptr1 + name1->length;
1459
1460   unsigned char* last1 = ptr1;
1461
1462   // scan name1, and find the last occurrence of '.'
1463   while (ptr1 < limit1) {
1464     int ch1 = UTF8_GET (ptr1, limit1);
1465
1466     if (ch1 == '.')
1467       last1 = ptr1;
1468         
1469     else if (ch1 == -1)
1470       return false;
1471   }
1472
1473   // now the length of name1's package name is len
1474   int len = last1 - (unsigned char*) name1->data;
1475
1476   // if this is longer than name2, then we're off
1477   if (len > name2->length)
1478     return false;
1479
1480   // then compare the first len bytes for equality
1481   if (memcmp ((void*) name1->data, (void*) name2->data, len) == 0)
1482     {
1483       // check that there are no .'s after position len in name2
1484
1485       unsigned char* ptr2 = (unsigned char*) name2->data + len;
1486       unsigned char* limit2 =
1487         (unsigned char*) name2->data + name2->length;
1488
1489       while (ptr2 < limit2)
1490         {
1491           int ch2 = UTF8_GET (ptr2, limit2);
1492           if (ch2 == -1 || ch2 == '.')
1493             return false;
1494         }
1495       return true;
1496     }
1497   return false;
1498 }
1499
1500
1501 \f
1502 /** Here we define the exceptions that can be thrown */
1503
1504 static void
1505 throw_no_class_def_found_error (jstring msg)
1506 {
1507   if (msg == 0)
1508     JvThrow (new java::lang::NoClassDefFoundError);
1509   else
1510     JvThrow (new java::lang::NoClassDefFoundError (msg));
1511 }
1512
1513 static void
1514 throw_no_class_def_found_error (char *msg)
1515 {
1516   throw_no_class_def_found_error (JvNewStringLatin1 (msg));
1517 }
1518
1519 static void
1520 throw_class_format_error (jstring msg)
1521 {
1522   if (msg == 0)
1523     JvThrow (new java::lang::ClassFormatError);
1524   else
1525     JvThrow (new java::lang::ClassFormatError (msg));
1526 }
1527
1528 static void
1529 throw_class_format_error (char *msg)
1530 {
1531   throw_class_format_error (JvNewStringLatin1 (msg));
1532 }
1533
1534 static void
1535 throw_internal_error (char *msg)
1536 {
1537   JvThrow 
1538     (new java::lang::InternalError (JvNewStringLatin1 (msg)));
1539 }
1540
1541 static jfloat int_bits_to_float (jint value)
1542 {
1543   return java::lang::Float::intBitsToFloat (value);
1544 }
1545
1546 static jdouble long_bits_to_double (jlong value)
1547 {
1548   return java::lang::Double::longBitsToDouble (value);
1549 }
1550
1551 static void throw_incompatible_class_change_error (jstring msg)
1552 {
1553   JvThrow (new java::lang::IncompatibleClassChangeError (msg));
1554 }
1555
1556 static void throw_class_circularity_error (jstring msg)
1557 {
1558   JvThrow (new java::lang::ClassCircularityError (msg));
1559 }
1560
1561 #endif /* INTERPRETER */
1562