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