OSDN Git Service

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