2006-08-15 Paolo Carlini <pcarlini@suse.de>
[official-gcc.git] / libjava / defineclass.cc
blob03d73a2c266cf3da9c7bd3c62735c5e527eaa3be
1 // defineclass.cc - defining a class from .class format.
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 details. */
11 /*
12 Author: Kresten Krab Thorup <krab@gnu.org>
14 Written using the online versions of Java Language Specification (1st
15 ed.) and The Java Virtual Machine Specification (2nd ed.).
17 Future work may include reading (and handling) attributes which are
18 currently being ignored ("InnerClasses", "LineNumber", etc...).
21 #include <config.h>
23 #include <java-interp.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <java-cpool.h>
28 #include <gcj/cni.h>
29 #include <execution.h>
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/IncompatibleClassChangeError.h>
41 #include <java/lang/reflect/Modifier.h>
42 #include <java/security/ProtectionDomain.h>
44 using namespace gcj;
46 #ifdef INTERPRETER
48 // these go in some separate functions, to avoid having _Jv_InitClass
49 // inserted all over the place.
50 static void throw_internal_error (const char *msg)
51 __attribute__ ((__noreturn__));
52 static void throw_no_class_def_found_error (jstring msg)
53 __attribute__ ((__noreturn__));
54 static void throw_no_class_def_found_error (const char *msg)
55 __attribute__ ((__noreturn__));
56 static void throw_class_format_error (jstring msg)
57 __attribute__ ((__noreturn__));
58 static void throw_incompatible_class_change_error (jstring msg)
59 __attribute__ ((__noreturn__));
60 static void throw_class_circularity_error (jstring msg)
61 __attribute__ ((__noreturn__));
63 /**
64 * We define class reading using a class. It is practical, since then
65 * the entire class-reader can be a friend of class Class (it needs to
66 * write all it's different structures); but also because this makes it
67 * easy to make class definition reentrant, and thus two threads can be
68 * defining classes at the same time. This class (_Jv_ClassReader) is
69 * never exposed outside this file, so we don't have to worry about
70 * public or private members here.
73 struct _Jv_ClassReader
76 // do verification? Currently, there is no option to disable this.
77 // This flag just controls the verificaiton done by the class loader;
78 // i.e., checking the integrity of the constant pool; and it is
79 // allways on. You always want this as far as I can see, but it also
80 // controls weither identifiers and type descriptors/signatures are
81 // verified as legal. This could be somewhat more expensive since it
82 // will call Character.isJavaIdentifier{Start,Part} for each character
83 // in any identifier (field name or method name) it comes by. Thus,
84 // it might be useful to turn off this verification for classes that
85 // come from a trusted source. However, for GCJ, trusted classes are
86 // most likely to be linked in.
88 bool verify;
90 // input data.
91 unsigned char *bytes;
92 int len;
94 // current input position
95 int pos;
97 // the constant pool data
98 int pool_count;
99 unsigned char *tags;
100 unsigned int *offsets;
102 // the class to define (see java-interp.h)
103 jclass def;
105 // the classes associated interpreter data.
106 _Jv_InterpClass *def_interp;
108 // The name we found.
109 _Jv_Utf8Const **found_name;
111 // True if this is a 1.5 class file.
112 bool is_15;
115 /* check that the given number of input bytes are available */
116 inline void check (int num)
118 if (pos + num > len)
119 throw_class_format_error ("Premature end of data");
122 /* skip a given number of bytes in input */
123 inline void skip (int num)
125 check (num);
126 pos += num;
129 /* read an unsignend 1-byte unit */
130 inline static jint get1u (unsigned char* bytes)
132 return bytes[0];
135 /* read an unsigned 1-byte unit */
136 inline jint read1u ()
138 skip (1);
139 return get1u (bytes+pos-1);
142 /* read an unsigned 2-byte unit */
143 inline static jint get2u (unsigned char *bytes)
145 return (((jint)bytes[0]) << 8) | ((jint)bytes[1]);
148 /* read an unsigned 2-byte unit */
149 inline jint read2u ()
151 skip (2);
152 return get2u (bytes+pos-2);
155 /* read a 4-byte unit */
156 static jint get4 (unsigned char *bytes)
158 return (((jint)bytes[0]) << 24)
159 | (((jint)bytes[1]) << 16)
160 | (((jint)bytes[2]) << 8)
161 | (((jint)bytes[3]) << 0);
164 /* read a 4-byte unit, (we don't do that quite so often) */
165 inline jint read4 ()
167 skip (4);
168 return get4 (bytes+pos-4);
171 /* read a 8-byte unit */
172 static jlong get8 (unsigned char* bytes)
174 return (((jlong)bytes[0]) << 56)
175 | (((jlong)bytes[1]) << 48)
176 | (((jlong)bytes[2]) << 40)
177 | (((jlong)bytes[3]) << 32)
178 | (((jlong)bytes[4]) << 24)
179 | (((jlong)bytes[5]) << 16)
180 | (((jlong)bytes[6]) << 8)
181 | (((jlong)bytes[7]) << 0);
184 /* read a 8-byte unit */
185 inline jlong read8 ()
187 skip (8);
188 return get8 (bytes+pos-8);
191 inline void check_tag (int index, char expected_tag)
193 if (index < 0
194 || index > pool_count
195 || tags[index] != expected_tag)
196 throw_class_format_error ("erroneous constant pool tag");
199 inline void verify_identifier (_Jv_Utf8Const* name)
201 if (! _Jv_VerifyIdentifier (name))
202 throw_class_format_error ("erroneous identifier");
205 inline void verify_classname (unsigned char* ptr, _Jv_ushort length)
207 if (! _Jv_VerifyClassName (ptr, length))
208 throw_class_format_error ("erroneous class name");
211 inline void verify_classname (_Jv_Utf8Const *name)
213 if (! _Jv_VerifyClassName (name))
214 throw_class_format_error ("erroneous class name");
217 inline void verify_field_signature (_Jv_Utf8Const *sig)
219 if (! _Jv_VerifyFieldSignature (sig))
220 throw_class_format_error ("erroneous type descriptor");
223 inline void verify_method_signature (_Jv_Utf8Const *sig)
225 if (! _Jv_VerifyMethodSignature (sig))
226 throw_class_format_error ("erroneous type descriptor");
229 _Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length,
230 java::security::ProtectionDomain *pd,
231 _Jv_Utf8Const **name_result)
233 if (klass == 0 || length < 0 || offset+length > data->length)
234 throw_internal_error ("arguments to _Jv_DefineClass");
236 verify = true;
237 bytes = (unsigned char*) (elements (data)+offset);
238 len = length;
239 pos = 0;
240 is_15 = false;
242 def = klass;
243 found_name = name_result;
245 def->size_in_bytes = -1;
246 def->vtable_method_count = -1;
247 def->engine = &_Jv_soleInterpreterEngine;
248 def->protectionDomain = pd;
251 /** and here goes the parser members defined out-of-line */
252 void parse ();
253 void read_constpool ();
254 void prepare_pool_entry (int index, unsigned char tag);
255 void read_fields ();
256 void read_methods ();
257 void read_one_class_attribute ();
258 void read_one_method_attribute (int method);
259 void read_one_code_attribute (int method);
260 void read_one_field_attribute (int field);
261 void throw_class_format_error (const char *msg);
263 /** check an utf8 entry, without creating a Utf8Const object */
264 bool is_attribute_name (int index, const char *name);
266 /** here goes the class-loader members defined out-of-line */
267 void handleConstantPool ();
268 void handleClassBegin (int, int, int);
269 void handleInterfacesBegin (int);
270 void handleInterface (int, int);
271 void handleFieldsBegin (int);
272 void handleField (int, int, int, int);
273 void handleFieldsEnd ();
274 void handleConstantValueAttribute (int,int);
275 void handleMethodsBegin (int);
276 void handleMethod (int, int, int, int);
277 void handleMethodsEnd ();
278 void handleCodeAttribute (int, int, int, int, int, int);
279 void handleExceptionTableEntry (int, int, int, int, int, int);
281 void checkExtends (jclass sub, jclass super);
282 void checkImplements (jclass sub, jclass super);
285 * FIXME: we should keep a hash table of utf8-strings, since many will
286 * be the same. It's a little tricky, however, because the hash table
287 * needs to interact gracefully with the garbage collector. Much
288 * memory is to be saved by this, however! perhaps the improvement
289 * could be implemented in prims.cc (_Jv_makeUtf8Const), since it
290 * computes the hash value anyway.
294 // Note that *NAME_RESULT will only be set if the class is registered
295 // with the class loader. This is how the caller can know whether
296 // unregistration is require.
297 void
298 _Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length,
299 java::security::ProtectionDomain *pd,
300 _Jv_Utf8Const **name_result)
302 _Jv_ClassReader reader (klass, data, offset, length, pd, name_result);
303 reader.parse();
305 /* that's it! */
309 /** This section defines the parsing/scanning of the class data */
311 // Major and minor version numbers for various releases.
312 #define MAJOR_1_1 45
313 #define MINOR_1_1 3
314 #define MAJOR_1_2 46
315 #define MINOR_1_2 0
316 #define MAJOR_1_3 47
317 #define MINOR_1_3 0
318 #define MAJOR_1_4 48
319 #define MINOR_1_4 0
320 #define MAJOR_1_5 49
321 #define MINOR_1_5 0
323 void
324 _Jv_ClassReader::parse ()
326 int magic = read4 ();
327 if (magic != (int) 0xCAFEBABE)
328 throw_class_format_error ("bad magic number");
330 int minor_version = read2u ();
331 int major_version = read2u ();
332 if (major_version < MAJOR_1_1 || major_version > MAJOR_1_5
333 || (major_version == MAJOR_1_5 && minor_version > MINOR_1_5))
334 throw_class_format_error ("unrecognized class file version");
335 is_15 = (major_version == MAJOR_1_5);
337 pool_count = read2u ();
339 read_constpool ();
341 int access_flags = read2u ();
342 int this_class = read2u ();
343 int super_class = read2u ();
345 check_tag (this_class, JV_CONSTANT_Class);
346 if (super_class != 0)
347 check_tag (super_class, JV_CONSTANT_Class);
349 handleClassBegin (access_flags, this_class, super_class);
351 // Allocate our aux_info here, after the name is set, to fulfill our
352 // contract with the collector interface.
353 def->aux_info = (void *) _Jv_AllocRawObj (sizeof (_Jv_InterpClass));
354 def_interp = (_Jv_InterpClass *) def->aux_info;
356 int interfaces_count = read2u ();
358 handleInterfacesBegin (interfaces_count);
360 for (int i = 0; i < interfaces_count; i++)
362 int iface = read2u ();
363 check_tag (iface, JV_CONSTANT_Class);
364 handleInterface (i, iface);
367 read_fields ();
368 read_methods ();
370 int attributes_count = read2u ();
372 for (int i = 0; i < attributes_count; i++)
374 read_one_class_attribute ();
377 if (pos != len)
378 throw_class_format_error ("unused data before end of file");
380 // Tell everyone we're done.
381 def->state = JV_STATE_READ;
382 if (gcj::verbose_class_flag)
383 _Jv_Linker::print_class_loaded (def);
384 def->notifyAll ();
387 void _Jv_ClassReader::read_constpool ()
389 tags = (unsigned char*) _Jv_AllocBytes (pool_count);
390 offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int) * pool_count) ;
392 /** first, we scan the constant pool, collecting tags and offsets */
393 tags[0] = JV_CONSTANT_Undefined;
394 offsets[0] = pos;
395 for (int c = 1; c < pool_count; c++)
397 tags[c] = read1u ();
398 offsets[c] = pos;
400 switch (tags[c])
402 case JV_CONSTANT_String:
403 case JV_CONSTANT_Class:
404 skip (2);
405 break;
407 case JV_CONSTANT_Fieldref:
408 case JV_CONSTANT_Methodref:
409 case JV_CONSTANT_InterfaceMethodref:
410 case JV_CONSTANT_NameAndType:
411 case JV_CONSTANT_Integer:
412 case JV_CONSTANT_Float:
413 skip (4);
414 break;
416 case JV_CONSTANT_Double:
417 case JV_CONSTANT_Long:
418 skip (8);
419 tags[++c] = JV_CONSTANT_Undefined;
420 break;
422 case JV_CONSTANT_Utf8:
424 int len = read2u ();
425 skip (len);
427 break;
429 case JV_CONSTANT_Unicode:
430 throw_class_format_error ("unicode not supported");
431 break;
433 default:
434 throw_class_format_error ("erroneous constant pool tag");
438 handleConstantPool ();
442 void _Jv_ClassReader::read_fields ()
444 int fields_count = read2u ();
445 handleFieldsBegin (fields_count);
447 for (int i = 0; i < fields_count; i++)
449 int access_flags = read2u ();
450 int name_index = read2u ();
451 int descriptor_index = read2u ();
452 int attributes_count = read2u ();
454 check_tag (name_index, JV_CONSTANT_Utf8);
455 prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
457 check_tag (descriptor_index, JV_CONSTANT_Utf8);
458 prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
460 handleField (i, access_flags, name_index, descriptor_index);
462 for (int j = 0; j < attributes_count; j++)
464 read_one_field_attribute (i);
468 handleFieldsEnd ();
471 bool
472 _Jv_ClassReader::is_attribute_name (int index, const char *name)
474 check_tag (index, JV_CONSTANT_Utf8);
475 int len = get2u (bytes+offsets[index]);
476 if (len != (int) strlen (name))
477 return false;
478 else
479 return !memcmp (bytes+offsets[index]+2, name, len);
482 void _Jv_ClassReader::read_one_field_attribute (int field_index)
484 int name = read2u ();
485 int length = read4 ();
487 if (is_attribute_name (name, "ConstantValue"))
489 int cv = read2u ();
491 if (cv < pool_count
492 && cv > 0
493 && (tags[cv] == JV_CONSTANT_Integer
494 || tags[cv] == JV_CONSTANT_Float
495 || tags[cv] == JV_CONSTANT_Long
496 || tags[cv] == JV_CONSTANT_Double
497 || tags[cv] == JV_CONSTANT_String))
499 handleConstantValueAttribute (field_index, cv);
501 else
503 throw_class_format_error ("erroneous ConstantValue attribute");
506 if (length != 2)
507 throw_class_format_error ("erroneous ConstantValue attribute");
510 else
512 skip (length);
516 void _Jv_ClassReader::read_methods ()
518 int methods_count = read2u ();
520 handleMethodsBegin (methods_count);
522 for (int i = 0; i < methods_count; i++)
524 int access_flags = read2u ();
525 int name_index = read2u ();
526 int descriptor_index = read2u ();
527 int attributes_count = read2u ();
529 check_tag (name_index, JV_CONSTANT_Utf8);
530 prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
532 check_tag (descriptor_index, JV_CONSTANT_Utf8);
533 prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
535 handleMethod (i, access_flags, name_index,
536 descriptor_index);
538 for (int j = 0; j < attributes_count; j++)
540 read_one_method_attribute (i);
544 handleMethodsEnd ();
547 void _Jv_ClassReader::read_one_method_attribute (int method_index)
549 int name = read2u ();
550 int length = read4 ();
552 if (is_attribute_name (name, "Exceptions"))
554 _Jv_Method *method = reinterpret_cast<_Jv_Method *>
555 (&def->methods[method_index]);
556 if (method->throws != NULL)
557 throw_class_format_error ("only one Exceptions attribute allowed per method");
559 int num_exceptions = read2u ();
560 _Jv_Utf8Const **exceptions =
561 (_Jv_Utf8Const **) _Jv_AllocBytes ((num_exceptions + 1)
562 * sizeof (_Jv_Utf8Const *));
564 int out = 0;
565 _Jv_word *pool_data = def->constants.data;
566 for (int i = 0; i < num_exceptions; ++i)
568 int ndx = read2u ();
569 // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
570 if (ndx != 0)
572 check_tag (ndx, JV_CONSTANT_Class);
573 exceptions[out++] = pool_data[ndx].utf8;
576 exceptions[out] = NULL;
577 method->throws = exceptions;
580 else if (is_attribute_name (name, "Code"))
582 int start_off = pos;
583 int max_stack = read2u ();
584 int max_locals = read2u ();
585 int code_length = read4 ();
587 int code_start = pos;
588 skip (code_length);
589 int exception_table_length = read2u ();
591 handleCodeAttribute (method_index,
592 max_stack, max_locals,
593 code_start, code_length,
594 exception_table_length);
597 for (int i = 0; i < exception_table_length; i++)
599 int start_pc = read2u ();
600 int end_pc = read2u ();
601 int handler_pc = read2u ();
602 int catch_type = read2u ();
604 if (start_pc > end_pc
605 || start_pc < 0
606 // END_PC can be equal to CODE_LENGTH.
607 // See JVM Spec 4.7.4.
608 || end_pc > code_length
609 || handler_pc >= code_length)
610 throw_class_format_error ("erroneous exception handler info");
612 if (! (tags[catch_type] == JV_CONSTANT_Class
613 || tags[catch_type] == 0))
615 throw_class_format_error ("erroneous exception handler info");
618 handleExceptionTableEntry (method_index,
620 start_pc,
621 end_pc,
622 handler_pc,
623 catch_type);
627 int attributes_count = read2u ();
629 for (int i = 0; i < attributes_count; i++)
631 read_one_code_attribute (method_index);
634 if ((pos - start_off) != length)
635 throw_class_format_error ("code attribute too short");
638 else
640 /* ignore unknown attributes */
641 skip (length);
645 void _Jv_ClassReader::read_one_code_attribute (int method_index)
647 int name = read2u ();
648 int length = read4 ();
649 if (is_attribute_name (name, "LineNumberTable"))
651 _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
652 (def_interp->interpreted_methods[method_index]);
653 if (method->line_table != NULL)
654 throw_class_format_error ("Method already has LineNumberTable");
656 int table_len = read2u ();
657 _Jv_LineTableEntry* table
658 = (_Jv_LineTableEntry *) _Jv_AllocBytes (table_len
659 * sizeof (_Jv_LineTableEntry));
660 for (int i = 0; i < table_len; i++)
662 table[i].bytecode_pc = read2u ();
663 table[i].line = read2u ();
665 method->line_table_len = table_len;
666 method->line_table = table;
668 else
670 /* ignore unknown code attributes */
671 skip (length);
675 void _Jv_ClassReader::read_one_class_attribute ()
677 int name = read2u ();
678 int length = read4 ();
679 if (is_attribute_name (name, "SourceFile"))
681 int source_index = read2u ();
682 check_tag (source_index, JV_CONSTANT_Utf8);
683 prepare_pool_entry (source_index, JV_CONSTANT_Utf8);
684 def_interp->source_file_name = _Jv_NewStringUtf8Const
685 (def->constants.data[source_index].utf8);
687 else
689 /* Currently, we ignore most class attributes.
690 FIXME: Add inner-classes attributes support. */
691 skip (length);
698 /* this section defines the semantic actions of the parser */
700 void _Jv_ClassReader::handleConstantPool ()
702 /** now, we actually define the class' constant pool */
704 jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
705 _Jv_word *pool_data
706 = (_Jv_word*) _Jv_AllocRawObj (pool_count * sizeof (_Jv_word));
708 def->constants.tags = pool_tags;
709 def->constants.data = pool_data;
710 def->constants.size = pool_count;
712 // Here we make a pass to collect the strings! We do this, because
713 // internally in the GCJ runtime, classes are encoded with .'s not /'s.
714 // Therefore, we first collect the strings, and then translate the rest
715 // of the utf8-entries (thus not representing strings) from /-notation
716 // to .-notation.
717 for (int i = 1; i < pool_count; i++)
719 if (tags[i] == JV_CONSTANT_String)
721 unsigned char* str_data = bytes + offsets [i];
722 int utf_index = get2u (str_data);
723 check_tag (utf_index, JV_CONSTANT_Utf8);
724 unsigned char *utf_data = bytes + offsets[utf_index];
725 int len = get2u (utf_data);
726 pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
727 pool_tags[i] = JV_CONSTANT_String;
729 else
731 pool_tags[i] = JV_CONSTANT_Undefined;
735 // and now, we scan everything else but strings & utf8-entries. This
736 // leaves out those utf8-entries which are not used; which will be left
737 // with a tag of JV_CONSTANT_Undefined in the class definition.
738 for (int index = 1; index < pool_count; index++)
740 switch (tags[index])
742 case JV_CONSTANT_Undefined:
743 case JV_CONSTANT_String:
744 case JV_CONSTANT_Utf8:
745 continue;
747 default:
748 prepare_pool_entry (index, tags[index]);
754 /* this is a recursive procedure, which will prepare pool entries as needed.
755 Which is how we avoid initializing those entries which go unused. */
756 void
757 _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
759 /* these two, pool_data and pool_tags, point into the class
760 structure we are currently defining */
762 unsigned char *pool_tags = (unsigned char*) def->constants.tags;
763 _Jv_word *pool_data = def->constants.data;
765 /* this entry was already prepared */
766 if (pool_tags[index] == this_tag)
767 return;
769 /* this_data points to the constant-pool information for the current
770 constant-pool entry */
772 unsigned char *this_data = bytes + offsets[index];
774 switch (this_tag)
776 case JV_CONSTANT_Utf8:
778 // If we came here, it is because some other tag needs this
779 // utf8-entry for type information! Thus, we translate /'s to .'s in
780 // order to accomondate gcj's internal representation.
782 int len = get2u (this_data);
783 char *buffer = (char*) __builtin_alloca (len);
784 char *s = ((char*) this_data)+2;
786 /* FIXME: avoid using a buffer here */
787 for (int i = 0; i < len; i++)
789 if (s[i] == '/')
790 buffer[i] = '.';
791 else
792 buffer[i] = (char) s[i];
795 pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
796 pool_tags[index] = JV_CONSTANT_Utf8;
798 break;
800 case JV_CONSTANT_Class:
802 int utf_index = get2u (this_data);
803 check_tag (utf_index, JV_CONSTANT_Utf8);
804 prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
806 if (verify)
807 verify_classname (pool_data[utf_index].utf8);
809 pool_data[index].utf8 = pool_data[utf_index].utf8;
810 pool_tags[index] = JV_CONSTANT_Class;
812 break;
814 case JV_CONSTANT_String:
815 // already handled before...
816 break;
818 case JV_CONSTANT_Fieldref:
819 case JV_CONSTANT_Methodref:
820 case JV_CONSTANT_InterfaceMethodref:
822 int class_index = get2u (this_data);
823 int nat_index = get2u (this_data+2);
825 check_tag (class_index, JV_CONSTANT_Class);
826 prepare_pool_entry (class_index, JV_CONSTANT_Class);
828 check_tag (nat_index, JV_CONSTANT_NameAndType);
829 prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
831 // here, verify the signature and identifier name
832 if (verify)
834 _Jv_ushort name_index, type_index;
835 _Jv_loadIndexes (&pool_data[nat_index],
836 name_index, type_index);
838 if (this_tag == JV_CONSTANT_Fieldref)
839 verify_field_signature (pool_data[type_index].utf8);
840 else
841 verify_method_signature (pool_data[type_index].utf8);
843 _Jv_Utf8Const* name = pool_data[name_index].utf8;
845 if (this_tag != JV_CONSTANT_Fieldref
846 && ( _Jv_equalUtf8Consts (name, clinit_name)
847 || _Jv_equalUtf8Consts (name, init_name)))
848 /* ignore */;
849 else
850 verify_identifier (pool_data[name_index].utf8);
853 _Jv_storeIndexes (&pool_data[index], class_index, nat_index);
854 pool_tags[index] = this_tag;
856 break;
858 case JV_CONSTANT_NameAndType:
860 _Jv_ushort name_index = get2u (this_data);
861 _Jv_ushort type_index = get2u (this_data+2);
863 check_tag (name_index, JV_CONSTANT_Utf8);
864 prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
866 check_tag (type_index, JV_CONSTANT_Utf8);
867 prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
869 _Jv_storeIndexes (&pool_data[index], name_index, type_index);
870 pool_tags[index] = JV_CONSTANT_NameAndType;
872 break;
874 case JV_CONSTANT_Float:
876 jfloat f = java::lang::Float::intBitsToFloat ((jint) get4 (this_data));
877 _Jv_storeFloat (&pool_data[index], f);
878 pool_tags[index] = JV_CONSTANT_Float;
880 break;
882 case JV_CONSTANT_Integer:
884 int i = get4 (this_data);
885 _Jv_storeInt (&pool_data[index], i);
886 pool_tags[index] = JV_CONSTANT_Integer;
888 break;
890 case JV_CONSTANT_Double:
892 jdouble d
893 = java::lang::Double::longBitsToDouble ((jlong) get8 (this_data));
894 _Jv_storeDouble (&pool_data[index], d);
895 pool_tags[index] = JV_CONSTANT_Double;
897 break;
899 case JV_CONSTANT_Long:
901 jlong i = get8 (this_data);
902 _Jv_storeLong (&pool_data[index], i);
903 pool_tags[index] = JV_CONSTANT_Long;
905 break;
907 default:
908 throw_class_format_error ("erroneous constant pool tag");
913 void
914 _Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_class)
916 using namespace java::lang::reflect;
918 unsigned char *pool_tags = (unsigned char*) def->constants.tags;
919 _Jv_word *pool_data = def->constants.data;
921 check_tag (this_class, JV_CONSTANT_Class);
922 _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
924 // was ClassLoader.defineClass called with an expected class name?
925 if (def->name == 0)
927 jclass orig = def->loader->findLoadedClass(loadedName->toString());
929 if (orig == 0)
931 def->name = loadedName;
933 else
935 jstring msg = JvNewStringUTF ("anonymous "
936 "class data denotes "
937 "existing class ");
938 msg = msg->concat (orig->getName ());
940 throw_no_class_def_found_error (msg);
944 // assert that the loaded class has the expected name, 5.3.5
945 else if (! _Jv_equalUtf8Consts (loadedName, def->name))
947 jstring msg = JvNewStringUTF ("loaded class ");
948 msg = msg->concat (def->getName ());
949 msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
950 jstring klass_name = loadedName->toString();
951 msg = msg->concat (klass_name);
953 throw_no_class_def_found_error (msg);
956 def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
957 pool_data[this_class].clazz = def;
958 pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
960 if (super_class == 0)
962 // Note that this is ok if we are defining java.lang.Object.
963 // But there is no way to have this class be interpreted.
964 throw_class_format_error ("no superclass reference");
967 def->state = JV_STATE_PRELOADING;
969 // Register this class with its defining loader as well (despite the
970 // name of the function we're calling), so that super class lookups
971 // work properly. If there is an error, our caller will unregister
972 // this class from the class loader. Also, we don't need to hold a
973 // lock here, as our caller has acquired it.
974 _Jv_RegisterInitiatingLoader (def, def->loader);
976 // Note that we found a name so that unregistration can happen if
977 // needed.
978 *found_name = def->name;
980 if (super_class != 0)
982 // Load the superclass.
983 check_tag (super_class, JV_CONSTANT_Class);
984 _Jv_Utf8Const* super_name = pool_data[super_class].utf8;
986 // Load the superclass using our defining loader.
987 jclass the_super = _Jv_FindClass (super_name, def->loader);
989 // This will establish that we are allowed to be a subclass,
990 // and check for class circularity error.
991 checkExtends (def, the_super);
993 // Note: for an interface we will find Object as the
994 // superclass. We still check it above to ensure class file
995 // validity, but we simply assign `null' to the actual field in
996 // this case.
997 def->superclass = (((access_flags & Modifier::INTERFACE))
998 ? NULL : the_super);
999 pool_data[super_class].clazz = the_super;
1000 pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
1003 // Now we've come past the circularity problem, we can
1004 // now say that we're loading.
1006 def->state = JV_STATE_LOADING;
1007 def->notifyAll ();
1010 ///// Implements the checks described in sect. 5.3.5.3
1011 void
1012 _Jv_ClassReader::checkExtends (jclass sub, jclass super)
1014 using namespace java::lang::reflect;
1016 _Jv_Linker::wait_for_state (super, JV_STATE_LOADING);
1018 // Having an interface or a final class as a superclass is no good.
1019 if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
1021 throw_incompatible_class_change_error (sub->getName ());
1024 // If the super class is not public, we need to check some more.
1025 if ((super->accflags & Modifier::PUBLIC) == 0)
1027 // With package scope, the classes must have the same class
1028 // loader.
1029 if ( sub->loader != super->loader
1030 || !_Jv_ClassNameSamePackage (sub->name, super->name))
1032 throw_incompatible_class_change_error (sub->getName ());
1036 for (; super != 0; super = super->getSuperclass ())
1038 if (super == sub)
1039 throw_class_circularity_error (sub->getName ());
1045 void _Jv_ClassReader::handleInterfacesBegin (int count)
1047 def->interfaces = (jclass*) _Jv_AllocRawObj (count*sizeof (jclass));
1048 def->interface_count = count;
1051 void _Jv_ClassReader::handleInterface (int if_number, int offset)
1053 _Jv_word * pool_data = def->constants.data;
1054 unsigned char * pool_tags = (unsigned char*) def->constants.tags;
1056 jclass the_interface;
1058 if (pool_tags[offset] == JV_CONSTANT_Class)
1060 _Jv_Utf8Const* name = pool_data[offset].utf8;
1061 the_interface = _Jv_FindClass (name, def->loader);
1063 else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
1065 the_interface = pool_data[offset].clazz;
1067 else
1069 throw_no_class_def_found_error ("erroneous constant pool tag");
1072 // checks the validity of the_interface, and that we are in fact
1073 // allowed to implement that interface.
1074 checkImplements (def, the_interface);
1076 pool_data[offset].clazz = the_interface;
1077 pool_tags[offset] = JV_CONSTANT_ResolvedClass;
1079 def->interfaces[if_number] = the_interface;
1082 void
1083 _Jv_ClassReader::checkImplements (jclass sub, jclass super)
1085 using namespace java::lang::reflect;
1087 // well, it *must* be an interface
1088 if ((super->accflags & Modifier::INTERFACE) == 0)
1090 throw_incompatible_class_change_error (sub->getName ());
1093 // if it has package scope, it must also be defined by the
1094 // same loader.
1095 if ((super->accflags & Modifier::PUBLIC) == 0)
1097 if ( sub->loader != super->loader
1098 || !_Jv_ClassNameSamePackage (sub->name, super->name))
1100 throw_incompatible_class_change_error (sub->getName ());
1104 // FIXME: add interface circularity check here
1105 if (sub == super)
1107 throw_class_circularity_error (sub->getName ());
1111 void _Jv_ClassReader::handleFieldsBegin (int count)
1113 def->fields = (_Jv_Field*) _Jv_AllocRawObj (count * sizeof (_Jv_Field));
1114 def->field_count = count;
1115 def_interp->field_initializers
1116 = (_Jv_ushort*) _Jv_AllocRawObj (count * sizeof (_Jv_ushort));
1117 for (int i = 0; i < count; i++)
1118 def_interp->field_initializers[i] = (_Jv_ushort) 0;
1121 void _Jv_ClassReader::handleField (int field_no,
1122 int flags,
1123 int name,
1124 int desc)
1126 using namespace java::lang::reflect;
1128 _Jv_word *pool_data = def->constants.data;
1130 _Jv_Field *field = &def->fields[field_no];
1131 _Jv_Utf8Const *field_name = pool_data[name].utf8;
1133 field->name = field_name;
1135 // Ignore flags we don't know about.
1136 field->flags = flags & Modifier::ALL_FLAGS;
1138 _Jv_Utf8Const* sig = pool_data[desc].utf8;
1140 if (verify)
1142 verify_identifier (field_name);
1144 for (int i = 0; i < field_no; ++i)
1146 if (_Jv_equalUtf8Consts (field_name, def->fields[i].name)
1147 && _Jv_equalUtf8Consts (sig,
1148 // We know the other fields are
1149 // unresolved.
1150 (_Jv_Utf8Const *) def->fields[i].type))
1151 throw_class_format_error ("duplicate field name");
1154 // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1155 if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
1156 +((field->flags & Modifier::PRIVATE) ? 1 : 0)
1157 +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
1158 throw_class_format_error ("erroneous field access flags");
1160 // FIXME: JVM spec S4.5: Verify ACC_FINAL and ACC_VOLATILE are not
1161 // both set. Verify modifiers for interface fields.
1165 if (verify)
1166 verify_field_signature (sig);
1168 // field->type is really a jclass, but while it is still
1169 // unresolved we keep an _Jv_Utf8Const* instead.
1170 field->type = (jclass) sig;
1171 field->flags |= _Jv_FIELD_UNRESOLVED_FLAG;
1172 field->u.boffset = 0;
1176 void _Jv_ClassReader::handleConstantValueAttribute (int field_index,
1177 int value)
1179 using namespace java::lang::reflect;
1181 _Jv_Field *field = &def->fields[field_index];
1183 if ((field->flags & (Modifier::STATIC
1184 | Modifier::FINAL
1185 | Modifier::PRIVATE)) == 0)
1187 // Ignore, as per vmspec #4.7.2
1188 return;
1191 // do not allow multiple constant fields!
1192 if (field->flags & _Jv_FIELD_CONSTANT_VALUE)
1193 throw_class_format_error ("field has multiple ConstantValue attributes");
1195 field->flags |= _Jv_FIELD_CONSTANT_VALUE;
1196 def_interp->field_initializers[field_index] = value;
1198 /* type check the initializer */
1200 if (value <= 0 || value >= pool_count)
1201 throw_class_format_error ("erroneous ConstantValue attribute");
1203 /* FIXME: do the rest */
1206 void _Jv_ClassReader::handleFieldsEnd ()
1208 using namespace java::lang::reflect;
1210 // We need to reorganize the fields so that the static ones are first,
1211 // to conform to GCJ class layout.
1213 int low = 0;
1214 int high = def->field_count-1;
1215 _Jv_Field *fields = def->fields;
1216 _Jv_ushort *inits = def_interp->field_initializers;
1218 // this is kind of a raw version of quicksort.
1219 while (low < high)
1221 // go forward on low, while it's a static
1222 while (low < high && (fields[low].flags & Modifier::STATIC) != 0)
1223 low++;
1225 // go backwards on high, while it's a non-static
1226 while (low < high && (fields[high].flags & Modifier::STATIC) == 0)
1227 high--;
1229 if (low==high)
1230 break;
1232 _Jv_Field tmp = fields[low];
1233 _Jv_ushort itmp = inits[low];
1235 fields[low] = fields[high];
1236 inits[low] = inits[high];
1238 fields[high] = tmp;
1239 inits[high] = itmp;
1241 high -= 1;
1242 low += 1;
1245 if ((fields[low].flags & Modifier::STATIC) != 0)
1246 low += 1;
1248 def->static_field_count = low;
1253 void
1254 _Jv_ClassReader::handleMethodsBegin (int count)
1256 def->methods = (_Jv_Method *) _Jv_AllocRawObj (sizeof (_Jv_Method) * count);
1258 def_interp->interpreted_methods
1259 = (_Jv_MethodBase **) _Jv_AllocRawObj (sizeof (_Jv_MethodBase *)
1260 * count);
1262 for (int i = 0; i < count; i++)
1264 def_interp->interpreted_methods[i] = 0;
1265 def->methods[i].index = (_Jv_ushort) -1;
1268 def->method_count = count;
1272 void _Jv_ClassReader::handleMethod
1273 (int mth_index, int accflags, int name, int desc)
1275 using namespace java::lang::reflect;
1277 _Jv_word *pool_data = def->constants.data;
1278 _Jv_Method *method = &def->methods[mth_index];
1280 check_tag (name, JV_CONSTANT_Utf8);
1281 prepare_pool_entry (name, JV_CONSTANT_Utf8);
1282 method->name = pool_data[name].utf8;
1284 check_tag (desc, JV_CONSTANT_Utf8);
1285 prepare_pool_entry (desc, JV_CONSTANT_Utf8);
1286 method->signature = pool_data[desc].utf8;
1288 // ignore unknown flags
1289 method->accflags = accflags & Modifier::ALL_FLAGS;
1291 // Initialize...
1292 method->ncode = 0;
1293 method->throws = NULL;
1295 if (verify)
1297 if (_Jv_equalUtf8Consts (method->name, clinit_name)
1298 || _Jv_equalUtf8Consts (method->name, init_name))
1299 /* ignore */;
1300 else
1301 verify_identifier (method->name);
1303 verify_method_signature (method->signature);
1305 for (int i = 0; i < mth_index; ++i)
1307 if (_Jv_equalUtf8Consts (method->name, def->methods[i].name)
1308 && _Jv_equalUtf8Consts (method->signature,
1309 def->methods[i].signature))
1310 throw_class_format_error ("duplicate method");
1313 // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1314 if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
1315 +((method->accflags & Modifier::PRIVATE) ? 1 : 0)
1316 +((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
1317 throw_class_format_error ("erroneous method access flags");
1319 // FIXME: JVM spec S4.6: if ABSTRACT modifier is set, verify other
1320 // flags are not set. Verify flags for interface methods. Verify
1321 // modifiers for initializers.
1325 void _Jv_ClassReader::handleCodeAttribute
1326 (int method_index, int max_stack, int max_locals,
1327 int code_start, int code_length, int exc_table_length)
1329 int size = _Jv_InterpMethod::size (exc_table_length, code_length);
1330 _Jv_InterpMethod *method =
1331 (_Jv_InterpMethod*) (_Jv_AllocRawObj (size));
1333 method->max_stack = max_stack;
1334 method->max_locals = max_locals;
1335 method->code_length = code_length;
1336 method->exc_count = exc_table_length;
1337 method->is_15 = is_15;
1338 method->defining_class = def;
1339 method->self = &def->methods[method_index];
1340 method->prepared = NULL;
1341 method->line_table_len = 0;
1342 method->line_table = NULL;
1345 // grab the byte code!
1346 memcpy ((void*) method->bytecode (),
1347 (void*) (bytes+code_start),
1348 code_length);
1350 def_interp->interpreted_methods[method_index] = method;
1352 if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
1354 // Precompute the ncode field for a static method. This lets us
1355 // call a static method of an interpreted class from precompiled
1356 // code without first resolving the class (that will happen
1357 // during class initialization instead).
1358 method->self->ncode = method->ncode ();
1362 void _Jv_ClassReader::handleExceptionTableEntry
1363 (int method_index, int exc_index,
1364 int start_pc, int end_pc, int handler_pc, int catch_type)
1366 _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1367 (def_interp->interpreted_methods[method_index]);
1368 _Jv_InterpException *exc = method->exceptions ();
1370 exc[exc_index].start_pc.i = start_pc;
1371 exc[exc_index].end_pc.i = end_pc;
1372 exc[exc_index].handler_pc.i = handler_pc;
1373 exc[exc_index].handler_type.i = catch_type;
1376 void _Jv_ClassReader::handleMethodsEnd ()
1378 using namespace java::lang::reflect;
1380 for (int i = 0; i < def->method_count; i++)
1382 _Jv_Method *method = &def->methods[i];
1383 if ((method->accflags & Modifier::NATIVE) != 0)
1385 if (def_interp->interpreted_methods[i] != 0)
1386 throw_class_format_error ("code provided for native method");
1387 else
1389 _Jv_JNIMethod *m = (_Jv_JNIMethod *)
1390 _Jv_AllocRawObj (sizeof (_Jv_JNIMethod));
1391 m->defining_class = def;
1392 m->self = method;
1393 m->function = NULL;
1394 def_interp->interpreted_methods[i] = m;
1396 if ((method->accflags & Modifier::STATIC))
1398 // Precompute the ncode field for a static method.
1399 // This lets us call a static method of an
1400 // interpreted class from precompiled code without
1401 // first resolving the class (that will happen
1402 // during class initialization instead).
1403 method->ncode = m->ncode ();
1407 else if ((method->accflags & Modifier::ABSTRACT) != 0)
1409 if (def_interp->interpreted_methods[i] != 0)
1410 throw_class_format_error ("code provided for abstract method");
1411 method->ncode = (void *) &_Jv_ThrowAbstractMethodError;
1413 else
1415 if (def_interp->interpreted_methods[i] == 0)
1416 throw_class_format_error ("method with no code");
1421 void _Jv_ClassReader::throw_class_format_error (const char *msg)
1423 jstring str;
1424 if (def->name != NULL)
1426 jsize mlen = strlen (msg);
1427 unsigned char* data = (unsigned char*) def->name->chars();
1428 int ulen = def->name->len();
1429 unsigned char* limit = data + ulen;
1430 jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
1431 jsize len = nlen + mlen + 3;
1432 str = JvAllocString(len);
1433 jchar *chrs = JvGetStringChars(str);
1434 while (data < limit)
1435 *chrs++ = UTF8_GET(data, limit);
1436 *chrs++ = ' ';
1437 *chrs++ = '(';
1438 for (;;)
1440 char c = *msg++;
1441 if (c == 0)
1442 break;
1443 *chrs++ = c & 0xFFFF;
1445 *chrs++ = ')';
1447 else
1448 str = JvNewStringLatin1 (msg);
1449 ::throw_class_format_error (str);
1452 /** Here we define the exceptions that can be thrown */
1454 static void
1455 throw_no_class_def_found_error (jstring msg)
1457 throw (msg
1458 ? new java::lang::NoClassDefFoundError (msg)
1459 : new java::lang::NoClassDefFoundError);
1462 static void
1463 throw_no_class_def_found_error (const char *msg)
1465 throw_no_class_def_found_error (JvNewStringLatin1 (msg));
1468 static void
1469 throw_class_format_error (jstring msg)
1471 throw (msg
1472 ? new java::lang::ClassFormatError (msg)
1473 : new java::lang::ClassFormatError);
1476 static void
1477 throw_internal_error (const char *msg)
1479 throw new java::lang::InternalError (JvNewStringLatin1 (msg));
1482 static void
1483 throw_incompatible_class_change_error (jstring msg)
1485 throw new java::lang::IncompatibleClassChangeError (msg);
1488 static void
1489 throw_class_circularity_error (jstring msg)
1491 throw new java::lang::ClassCircularityError (msg);
1494 #endif /* INTERPRETER */
1498 /** This section takes care of verifying integrity of identifiers,
1499 signatures, field ddescriptors, and class names */
1501 #define UTF8_PEEK(PTR, LIMIT) \
1502 ({ unsigned char* xxkeep = (PTR); \
1503 int xxch = UTF8_GET(PTR,LIMIT); \
1504 PTR = xxkeep; xxch; })
1506 /* Verify one element of a type descriptor or signature. */
1507 static unsigned char*
1508 _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
1510 if (ptr >= limit)
1511 return 0;
1513 int ch = UTF8_GET (ptr, limit);
1515 switch (ch)
1517 case 'V':
1518 if (! void_ok)
1519 return 0;
1521 case 'S': case 'B': case 'I': case 'J':
1522 case 'Z': case 'C': case 'F': case 'D':
1523 break;
1525 case 'L':
1527 unsigned char *start = ptr, *end;
1530 if (ptr > limit)
1531 return 0;
1533 end = ptr;
1535 if ((ch = UTF8_GET (ptr, limit)) == -1)
1536 return 0;
1539 while (ch != ';');
1540 if (! _Jv_VerifyClassName (start, (unsigned short) (end-start)))
1541 return 0;
1543 break;
1545 case '[':
1546 return _Jv_VerifyOne (ptr, limit, false);
1547 break;
1549 default:
1550 return 0;
1553 return ptr;
1556 /* Verification and loading procedures. */
1557 bool
1558 _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
1560 unsigned char* ptr = (unsigned char*) sig->chars();
1561 unsigned char* limit = ptr + sig->len();
1563 ptr = _Jv_VerifyOne (ptr, limit, false);
1565 return ptr == limit;
1568 bool
1569 _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
1571 unsigned char* ptr = (unsigned char*) sig->chars();
1572 unsigned char* limit = ptr + sig->len();
1574 if (ptr == limit || UTF8_GET(ptr,limit) != '(')
1575 return false;
1577 while (ptr && UTF8_PEEK (ptr, limit) != ')')
1578 ptr = _Jv_VerifyOne (ptr, limit, false);
1580 if (! ptr || UTF8_GET (ptr, limit) != ')')
1581 return false;
1583 // get the return type
1584 ptr = _Jv_VerifyOne (ptr, limit, true);
1586 return ptr == limit;
1589 /* We try to avoid calling the Character methods all the time, in
1590 fact, they will only be called for non-standard things. */
1591 static __inline__ int
1592 is_identifier_start (int c)
1594 unsigned int ch = (unsigned)c;
1596 if ((ch - 0x41U) < 29U) /* A ... Z */
1597 return 1;
1598 if ((ch - 0x61U) < 29U) /* a ... z */
1599 return 1;
1600 if (ch == 0x5FU) /* _ */
1601 return 1;
1603 return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1606 static __inline__ int
1607 is_identifier_part (int c)
1609 unsigned int ch = (unsigned)c;
1611 if ((ch - 0x41U) < 29U) /* A ... Z */
1612 return 1;
1613 if ((ch - 0x61U) < 29U) /* a ... z */
1614 return 1;
1615 if ((ch - 0x30) < 10U) /* 0 .. 9 */
1616 return 1;
1617 if (ch == 0x5FU || ch == 0x24U) /* _ $ */
1618 return 1;
1620 return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1623 bool
1624 _Jv_VerifyIdentifier (_Jv_Utf8Const* name)
1626 unsigned char *ptr = (unsigned char*) name->chars();
1627 unsigned char *limit = (unsigned char*) name->limit();
1628 int ch;
1630 if ((ch = UTF8_GET (ptr, limit))==-1
1631 || ! is_identifier_start (ch))
1632 return false;
1634 while (ptr != limit)
1636 if ((ch = UTF8_GET (ptr, limit))==-1
1637 || ! is_identifier_part (ch))
1638 return false;
1640 return true;
1643 bool
1644 _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
1646 unsigned char *limit = ptr+length;
1647 int ch;
1649 if ('[' == UTF8_PEEK (ptr, limit))
1651 unsigned char *end = _Jv_VerifyOne (++ptr, limit, false);
1652 // _Jv_VerifyOne must leave us looking at the terminating nul
1653 // byte.
1654 if (! end || *end)
1655 return false;
1656 else
1657 return true;
1660 next_level:
1661 for (;;) {
1662 if ((ch = UTF8_GET (ptr, limit))==-1)
1663 return false;
1664 if (! is_identifier_start (ch))
1665 return false;
1666 for (;;) {
1667 if (ptr == limit)
1668 return true;
1669 else if ((ch = UTF8_GET (ptr, limit))==-1)
1670 return false;
1671 else if (ch == '.')
1672 goto next_level;
1673 else if (! is_identifier_part (ch))
1674 return false;
1679 bool
1680 _Jv_VerifyClassName (_Jv_Utf8Const *name)
1682 return _Jv_VerifyClassName ((unsigned char*)name->chars(), name->len());
1685 /* Returns true, if NAME1 and NAME2 represent classes in the same
1686 package. Neither NAME2 nor NAME2 may name an array type. */
1687 bool
1688 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
1690 unsigned char* ptr1 = (unsigned char*) name1->chars();
1691 unsigned char* limit1 = (unsigned char*) name1->limit();
1693 unsigned char* last1 = ptr1;
1695 // scan name1, and find the last occurrence of '.'
1696 while (ptr1 < limit1) {
1697 int ch1 = UTF8_GET (ptr1, limit1);
1699 if (ch1 == '.')
1700 last1 = ptr1;
1702 else if (ch1 == -1)
1703 return false;
1706 // Now the length of NAME1's package name is LEN.
1707 int len = last1 - (unsigned char*) name1->chars();
1709 // If this is longer than NAME2, then we're off.
1710 if (len > name2->len())
1711 return false;
1713 // Then compare the first len bytes for equality.
1714 if (memcmp ((void*) name1->chars(), (void*) name2->chars(), len) == 0)
1716 // Check that there are no .'s after position LEN in NAME2.
1718 unsigned char* ptr2 = (unsigned char*) name2->chars() + len;
1719 unsigned char* limit2 = (unsigned char*) name2->limit();
1721 while (ptr2 < limit2)
1723 int ch2 = UTF8_GET (ptr2, limit2);
1724 if (ch2 == -1 || ch2 == '.')
1725 return false;
1727 return true;
1729 return false;