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