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