OSDN Git Service

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