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