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