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