2005-05-23 Andreas Krebbel <krebbel1@de.ibm.com>
[official-gcc.git] / libjava / defineclass.cc
blob111b1fb2ca2fb83120b23cdb293c8f4531783524
1 // defineclass.cc - defining a class from .class format.
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 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 (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 (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 {
75 // do verification? Currently, there is no option to disable this.
76 // This flag just controls the verificaiton done by the class loader;
77 // i.e., checking the integrity of the constant pool; and it is
78 // allways on. You always want this as far as I can see, but it also
79 // controls weither identifiers and type descriptors/signatures are
80 // verified as legal. This could be somewhat more expensive since it
81 // will call Character.isJavaIdentifier{Start,Part} for each character
82 // in any identifier (field name or method name) it comes by. Thus,
83 // it might be useful to turn off this verification for classes that
84 // come from a trusted source. However, for GCJ, trusted classes are
85 // most likely to be linked in.
87 bool verify;
89 // input data.
90 unsigned char *bytes;
91 int len;
93 // current input position
94 int pos;
96 // the constant pool data
97 int pool_count;
98 unsigned char *tags;
99 unsigned int *offsets;
101 // the class to define (see java-interp.h)
102 jclass def;
104 // the classes associated interpreter data.
105 _Jv_InterpClass *def_interp;
107 /* check that the given number of input bytes are available */
108 inline void check (int num)
110 if (pos + num > len)
111 throw_class_format_error ("Premature end of data");
114 /* skip a given number of bytes in input */
115 inline void skip (int num)
117 check (num);
118 pos += num;
121 /* read an unsignend 1-byte unit */
122 inline static jint get1u (unsigned char* bytes)
124 return bytes[0];
127 /* read an unsigned 1-byte unit */
128 inline jint read1u ()
130 skip (1);
131 return get1u (bytes+pos-1);
134 /* read an unsigned 2-byte unit */
135 inline static jint get2u (unsigned char *bytes)
137 return (((jint)bytes[0]) << 8) | ((jint)bytes[1]);
140 /* read an unsigned 2-byte unit */
141 inline jint read2u ()
143 skip (2);
144 return get2u (bytes+pos-2);
147 /* read a 4-byte unit */
148 static jint get4 (unsigned char *bytes)
150 return (((jint)bytes[0]) << 24)
151 | (((jint)bytes[1]) << 16)
152 | (((jint)bytes[2]) << 8)
153 | (((jint)bytes[3]) << 0);
156 /* read a 4-byte unit, (we don't do that quite so often) */
157 inline jint read4 ()
159 skip (4);
160 return get4 (bytes+pos-4);
163 /* read a 8-byte unit */
164 static jlong get8 (unsigned char* bytes)
166 return (((jlong)bytes[0]) << 56)
167 | (((jlong)bytes[1]) << 48)
168 | (((jlong)bytes[2]) << 40)
169 | (((jlong)bytes[3]) << 32)
170 | (((jlong)bytes[4]) << 24)
171 | (((jlong)bytes[5]) << 16)
172 | (((jlong)bytes[6]) << 8)
173 | (((jlong)bytes[7]) << 0);
176 /* read a 8-byte unit */
177 inline jlong read8 ()
179 skip (8);
180 return get8 (bytes+pos-8);
183 inline void check_tag (int index, char expected_tag)
185 if (index < 0
186 || index > pool_count
187 || tags[index] != expected_tag)
188 throw_class_format_error ("erroneous constant pool tag");
191 inline void verify_identifier (_Jv_Utf8Const* name)
193 if (! _Jv_VerifyIdentifier (name))
194 throw_class_format_error ("erroneous identifier");
197 inline void verify_classname (unsigned char* ptr, _Jv_ushort length)
199 if (! _Jv_VerifyClassName (ptr, length))
200 throw_class_format_error ("erroneous class name");
203 inline void verify_classname (_Jv_Utf8Const *name)
205 if (! _Jv_VerifyClassName (name))
206 throw_class_format_error ("erroneous class name");
209 inline void verify_field_signature (_Jv_Utf8Const *sig)
211 if (! _Jv_VerifyFieldSignature (sig))
212 throw_class_format_error ("erroneous type descriptor");
215 inline void verify_method_signature (_Jv_Utf8Const *sig)
217 if (! _Jv_VerifyMethodSignature (sig))
218 throw_class_format_error ("erroneous type descriptor");
221 _Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length,
222 java::security::ProtectionDomain *pd)
224 if (klass == 0 || length < 0 || offset+length > data->length)
225 throw_internal_error ("arguments to _Jv_DefineClass");
227 verify = true;
228 bytes = (unsigned char*) (elements (data)+offset);
229 len = length;
230 pos = 0;
231 def = klass;
233 def->size_in_bytes = -1;
234 def->vtable_method_count = -1;
235 def->engine = &_Jv_soleInterpreterEngine;
236 def->protectionDomain = pd;
239 /** and here goes the parser members defined out-of-line */
240 void parse ();
241 void read_constpool ();
242 void prepare_pool_entry (int index, unsigned char tag);
243 void read_fields ();
244 void read_methods ();
245 void read_one_class_attribute ();
246 void read_one_method_attribute (int method);
247 void read_one_code_attribute (int method);
248 void read_one_field_attribute (int field);
249 void throw_class_format_error (char *msg);
251 /** check an utf8 entry, without creating a Utf8Const object */
252 bool is_attribute_name (int index, char *name);
254 /** here goes the class-loader members defined out-of-line */
255 void handleConstantPool ();
256 void handleClassBegin (int, int, int);
257 void handleInterfacesBegin (int);
258 void handleInterface (int, int);
259 void handleFieldsBegin (int);
260 void handleField (int, int, int, int);
261 void handleFieldsEnd ();
262 void handleConstantValueAttribute (int,int);
263 void handleMethodsBegin (int);
264 void handleMethod (int, int, int, int);
265 void handleMethodsEnd ();
266 void handleCodeAttribute (int, int, int, int, int, int);
267 void handleExceptionTableEntry (int, int, int, int, int, int);
269 void checkExtends (jclass sub, jclass super);
270 void checkImplements (jclass sub, jclass super);
273 * FIXME: we should keep a hash table of utf8-strings, since many will
274 * be the same. It's a little tricky, however, because the hash table
275 * needs to interact gracefully with the garbage collector. Much
276 * memory is to be saved by this, however! perhaps the improvement
277 * could be implemented in prims.cc (_Jv_makeUtf8Const), since it
278 * computes the hash value anyway.
282 void
283 _Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length,
284 java::security::ProtectionDomain *pd)
286 _Jv_ClassReader reader (klass, data, offset, length, pd);
287 reader.parse();
289 /* that's it! */
293 /** This section defines the parsing/scanning of the class data */
295 void
296 _Jv_ClassReader::parse ()
298 int magic = read4 ();
300 /* FIXME: Decide which range of version numbers to allow */
302 /* int minor_version = */ read2u ();
303 /* int major_verson = */ read2u ();
305 if (magic != (int) 0xCAFEBABE)
306 throw_class_format_error ("bad magic number");
308 pool_count = read2u ();
310 read_constpool ();
312 int access_flags = read2u ();
313 int this_class = read2u ();
314 int super_class = read2u ();
316 check_tag (this_class, JV_CONSTANT_Class);
317 if (super_class != 0)
318 check_tag (super_class, JV_CONSTANT_Class);
320 handleClassBegin (access_flags, this_class, super_class);
322 // Allocate our aux_info here, after the name is set, to fulfill our
323 // contract with the collector interface.
324 def->aux_info = (void *) _Jv_AllocBytes (sizeof (_Jv_InterpClass));
325 def_interp = (_Jv_InterpClass *) def->aux_info;
327 int interfaces_count = read2u ();
329 handleInterfacesBegin (interfaces_count);
331 for (int i = 0; i < interfaces_count; i++)
333 int iface = read2u ();
334 check_tag (iface, JV_CONSTANT_Class);
335 handleInterface (i, iface);
338 read_fields ();
339 read_methods ();
341 int attributes_count = read2u ();
343 for (int i = 0; i < attributes_count; i++)
345 read_one_class_attribute ();
348 if (pos != len)
349 throw_class_format_error ("unused data before end of file");
351 // Tell everyone we're done.
352 def->state = JV_STATE_READ;
353 if (gcj::verbose_class_flag)
354 _Jv_Linker::print_class_loaded (def);
355 def->notifyAll ();
358 void _Jv_ClassReader::read_constpool ()
360 tags = (unsigned char*) _Jv_AllocBytes (pool_count);
361 offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int)
362 * pool_count) ;
364 /** first, we scan the constant pool, collecting tags and offsets */
365 tags[0] = JV_CONSTANT_Undefined;
366 offsets[0] = pos;
367 for (int c = 1; c < pool_count; c++)
369 tags[c] = read1u ();
370 offsets[c] = pos;
372 switch (tags[c])
374 case JV_CONSTANT_String:
375 case JV_CONSTANT_Class:
376 skip (2);
377 break;
379 case JV_CONSTANT_Fieldref:
380 case JV_CONSTANT_Methodref:
381 case JV_CONSTANT_InterfaceMethodref:
382 case JV_CONSTANT_NameAndType:
383 case JV_CONSTANT_Integer:
384 case JV_CONSTANT_Float:
385 skip (4);
386 break;
388 case JV_CONSTANT_Double:
389 case JV_CONSTANT_Long:
390 skip (8);
391 tags[++c] = JV_CONSTANT_Undefined;
392 break;
394 case JV_CONSTANT_Utf8:
396 int len = read2u ();
397 skip (len);
399 break;
401 case JV_CONSTANT_Unicode:
402 throw_class_format_error ("unicode not supported");
403 break;
405 default:
406 throw_class_format_error ("erroneous constant pool tag");
410 handleConstantPool ();
414 void _Jv_ClassReader::read_fields ()
416 int fields_count = read2u ();
417 handleFieldsBegin (fields_count);
419 for (int i = 0; i < fields_count; i++)
421 int access_flags = read2u ();
422 int name_index = read2u ();
423 int descriptor_index = read2u ();
424 int attributes_count = read2u ();
426 check_tag (name_index, JV_CONSTANT_Utf8);
427 prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
429 check_tag (descriptor_index, JV_CONSTANT_Utf8);
430 prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
432 handleField (i, access_flags, name_index, descriptor_index);
434 for (int j = 0; j < attributes_count; j++)
436 read_one_field_attribute (i);
440 handleFieldsEnd ();
443 bool
444 _Jv_ClassReader::is_attribute_name (int index, char *name)
446 check_tag (index, JV_CONSTANT_Utf8);
447 int len = get2u (bytes+offsets[index]);
448 if (len != (int) strlen (name))
449 return false;
450 else
451 return !memcmp (bytes+offsets[index]+2, name, len);
454 void _Jv_ClassReader::read_one_field_attribute (int field_index)
456 int name = read2u ();
457 int length = read4 ();
459 if (is_attribute_name (name, "ConstantValue"))
461 int cv = read2u ();
463 if (cv < pool_count
464 && cv > 0
465 && (tags[cv] == JV_CONSTANT_Integer
466 || tags[cv] == JV_CONSTANT_Float
467 || tags[cv] == JV_CONSTANT_Long
468 || tags[cv] == JV_CONSTANT_Double
469 || tags[cv] == JV_CONSTANT_String))
471 handleConstantValueAttribute (field_index, cv);
473 else
475 throw_class_format_error ("erroneous ConstantValue attribute");
478 if (length != 2)
479 throw_class_format_error ("erroneous ConstantValue attribute");
482 else
484 skip (length);
488 void _Jv_ClassReader::read_methods ()
490 int methods_count = read2u ();
492 handleMethodsBegin (methods_count);
494 for (int i = 0; i < methods_count; i++)
496 int access_flags = read2u ();
497 int name_index = read2u ();
498 int descriptor_index = read2u ();
499 int attributes_count = read2u ();
501 check_tag (name_index, JV_CONSTANT_Utf8);
502 prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
504 check_tag (name_index, JV_CONSTANT_Utf8);
505 prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
507 handleMethod (i, access_flags, name_index,
508 descriptor_index);
510 for (int j = 0; j < attributes_count; j++)
512 read_one_method_attribute (i);
516 handleMethodsEnd ();
519 void _Jv_ClassReader::read_one_method_attribute (int method_index)
521 int name = read2u ();
522 int length = read4 ();
524 if (is_attribute_name (name, "Exceptions"))
526 _Jv_Method *method = reinterpret_cast<_Jv_Method *>
527 (&def->methods[method_index]);
528 if (method->throws != NULL)
529 throw_class_format_error ("only one Exceptions attribute allowed per method");
531 int num_exceptions = read2u ();
532 _Jv_Utf8Const **exceptions =
533 (_Jv_Utf8Const **) _Jv_AllocBytes ((num_exceptions + 1)
534 * sizeof (_Jv_Utf8Const *));
536 int out = 0;
537 _Jv_word *pool_data = def->constants.data;
538 for (int i = 0; i < num_exceptions; ++i)
540 int ndx = read2u ();
541 // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
542 if (ndx != 0)
544 check_tag (ndx, JV_CONSTANT_Class);
545 exceptions[out++] = pool_data[ndx].utf8;
548 exceptions[out] = NULL;
549 method->throws = exceptions;
552 else if (is_attribute_name (name, "Code"))
554 int start_off = pos;
555 int max_stack = read2u ();
556 int max_locals = read2u ();
557 int code_length = read4 ();
559 int code_start = pos;
560 skip (code_length);
561 int exception_table_length = read2u ();
563 handleCodeAttribute (method_index,
564 max_stack, max_locals,
565 code_start, code_length,
566 exception_table_length);
569 for (int i = 0; i < exception_table_length; i++)
571 int start_pc = read2u ();
572 int end_pc = read2u ();
573 int handler_pc = read2u ();
574 int catch_type = read2u ();
576 if (start_pc > end_pc
577 || start_pc < 0
578 // END_PC can be equal to CODE_LENGTH.
579 // See JVM Spec 4.7.4.
580 || end_pc > code_length
581 || handler_pc >= code_length)
582 throw_class_format_error ("erroneous exception handler info");
584 if (! (tags[catch_type] == JV_CONSTANT_Class
585 || tags[catch_type] == 0))
587 throw_class_format_error ("erroneous exception handler info");
590 handleExceptionTableEntry (method_index,
592 start_pc,
593 end_pc,
594 handler_pc,
595 catch_type);
599 int attributes_count = read2u ();
601 for (int i = 0; i < attributes_count; i++)
603 read_one_code_attribute (method_index);
606 if ((pos - start_off) != length)
607 throw_class_format_error ("code attribute too short");
610 else
612 /* ignore unknown attributes */
613 skip (length);
617 void _Jv_ClassReader::read_one_code_attribute (int method_index)
619 int name = read2u ();
620 int length = read4 ();
621 if (is_attribute_name (name, "LineNumberTable"))
623 _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
624 (def_interp->interpreted_methods[method_index]);
625 if (method->line_table != NULL)
626 throw_class_format_error ("Method already has LineNumberTable");
628 int table_len = read2u ();
629 _Jv_LineTableEntry* table
630 = (_Jv_LineTableEntry *) JvAllocBytes (table_len
631 * sizeof (_Jv_LineTableEntry));
632 for (int i = 0; i < table_len; i++)
634 table[i].bytecode_pc = read2u ();
635 table[i].line = read2u ();
637 method->line_table_len = table_len;
638 method->line_table = table;
640 else
642 /* ignore unknown code attributes */
643 skip (length);
647 void _Jv_ClassReader::read_one_class_attribute ()
649 int name = read2u ();
650 int length = read4 ();
651 if (is_attribute_name (name, "SourceFile"))
653 int source_index = read2u ();
654 check_tag (source_index, JV_CONSTANT_Utf8);
655 prepare_pool_entry (source_index, JV_CONSTANT_Utf8);
656 def_interp->source_file_name = _Jv_NewStringUtf8Const
657 (def->constants.data[source_index].utf8);
659 else
661 /* Currently, we ignore most class attributes.
662 FIXME: Add inner-classes attributes support. */
663 skip (length);
670 /* this section defines the semantic actions of the parser */
672 void _Jv_ClassReader::handleConstantPool ()
674 /** now, we actually define the class' constant pool */
676 // the pool is scanned explicitly by the collector
677 jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
678 _Jv_word *pool_data
679 = (_Jv_word*) _Jv_AllocBytes (pool_count * sizeof (_Jv_word));
681 def->constants.tags = pool_tags;
682 def->constants.data = pool_data;
683 def->constants.size = pool_count;
685 // Here we make a pass to collect the strings! We do this, because
686 // internally in the GCJ runtime, classes are encoded with .'s not /'s.
687 // Therefore, we first collect the strings, and then translate the rest
688 // of the utf8-entries (thus not representing strings) from /-notation
689 // to .-notation.
690 for (int i = 1; i < pool_count; i++)
692 if (tags[i] == JV_CONSTANT_String)
694 unsigned char* str_data = bytes + offsets [i];
695 int utf_index = get2u (str_data);
696 check_tag (utf_index, JV_CONSTANT_Utf8);
697 unsigned char *utf_data = bytes + offsets[utf_index];
698 int len = get2u (utf_data);
699 pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
700 pool_tags[i] = JV_CONSTANT_String;
702 else
704 pool_tags[i] = JV_CONSTANT_Undefined;
708 // and now, we scan everything else but strings & utf8-entries. This
709 // leaves out those utf8-entries which are not used; which will be left
710 // with a tag of JV_CONSTANT_Undefined in the class definition.
711 for (int index = 1; index < pool_count; index++)
713 switch (tags[index])
715 case JV_CONSTANT_Undefined:
716 case JV_CONSTANT_String:
717 case JV_CONSTANT_Utf8:
718 continue;
720 default:
721 prepare_pool_entry (index, tags[index]);
727 /* this is a recursive procedure, which will prepare pool entries as needed.
728 Which is how we avoid initializing those entries which go unused. */
729 void
730 _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
732 /* these two, pool_data and pool_tags, point into the class
733 structure we are currently defining */
735 unsigned char *pool_tags = (unsigned char*) def->constants.tags;
736 _Jv_word *pool_data = def->constants.data;
738 /* this entry was already prepared */
739 if (pool_tags[index] == this_tag)
740 return;
742 /* this_data points to the constant-pool information for the current
743 constant-pool entry */
745 unsigned char *this_data = bytes + offsets[index];
747 switch (this_tag)
749 case JV_CONSTANT_Utf8:
751 // If we came here, it is because some other tag needs this
752 // utf8-entry for type information! Thus, we translate /'s to .'s in
753 // order to accomondate gcj's internal representation.
755 int len = get2u (this_data);
756 char *buffer = (char*) __builtin_alloca (len);
757 char *s = ((char*) this_data)+2;
759 /* FIXME: avoid using a buffer here */
760 for (int i = 0; i < len; i++)
762 if (s[i] == '/')
763 buffer[i] = '.';
764 else
765 buffer[i] = (char) s[i];
768 pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
769 pool_tags[index] = JV_CONSTANT_Utf8;
771 break;
773 case JV_CONSTANT_Class:
775 int utf_index = get2u (this_data);
776 check_tag (utf_index, JV_CONSTANT_Utf8);
777 prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
779 if (verify)
780 verify_classname (pool_data[utf_index].utf8);
782 pool_data[index].utf8 = pool_data[utf_index].utf8;
783 pool_tags[index] = JV_CONSTANT_Class;
785 break;
787 case JV_CONSTANT_String:
788 // already handled before...
789 break;
791 case JV_CONSTANT_Fieldref:
792 case JV_CONSTANT_Methodref:
793 case JV_CONSTANT_InterfaceMethodref:
795 int class_index = get2u (this_data);
796 int nat_index = get2u (this_data+2);
798 check_tag (class_index, JV_CONSTANT_Class);
799 prepare_pool_entry (class_index, JV_CONSTANT_Class);
801 check_tag (nat_index, JV_CONSTANT_NameAndType);
802 prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
804 // here, verify the signature and identifier name
805 if (verify)
807 _Jv_ushort name_index, type_index;
808 _Jv_loadIndexes (&pool_data[nat_index],
809 name_index, type_index);
811 if (this_tag == JV_CONSTANT_Fieldref)
812 verify_field_signature (pool_data[type_index].utf8);
813 else
814 verify_method_signature (pool_data[type_index].utf8);
816 _Jv_Utf8Const* name = pool_data[name_index].utf8;
818 if (this_tag != JV_CONSTANT_Fieldref
819 && ( _Jv_equalUtf8Consts (name, clinit_name)
820 || _Jv_equalUtf8Consts (name, init_name)))
821 /* ignore */;
822 else
823 verify_identifier (pool_data[name_index].utf8);
826 _Jv_storeIndexes (&pool_data[index], class_index, nat_index);
827 pool_tags[index] = this_tag;
829 break;
831 case JV_CONSTANT_NameAndType:
833 _Jv_ushort name_index = get2u (this_data);
834 _Jv_ushort type_index = get2u (this_data+2);
836 check_tag (name_index, JV_CONSTANT_Utf8);
837 prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
839 check_tag (type_index, JV_CONSTANT_Utf8);
840 prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
842 _Jv_storeIndexes (&pool_data[index], name_index, type_index);
843 pool_tags[index] = JV_CONSTANT_NameAndType;
845 break;
847 case JV_CONSTANT_Float:
849 jfloat f = java::lang::Float::intBitsToFloat ((jint) get4 (this_data));
850 _Jv_storeFloat (&pool_data[index], f);
851 pool_tags[index] = JV_CONSTANT_Float;
853 break;
855 case JV_CONSTANT_Integer:
857 int i = get4 (this_data);
858 _Jv_storeInt (&pool_data[index], i);
859 pool_tags[index] = JV_CONSTANT_Integer;
861 break;
863 case JV_CONSTANT_Double:
865 jdouble d
866 = java::lang::Double::longBitsToDouble ((jlong) get8 (this_data));
867 _Jv_storeDouble (&pool_data[index], d);
868 pool_tags[index] = JV_CONSTANT_Double;
870 break;
872 case JV_CONSTANT_Long:
874 jlong i = get8 (this_data);
875 _Jv_storeLong (&pool_data[index], i);
876 pool_tags[index] = JV_CONSTANT_Long;
878 break;
880 default:
881 throw_class_format_error ("erroneous constant pool tag");
886 void
887 _Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_class)
889 using namespace java::lang::reflect;
891 unsigned char *pool_tags = (unsigned char*) def->constants.tags;
892 _Jv_word *pool_data = def->constants.data;
894 check_tag (this_class, JV_CONSTANT_Class);
895 _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
897 // was ClassLoader.defineClass called with an expected class name?
898 if (def->name == 0)
900 jclass orig = def->loader->findLoadedClass(loadedName->toString());
902 if (orig == 0)
904 def->name = loadedName;
906 else
908 jstring msg = JvNewStringUTF ("anonymous "
909 "class data denotes "
910 "existing class ");
911 msg = msg->concat (orig->getName ());
913 throw_no_class_def_found_error (msg);
917 // assert that the loaded class has the expected name, 5.3.5
918 else if (! _Jv_equalUtf8Consts (loadedName, def->name))
920 jstring msg = JvNewStringUTF ("loaded class ");
921 msg = msg->concat (def->getName ());
922 msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
923 jstring klass_name = loadedName->toString();
924 msg = msg->concat (klass_name);
926 throw_no_class_def_found_error (msg);
929 def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
930 pool_data[this_class].clazz = def;
931 pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
933 if (super_class == 0 && ! (access_flags & Modifier::INTERFACE))
935 // FIXME: Consider this carefully!
936 if (! _Jv_equalUtf8Consts (def->name, java::lang::Object::class$.name))
937 throw_no_class_def_found_error ("loading java.lang.Object");
940 def->state = JV_STATE_PRELOADING;
942 // Register this class with its defining loader as well (despite the
943 // name of the function we're calling), so that super class lookups
944 // work properly. If there is an error, our caller will unregister
945 // this class from the class loader. Also, we don't need to hold a
946 // lock here, as our caller has acquired it.
947 _Jv_RegisterInitiatingLoader (def, def->loader);
949 if (super_class != 0)
951 // Load the superclass.
952 check_tag (super_class, JV_CONSTANT_Class);
953 _Jv_Utf8Const* super_name = pool_data[super_class].utf8;
955 // Load the superclass using our defining loader.
956 jclass the_super = _Jv_FindClass (super_name,
957 def->loader);
959 // This will establish that we are allowed to be a subclass,
960 // and check for class circularity error.
961 checkExtends (def, the_super);
963 // Note: for an interface we will find Object as the
964 // superclass. We still check it above to ensure class file
965 // validity, but we simply assign `null' to the actual field in
966 // this case.
967 def->superclass = (((access_flags & Modifier::INTERFACE))
968 ? NULL : the_super);
969 pool_data[super_class].clazz = the_super;
970 pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
973 // Now we've come past the circularity problem, we can
974 // now say that we're loading.
976 def->state = JV_STATE_LOADING;
977 def->notifyAll ();
980 ///// Implements the checks described in sect. 5.3.5.3
981 void
982 _Jv_ClassReader::checkExtends (jclass sub, jclass super)
984 using namespace java::lang::reflect;
986 _Jv_Linker::wait_for_state (super, JV_STATE_LOADING);
988 // Having an interface or a final class as a superclass is no good.
989 if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
991 throw_incompatible_class_change_error (sub->getName ());
994 // If the super class is not public, we need to check some more.
995 if ((super->accflags & Modifier::PUBLIC) == 0)
997 // With package scope, the classes must have the same class
998 // loader.
999 if ( sub->loader != super->loader
1000 || !_Jv_ClassNameSamePackage (sub->name, super->name))
1002 throw_incompatible_class_change_error (sub->getName ());
1006 for (; super != 0; super = super->getSuperclass ())
1008 if (super == sub)
1009 throw_class_circularity_error (sub->getName ());
1015 void _Jv_ClassReader::handleInterfacesBegin (int count)
1017 def->interfaces = (jclass*) _Jv_AllocBytes (count*sizeof (jclass));
1018 def->interface_count = count;
1021 void _Jv_ClassReader::handleInterface (int if_number, int offset)
1023 _Jv_word * pool_data = def->constants.data;
1024 unsigned char * pool_tags = (unsigned char*) def->constants.tags;
1026 jclass the_interface;
1028 if (pool_tags[offset] == JV_CONSTANT_Class)
1030 _Jv_Utf8Const* name = pool_data[offset].utf8;
1031 the_interface = _Jv_FindClass (name, def->loader);
1033 else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
1035 the_interface = pool_data[offset].clazz;
1037 else
1039 throw_no_class_def_found_error ("erroneous constant pool tag");
1042 // checks the validity of the_interface, and that we are in fact
1043 // allowed to implement that interface.
1044 checkImplements (def, the_interface);
1046 pool_data[offset].clazz = the_interface;
1047 pool_tags[offset] = JV_CONSTANT_ResolvedClass;
1049 def->interfaces[if_number] = the_interface;
1052 void
1053 _Jv_ClassReader::checkImplements (jclass sub, jclass super)
1055 using namespace java::lang::reflect;
1057 // well, it *must* be an interface
1058 if ((super->accflags & Modifier::INTERFACE) == 0)
1060 throw_incompatible_class_change_error (sub->getName ());
1063 // if it has package scope, it must also be defined by the
1064 // same loader.
1065 if ((super->accflags & Modifier::PUBLIC) == 0)
1067 if ( sub->loader != super->loader
1068 || !_Jv_ClassNameSamePackage (sub->name, super->name))
1070 throw_incompatible_class_change_error (sub->getName ());
1074 // FIXME: add interface circularity check here
1075 if (sub == super)
1077 throw_class_circularity_error (sub->getName ());
1081 void _Jv_ClassReader::handleFieldsBegin (int count)
1083 def->fields = (_Jv_Field*)
1084 _Jv_AllocBytes (count * sizeof (_Jv_Field));
1085 def->field_count = count;
1086 def_interp->field_initializers = (_Jv_ushort*)
1087 _Jv_AllocBytes (count * sizeof (_Jv_ushort));
1088 for (int i = 0; i < count; i++)
1089 def_interp->field_initializers[i] = (_Jv_ushort) 0;
1092 void _Jv_ClassReader::handleField (int field_no,
1093 int flags,
1094 int name,
1095 int desc)
1097 using namespace java::lang::reflect;
1099 _Jv_word *pool_data = def->constants.data;
1101 _Jv_Field *field = &def->fields[field_no];
1102 _Jv_Utf8Const *field_name = pool_data[name].utf8;
1104 field->name = field_name;
1106 // Ignore flags we don't know about.
1107 field->flags = flags & Modifier::ALL_FLAGS;
1109 _Jv_Utf8Const* sig = pool_data[desc].utf8;
1111 if (verify)
1113 verify_identifier (field_name);
1115 for (int i = 0; i < field_no; ++i)
1117 if (_Jv_equalUtf8Consts (field_name, def->fields[i].name)
1118 && _Jv_equalUtf8Consts (sig,
1119 // We know the other fields are
1120 // unresolved.
1121 (_Jv_Utf8Const *) def->fields[i].type))
1122 throw_class_format_error ("duplicate field name");
1125 // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1126 if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
1127 +((field->flags & Modifier::PRIVATE) ? 1 : 0)
1128 +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
1129 throw_class_format_error ("erroneous field access flags");
1131 // FIXME: JVM spec S4.5: Verify ACC_FINAL and ACC_VOLATILE are not
1132 // both set. Verify modifiers for interface fields.
1136 if (verify)
1137 verify_field_signature (sig);
1139 // field->type is really a jclass, but while it is still
1140 // unresolved we keep an _Jv_Utf8Const* instead.
1141 field->type = (jclass) sig;
1142 field->flags |= _Jv_FIELD_UNRESOLVED_FLAG;
1143 field->u.boffset = 0;
1147 void _Jv_ClassReader::handleConstantValueAttribute (int field_index,
1148 int value)
1150 using namespace java::lang::reflect;
1152 _Jv_Field *field = &def->fields[field_index];
1154 if ((field->flags & (Modifier::STATIC
1155 | Modifier::FINAL
1156 | Modifier::PRIVATE)) == 0)
1158 // Ignore, as per vmspec #4.7.2
1159 return;
1162 // do not allow multiple constant fields!
1163 if (field->flags & _Jv_FIELD_CONSTANT_VALUE)
1164 throw_class_format_error ("field has multiple ConstantValue attributes");
1166 field->flags |= _Jv_FIELD_CONSTANT_VALUE;
1167 def_interp->field_initializers[field_index] = value;
1169 /* type check the initializer */
1171 if (value <= 0 || value >= pool_count)
1172 throw_class_format_error ("erroneous ConstantValue attribute");
1174 /* FIXME: do the rest */
1177 void _Jv_ClassReader::handleFieldsEnd ()
1179 using namespace java::lang::reflect;
1181 // We need to reorganize the fields so that the static ones are first,
1182 // to conform to GCJ class layout.
1184 int low = 0;
1185 int high = def->field_count-1;
1186 _Jv_Field *fields = def->fields;
1187 _Jv_ushort *inits = def_interp->field_initializers;
1189 // this is kind of a raw version of quicksort.
1190 while (low < high)
1192 // go forward on low, while it's a static
1193 while (low < high && (fields[low].flags & Modifier::STATIC) != 0)
1194 low++;
1196 // go backwards on high, while it's a non-static
1197 while (low < high && (fields[high].flags & Modifier::STATIC) == 0)
1198 high--;
1200 if (low==high)
1201 break;
1203 _Jv_Field tmp = fields[low];
1204 _Jv_ushort itmp = inits[low];
1206 fields[low] = fields[high];
1207 inits[low] = inits[high];
1209 fields[high] = tmp;
1210 inits[high] = itmp;
1212 high -= 1;
1213 low += 1;
1216 if ((fields[low].flags & Modifier::STATIC) != 0)
1217 low += 1;
1219 def->static_field_count = low;
1224 void
1225 _Jv_ClassReader::handleMethodsBegin (int count)
1227 def->methods = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method) * count);
1229 def_interp->interpreted_methods
1230 = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
1231 * count);
1233 for (int i = 0; i < count; i++)
1235 def_interp->interpreted_methods[i] = 0;
1236 def->methods[i].index = (_Jv_ushort) -1;
1239 def->method_count = count;
1243 void _Jv_ClassReader::handleMethod
1244 (int mth_index, int accflags, int name, int desc)
1246 using namespace java::lang::reflect;
1248 _Jv_word *pool_data = def->constants.data;
1249 _Jv_Method *method = &def->methods[mth_index];
1251 check_tag (name, JV_CONSTANT_Utf8);
1252 prepare_pool_entry (name, JV_CONSTANT_Utf8);
1253 method->name = pool_data[name].utf8;
1255 check_tag (desc, JV_CONSTANT_Utf8);
1256 prepare_pool_entry (desc, JV_CONSTANT_Utf8);
1257 method->signature = pool_data[desc].utf8;
1259 // ignore unknown flags
1260 method->accflags = accflags & Modifier::ALL_FLAGS;
1262 // Initialize...
1263 method->ncode = 0;
1264 method->throws = NULL;
1266 if (verify)
1268 if (_Jv_equalUtf8Consts (method->name, clinit_name)
1269 || _Jv_equalUtf8Consts (method->name, init_name))
1270 /* ignore */;
1271 else
1272 verify_identifier (method->name);
1274 verify_method_signature (method->signature);
1276 for (int i = 0; i < mth_index; ++i)
1278 if (_Jv_equalUtf8Consts (method->name, def->methods[i].name)
1279 && _Jv_equalUtf8Consts (method->signature,
1280 def->methods[i].signature))
1281 throw_class_format_error ("duplicate method");
1284 // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1285 if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
1286 +((method->accflags & Modifier::PRIVATE) ? 1 : 0)
1287 +((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
1288 throw_class_format_error ("erroneous method access flags");
1290 // FIXME: JVM spec S4.6: if ABSTRACT modifier is set, verify other
1291 // flags are not set. Verify flags for interface methods. Verifiy
1292 // modifiers for initializers.
1296 void _Jv_ClassReader::handleCodeAttribute
1297 (int method_index, int max_stack, int max_locals,
1298 int code_start, int code_length, int exc_table_length)
1300 int size = _Jv_InterpMethod::size (exc_table_length, code_length);
1301 _Jv_InterpMethod *method =
1302 (_Jv_InterpMethod*) (_Jv_AllocBytes (size));
1304 method->max_stack = max_stack;
1305 method->max_locals = max_locals;
1306 method->code_length = code_length;
1307 method->exc_count = exc_table_length;
1308 method->defining_class = def;
1309 method->self = &def->methods[method_index];
1310 method->prepared = NULL;
1311 method->line_table_len = 0;
1312 method->line_table = NULL;
1315 // grab the byte code!
1316 memcpy ((void*) method->bytecode (),
1317 (void*) (bytes+code_start),
1318 code_length);
1320 def_interp->interpreted_methods[method_index] = method;
1322 if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
1324 // Precompute the ncode field for a static method. This lets us
1325 // call a static method of an interpreted class from precompiled
1326 // code without first resolving the class (that will happen
1327 // during class initialization instead).
1328 method->self->ncode = method->ncode ();
1332 void _Jv_ClassReader::handleExceptionTableEntry
1333 (int method_index, int exc_index,
1334 int start_pc, int end_pc, int handler_pc, int catch_type)
1336 _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1337 (def_interp->interpreted_methods[method_index]);
1338 _Jv_InterpException *exc = method->exceptions ();
1340 exc[exc_index].start_pc.i = start_pc;
1341 exc[exc_index].end_pc.i = end_pc;
1342 exc[exc_index].handler_pc.i = handler_pc;
1343 exc[exc_index].handler_type.i = catch_type;
1346 void _Jv_ClassReader::handleMethodsEnd ()
1348 using namespace java::lang::reflect;
1350 for (int i = 0; i < def->method_count; i++)
1352 _Jv_Method *method = &def->methods[i];
1353 if ((method->accflags & Modifier::NATIVE) != 0)
1355 if (def_interp->interpreted_methods[i] != 0)
1356 throw_class_format_error ("code provided for native method");
1357 else
1359 _Jv_JNIMethod *m = (_Jv_JNIMethod *)
1360 _Jv_AllocBytes (sizeof (_Jv_JNIMethod));
1361 m->defining_class = def;
1362 m->self = method;
1363 m->function = NULL;
1364 def_interp->interpreted_methods[i] = m;
1366 if ((method->accflags & Modifier::STATIC))
1368 // Precompute the ncode field for a static method.
1369 // This lets us call a static method of an
1370 // interpreted class from precompiled code without
1371 // first resolving the class (that will happen
1372 // during class initialization instead).
1373 method->ncode = m->ncode ();
1377 else if ((method->accflags & Modifier::ABSTRACT) != 0)
1379 if (def_interp->interpreted_methods[i] != 0)
1380 throw_class_format_error ("code provided for abstract method");
1382 else
1384 if (def_interp->interpreted_methods[i] == 0)
1385 throw_class_format_error ("method with no code");
1390 void _Jv_ClassReader::throw_class_format_error (char *msg)
1392 jstring str;
1393 if (def->name != NULL)
1395 jsize mlen = strlen (msg);
1396 unsigned char* data = (unsigned char*) def->name->chars();
1397 int ulen = def->name->len();
1398 unsigned char* limit = data + ulen;
1399 jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
1400 jsize len = nlen + mlen + 3;
1401 str = JvAllocString(len);
1402 jchar *chrs = JvGetStringChars(str);
1403 while (data < limit)
1404 *chrs++ = UTF8_GET(data, limit);
1405 *chrs++ = ' ';
1406 *chrs++ = '(';
1407 for (;;)
1409 char c = *msg++;
1410 if (c == 0)
1411 break;
1412 *chrs++ = c & 0xFFFF;
1414 *chrs++ = ')';
1416 else
1417 str = JvNewStringLatin1 (msg);
1418 ::throw_class_format_error (str);
1421 /** Here we define the exceptions that can be thrown */
1423 static void
1424 throw_no_class_def_found_error (jstring msg)
1426 throw (msg
1427 ? new java::lang::NoClassDefFoundError (msg)
1428 : new java::lang::NoClassDefFoundError);
1431 static void
1432 throw_no_class_def_found_error (char *msg)
1434 throw_no_class_def_found_error (JvNewStringLatin1 (msg));
1437 static void
1438 throw_class_format_error (jstring msg)
1440 throw (msg
1441 ? new java::lang::ClassFormatError (msg)
1442 : new java::lang::ClassFormatError);
1445 static void
1446 throw_internal_error (char *msg)
1448 throw new java::lang::InternalError (JvNewStringLatin1 (msg));
1451 static void
1452 throw_incompatible_class_change_error (jstring msg)
1454 throw new java::lang::IncompatibleClassChangeError (msg);
1457 static void
1458 throw_class_circularity_error (jstring msg)
1460 throw new java::lang::ClassCircularityError (msg);
1463 #endif /* INTERPRETER */
1467 /** This section takes care of verifying integrity of identifiers,
1468 signatures, field ddescriptors, and class names */
1470 #define UTF8_PEEK(PTR, LIMIT) \
1471 ({ unsigned char* xxkeep = (PTR); \
1472 int xxch = UTF8_GET(PTR,LIMIT); \
1473 PTR = xxkeep; xxch; })
1475 /* Verify one element of a type descriptor or signature. */
1476 static unsigned char*
1477 _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
1479 if (ptr >= limit)
1480 return 0;
1482 int ch = UTF8_GET (ptr, limit);
1484 switch (ch)
1486 case 'V':
1487 if (! void_ok)
1488 return 0;
1490 case 'S': case 'B': case 'I': case 'J':
1491 case 'Z': case 'C': case 'F': case 'D':
1492 break;
1494 case 'L':
1496 unsigned char *start = ptr, *end;
1499 if (ptr > limit)
1500 return 0;
1502 end = ptr;
1504 if ((ch = UTF8_GET (ptr, limit)) == -1)
1505 return 0;
1508 while (ch != ';');
1509 if (! _Jv_VerifyClassName (start, (unsigned short) (end-start)))
1510 return 0;
1512 break;
1514 case '[':
1515 return _Jv_VerifyOne (ptr, limit, false);
1516 break;
1518 default:
1519 return 0;
1522 return ptr;
1525 /* Verification and loading procedures. */
1526 bool
1527 _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
1529 unsigned char* ptr = (unsigned char*) sig->chars();
1530 unsigned char* limit = ptr + sig->len();
1532 ptr = _Jv_VerifyOne (ptr, limit, false);
1534 return ptr == limit;
1537 bool
1538 _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
1540 unsigned char* ptr = (unsigned char*) sig->chars();
1541 unsigned char* limit = ptr + sig->len();
1543 if (ptr == limit || UTF8_GET(ptr,limit) != '(')
1544 return false;
1546 while (ptr && UTF8_PEEK (ptr, limit) != ')')
1547 ptr = _Jv_VerifyOne (ptr, limit, false);
1549 if (UTF8_GET (ptr, limit) != ')')
1550 return false;
1552 // get the return type
1553 ptr = _Jv_VerifyOne (ptr, limit, true);
1555 return ptr == limit;
1558 /* We try to avoid calling the Character methods all the time, in
1559 fact, they will only be called for non-standard things. */
1560 static __inline__ int
1561 is_identifier_start (int c)
1563 unsigned int ch = (unsigned)c;
1565 if ((ch - 0x41U) < 29U) /* A ... Z */
1566 return 1;
1567 if ((ch - 0x61U) < 29U) /* a ... z */
1568 return 1;
1569 if (ch == 0x5FU) /* _ */
1570 return 1;
1572 return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1575 static __inline__ int
1576 is_identifier_part (int c)
1578 unsigned int ch = (unsigned)c;
1580 if ((ch - 0x41U) < 29U) /* A ... Z */
1581 return 1;
1582 if ((ch - 0x61U) < 29U) /* a ... z */
1583 return 1;
1584 if ((ch - 0x30) < 10U) /* 0 .. 9 */
1585 return 1;
1586 if (ch == 0x5FU || ch == 0x24U) /* _ $ */
1587 return 1;
1589 return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1592 bool
1593 _Jv_VerifyIdentifier (_Jv_Utf8Const* name)
1595 unsigned char *ptr = (unsigned char*) name->chars();
1596 unsigned char *limit = (unsigned char*) name->limit();
1597 int ch;
1599 if ((ch = UTF8_GET (ptr, limit))==-1
1600 || ! is_identifier_start (ch))
1601 return false;
1603 while (ptr != limit)
1605 if ((ch = UTF8_GET (ptr, limit))==-1
1606 || ! is_identifier_part (ch))
1607 return false;
1609 return true;
1612 bool
1613 _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
1615 unsigned char *limit = ptr+length;
1616 int ch;
1618 if ('[' == UTF8_PEEK (ptr, limit))
1620 unsigned char *end = _Jv_VerifyOne (++ptr, limit, false);
1621 // _Jv_VerifyOne must leave us looking at the terminating nul
1622 // byte.
1623 if (! end || *end)
1624 return false;
1625 else
1626 return true;
1629 next_level:
1630 for (;;) {
1631 if ((ch = UTF8_GET (ptr, limit))==-1)
1632 return false;
1633 if (! is_identifier_start (ch))
1634 return false;
1635 for (;;) {
1636 if (ptr == limit)
1637 return true;
1638 else if ((ch = UTF8_GET (ptr, limit))==-1)
1639 return false;
1640 else if (ch == '.')
1641 goto next_level;
1642 else if (! is_identifier_part (ch))
1643 return false;
1648 bool
1649 _Jv_VerifyClassName (_Jv_Utf8Const *name)
1651 return _Jv_VerifyClassName ((unsigned char*)name->chars(), name->len());
1654 /* Returns true, if NAME1 and NAME2 represent classes in the same
1655 package. Neither NAME2 nor NAME2 may name an array type. */
1656 bool
1657 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
1659 unsigned char* ptr1 = (unsigned char*) name1->chars();
1660 unsigned char* limit1 = (unsigned char*) name1->limit();
1662 unsigned char* last1 = ptr1;
1664 // scan name1, and find the last occurrence of '.'
1665 while (ptr1 < limit1) {
1666 int ch1 = UTF8_GET (ptr1, limit1);
1668 if (ch1 == '.')
1669 last1 = ptr1;
1671 else if (ch1 == -1)
1672 return false;
1675 // Now the length of NAME1's package name is LEN.
1676 int len = last1 - (unsigned char*) name1->chars();
1678 // If this is longer than NAME2, then we're off.
1679 if (len > name2->len())
1680 return false;
1682 // Then compare the first len bytes for equality.
1683 if (memcmp ((void*) name1->chars(), (void*) name2->chars(), len) == 0)
1685 // Check that there are no .'s after position LEN in NAME2.
1687 unsigned char* ptr2 = (unsigned char*) name2->chars() + len;
1688 unsigned char* limit2 = (unsigned char*) name2->limit();
1690 while (ptr2 < limit2)
1692 int ch2 = UTF8_GET (ptr2, limit2);
1693 if (ch2 == -1 || ch2 == '.')
1694 return false;
1696 return true;
1698 return false;