1 // defineclass.cc - defining a class from .class format.
2 
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2012
4    Free Software Foundation
5 
6    This file is part of libgcj.
7 
8 This software is copyrighted work licensed under the terms of the
9 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
10 details.  */
11 
12 /*
13    Author: Kresten Krab Thorup <krab@gnu.org>
14 
15    Written using the online versions of Java Language Specification (1st
16    ed.) and The Java Virtual Machine Specification (2nd ed.).
17 
18    Future work may include reading (and handling) attributes which are
19    currently being ignored ("InnerClasses", "LineNumber", etc...).
20 */
21 
22 #include <config.h>
23 
24 #include <java-interp.h>
25 
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <java-cpool.h>
29 #include <gcj/cni.h>
30 #include <execution.h>
31 
32 #include <java/lang/Class.h>
33 #include <java/lang/Float.h>
34 #include <java/lang/Double.h>
35 #include <java/lang/Character.h>
36 #include <java/lang/LinkageError.h>
37 #include <java/lang/InternalError.h>
38 #include <java/lang/ClassFormatError.h>
39 #include <java/lang/NoClassDefFoundError.h>
40 #include <java/lang/ClassCircularityError.h>
41 #include <java/lang/IncompatibleClassChangeError.h>
42 #include <java/lang/reflect/Modifier.h>
43 #include <java/lang/reflect/Field.h>
44 #include <java/lang/reflect/Method.h>
45 #include <java/security/ProtectionDomain.h>
46 #include <java/io/DataOutputStream.h>
47 #include <java/io/ByteArrayOutputStream.h>
48 
49 using namespace gcj;
50 
51 #ifdef INTERPRETER
52 
53 // these go in some separate functions, to avoid having _Jv_InitClass
54 // inserted all over the place.
55 static void throw_internal_error (const char *msg)
56 	__attribute__ ((__noreturn__));
57 static void throw_no_class_def_found_error (jstring msg)
58 	__attribute__ ((__noreturn__));
59 static void throw_no_class_def_found_error (const char *msg)
60 	__attribute__ ((__noreturn__));
61 static void throw_class_format_error (jstring msg)
62 	__attribute__ ((__noreturn__));
63 static void throw_incompatible_class_change_error (jstring msg)
64 	__attribute__ ((__noreturn__));
65 static void throw_class_circularity_error (jstring msg)
66 	__attribute__ ((__noreturn__));
67 
68 /**
69  * We define class reading using a class.  It is practical, since then
70  * the entire class-reader can be a friend of class Class (it needs to
71  * write all it's different structures); but also because this makes it
72  * easy to make class definition reentrant, and thus two threads can be
73  * defining classes at the same time.   This class (_Jv_ClassReader) is
74  * never exposed outside this file, so we don't have to worry about
75  * public or private members here.
76  */
77 
78 struct _Jv_ClassReader
79 {
80 
81   // do verification?  Currently, there is no option to disable this.
82   // This flag just controls the verificaiton done by the class loader;
83   // i.e., checking the integrity of the constant pool; and it is
84   // allways on.  You always want this as far as I can see, but it also
85   // controls weither identifiers and type descriptors/signatures are
86   // verified as legal.  This could be somewhat more expensive since it
87   // will call Character.isJavaIdentifier{Start,Part} for each character
88   // in any identifier (field name or method name) it comes by.  Thus,
89   // it might be useful to turn off this verification for classes that
90   // come from a trusted source.  However, for GCJ, trusted classes are
91   // most likely to be linked in.
92 
93   bool verify;
94 
95   // original input data.
96   jbyteArray input_data;
97   jint input_offset;
98 
99   // input data.
100   unsigned char     *bytes;
101   int                len;
102 
103   // current input position
104   int                pos;
105 
106   // the constant pool data
107   int pool_count;
108   unsigned char     *tags;
109   unsigned int      *offsets;
110 
111   // the class to define (see java-interp.h)
112   jclass	   def;
113 
114   // the classes associated interpreter data.
115   _Jv_InterpClass  *def_interp;
116 
117   // The name we found.
118   _Jv_Utf8Const **found_name;
119 
120   // True if this is a 1.5 class file.
121   bool             is_15;
122 
123   // Buffer holding extra reflection data.
124   ::java::io::ByteArrayOutputStream *reflection_data;
125   ::java::io::DataOutputStream *data_stream;
126 
127 
128   /* check that the given number of input bytes are available */
check_Jv_ClassReader129   inline void check (int num)
130   {
131     if (pos + num > len)
132       throw_class_format_error ("Premature end of data");
133   }
134 
135   /* skip a given number of bytes in input */
skip_Jv_ClassReader136   inline void skip (int num)
137   {
138     check (num);
139     pos += num;
140   }
141 
142   /* read an unsigned 1-byte unit */
get1u_Jv_ClassReader143   inline static jint get1u (unsigned char* bytes)
144   {
145     return bytes[0];
146   }
147 
148   /* read an unsigned 1-byte unit */
read1u_Jv_ClassReader149   inline jint read1u ()
150   {
151     skip (1);
152     return get1u (bytes+pos-1);
153   }
154 
155   /* read an unsigned 2-byte unit */
get2u_Jv_ClassReader156   inline static jint get2u (unsigned char *bytes)
157   {
158     return (((jint)bytes[0]) << 8) | ((jint)bytes[1]);
159   }
160 
161   /* read an unsigned 2-byte unit */
read2u_Jv_ClassReader162   inline jint read2u ()
163   {
164     skip (2);
165     return get2u (bytes+pos-2);
166   }
167 
168   /* read a 4-byte unit */
get4_Jv_ClassReader169   static jint get4 (unsigned char *bytes)
170   {
171     return (((jint)bytes[0]) << 24)
172          | (((jint)bytes[1]) << 16)
173          | (((jint)bytes[2]) << 8)
174          | (((jint)bytes[3]) << 0);
175   }
176 
177   /* read a 4-byte unit, (we don't do that quite so often) */
read4_Jv_ClassReader178   inline jint read4 ()
179   {
180     skip (4);
181     return get4 (bytes+pos-4);
182   }
183 
184   /* read a 8-byte unit */
get8_Jv_ClassReader185   static jlong get8 (unsigned char* bytes)
186   {
187     return (((jlong)bytes[0]) << 56)
188          | (((jlong)bytes[1]) << 48)
189          | (((jlong)bytes[2]) << 40)
190          | (((jlong)bytes[3]) << 32)
191          | (((jlong)bytes[4]) << 24)
192          | (((jlong)bytes[5]) << 16)
193          | (((jlong)bytes[6]) << 8)
194          | (((jlong)bytes[7]) << 0);
195   }
196 
197   /* read a 8-byte unit */
read8_Jv_ClassReader198   inline jlong read8 ()
199   {
200     skip (8);
201     return get8 (bytes+pos-8);
202   }
203 
check_tag_Jv_ClassReader204   inline void check_tag (int index, char expected_tag)
205   {
206     if (index < 0
207 	|| index > pool_count
208 	|| tags[index] != expected_tag)
209       throw_class_format_error ("erroneous constant pool tag");
210   }
211 
verify_identifier_Jv_ClassReader212   inline void verify_identifier (_Jv_Utf8Const* name)
213   {
214     if (! _Jv_VerifyIdentifier (name))
215       throw_class_format_error ("erroneous identifier");
216   }
217 
verify_classname_Jv_ClassReader218   inline void verify_classname (unsigned char* ptr, _Jv_ushort length)
219   {
220     if (! _Jv_VerifyClassName (ptr, length))
221       throw_class_format_error ("erroneous class name");
222   }
223 
verify_classname_Jv_ClassReader224   inline void verify_classname (_Jv_Utf8Const *name)
225   {
226     if (! _Jv_VerifyClassName (name))
227       throw_class_format_error ("erroneous class name");
228   }
229 
verify_field_signature_Jv_ClassReader230   inline void verify_field_signature (_Jv_Utf8Const *sig)
231   {
232     if (! _Jv_VerifyFieldSignature (sig))
233       throw_class_format_error ("erroneous type descriptor");
234   }
235 
verify_method_signature_Jv_ClassReader236   inline void verify_method_signature (_Jv_Utf8Const *sig)
237   {
238     if (! _Jv_VerifyMethodSignature (sig))
239       throw_class_format_error ("erroneous type descriptor");
240   }
241 
get_reflection_stream_Jv_ClassReader242   ::java::io::DataOutputStream *get_reflection_stream ()
243   {
244     if (reflection_data == NULL)
245       {
246 	reflection_data = new ::java::io::ByteArrayOutputStream();
247 	data_stream = new ::java::io::DataOutputStream(reflection_data);
248       }
249     return data_stream;
250   }
251 
_Jv_ClassReader_Jv_ClassReader252   _Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length,
253 		   java::security::ProtectionDomain *pd,
254 		   _Jv_Utf8Const **name_result)
255   {
256     if (klass == 0 || length < 0 || offset+length > data->length)
257       throw_internal_error ("arguments to _Jv_DefineClass");
258 
259     verify = true;
260     input_data = data;
261     input_offset = offset;
262     bytes  = (unsigned char*) (elements (data)+offset);
263     len    = length;
264     pos    = 0;
265     is_15  = false;
266 
267     def    = klass;
268     found_name = name_result;
269     reflection_data = NULL;
270     data_stream = NULL;
271 
272     def->size_in_bytes = -1;
273     def->vtable_method_count = -1;
274     def->engine = &_Jv_soleInterpreterEngine;
275     def->protectionDomain = pd;
276   }
277 
278   /** and here goes the parser members defined out-of-line */
279   void parse ();
280   void read_constpool ();
281   void prepare_pool_entry (int index, unsigned char tag,
282 			   bool rewrite = true);
283   void read_fields ();
284   void read_methods ();
285   void read_one_class_attribute ();
286   void read_one_method_attribute (int method);
287   void read_one_code_attribute (int method);
288   void read_one_field_attribute (int field, bool *);
289   void throw_class_format_error (const char *msg);
290 
291   void handleEnclosingMethod(int);
292   void handleGenericSignature(jv_attr_type, unsigned short, int);
293   void handleAnnotationElement();
294   void handleAnnotation();
295   void handleAnnotations();
296   void handleMemberAnnotations(jv_attr_type, int, int);
297   void handleAnnotationDefault(int, int);
298   void handleParameterAnnotations(int, int);
299   void finish_reflection_data ();
300 
301   /** check an utf8 entry, without creating a Utf8Const object */
302   bool is_attribute_name (int index, const char *name);
303 
304   /** return the value of a utf8 entry in the passed array */
305   int pool_Utf8_to_char_arr (int index, char **entry);
306 
307   /** here goes the class-loader members defined out-of-line */
308   void handleConstantPool ();
309   void handleClassBegin (int, int, int);
310   void handleInterfacesBegin (int);
311   void handleInterface (int, int);
312   void handleFieldsBegin (int);
313   void handleField (int, int, int, int, int *);
314   void handleConstantValueAttribute (int, int, bool *);
315   void handleMethodsBegin (int);
316   void handleMethod (int, int, int, int);
317   void handleMethodsEnd ();
318   void handleCodeAttribute (int, int, int, int, int, int);
319   void handleExceptionTableEntry (int, int, int, int, int, int);
320 
321   void checkExtends (jclass sub, jclass super);
322   void checkImplements (jclass sub, jclass super);
323 
324   /*
325    * FIXME: we should keep a hash table of utf8-strings, since many will
326    * be the same.  It's a little tricky, however, because the hash table
327    * needs to interact gracefully with the garbage collector.  Much
328    * memory is to be saved by this, however!  perhaps the improvement
329    * could be implemented in prims.cc (_Jv_makeUtf8Const), since it
330    * computes the hash value anyway.
331    */
332 };
333 
334 // Note that *NAME_RESULT will only be set if the class is registered
335 // with the class loader.  This is how the caller can know whether
336 // unregistration is require.
337 void
_Jv_DefineClass(jclass klass,jbyteArray data,jint offset,jint length,java::security::ProtectionDomain * pd,_Jv_Utf8Const ** name_result)338 _Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length,
339 		 java::security::ProtectionDomain *pd,
340 		 _Jv_Utf8Const **name_result)
341 {
342   _Jv_ClassReader reader (klass, data, offset, length, pd, name_result);
343   reader.parse();
344 
345   /* that's it! */
346 }
347 
348 
349 /** This section defines the parsing/scanning of the class data */
350 
351 // Major and minor version numbers for various releases.
352 #define MAJOR_1_1 45
353 #define MINOR_1_1  3
354 #define MAJOR_1_2 46
355 #define MINOR_1_2  0
356 #define MAJOR_1_3 47
357 #define MINOR_1_3  0
358 #define MAJOR_1_4 48
359 #define MINOR_1_4  0
360 #define MAJOR_1_5 49
361 #define MINOR_1_5  0
362 #define MAJOR_1_6 50
363 #define MINOR_1_6  0
364 #define MAJOR_1_7 51
365 #define MINOR_1_7  0
366 
367 void
parse()368 _Jv_ClassReader::parse ()
369 {
370   int magic = read4 ();
371   if (magic != (int) 0xCAFEBABE)
372     throw_class_format_error ("bad magic number");
373 
374   int minor_version = read2u ();
375   int major_version = read2u ();
376   if (major_version < MAJOR_1_1 || major_version > MAJOR_1_7
377       || (major_version == MAJOR_1_7 && minor_version > MINOR_1_7))
378     throw_class_format_error ("unrecognized class file version");
379   is_15 = (major_version >= MAJOR_1_5);
380 
381   pool_count = read2u ();
382 
383   read_constpool ();
384 
385   int access_flags = read2u ();
386   int this_class = read2u ();
387   int super_class = read2u ();
388 
389   check_tag (this_class, JV_CONSTANT_Class);
390   if (super_class != 0)
391     check_tag (super_class, JV_CONSTANT_Class);
392 
393   handleClassBegin (access_flags, this_class, super_class);
394 
395   // Allocate our aux_info here, after the name is set, to fulfill our
396   // contract with the collector interface.
397   def->aux_info = (void *) _Jv_AllocRawObj (sizeof (_Jv_InterpClass));
398   def_interp = (_Jv_InterpClass *) def->aux_info;
399 
400   int interfaces_count = read2u ();
401 
402   handleInterfacesBegin (interfaces_count);
403 
404   for (int i = 0; i < interfaces_count; i++)
405     {
406       int iface = read2u ();
407       check_tag (iface, JV_CONSTANT_Class);
408       handleInterface (i, iface);
409     }
410 
411   read_fields ();
412   read_methods ();
413 
414   int attributes_count = read2u ();
415 
416   for (int i = 0; i < attributes_count; i++)
417     {
418       read_one_class_attribute ();
419     }
420 
421   if (pos != len)
422     throw_class_format_error ("unused data before end of file");
423 
424   finish_reflection_data ();
425 
426   // Tell everyone we're done.
427   def->state = JV_STATE_READ;
428   if (gcj::verbose_class_flag)
429     _Jv_Linker::print_class_loaded (def);
430   ++gcj::loadedClasses;
431   def->notifyAll ();
432 }
433 
434 void
finish_reflection_data()435 _Jv_ClassReader::finish_reflection_data ()
436 {
437   if (data_stream == NULL)
438     return;
439   data_stream->writeByte(JV_DONE_ATTR);
440   data_stream->flush();
441   int nbytes = reflection_data->count;
442   unsigned char *new_bytes = (unsigned char *) _Jv_AllocBytes (nbytes);
443   memcpy (new_bytes, elements (reflection_data->buf), nbytes);
444   def->reflection_data = new_bytes;
445 }
446 
447 void
handleEnclosingMethod(int len)448 _Jv_ClassReader::handleEnclosingMethod (int len)
449 {
450   if (len != 4)
451     throw_class_format_error ("invalid EnclosingMethod attribute");
452   // FIXME: only allow one...
453 
454   int class_index = read2u();
455   check_tag (class_index, JV_CONSTANT_Class);
456   prepare_pool_entry (class_index, JV_CONSTANT_Class);
457 
458   int method_index = read2u();
459   // Zero is ok and means no enclosing method.
460   if (method_index != 0)
461     {
462       check_tag (method_index, JV_CONSTANT_NameAndType);
463       prepare_pool_entry (method_index, JV_CONSTANT_NameAndType);
464     }
465 
466   ::java::io::DataOutputStream *stream = get_reflection_stream ();
467   stream->writeByte(JV_CLASS_ATTR);
468   stream->writeInt(5);
469   stream->writeByte(JV_ENCLOSING_METHOD_KIND);
470   stream->writeShort(class_index);
471   stream->writeShort(method_index);
472 }
473 
474 void
handleGenericSignature(jv_attr_type type,unsigned short index,int len)475 _Jv_ClassReader::handleGenericSignature (jv_attr_type type,
476 					 unsigned short index,
477 					 int len)
478 {
479   if (len != 2)
480     throw_class_format_error ("invalid Signature attribute");
481 
482   int cpool_idx = read2u();
483   check_tag (cpool_idx, JV_CONSTANT_Utf8);
484   prepare_pool_entry (cpool_idx, JV_CONSTANT_Utf8, false);
485 
486   ::java::io::DataOutputStream *stream = get_reflection_stream ();
487   stream->writeByte(type);
488   int attrlen = 3;
489   if (type != JV_CLASS_ATTR)
490     attrlen += 2;
491   stream->writeInt(attrlen);
492   if (type != JV_CLASS_ATTR)
493     stream->writeShort(index);
494   stream->writeByte(JV_SIGNATURE_KIND);
495   stream->writeShort(cpool_idx);
496 }
497 
498 void
handleAnnotationElement()499 _Jv_ClassReader::handleAnnotationElement()
500 {
501   int tag = read1u();
502   switch (tag)
503     {
504     case 'B':
505     case 'C':
506     case 'S':
507     case 'Z':
508     case 'I':
509       {
510 	int index = read2u();
511 	check_tag (index, JV_CONSTANT_Integer);
512 	prepare_pool_entry (index, JV_CONSTANT_Integer);
513       }
514       break;
515     case 'D':
516       {
517 	int index = read2u();
518 	check_tag (index, JV_CONSTANT_Double);
519 	prepare_pool_entry (index, JV_CONSTANT_Double);
520       }
521       break;
522     case 'F':
523       {
524 	int index = read2u();
525 	check_tag (index, JV_CONSTANT_Float);
526 	prepare_pool_entry (index, JV_CONSTANT_Float);
527       }
528       break;
529     case 'J':
530       {
531 	int index = read2u();
532 	check_tag (index, JV_CONSTANT_Long);
533 	prepare_pool_entry (index, JV_CONSTANT_Long);
534       }
535       break;
536     case 's':
537       {
538 	int index = read2u();
539 	// Despite what the JVM spec says, compilers generate a Utf8
540 	// constant here, not a String.
541 	check_tag (index, JV_CONSTANT_Utf8);
542 	prepare_pool_entry (index, JV_CONSTANT_Utf8, false);
543       }
544       break;
545 
546     case 'e':
547       {
548 	int type_name_index = read2u();
549 	int const_name_index = read2u ();
550 	check_tag (type_name_index, JV_CONSTANT_Utf8);
551 	prepare_pool_entry (type_name_index, JV_CONSTANT_Utf8);
552 	check_tag (const_name_index, JV_CONSTANT_Utf8);
553 	prepare_pool_entry (const_name_index, JV_CONSTANT_Utf8, false);
554       }
555       break;
556     case 'c':
557       {
558 	int index = read2u();
559 	check_tag (index, JV_CONSTANT_Utf8);
560 	prepare_pool_entry (index, JV_CONSTANT_Utf8);
561       }
562       break;
563     case '@':
564       handleAnnotation();
565       break;
566     case '[':
567       {
568 	int n_array_elts = read2u ();
569 	for (int i = 0; i < n_array_elts; ++i)
570 	  handleAnnotationElement();
571       }
572       break;
573     default:
574       throw_class_format_error ("invalid annotation element");
575     }
576 }
577 
578 void
handleAnnotation()579 _Jv_ClassReader::handleAnnotation()
580 {
581   int type_index = read2u();
582   check_tag (type_index, JV_CONSTANT_Utf8);
583   prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
584 
585   int npairs = read2u();
586   for (int i = 0; i < npairs; ++i)
587     {
588       int name_index = read2u();
589       check_tag (name_index, JV_CONSTANT_Utf8);
590       prepare_pool_entry (name_index, JV_CONSTANT_Utf8, false);
591       handleAnnotationElement();
592     }
593 }
594 
595 void
handleAnnotations()596 _Jv_ClassReader::handleAnnotations()
597 {
598   int num = read2u();
599   while (num--)
600     handleAnnotation();
601 }
602 
603 void
handleMemberAnnotations(jv_attr_type member_type,int member_index,int len)604 _Jv_ClassReader::handleMemberAnnotations(jv_attr_type member_type,
605 					 int member_index,
606 					 int len)
607 {
608   // We're going to copy the bytes in verbatim.  But first we want to
609   // make sure the attribute is well-formed, and we want to prepare
610   // the constant pool.  So, we save our starting point.
611   int orig_pos = pos;
612 
613   handleAnnotations();
614   // FIXME: check that we read all LEN bytes?
615 
616   ::java::io::DataOutputStream *stream = get_reflection_stream ();
617   stream->writeByte(member_type);
618   int newLen = len + 1;
619   if (member_type != JV_CLASS_ATTR)
620     newLen += 2;
621   stream->writeInt(newLen);
622   stream->writeByte(JV_ANNOTATIONS_KIND);
623   if (member_type != JV_CLASS_ATTR)
624     stream->writeShort(member_index);
625   // Write the data as-is.
626   stream->write(input_data, input_offset + orig_pos, len);
627 }
628 
629 void
handleAnnotationDefault(int member_index,int len)630 _Jv_ClassReader::handleAnnotationDefault(int member_index, int len)
631 {
632   int orig_pos = pos;
633   handleAnnotationElement();
634 
635   ::java::io::DataOutputStream *stream = get_reflection_stream ();
636   stream->writeByte(JV_METHOD_ATTR);
637   stream->writeInt(len + 3);
638   stream->writeByte(JV_ANNOTATION_DEFAULT_KIND);
639   stream->writeShort(member_index);
640   stream->write(input_data, input_offset + orig_pos, len);
641 }
642 
643 void
handleParameterAnnotations(int member_index,int len)644 _Jv_ClassReader::handleParameterAnnotations(int member_index, int len)
645 {
646   int orig_pos = pos;
647 
648   int n_params = read1u();
649   for (int i = 0; i < n_params; ++i)
650     handleAnnotations();
651 
652   ::java::io::DataOutputStream *stream = get_reflection_stream ();
653   stream->writeByte(JV_METHOD_ATTR);
654   stream->writeInt(len + 3);
655   stream->writeByte(JV_PARAMETER_ANNOTATIONS_KIND);
656   stream->writeShort(member_index);
657   stream->write(input_data, input_offset + orig_pos, len);
658 }
659 
read_constpool()660 void _Jv_ClassReader::read_constpool ()
661 {
662   tags    = (unsigned char*) _Jv_AllocBytes (pool_count);
663   offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int) * pool_count) ;
664 
665   /** first, we scan the constant pool, collecting tags and offsets */
666   tags[0]   = JV_CONSTANT_Undefined;
667   offsets[0] = pos;
668   for (int c = 1; c < pool_count; c++)
669     {
670       tags[c]    = read1u ();
671       offsets[c] = pos;
672 
673       switch (tags[c])
674 	{
675 	case JV_CONSTANT_String:
676 	case JV_CONSTANT_Class:
677 	  skip (2);
678 	  break;
679 
680 	case JV_CONSTANT_Fieldref:
681 	case JV_CONSTANT_Methodref:
682 	case JV_CONSTANT_InterfaceMethodref:
683 	case JV_CONSTANT_NameAndType:
684 	case JV_CONSTANT_Integer:
685 	case JV_CONSTANT_Float:
686 	  skip (4);
687 	  break;
688 
689 	case JV_CONSTANT_Double:
690 	case JV_CONSTANT_Long:
691 	  skip (8);
692 	  tags[++c] = JV_CONSTANT_Undefined;
693 	  break;
694 
695 	case JV_CONSTANT_Utf8:
696 	  {
697 	    int len = read2u ();
698 	    skip (len);
699 	  }
700 	  break;
701 
702 	case JV_CONSTANT_Unicode:
703 	  throw_class_format_error ("unicode not supported");
704 	  break;
705 
706 	default:
707 	  throw_class_format_error ("erroneous constant pool tag");
708 	}
709     }
710 
711   handleConstantPool ();
712 }
713 
714 
read_fields()715 void _Jv_ClassReader::read_fields ()
716 {
717   int fields_count = read2u ();
718   handleFieldsBegin (fields_count);
719 
720   // We want to sort the fields so that static fields come first,
721   // followed by instance fields.  We do this before parsing the
722   // fields so that we can have the new indices available when
723   // creating the annotation data structures.
724 
725   // Allocate this on the heap in case there are a large number of
726   // fields.
727   int *fieldmap = (int *) _Jv_AllocBytes (fields_count * sizeof (int));
728   int save_pos = pos;
729   int static_count = 0, instance_count = -1;
730   for (int i = 0; i < fields_count; ++i)
731     {
732       using namespace java::lang::reflect;
733 
734       int access_flags = read2u ();
735       skip (4);
736       int attributes_count = read2u ();
737 
738       if ((access_flags & Modifier::STATIC) != 0)
739 	fieldmap[i] = static_count++;
740       else
741 	fieldmap[i] = instance_count--;
742 
743       for (int j = 0; j < attributes_count; ++j)
744 	{
745 	  skip (2);
746 	  int length = read4 ();
747 	  skip (length);
748 	}
749     }
750   pos = save_pos;
751 
752   // In the loop above, instance fields are represented by negative
753   // numbers.  Here we rewrite these to be proper offsets.
754   for (int i = 0; i < fields_count; ++i)
755     {
756       if (fieldmap[i] < 0)
757 	fieldmap[i] = static_count - 1 - fieldmap[i];
758     }
759   def->static_field_count = static_count;
760 
761   for (int i = 0; i < fields_count; i++)
762     {
763       int access_flags     = read2u ();
764       int name_index       = read2u ();
765       int descriptor_index = read2u ();
766       int attributes_count = read2u ();
767 
768       check_tag (name_index, JV_CONSTANT_Utf8);
769       prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
770 
771       check_tag (descriptor_index, JV_CONSTANT_Utf8);
772       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
773 
774       handleField (i, access_flags, name_index, descriptor_index, fieldmap);
775 
776       bool found_value = false;
777       for (int j = 0; j < attributes_count; j++)
778 	{
779 	  read_one_field_attribute (fieldmap[i], &found_value);
780 	}
781     }
782 }
783 
784 bool
is_attribute_name(int index,const char * name)785 _Jv_ClassReader::is_attribute_name (int index, const char *name)
786 {
787   check_tag (index, JV_CONSTANT_Utf8);
788   int len = get2u (bytes+offsets[index]);
789   if (len != (int) strlen (name))
790     return false;
791   else
792     return !memcmp (bytes+offsets[index]+2, name, len);
793 }
794 
795 // Get a UTF8 value from the constant pool and turn it into a garbage
796 // collected char array.
pool_Utf8_to_char_arr(int index,char ** entry)797 int _Jv_ClassReader::pool_Utf8_to_char_arr (int index, char** entry)
798 {
799   check_tag (index, JV_CONSTANT_Utf8);
800   int len = get2u (bytes + offsets[index]);
801   *entry = reinterpret_cast<char *> (_Jv_AllocBytes (len + 1));
802   (*entry)[len] = '\0';
803   memcpy (*entry, bytes + offsets[index] + 2, len);
804   return len + 1;
805 }
806 
read_one_field_attribute(int field_index,bool * found_value)807 void _Jv_ClassReader::read_one_field_attribute (int field_index,
808 						bool *found_value)
809 {
810   int name = read2u ();
811   int length = read4 ();
812 
813   if (is_attribute_name (name, "ConstantValue"))
814     {
815       int cv = read2u ();
816 
817       if (cv < pool_count
818 	  && cv > 0
819 	  && (tags[cv] == JV_CONSTANT_Integer
820 	      || tags[cv] == JV_CONSTANT_Float
821 	      || tags[cv] == JV_CONSTANT_Long
822 	      || tags[cv] == JV_CONSTANT_Double
823 	      || tags[cv] == JV_CONSTANT_String))
824 	{
825 	  handleConstantValueAttribute (field_index, cv, found_value);
826 	}
827       else
828 	{
829 	  throw_class_format_error ("erroneous ConstantValue attribute");
830 	}
831 
832       if (length != 2)
833 	throw_class_format_error ("erroneous ConstantValue attribute");
834     }
835   else if (is_attribute_name (name, "Signature"))
836     handleGenericSignature(JV_FIELD_ATTR, field_index, length);
837   else if (is_attribute_name (name, "RuntimeVisibleAnnotations"))
838     handleMemberAnnotations(JV_FIELD_ATTR, field_index, length);
839   else
840     skip (length);
841 }
842 
read_methods()843 void _Jv_ClassReader::read_methods ()
844 {
845   int methods_count = read2u ();
846 
847   handleMethodsBegin (methods_count);
848 
849   for (int i = 0; i < methods_count; i++)
850     {
851       int access_flags     = read2u ();
852       int name_index       = read2u ();
853       int descriptor_index = read2u ();
854       int attributes_count = read2u ();
855 
856       check_tag (name_index, JV_CONSTANT_Utf8);
857       prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
858 
859       check_tag (descriptor_index, JV_CONSTANT_Utf8);
860       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
861 
862       handleMethod (i, access_flags, name_index,
863 		    descriptor_index);
864 
865       for (int j = 0; j < attributes_count; j++)
866 	{
867 	  read_one_method_attribute (i);
868 	}
869     }
870 
871   handleMethodsEnd ();
872 }
873 
read_one_method_attribute(int method_index)874 void _Jv_ClassReader::read_one_method_attribute (int method_index)
875 {
876   int name = read2u ();
877   int length = read4 ();
878 
879   if (is_attribute_name (name, "Exceptions"))
880     {
881       _Jv_Method *method = reinterpret_cast<_Jv_Method *>
882 	(&def->methods[method_index]);
883       if (method->throws != NULL)
884 	throw_class_format_error ("only one Exceptions attribute allowed per method");
885 
886       int num_exceptions = read2u ();
887       _Jv_Utf8Const **exceptions =
888 	(_Jv_Utf8Const **) _Jv_AllocBytes ((num_exceptions + 1)
889 					   * sizeof (_Jv_Utf8Const *));
890 
891       int out = 0;
892       _Jv_word *pool_data = def->constants.data;
893       for (int i = 0; i < num_exceptions; ++i)
894 	{
895 	  int ndx = read2u ();
896 	  // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
897 	  if (ndx != 0)
898 	    {
899 	      check_tag (ndx, JV_CONSTANT_Class);
900 	      exceptions[out++] = pool_data[ndx].utf8;
901 	    }
902 	}
903       exceptions[out] = NULL;
904       method->throws = exceptions;
905     }
906 
907   else if (is_attribute_name (name, "Code"))
908     {
909       int start_off = pos;
910       int max_stack = read2u ();
911       int max_locals = read2u ();
912       int code_length = read4 ();
913 
914       int code_start = pos;
915       skip (code_length);
916       int exception_table_length = read2u ();
917 
918       handleCodeAttribute (method_index,
919 			   max_stack, max_locals,
920 			   code_start, code_length,
921 			   exception_table_length);
922 
923 
924       for (int i = 0; i < exception_table_length; i++)
925 	{
926 	  int start_pc   = read2u ();
927 	  int end_pc     = read2u ();
928 	  int handler_pc = read2u ();
929 	  int catch_type = read2u ();
930 
931 	  if (start_pc > end_pc
932 	      || start_pc < 0
933 	      // END_PC can be equal to CODE_LENGTH.
934 	      // See JVM Spec 4.7.4.
935 	      || end_pc > code_length
936 	      || handler_pc >= code_length)
937 	    throw_class_format_error ("erroneous exception handler info");
938 
939 	  if (! (tags[catch_type] == JV_CONSTANT_Class
940 		 || tags[catch_type] == 0))
941 	    {
942 	      throw_class_format_error ("erroneous exception handler info");
943 	    }
944 
945 	  handleExceptionTableEntry (method_index,
946 				     i,
947 				     start_pc,
948 				     end_pc,
949 				     handler_pc,
950 				     catch_type);
951 
952 	}
953 
954       int attributes_count = read2u ();
955 
956       for (int i = 0; i < attributes_count; i++)
957 	{
958 	  read_one_code_attribute (method_index);
959 	}
960 
961       if ((pos - start_off) != length)
962 	throw_class_format_error ("code attribute too short");
963     }
964   else if (is_attribute_name (name, "Signature"))
965     handleGenericSignature(JV_METHOD_ATTR, method_index, length);
966   else if (is_attribute_name (name, "RuntimeVisibleAnnotations"))
967     handleMemberAnnotations(JV_METHOD_ATTR, method_index, length);
968   else if (is_attribute_name (name, "RuntimeVisibleParameterAnnotations"))
969     handleParameterAnnotations(method_index, length);
970   else if (is_attribute_name (name, "AnnotationDefault"))
971     handleAnnotationDefault(method_index, length);
972   else
973     {
974       /* ignore unknown attributes */
975       skip (length);
976     }
977 }
978 
read_one_code_attribute(int method_index)979 void _Jv_ClassReader::read_one_code_attribute (int method_index)
980 {
981   int name = read2u ();
982   int length = read4 ();
983   if (is_attribute_name (name, "LineNumberTable"))
984     {
985       _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
986 	(def_interp->interpreted_methods[method_index]);
987       if (method->line_table != NULL)
988 	throw_class_format_error ("Method already has LineNumberTable");
989 
990       int table_len = read2u ();
991       _Jv_LineTableEntry* table
992 	= (_Jv_LineTableEntry *) _Jv_AllocBytes (table_len
993 						 * sizeof (_Jv_LineTableEntry));
994       for (int i = 0; i < table_len; i++)
995        {
996 	 table[i].bytecode_pc = read2u ();
997 	 table[i].line = read2u ();
998        }
999       method->line_table_len = table_len;
1000       method->line_table = table;
1001     }
1002   else if (is_attribute_name (name, "LocalVariableTable"))
1003     {
1004       _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1005 	                       (def_interp->interpreted_methods[method_index]);
1006       if (method->local_var_table != NULL)
1007         throw_class_format_error ("Method already has LocalVariableTable");
1008 
1009       int table_len = read2u ();
1010       _Jv_LocalVarTableEntry *table
1011         = reinterpret_cast<_Jv_LocalVarTableEntry *>
1012             (_Jv_AllocRawObj (table_len * sizeof (_Jv_LocalVarTableEntry)));
1013 
1014       for (int i = 0; i < table_len; i++)
1015         {
1016           table[i].bytecode_pc = read2u ();
1017           table[i].length = read2u ();
1018           pool_Utf8_to_char_arr (read2u (), &table[i].name);
1019           pool_Utf8_to_char_arr (read2u (), &table[i].descriptor);
1020           table[i].slot = read2u ();
1021 
1022           if (table[i].slot > method->max_locals || table[i].slot < 0)
1023             throw_class_format_error ("Malformed Local Variable Table: Invalid Slot");
1024         }
1025 
1026       method->local_var_table_len = table_len;
1027       method->local_var_table = table;
1028     }
1029   else
1030     {
1031       /* ignore unknown code attributes */
1032       skip (length);
1033     }
1034 }
1035 
read_one_class_attribute()1036 void _Jv_ClassReader::read_one_class_attribute ()
1037 {
1038   int name = read2u ();
1039   int length = read4 ();
1040   if (is_attribute_name (name, "SourceFile"))
1041     {
1042       int source_index = read2u ();
1043       check_tag (source_index, JV_CONSTANT_Utf8);
1044       prepare_pool_entry (source_index, JV_CONSTANT_Utf8, false);
1045       def_interp->source_file_name = _Jv_NewStringUtf8Const
1046 	(def->constants.data[source_index].utf8);
1047     }
1048   else if (is_attribute_name (name, "Signature"))
1049     handleGenericSignature(JV_CLASS_ATTR, 0, length);
1050   else if (is_attribute_name (name, "EnclosingMethod"))
1051     handleEnclosingMethod(length);
1052   else if (is_attribute_name (name, "RuntimeVisibleAnnotations"))
1053     handleMemberAnnotations(JV_CLASS_ATTR, 0, length);
1054   else if (is_attribute_name (name, "InnerClasses"))
1055     {
1056       ::java::io::DataOutputStream *stream = get_reflection_stream ();
1057       stream->writeByte(JV_CLASS_ATTR);
1058       stream->writeInt(length + 1);
1059       stream->writeByte(JV_INNER_CLASSES_KIND);
1060       stream->write(input_data, input_offset + pos, length);
1061       skip (length);
1062     }
1063   else
1064     {
1065       /* Currently, we ignore most class attributes. */
1066      skip (length);
1067     }
1068 }
1069 
1070 
1071 
1072 
1073 /* this section defines the semantic actions of the parser */
1074 
handleConstantPool()1075 void _Jv_ClassReader::handleConstantPool ()
1076 {
1077   /** now, we actually define the class' constant pool */
1078 
1079   jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
1080   _Jv_word *pool_data
1081     = (_Jv_word*) _Jv_AllocRawObj (pool_count * sizeof (_Jv_word));
1082 
1083   def->constants.tags = pool_tags;
1084   def->constants.data = pool_data;
1085   def->constants.size = pool_count;
1086 
1087   // Here we make a pass to collect the strings!   We do this, because
1088   // internally in the GCJ runtime, classes are encoded with .'s not /'s.
1089   // Therefore, we first collect the strings, and then translate the rest
1090   // of the utf8-entries (thus not representing strings) from /-notation
1091   // to .-notation.
1092   for (int i = 1; i < pool_count; i++)
1093     {
1094       if (tags[i] == JV_CONSTANT_String)
1095 	{
1096 	  unsigned char* str_data = bytes + offsets [i];
1097 	  int utf_index = get2u (str_data);
1098 	  check_tag (utf_index, JV_CONSTANT_Utf8);
1099 	  unsigned char *utf_data = bytes + offsets[utf_index];
1100 	  int len = get2u (utf_data);
1101 	  pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
1102 	  pool_tags[i] = JV_CONSTANT_String;
1103 	}
1104       else
1105 	{
1106 	  pool_tags[i] = JV_CONSTANT_Undefined;
1107 	}
1108     }
1109 
1110   // and now, we scan everything else but strings & utf8-entries.  This
1111   // leaves out those utf8-entries which are not used; which will be left
1112   // with a tag of JV_CONSTANT_Undefined in the class definition.
1113   for (int index = 1; index < pool_count; index++)
1114     {
1115       switch (tags[index])
1116 	{
1117 	case JV_CONSTANT_Undefined:
1118 	case JV_CONSTANT_String:
1119 	case JV_CONSTANT_Utf8:
1120 	  continue;
1121 
1122 	default:
1123 	  prepare_pool_entry (index, tags[index]);
1124 	}
1125     }
1126 
1127 }
1128 
1129 /* this is a recursive procedure, which will prepare pool entries as needed.
1130    Which is how we avoid initializing those entries which go unused.
1131 
1132    REWRITE is true iff this pool entry is the Utf8 representation of a
1133    class name or a signature.
1134 */
1135 
1136 void
prepare_pool_entry(int index,unsigned char this_tag,bool rewrite)1137 _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag,
1138 				     bool rewrite)
1139 {
1140   /* these two, pool_data and pool_tags, point into the class
1141      structure we are currently defining */
1142 
1143   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
1144   _Jv_word      *pool_data = def->constants.data;
1145 
1146   /* this entry was already prepared */
1147   if (pool_tags[index] == this_tag)
1148     return;
1149 
1150   /* this_data points to the constant-pool information for the current
1151      constant-pool entry */
1152 
1153   unsigned char *this_data = bytes + offsets[index];
1154 
1155   switch (this_tag)
1156     {
1157     case JV_CONSTANT_Utf8:
1158       {
1159 	int len = get2u (this_data);
1160 	char *s = ((char*) this_data)+2;
1161 	pool_tags[index] = JV_CONSTANT_Utf8;
1162 
1163 	if (! rewrite)
1164 	  {
1165 	    pool_data[index].utf8 = _Jv_makeUtf8Const (s, len);
1166 	    break;
1167 	  }
1168 
1169 	// If REWRITE is set, it is because some other tag needs this
1170 	// utf8-entry for type information: it is a class or a
1171 	// signature.  Thus, we translate /'s to .'s in order to
1172 	// accomondate gcj's internal representation.
1173 	char *buffer = (char*) __builtin_alloca (len);
1174 	for (int i = 0; i < len; i++)
1175 	  {
1176 	    if (s[i] == '/')
1177 	      buffer[i] = '.';
1178 	    else
1179 	      buffer[i] = s[i];
1180 	  }
1181 	pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
1182       }
1183       break;
1184 
1185     case JV_CONSTANT_Class:
1186       {
1187 	int utf_index = get2u (this_data);
1188 	check_tag (utf_index, JV_CONSTANT_Utf8);
1189 	prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
1190 
1191 	if (verify)
1192 	  verify_classname (pool_data[utf_index].utf8);
1193 
1194 	pool_data[index].utf8 = pool_data[utf_index].utf8;
1195 	pool_tags[index] = JV_CONSTANT_Class;
1196       }
1197       break;
1198 
1199     case JV_CONSTANT_String:
1200       // already handled before...
1201       break;
1202 
1203     case JV_CONSTANT_Fieldref:
1204     case JV_CONSTANT_Methodref:
1205     case JV_CONSTANT_InterfaceMethodref:
1206       {
1207 	int class_index = get2u (this_data);
1208 	int nat_index = get2u (this_data+2);
1209 
1210 	check_tag (class_index, JV_CONSTANT_Class);
1211 	prepare_pool_entry (class_index, JV_CONSTANT_Class);
1212 
1213 	check_tag (nat_index, JV_CONSTANT_NameAndType);
1214 	prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
1215 
1216 	// here, verify the signature and identifier name
1217 	if (verify)
1218 	{
1219 	  _Jv_ushort name_index, type_index;
1220 	  _Jv_loadIndexes (&pool_data[nat_index],
1221 			   name_index, type_index);
1222 
1223 	  if (this_tag == JV_CONSTANT_Fieldref)
1224 	    verify_field_signature (pool_data[type_index].utf8);
1225 	  else
1226 	    verify_method_signature (pool_data[type_index].utf8);
1227 
1228 	  _Jv_Utf8Const* name = pool_data[name_index].utf8;
1229 
1230 	  if (this_tag != JV_CONSTANT_Fieldref
1231 	      && (   _Jv_equalUtf8Consts (name, clinit_name)
1232 		  || _Jv_equalUtf8Consts (name, init_name)))
1233 	    /* ignore */;
1234 	  else
1235 	    verify_identifier (pool_data[name_index].utf8);
1236 	}
1237 
1238 	_Jv_storeIndexes (&pool_data[index], class_index, nat_index);
1239 	pool_tags[index] = this_tag;
1240       }
1241       break;
1242 
1243     case JV_CONSTANT_NameAndType:
1244       {
1245 	_Jv_ushort name_index = get2u (this_data);
1246 	_Jv_ushort type_index = get2u (this_data+2);
1247 
1248 	check_tag (name_index, JV_CONSTANT_Utf8);
1249 	prepare_pool_entry (name_index, JV_CONSTANT_Utf8, false);
1250 	check_tag (type_index, JV_CONSTANT_Utf8);
1251 	prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
1252 
1253 	_Jv_storeIndexes (&pool_data[index], name_index, type_index);
1254 	pool_tags[index] = JV_CONSTANT_NameAndType;
1255       }
1256       break;
1257 
1258     case JV_CONSTANT_Float:
1259       {
1260 	jfloat f = java::lang::Float::intBitsToFloat ((jint) get4 (this_data));
1261 	_Jv_storeFloat (&pool_data[index], f);
1262 	pool_tags[index] = JV_CONSTANT_Float;
1263       }
1264       break;
1265 
1266     case JV_CONSTANT_Integer:
1267       {
1268 	int i = get4 (this_data);
1269 	_Jv_storeInt (&pool_data[index], i);
1270 	pool_tags[index] = JV_CONSTANT_Integer;
1271       }
1272       break;
1273 
1274     case JV_CONSTANT_Double:
1275       {
1276 	jdouble d
1277 	  = java::lang::Double::longBitsToDouble ((jlong) get8 (this_data));
1278 	_Jv_storeDouble (&pool_data[index], d);
1279 	pool_tags[index] = JV_CONSTANT_Double;
1280       }
1281       break;
1282 
1283     case JV_CONSTANT_Long:
1284       {
1285 	jlong i = get8 (this_data);
1286 	_Jv_storeLong (&pool_data[index], i);
1287 	pool_tags[index] = JV_CONSTANT_Long;
1288       }
1289       break;
1290 
1291     default:
1292       throw_class_format_error ("erroneous constant pool tag");
1293     }
1294 }
1295 
1296 
1297 void
handleClassBegin(int access_flags,int this_class,int super_class)1298 _Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_class)
1299 {
1300   using namespace java::lang::reflect;
1301 
1302   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
1303   _Jv_word      *pool_data = def->constants.data;
1304 
1305   check_tag (this_class, JV_CONSTANT_Class);
1306   _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
1307 
1308   // was ClassLoader.defineClass called with an expected class name?
1309   if (def->name == 0)
1310     {
1311       jclass orig = def->loader->findLoadedClass(loadedName->toString());
1312 
1313       if (orig == 0)
1314 	{
1315 	  def->name = loadedName;
1316 	}
1317       else
1318 	{
1319 	  jstring msg = JvNewStringUTF ("anonymous "
1320 					"class data denotes "
1321 					"existing class ");
1322 	  msg = msg->concat (orig->getName ());
1323 
1324 	  throw_no_class_def_found_error (msg);
1325 	}
1326     }
1327 
1328   // assert that the loaded class has the expected name, 5.3.5
1329   else if (! _Jv_equalUtf8Consts (loadedName, def->name))
1330     {
1331       jstring msg = JvNewStringUTF ("loaded class ");
1332       msg = msg->concat (def->getName ());
1333       msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
1334       jstring klass_name = loadedName->toString();
1335       msg = msg->concat (klass_name);
1336 
1337       throw_no_class_def_found_error (msg);
1338     }
1339 
1340   def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
1341   pool_data[this_class].clazz = def;
1342   pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
1343 
1344   if (super_class == 0)
1345     {
1346       // Note that this is ok if we are defining java.lang.Object.
1347       // But there is no way to have this class be interpreted.
1348       throw_class_format_error ("no superclass reference");
1349     }
1350 
1351   def->state = JV_STATE_PRELOADING;
1352 
1353   // Register this class with its defining loader as well (despite the
1354   // name of the function we're calling), so that super class lookups
1355   // work properly.  If there is an error, our caller will unregister
1356   // this class from the class loader.  Also, we don't need to hold a
1357   // lock here, as our caller has acquired it.
1358   _Jv_RegisterInitiatingLoader (def, def->loader);
1359 
1360   // Note that we found a name so that unregistration can happen if
1361   // needed.
1362   *found_name = def->name;
1363 
1364   if (super_class != 0)
1365     {
1366       // Load the superclass.
1367       check_tag (super_class, JV_CONSTANT_Class);
1368       _Jv_Utf8Const* super_name = pool_data[super_class].utf8;
1369 
1370       // Load the superclass using our defining loader.
1371       jclass the_super = _Jv_FindClass (super_name, def->loader);
1372 
1373       // This will establish that we are allowed to be a subclass,
1374       // and check for class circularity error.
1375       checkExtends (def, the_super);
1376 
1377       // Note: for an interface we will find Object as the
1378       // superclass.  We still check it above to ensure class file
1379       // validity, but we simply assign `null' to the actual field in
1380       // this case.
1381       def->superclass = (((access_flags & Modifier::INTERFACE))
1382 			 ? NULL : the_super);
1383       pool_data[super_class].clazz = the_super;
1384       pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
1385     }
1386 
1387   // Now we've come past the circularity problem, we can
1388   // now say that we're loading.
1389 
1390   def->state = JV_STATE_LOADING;
1391   def->notifyAll ();
1392 }
1393 
1394 ///// Implements the checks described in sect. 5.3.5.3
1395 void
checkExtends(jclass sub,jclass super)1396 _Jv_ClassReader::checkExtends (jclass sub, jclass super)
1397 {
1398   using namespace java::lang::reflect;
1399 
1400   _Jv_Linker::wait_for_state (super, JV_STATE_LOADING);
1401 
1402   // Having an interface or a final class as a superclass is no good.
1403   if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
1404     {
1405       throw_incompatible_class_change_error (sub->getName ());
1406     }
1407 
1408   // If the super class is not public, we need to check some more.
1409   if ((super->accflags & Modifier::PUBLIC) == 0)
1410     {
1411       // With package scope, the classes must have the same class
1412       // loader.
1413       if (   sub->loader != super->loader
1414 	  || !_Jv_ClassNameSamePackage (sub->name, super->name))
1415 	{
1416 	  throw_incompatible_class_change_error (sub->getName ());
1417 	}
1418     }
1419 
1420   for (; super != 0; super = super->getSuperclass ())
1421     {
1422       if (super == sub)
1423 	throw_class_circularity_error (sub->getName ());
1424     }
1425 }
1426 
1427 
1428 
handleInterfacesBegin(int count)1429 void _Jv_ClassReader::handleInterfacesBegin (int count)
1430 {
1431   def->interfaces = (jclass*) _Jv_AllocRawObj (count*sizeof (jclass));
1432   def->interface_count = count;
1433 }
1434 
handleInterface(int if_number,int offset)1435 void _Jv_ClassReader::handleInterface (int if_number, int offset)
1436 {
1437   _Jv_word       * pool_data = def->constants.data;
1438   unsigned char  * pool_tags = (unsigned char*) def->constants.tags;
1439 
1440   jclass the_interface;
1441 
1442   if (pool_tags[offset] == JV_CONSTANT_Class)
1443     {
1444       _Jv_Utf8Const* name = pool_data[offset].utf8;
1445       the_interface =  _Jv_FindClass (name, def->loader);
1446     }
1447   else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
1448     {
1449       the_interface = pool_data[offset].clazz;
1450     }
1451   else
1452     {
1453       throw_no_class_def_found_error ("erroneous constant pool tag");
1454     }
1455 
1456   // checks the validity of the_interface, and that we are in fact
1457   // allowed to implement that interface.
1458   checkImplements (def, the_interface);
1459 
1460   pool_data[offset].clazz = the_interface;
1461   pool_tags[offset] = JV_CONSTANT_ResolvedClass;
1462 
1463   def->interfaces[if_number] = the_interface;
1464 }
1465 
1466 void
checkImplements(jclass sub,jclass super)1467 _Jv_ClassReader::checkImplements (jclass sub, jclass super)
1468 {
1469   using namespace java::lang::reflect;
1470 
1471   // well, it *must* be an interface
1472   if ((super->accflags & Modifier::INTERFACE) == 0)
1473     {
1474       throw_incompatible_class_change_error (sub->getName ());
1475     }
1476 
1477   // if it has package scope, it must also be defined by the
1478   // same loader.
1479   if ((super->accflags & Modifier::PUBLIC) == 0)
1480     {
1481       if (    sub->loader != super->loader
1482 	  || !_Jv_ClassNameSamePackage (sub->name, super->name))
1483 	{
1484 	  throw_incompatible_class_change_error (sub->getName ());
1485 	}
1486     }
1487 
1488   // FIXME: add interface circularity check here
1489   if (sub == super)
1490     {
1491       throw_class_circularity_error (sub->getName ());
1492     }
1493 }
1494 
handleFieldsBegin(int count)1495 void _Jv_ClassReader::handleFieldsBegin (int count)
1496 {
1497   def->fields = (_Jv_Field*) _Jv_AllocRawObj (count * sizeof (_Jv_Field));
1498   def->field_count = count;
1499   def_interp->field_initializers
1500     = (_Jv_ushort*) _Jv_AllocRawObj (count * sizeof (_Jv_ushort));
1501   for (int i = 0; i < count; i++)
1502     def_interp->field_initializers[i] = (_Jv_ushort) 0;
1503 }
1504 
handleField(int field_no,int flags,int name,int desc,int * fieldmap)1505 void _Jv_ClassReader::handleField (int field_no,
1506 				   int flags,
1507 				   int name,
1508 				   int desc,
1509 				   int *fieldmap)
1510 {
1511   using namespace java::lang::reflect;
1512 
1513   _Jv_word *pool_data = def->constants.data;
1514 
1515   _Jv_Field *field = &def->fields[fieldmap[field_no]];
1516   _Jv_Utf8Const *field_name = pool_data[name].utf8;
1517 
1518   field->name      = field_name;
1519 
1520   // Ignore flags we don't know about.
1521   field->flags = flags & (Field::FIELD_MODIFIERS
1522 			  | Modifier::SYNTHETIC
1523 			  | Modifier::ENUM);
1524 
1525   _Jv_Utf8Const* sig = pool_data[desc].utf8;
1526 
1527   if (verify)
1528     {
1529       verify_identifier (field_name);
1530 
1531       for (int i = 0; i < field_no; ++i)
1532 	{
1533 	  if (_Jv_equalUtf8Consts (field_name, def->fields[fieldmap[i]].name)
1534 	      && _Jv_equalUtf8Consts (sig,
1535 				      // We know the other fields are
1536 				      // unresolved.
1537 				      (_Jv_Utf8Const *) def->fields[i].type))
1538 	    throw_class_format_error ("duplicate field name");
1539 	}
1540 
1541       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1542       if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
1543 		+((field->flags & Modifier::PRIVATE) ? 1 : 0)
1544 		+((field->flags & Modifier::PROTECTED) ? 1 : 0)))
1545 	throw_class_format_error ("erroneous field access flags");
1546 
1547       // FIXME: JVM spec S4.5: Verify ACC_FINAL and ACC_VOLATILE are not
1548       // both set. Verify modifiers for interface fields.
1549 
1550     }
1551 
1552   if (verify)
1553     verify_field_signature (sig);
1554 
1555   // field->type is really a jclass, but while it is still
1556   // unresolved we keep an _Jv_Utf8Const* instead.
1557   field->type       = (jclass) sig;
1558   field->flags     |= _Jv_FIELD_UNRESOLVED_FLAG;
1559   field->u.boffset  = 0;
1560 }
1561 
1562 
handleConstantValueAttribute(int field_index,int value,bool * found_value)1563 void _Jv_ClassReader::handleConstantValueAttribute (int field_index,
1564 						    int value,
1565 						    bool *found_value)
1566 {
1567   using namespace java::lang::reflect;
1568 
1569   _Jv_Field *field = &def->fields[field_index];
1570 
1571   if ((field->flags & (Modifier::STATIC
1572 		       | Modifier::FINAL
1573 		       | Modifier::PRIVATE)) == 0)
1574     {
1575       // Ignore, as per vmspec #4.7.2
1576       return;
1577     }
1578 
1579   // do not allow multiple constant fields!
1580   if (*found_value)
1581     throw_class_format_error ("field has multiple ConstantValue attributes");
1582 
1583   *found_value = true;
1584   def_interp->field_initializers[field_index] = value;
1585 
1586   /* type check the initializer */
1587 
1588   if (value <= 0 || value >= pool_count)
1589     throw_class_format_error ("erroneous ConstantValue attribute");
1590 
1591   /* FIXME: do the rest */
1592 }
1593 
1594 void
handleMethodsBegin(int count)1595 _Jv_ClassReader::handleMethodsBegin (int count)
1596 {
1597   def->methods = (_Jv_Method *) _Jv_AllocRawObj (sizeof (_Jv_Method) * count);
1598 
1599   def_interp->interpreted_methods
1600     = (_Jv_MethodBase **) _Jv_AllocRawObj (sizeof (_Jv_MethodBase *)
1601 					   * count);
1602 
1603   for (int i = 0; i < count; i++)
1604     {
1605       def_interp->interpreted_methods[i] = 0;
1606       def->methods[i].index = (_Jv_ushort) -1;
1607     }
1608 
1609   def->method_count = count;
1610 }
1611 
1612 
handleMethod(int mth_index,int accflags,int name,int desc)1613 void _Jv_ClassReader::handleMethod
1614     (int mth_index, int accflags, int name, int desc)
1615 {
1616   using namespace java::lang::reflect;
1617 
1618   _Jv_word *pool_data = def->constants.data;
1619   _Jv_Method *method = &def->methods[mth_index];
1620 
1621   check_tag (name, JV_CONSTANT_Utf8);
1622   prepare_pool_entry (name, JV_CONSTANT_Utf8, false);
1623   method->name = pool_data[name].utf8;
1624 
1625   check_tag (desc, JV_CONSTANT_Utf8);
1626   prepare_pool_entry (desc, JV_CONSTANT_Utf8);
1627   method->signature = pool_data[desc].utf8;
1628 
1629   // ignore unknown flags
1630   method->accflags = accflags & (Method::METHOD_MODIFIERS
1631 				 | Modifier::BRIDGE
1632 				 | Modifier::SYNTHETIC
1633 				 | Modifier::VARARGS);
1634 
1635   // Initialize...
1636   method->ncode = 0;
1637   method->throws = NULL;
1638 
1639   if (verify)
1640     {
1641       if (_Jv_equalUtf8Consts (method->name, clinit_name)
1642 	  || _Jv_equalUtf8Consts (method->name, init_name))
1643 	/* ignore */;
1644       else
1645 	verify_identifier (method->name);
1646 
1647       verify_method_signature (method->signature);
1648 
1649       for (int i = 0; i < mth_index; ++i)
1650 	{
1651 	  if (_Jv_equalUtf8Consts (method->name, def->methods[i].name)
1652 	      && _Jv_equalUtf8Consts (method->signature,
1653 				      def->methods[i].signature))
1654 	    throw_class_format_error ("duplicate method");
1655 	}
1656 
1657       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1658       if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
1659 		+((method->accflags & Modifier::PRIVATE) ? 1 : 0)
1660 		+((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
1661 	throw_class_format_error ("erroneous method access flags");
1662 
1663       // FIXME: JVM spec S4.6: if ABSTRACT modifier is set, verify other
1664       // flags are not set. Verify flags for interface methods.  Verify
1665       // modifiers for initializers.
1666     }
1667 }
1668 
handleCodeAttribute(int method_index,int max_stack,int max_locals,int code_start,int code_length,int exc_table_length)1669 void _Jv_ClassReader::handleCodeAttribute
1670   (int method_index, int max_stack, int max_locals,
1671    int code_start, int code_length, int exc_table_length)
1672 {
1673   int size = _Jv_InterpMethod::size (exc_table_length, code_length);
1674   _Jv_InterpMethod *method =
1675     (_Jv_InterpMethod*) (_Jv_AllocRawObj (size));
1676 
1677   method->max_stack      = max_stack;
1678   method->max_locals     = max_locals;
1679   method->code_length    = code_length;
1680   method->exc_count      = exc_table_length;
1681   method->is_15          = is_15;
1682   method->defining_class = def;
1683   method->self           = &def->methods[method_index];
1684   method->prepared       = NULL;
1685   method->line_table_len = 0;
1686   method->line_table     = NULL;
1687 #ifdef DIRECT_THREADED
1688   method->thread_count   = 0;
1689 #endif
1690 
1691   // grab the byte code!
1692   memcpy ((void*) method->bytecode (),
1693 	  (void*) (bytes+code_start),
1694 	  code_length);
1695 
1696   def_interp->interpreted_methods[method_index] = method;
1697 
1698   if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
1699     {
1700       // Precompute the ncode field for a static method.  This lets us
1701       // call a static method of an interpreted class from precompiled
1702       // code without first resolving the class (that will happen
1703       // during class initialization instead).
1704       method->self->ncode = method->ncode (def);
1705     }
1706 }
1707 
handleExceptionTableEntry(int method_index,int exc_index,int start_pc,int end_pc,int handler_pc,int catch_type)1708 void _Jv_ClassReader::handleExceptionTableEntry
1709   (int method_index, int exc_index,
1710    int start_pc, int end_pc, int handler_pc, int catch_type)
1711 {
1712   _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1713     (def_interp->interpreted_methods[method_index]);
1714   _Jv_InterpException *exc = method->exceptions ();
1715 
1716   exc[exc_index].start_pc.i     = start_pc;
1717   exc[exc_index].end_pc.i       = end_pc;
1718   exc[exc_index].handler_pc.i   = handler_pc;
1719   exc[exc_index].handler_type.i = catch_type;
1720 }
1721 
handleMethodsEnd()1722 void _Jv_ClassReader::handleMethodsEnd ()
1723 {
1724   using namespace java::lang::reflect;
1725 
1726   for (int i = 0; i < def->method_count; i++)
1727     {
1728       _Jv_Method *method = &def->methods[i];
1729       if ((method->accflags & Modifier::NATIVE) != 0)
1730 	{
1731 	  if (def_interp->interpreted_methods[i] != 0)
1732 	    throw_class_format_error ("code provided for native method");
1733 	  else
1734 	    {
1735 	      _Jv_JNIMethod *m = (_Jv_JNIMethod *)
1736 		_Jv_AllocRawObj (sizeof (_Jv_JNIMethod));
1737 	      m->defining_class = def;
1738 	      m->self = method;
1739 	      m->function = NULL;
1740 	      def_interp->interpreted_methods[i] = m;
1741 
1742 	      if ((method->accflags & Modifier::STATIC))
1743 		{
1744 		  // Precompute the ncode field for a static method.
1745 		  // This lets us call a static method of an
1746 		  // interpreted class from precompiled code without
1747 		  // first resolving the class (that will happen
1748 		  // during class initialization instead).
1749 		  method->ncode = m->ncode (def);
1750 		}
1751 	    }
1752 	}
1753       else if ((method->accflags & Modifier::ABSTRACT) != 0)
1754 	{
1755 	  if (def_interp->interpreted_methods[i] != 0)
1756 	    throw_class_format_error ("code provided for abstract method");
1757 	  method->ncode = (void *) &_Jv_ThrowAbstractMethodError;
1758 	}
1759       else
1760 	{
1761 	  if (def_interp->interpreted_methods[i] == 0)
1762 	    throw_class_format_error ("method with no code");
1763 	}
1764     }
1765 }
1766 
throw_class_format_error(const char * msg)1767 void _Jv_ClassReader::throw_class_format_error (const char *msg)
1768 {
1769   jstring str;
1770   if (def->name != NULL)
1771     {
1772       jsize mlen = strlen (msg);
1773       unsigned char* data = (unsigned char*) def->name->chars();
1774       int ulen = def->name->len();
1775       unsigned char* limit = data + ulen;
1776       jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
1777       jsize len = nlen + mlen + 3;
1778       str = JvAllocString(len);
1779       jchar *chrs = JvGetStringChars(str);
1780       while (data < limit)
1781 	*chrs++ = UTF8_GET(data, limit);
1782       *chrs++ = ' ';
1783       *chrs++ = '(';
1784       for (;;)
1785 	{
1786 	  char c = *msg++;
1787 	  if (c == 0)
1788 	    break;
1789 	  *chrs++ = c & 0xFFFF;
1790 	}
1791       *chrs++ = ')';
1792     }
1793   else
1794     str = JvNewStringLatin1 (msg);
1795   ::throw_class_format_error (str);
1796 }
1797 
1798 /** Here we define the exceptions that can be thrown */
1799 
1800 static void
throw_no_class_def_found_error(jstring msg)1801 throw_no_class_def_found_error (jstring msg)
1802 {
1803   throw (msg
1804 	 ? new java::lang::NoClassDefFoundError (msg)
1805 	 : new java::lang::NoClassDefFoundError);
1806 }
1807 
1808 static void
throw_no_class_def_found_error(const char * msg)1809 throw_no_class_def_found_error (const char *msg)
1810 {
1811   throw_no_class_def_found_error (JvNewStringLatin1 (msg));
1812 }
1813 
1814 static void
throw_class_format_error(jstring msg)1815 throw_class_format_error (jstring msg)
1816 {
1817   throw (msg
1818 	 ? new java::lang::ClassFormatError (msg)
1819 	 : new java::lang::ClassFormatError);
1820 }
1821 
1822 static void
throw_internal_error(const char * msg)1823 throw_internal_error (const char *msg)
1824 {
1825   throw new java::lang::InternalError (JvNewStringLatin1 (msg));
1826 }
1827 
1828 static void
throw_incompatible_class_change_error(jstring msg)1829 throw_incompatible_class_change_error (jstring msg)
1830 {
1831   throw new java::lang::IncompatibleClassChangeError (msg);
1832 }
1833 
1834 static void
throw_class_circularity_error(jstring msg)1835 throw_class_circularity_error (jstring msg)
1836 {
1837   throw new java::lang::ClassCircularityError (msg);
1838 }
1839 
1840 #endif /* INTERPRETER */
1841 
1842 
1843 
1844 /** This section takes care of verifying integrity of identifiers,
1845     signatures, field ddescriptors, and class names */
1846 
1847 #define UTF8_PEEK(PTR, LIMIT) \
1848   ({ unsigned char* xxkeep = (PTR); \
1849      int xxch = UTF8_GET(PTR,LIMIT); \
1850      PTR = xxkeep; xxch; })
1851 
1852 /* Verify one element of a type descriptor or signature.  */
1853 static unsigned char*
_Jv_VerifyOne(unsigned char * ptr,unsigned char * limit,bool void_ok)1854 _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
1855 {
1856   if (ptr >= limit)
1857     return 0;
1858 
1859   int ch = UTF8_GET (ptr, limit);
1860 
1861   switch (ch)
1862     {
1863     case 'V':
1864       if (! void_ok)
1865 	return 0;
1866 
1867     case 'S': case 'B': case 'I': case 'J':
1868     case 'Z': case 'C': case 'F': case 'D':
1869       break;
1870 
1871     case 'L':
1872       {
1873 	unsigned char *start = ptr, *end;
1874 	do
1875 	  {
1876 	    if (ptr > limit)
1877 	      return 0;
1878 
1879 	    end = ptr;
1880 
1881 	    if ((ch = UTF8_GET (ptr, limit)) == -1)
1882 	      return 0;
1883 
1884 	  }
1885 	while (ch != ';');
1886 	if (! _Jv_VerifyClassName (start, (unsigned short) (end-start)))
1887 	  return 0;
1888       }
1889       break;
1890 
1891     case '[':
1892       return _Jv_VerifyOne (ptr, limit, false);
1893       break;
1894 
1895     default:
1896       return 0;
1897     }
1898 
1899   return ptr;
1900 }
1901 
1902 /* Verification and loading procedures.  */
1903 bool
_Jv_VerifyFieldSignature(_Jv_Utf8Const * sig)1904 _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
1905 {
1906   unsigned char* ptr = (unsigned char*) sig->chars();
1907   unsigned char* limit = ptr + sig->len();
1908 
1909   ptr = _Jv_VerifyOne (ptr, limit, false);
1910 
1911   return ptr == limit;
1912 }
1913 
1914 bool
_Jv_VerifyMethodSignature(_Jv_Utf8Const * sig)1915 _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
1916 {
1917   unsigned char* ptr = (unsigned char*) sig->chars();
1918   unsigned char* limit = ptr + sig->len();
1919 
1920   if (ptr == limit || UTF8_GET(ptr,limit) != '(')
1921     return false;
1922 
1923   while (ptr && UTF8_PEEK (ptr, limit) != ')')
1924     ptr = _Jv_VerifyOne (ptr, limit, false);
1925 
1926   if (! ptr || UTF8_GET (ptr, limit) != ')')
1927     return false;
1928 
1929   // get the return type
1930   ptr = _Jv_VerifyOne (ptr, limit, true);
1931 
1932   return ptr == limit;
1933 }
1934 
1935 /* We try to avoid calling the Character methods all the time, in
1936    fact, they will only be called for non-standard things. */
1937 static __inline__ int
is_identifier_start(int c)1938 is_identifier_start (int c)
1939 {
1940   unsigned int ch = (unsigned)c;
1941 
1942   if ((ch - 0x41U) < 29U) 		/* A ... Z */
1943     return 1;
1944   if ((ch - 0x61U) < 29U) 		/* a ... z */
1945     return 1;
1946   if (ch == 0x5FU)       		/* _ */
1947     return 1;
1948 
1949   return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1950 }
1951 
1952 static __inline__ int
is_identifier_part(int c)1953 is_identifier_part (int c)
1954 {
1955   unsigned int ch = (unsigned)c;
1956 
1957   if ((ch - 0x41U) < 29U) 		/* A ... Z */
1958     return 1;
1959   if ((ch - 0x61U) < 29U) 		/* a ... z */
1960     return 1;
1961   if ((ch - 0x30) < 10U)       		/* 0 .. 9 */
1962     return 1;
1963   if (ch == 0x5FU || ch == 0x24U)       /* _ $ */
1964     return 1;
1965 
1966   return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1967 }
1968 
1969 bool
_Jv_VerifyIdentifier(_Jv_Utf8Const * name)1970 _Jv_VerifyIdentifier (_Jv_Utf8Const* name)
1971 {
1972   unsigned char *ptr   = (unsigned char*) name->chars();
1973   unsigned char *limit = (unsigned char*) name->limit();
1974   int ch;
1975 
1976   if ((ch = UTF8_GET (ptr, limit))==-1
1977       || ! is_identifier_start (ch))
1978     return false;
1979 
1980   while (ptr != limit)
1981     {
1982       if ((ch = UTF8_GET (ptr, limit))==-1
1983 	  || ! is_identifier_part (ch))
1984 	return false;
1985     }
1986   return true;
1987 }
1988 
1989 bool
_Jv_VerifyClassName(unsigned char * ptr,_Jv_ushort length)1990 _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
1991 {
1992   unsigned char *limit = ptr+length;
1993   int ch;
1994 
1995   if ('[' == UTF8_PEEK (ptr, limit))
1996     {
1997       unsigned char *end = _Jv_VerifyOne (++ptr, limit, false);
1998       // _Jv_VerifyOne must leave us looking at the terminating nul
1999       // byte.
2000       if (! end || *end)
2001 	return false;
2002       else
2003         return true;
2004     }
2005 
2006  next_level:
2007   for (;;) {
2008     if ((ch = UTF8_GET (ptr, limit))==-1)
2009       return false;
2010     if (! is_identifier_start (ch))
2011       return false;
2012     for (;;) {
2013       if (ptr == limit)
2014 	return true;
2015       else if ((ch = UTF8_GET (ptr, limit))==-1)
2016 	return false;
2017       else if (ch == '.')
2018 	goto next_level;
2019       else if (! is_identifier_part (ch))
2020 	return false;
2021     }
2022   }
2023 }
2024 
2025 bool
_Jv_VerifyClassName(_Jv_Utf8Const * name)2026 _Jv_VerifyClassName (_Jv_Utf8Const *name)
2027 {
2028   return _Jv_VerifyClassName ((unsigned char*)name->chars(), name->len());
2029 }
2030 
2031 /* Returns true, if NAME1 and NAME2 represent classes in the same
2032    package.  Neither NAME2 nor NAME2 may name an array type.  */
2033 bool
_Jv_ClassNameSamePackage(_Jv_Utf8Const * name1,_Jv_Utf8Const * name2)2034 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
2035 {
2036   unsigned char* ptr1 = (unsigned char*) name1->chars();
2037   unsigned char* limit1 = (unsigned char*) name1->limit();
2038 
2039   unsigned char* last1 = ptr1;
2040 
2041   // scan name1, and find the last occurrence of '.'
2042   while (ptr1 < limit1) {
2043     int ch1 = UTF8_GET (ptr1, limit1);
2044 
2045     if (ch1 == '.')
2046       last1 = ptr1;
2047 
2048     else if (ch1 == -1)
2049       return false;
2050   }
2051 
2052   // Now the length of NAME1's package name is LEN.
2053   int len = last1 - (unsigned char*) name1->chars();
2054 
2055   // If this is longer than NAME2, then we're off.
2056   if (len > name2->len())
2057     return false;
2058 
2059   // Then compare the first len bytes for equality.
2060   if (memcmp ((void*) name1->chars(), (void*) name2->chars(), len) == 0)
2061     {
2062       // Check that there are no .'s after position LEN in NAME2.
2063 
2064       unsigned char* ptr2 = (unsigned char*) name2->chars() + len;
2065       unsigned char* limit2 = (unsigned char*) name2->limit();
2066 
2067       while (ptr2 < limit2)
2068 	{
2069 	  int ch2 = UTF8_GET (ptr2, limit2);
2070 	  if (ch2 == -1 || ch2 == '.')
2071 	    return false;
2072 	}
2073       return true;
2074     }
2075   return false;
2076 }
2077