// defineclass.cc - defining a class from .class format.

/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

/* 
   Author: Kresten Krab Thorup <krab@gnu.org> 

   Written using the online versions of Java Language Specification (1st
   ed.) and The Java Virtual Machine Specification (2nd ed.). 

   Future work may include reading (and handling) attributes which are
   currently being ignored ("InnerClasses", "LineNumber", etc...).  
*/

#include <config.h>

#include <java-interp.h>

#include <stdlib.h>
#include <stdio.h>
#include <java-cpool.h>
#include <gcj/cni.h>
#include <execution.h>

#include <java/lang/Class.h>
#include <java/lang/Float.h>
#include <java/lang/Double.h>
#include <java/lang/Character.h>
#include <java/lang/LinkageError.h>
#include <java/lang/InternalError.h>
#include <java/lang/ClassFormatError.h>
#include <java/lang/NoClassDefFoundError.h>
#include <java/lang/ClassCircularityError.h>
#include <java/lang/IncompatibleClassChangeError.h>
#include <java/lang/reflect/Modifier.h>
#include <java/security/ProtectionDomain.h>

using namespace gcj;

#ifdef INTERPRETER

// these go in some separate functions, to avoid having _Jv_InitClass
// inserted all over the place.
static void throw_internal_error (char *msg)
	__attribute__ ((__noreturn__));
static void throw_no_class_def_found_error (jstring msg)
	__attribute__ ((__noreturn__));
static void throw_no_class_def_found_error (char *msg)
	__attribute__ ((__noreturn__));
static void throw_class_format_error (jstring msg)
	__attribute__ ((__noreturn__));
static void throw_incompatible_class_change_error (jstring msg)
	__attribute__ ((__noreturn__));
static void throw_class_circularity_error (jstring msg)
	__attribute__ ((__noreturn__));

/**
 * We define class reading using a class.  It is practical, since then
 * the entire class-reader can be a friend of class Class (it needs to
 * write all it's different structures); but also because this makes it
 * easy to make class definition reentrant, and thus two threads can be
 * defining classes at the same time.   This class (_Jv_ClassReader) is
 * never exposed outside this file, so we don't have to worry about
 * public or private members here.
 */

struct _Jv_ClassReader {

  // do verification?  Currently, there is no option to disable this.
  // This flag just controls the verificaiton done by the class loader;
  // i.e., checking the integrity of the constant pool; and it is
  // allways on.  You always want this as far as I can see, but it also
  // controls weither identifiers and type descriptors/signatures are
  // verified as legal.  This could be somewhat more expensive since it
  // will call Character.isJavaIdentifier{Start,Part} for each character
  // in any identifier (field name or method name) it comes by.  Thus,
  // it might be useful to turn off this verification for classes that
  // come from a trusted source.  However, for GCJ, trusted classes are
  // most likely to be linked in.

  bool verify;

  // input data.
  unsigned char     *bytes;
  int                len;

  // current input position
  int                pos;

  // the constant pool data
  int pool_count;
  unsigned char     *tags;
  unsigned int      *offsets;

  // the class to define (see java-interp.h)
  jclass	   def;
  
  // the classes associated interpreter data.
  _Jv_InterpClass  *def_interp;

  /* check that the given number of input bytes are available */
  inline void check (int num)
  {
    if (pos + num > len)
      throw_class_format_error ("Premature end of data");
  }

  /* skip a given number of bytes in input */
  inline void skip (int num)
  {
    check (num);
    pos += num;
  }
  
  /* read an unsignend 1-byte unit */
  inline static jint get1u (unsigned char* bytes)
  {
    return bytes[0];
  }
  
  /* read an unsigned 1-byte unit */
  inline jint read1u ()
  {
    skip (1);
    return get1u (bytes+pos-1);
  }
  
  /* read an unsigned 2-byte unit */
  inline static jint get2u (unsigned char *bytes)
  {
    return (((jint)bytes[0]) << 8) | ((jint)bytes[1]);
  }
  
  /* read an unsigned 2-byte unit */
  inline jint read2u ()
  {
    skip (2);  
    return get2u (bytes+pos-2);
  }
  
  /* read a 4-byte unit */
  static jint get4 (unsigned char *bytes)
  {
    return (((jint)bytes[0]) << 24)
         | (((jint)bytes[1]) << 16)
         | (((jint)bytes[2]) << 8)
         | (((jint)bytes[3]) << 0);
  }

  /* read a 4-byte unit, (we don't do that quite so often) */
  inline jint read4 ()
  {
    skip (4);  
    return get4 (bytes+pos-4);
  }

  /* read a 8-byte unit */
  static jlong get8 (unsigned char* bytes)
  {
    return (((jlong)bytes[0]) << 56)
         | (((jlong)bytes[1]) << 48)
         | (((jlong)bytes[2]) << 40)
         | (((jlong)bytes[3]) << 32) 
         | (((jlong)bytes[4]) << 24)
         | (((jlong)bytes[5]) << 16)
         | (((jlong)bytes[6]) << 8)
         | (((jlong)bytes[7]) << 0);
  }

  /* read a 8-byte unit */
  inline jlong read8 ()
  {
    skip (8);  
    return get8 (bytes+pos-8);
  }

  inline void check_tag (int index, char expected_tag)
  {
    if (index < 0
	|| index > pool_count
	|| tags[index] != expected_tag)
      throw_class_format_error ("erroneous constant pool tag");
  }

  inline void verify_identifier (_Jv_Utf8Const* name)
  {
    if (! _Jv_VerifyIdentifier (name))
      throw_class_format_error ("erroneous identifier");
  }

  inline void verify_classname (unsigned char* ptr, _Jv_ushort length)
  {
    if (! _Jv_VerifyClassName (ptr, length))
      throw_class_format_error ("erroneous class name");
  }

  inline void verify_classname (_Jv_Utf8Const *name)
  {
    if (! _Jv_VerifyClassName (name))
      throw_class_format_error ("erroneous class name");
  }

  inline void verify_field_signature (_Jv_Utf8Const *sig)
  {
    if (! _Jv_VerifyFieldSignature (sig))
      throw_class_format_error ("erroneous type descriptor");
  }

  inline void verify_method_signature (_Jv_Utf8Const *sig)
  {
    if (! _Jv_VerifyMethodSignature (sig))
      throw_class_format_error ("erroneous type descriptor");
  }

  _Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length,
		   java::security::ProtectionDomain *pd)
  {
    if (klass == 0 || length < 0 || offset+length > data->length)
      throw_internal_error ("arguments to _Jv_DefineClass");

    verify = true;
    bytes  = (unsigned char*) (elements (data)+offset);
    len    = length;
    pos    = 0;
    def    = klass;
    def->size_in_bytes = -1;
    def->vtable_method_count = -1;
    def->engine = &_Jv_soleInterpreterEngine;
    def->protectionDomain = pd;
  }

  /** and here goes the parser members defined out-of-line */
  void parse ();
  void read_constpool ();
  void prepare_pool_entry (int index, unsigned char tag);
  void read_fields ();
  void read_methods ();
  void read_one_class_attribute ();
  void read_one_method_attribute (int method);
  void read_one_code_attribute (int method);
  void read_one_field_attribute (int field);
  void throw_class_format_error (char *msg);

  /** check an utf8 entry, without creating a Utf8Const object */
  bool is_attribute_name (int index, char *name);

  /** here goes the class-loader members defined out-of-line */
  void handleConstantPool ();
  void handleClassBegin (int, int, int);
  void handleInterfacesBegin (int);
  void handleInterface (int, int);
  void handleFieldsBegin (int);
  void handleField (int, int, int, int);
  void handleFieldsEnd ();
  void handleConstantValueAttribute (int,int);
  void handleMethodsBegin (int);
  void handleMethod (int, int, int, int);
  void handleMethodsEnd ();
  void handleCodeAttribute (int, int, int, int, int, int);
  void handleExceptionTableEntry (int, int, int, int, int, int);

  void checkExtends (jclass sub, jclass super);
  void checkImplements (jclass sub, jclass super);

  /*
   * FIXME: we should keep a hash table of utf8-strings, since many will
   * be the same.  It's a little tricky, however, because the hash table
   * needs to interact gracefully with the garbage collector.  Much
   * memory is to be saved by this, however!  perhaps the improvement
   * could be implemented in prims.cc (_Jv_makeUtf8Const), since it
   * computes the hash value anyway.
   */
};

void
_Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length,
		 java::security::ProtectionDomain *pd)
{
  _Jv_ClassReader reader (klass, data, offset, length, pd);
  reader.parse();

  /* that's it! */
}


/** This section defines the parsing/scanning of the class data */

void
_Jv_ClassReader::parse ()
{
  int magic = read4 ();

  /* FIXME: Decide which range of version numbers to allow */

  /* int minor_version = */ read2u ();
  /* int major_verson  = */ read2u ();

  if (magic != (int) 0xCAFEBABE)
    throw_class_format_error ("bad magic number");

  pool_count = read2u ();

  read_constpool ();

  int access_flags = read2u ();
  int this_class = read2u ();
  int super_class = read2u ();

  check_tag (this_class, JV_CONSTANT_Class);
  if (super_class != 0) 
    check_tag (super_class, JV_CONSTANT_Class);

  handleClassBegin (access_flags, this_class, super_class);

  // Allocate our aux_info here, after the name is set, to fulfill our
  // contract with the collector interface.
  def->aux_info = (void *) _Jv_AllocBytes (sizeof (_Jv_InterpClass));
  def_interp = (_Jv_InterpClass *) def->aux_info;

  int interfaces_count = read2u (); 

  handleInterfacesBegin (interfaces_count);

  for (int i = 0; i < interfaces_count; i++)
    {
      int iface = read2u ();
      check_tag (iface, JV_CONSTANT_Class);
      handleInterface (i, iface);
    }
  
  read_fields ();
  read_methods ();
  
  int attributes_count = read2u ();
  
  for (int i = 0; i < attributes_count; i++)
    {
      read_one_class_attribute ();
    }

  if (pos != len)
    throw_class_format_error ("unused data before end of file");

  // Tell everyone we're done.
  def->state = JV_STATE_READ;
  if (gcj::verbose_class_flag)
    _Jv_Linker::print_class_loaded (def);
  def->notifyAll ();
}

void _Jv_ClassReader::read_constpool ()
{
  tags    = (unsigned char*) _Jv_AllocBytes (pool_count);
  offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int)
						    * pool_count) ;

  /** first, we scan the constant pool, collecting tags and offsets */
  tags[0]   = JV_CONSTANT_Undefined;
  offsets[0] = pos;
  for (int c = 1; c < pool_count; c++)
    {
      tags[c]    = read1u ();
      offsets[c] = pos;

      switch (tags[c])
	{
	case JV_CONSTANT_String:
	case JV_CONSTANT_Class:
	  skip (2);
	  break;

	case JV_CONSTANT_Fieldref:
	case JV_CONSTANT_Methodref:
	case JV_CONSTANT_InterfaceMethodref:
	case JV_CONSTANT_NameAndType:
	case JV_CONSTANT_Integer:
	case JV_CONSTANT_Float:
	  skip (4);
	  break;

	case JV_CONSTANT_Double:
	case JV_CONSTANT_Long:
	  skip (8);
	  tags[++c] = JV_CONSTANT_Undefined;
	  break;
	    
	case JV_CONSTANT_Utf8:
	  {		    
	    int len = read2u ();
	    skip (len);
	  }
	  break;

	case JV_CONSTANT_Unicode:
	  throw_class_format_error ("unicode not supported");
	  break;

	default:
	  throw_class_format_error ("erroneous constant pool tag");
	}
    }

  handleConstantPool ();
}


void _Jv_ClassReader::read_fields ()
{
  int fields_count = read2u ();
  handleFieldsBegin (fields_count);

  for (int i = 0; i < fields_count; i++)
    {
      int access_flags     = read2u ();
      int name_index       = read2u ();
      int descriptor_index = read2u ();
      int attributes_count = read2u ();

      check_tag (name_index, JV_CONSTANT_Utf8);
      prepare_pool_entry (name_index, JV_CONSTANT_Utf8);

      check_tag (descriptor_index, JV_CONSTANT_Utf8);
      prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);

      handleField (i, access_flags, name_index, descriptor_index);

      for (int j = 0; j < attributes_count; j++)
	{
	  read_one_field_attribute (i);
	}
    }

  handleFieldsEnd ();
}

bool
_Jv_ClassReader::is_attribute_name (int index, char *name)
{
  check_tag (index, JV_CONSTANT_Utf8);
  int len = get2u (bytes+offsets[index]);
  if (len != (int) strlen (name))
    return false;
  else
    return !memcmp (bytes+offsets[index]+2, name, len);
}

void _Jv_ClassReader::read_one_field_attribute (int field_index)
{
  int name = read2u ();
  int length = read4 ();

  if (is_attribute_name (name, "ConstantValue"))
    {
      int cv = read2u ();

      if (cv < pool_count 
	  && cv > 0
	  && (tags[cv] == JV_CONSTANT_Integer
	      || tags[cv] == JV_CONSTANT_Float
	      || tags[cv] == JV_CONSTANT_Long
	      || tags[cv] == JV_CONSTANT_Double
	      || tags[cv] == JV_CONSTANT_String))
	  {
	    handleConstantValueAttribute (field_index, cv);
	  }
	else
	  {
	    throw_class_format_error ("erroneous ConstantValue attribute");
	  }

	if (length != 2) 
	  throw_class_format_error ("erroneous ConstantValue attribute");
      }

    else
      {
	skip (length);
      }
}

void _Jv_ClassReader::read_methods ()
{
  int methods_count = read2u ();
  
  handleMethodsBegin (methods_count);
  
  for (int i = 0; i < methods_count; i++)
    {
      int access_flags     = read2u ();
      int name_index       = read2u ();
      int descriptor_index = read2u ();
      int attributes_count = read2u ();
      
      check_tag (name_index, JV_CONSTANT_Utf8);
      prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);

      check_tag (name_index, JV_CONSTANT_Utf8);
      prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);

      handleMethod (i, access_flags, name_index,
		    descriptor_index);

      for (int j = 0; j < attributes_count; j++)
	{
	  read_one_method_attribute (i);
	}
    }
  
  handleMethodsEnd ();
}

void _Jv_ClassReader::read_one_method_attribute (int method_index) 
{
  int name = read2u ();
  int length = read4 ();

  if (is_attribute_name (name, "Exceptions"))
    {
      _Jv_Method *method = reinterpret_cast<_Jv_Method *>
	(&def->methods[method_index]);
      if (method->throws != NULL)
	throw_class_format_error ("only one Exceptions attribute allowed per method");

      int num_exceptions = read2u ();
      _Jv_Utf8Const **exceptions =
	(_Jv_Utf8Const **) _Jv_AllocBytes ((num_exceptions + 1)
					   * sizeof (_Jv_Utf8Const *));

      int out = 0;
      _Jv_word *pool_data = def->constants.data;
      for (int i = 0; i < num_exceptions; ++i)
	{
	  int ndx = read2u ();
	  // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
	  if (ndx != 0)
	    {
	      check_tag (ndx, JV_CONSTANT_Class);
	      exceptions[out++] = pool_data[ndx].utf8; 
	    }
	}
      exceptions[out] = NULL;
      method->throws = exceptions;
    }

  else if (is_attribute_name (name, "Code"))
    {
      int start_off = pos;
      int max_stack = read2u ();
      int max_locals = read2u ();
      int code_length = read4 ();

      int code_start = pos;
      skip (code_length);
      int exception_table_length = read2u ();

      handleCodeAttribute (method_index, 
			   max_stack, max_locals,
			   code_start, code_length,
			   exception_table_length);
      

      for (int i = 0; i < exception_table_length; i++)
	{
	  int start_pc   = read2u ();
	  int end_pc     = read2u ();
	  int handler_pc = read2u ();
	  int catch_type = read2u ();

	  if (start_pc > end_pc
	      || start_pc < 0
	      // END_PC can be equal to CODE_LENGTH.
	      // See JVM Spec 4.7.4.
	      || end_pc > code_length
	      || handler_pc >= code_length)
	    throw_class_format_error ("erroneous exception handler info");

	  if (! (tags[catch_type] == JV_CONSTANT_Class
		 || tags[catch_type] == 0))
	    {
	      throw_class_format_error ("erroneous exception handler info");
	    }

	  handleExceptionTableEntry (method_index,
				     i,
				     start_pc,
				     end_pc,
				     handler_pc, 
				     catch_type);

	}

      int attributes_count = read2u ();

      for (int i = 0; i < attributes_count; i++)
	{
	  read_one_code_attribute (method_index);
	}

      if ((pos - start_off) != length)
	throw_class_format_error ("code attribute too short");
    }

  else
    {
      /* ignore unknown attributes */
      skip (length);
    }
}

void _Jv_ClassReader::read_one_code_attribute (int /*method*/) 
{
  /* ignore for now, ... later we may want to pick up
     line number information, for debugging purposes;
     in fact, the whole debugger issue is open!  */

  /* int name = */ read2u ();
  int length = read4 ();
  skip (length);

}

void _Jv_ClassReader::read_one_class_attribute () 
{
  /* we also ignore the class attributes, ...
     some day we'll add inner-classes support. */

  /* int name = */ read2u ();
  int length = read4 ();
  skip (length);
}




/* this section defines the semantic actions of the parser */

void _Jv_ClassReader::handleConstantPool ()
{
  /** now, we actually define the class' constant pool */

  // the pool is scanned explicitly by the collector
  jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
  _Jv_word *pool_data
    = (_Jv_word*) _Jv_AllocBytes (pool_count * sizeof (_Jv_word));
  
  def->constants.tags = pool_tags;
  def->constants.data = pool_data;
  def->constants.size = pool_count;

  // Here we make a pass to collect the strings!   We do this, because
  // internally in the GCJ runtime, classes are encoded with .'s not /'s. 
  // Therefore, we first collect the strings, and then translate the rest
  // of the utf8-entries (thus not representing strings) from /-notation
  // to .-notation.
  for (int i = 1; i < pool_count; i++)
    {
      if (tags[i] == JV_CONSTANT_String)
	{
	  unsigned char* str_data = bytes + offsets [i];
	  int utf_index = get2u (str_data);
	  check_tag (utf_index, JV_CONSTANT_Utf8);
	  unsigned char *utf_data = bytes + offsets[utf_index];
	  int len = get2u (utf_data);
	  pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
	  pool_tags[i] = JV_CONSTANT_String;
	}
      else
	{
	  pool_tags[i] = JV_CONSTANT_Undefined;
	}
    }

  // and now, we scan everything else but strings & utf8-entries.  This
  // leaves out those utf8-entries which are not used; which will be left
  // with a tag of JV_CONSTANT_Undefined in the class definition.
  for (int index = 1; index < pool_count; index++)
    {
      switch (tags[index])
	{
	case JV_CONSTANT_Undefined:
	case JV_CONSTANT_String:
	case JV_CONSTANT_Utf8:
	  continue;
	  
	default:
	  prepare_pool_entry (index, tags[index]);
	}
    }  
  
}

/* this is a recursive procedure, which will prepare pool entries as needed.
   Which is how we avoid initializing those entries which go unused. */
void
_Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
{
  /* these two, pool_data and pool_tags, point into the class
     structure we are currently defining */

  unsigned char *pool_tags = (unsigned char*) def->constants.tags;
  _Jv_word      *pool_data = def->constants.data;

  /* this entry was already prepared */
  if (pool_tags[index] == this_tag)
    return;

  /* this_data points to the constant-pool information for the current
     constant-pool entry */

  unsigned char *this_data = bytes + offsets[index];

  switch (this_tag)
    {
    case JV_CONSTANT_Utf8: 
      {
	// If we came here, it is because some other tag needs this
	// utf8-entry for type information!  Thus, we translate /'s to .'s in
	// order to accomondate gcj's internal representation.

	int len = get2u (this_data);
	char *buffer = (char*) __builtin_alloca (len);
	char *s = ((char*) this_data)+2;

	/* FIXME: avoid using a buffer here */
	for (int i = 0; i < len; i++)
	  {
	    if (s[i] == '/')
	      buffer[i] = '.';
	    else
	      buffer[i] = (char) s[i];
	  }
	
	pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
	pool_tags[index] = JV_CONSTANT_Utf8;
      }
      break;
	    
    case JV_CONSTANT_Class:      
      {
	int utf_index = get2u (this_data);
	check_tag (utf_index, JV_CONSTANT_Utf8);
	prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);

	if (verify)
	  verify_classname (pool_data[utf_index].utf8);
		
	pool_data[index].utf8 = pool_data[utf_index].utf8;
	pool_tags[index] = JV_CONSTANT_Class;
      }
      break;
	    
    case JV_CONSTANT_String:
      // already handled before... 
      break;
	    
    case JV_CONSTANT_Fieldref:
    case JV_CONSTANT_Methodref:
    case JV_CONSTANT_InterfaceMethodref:
      {
	int class_index = get2u (this_data);
	int nat_index = get2u (this_data+2);

	check_tag (class_index, JV_CONSTANT_Class);
	prepare_pool_entry (class_index, JV_CONSTANT_Class);	    

	check_tag (nat_index, JV_CONSTANT_NameAndType);
	prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);

	// here, verify the signature and identifier name
	if (verify)
	{
	  _Jv_ushort name_index, type_index;
	  _Jv_loadIndexes (&pool_data[nat_index],
			   name_index, type_index);

	  if (this_tag == JV_CONSTANT_Fieldref)
	    verify_field_signature (pool_data[type_index].utf8);
	  else
	    verify_method_signature (pool_data[type_index].utf8);

	  _Jv_Utf8Const* name = pool_data[name_index].utf8;

	  if (this_tag != JV_CONSTANT_Fieldref
	      && (   _Jv_equalUtf8Consts (name, clinit_name)
		  || _Jv_equalUtf8Consts (name, init_name)))
	    /* ignore */;
	  else
	    verify_identifier (pool_data[name_index].utf8);
	}
	    
	_Jv_storeIndexes (&pool_data[index], class_index, nat_index);
	pool_tags[index] = this_tag;
      }
      break;
	    
    case JV_CONSTANT_NameAndType:
      {
	_Jv_ushort name_index = get2u (this_data);
	_Jv_ushort type_index = get2u (this_data+2);

	check_tag (name_index, JV_CONSTANT_Utf8);
	prepare_pool_entry (name_index, JV_CONSTANT_Utf8);	    

	check_tag (type_index, JV_CONSTANT_Utf8);
	prepare_pool_entry (type_index, JV_CONSTANT_Utf8);

	_Jv_storeIndexes (&pool_data[index], name_index, type_index);
	pool_tags[index] = JV_CONSTANT_NameAndType;
      }
      break;
	    
    case JV_CONSTANT_Float:
      {
	jfloat f = java::lang::Float::intBitsToFloat ((jint) get4 (this_data));
	_Jv_storeFloat (&pool_data[index], f);
	pool_tags[index] = JV_CONSTANT_Float;
      }
      break;
	    
    case JV_CONSTANT_Integer:
      {
	int i = get4 (this_data);
	_Jv_storeInt (&pool_data[index], i);
	pool_tags[index] = JV_CONSTANT_Integer;
      }
      break;
	    
    case JV_CONSTANT_Double:
      {
	jdouble d
	  = java::lang::Double::longBitsToDouble ((jlong) get8 (this_data));
	_Jv_storeDouble (&pool_data[index], d);
	pool_tags[index] = JV_CONSTANT_Double;
      }
      break;
	    
    case JV_CONSTANT_Long:
      {
	jlong i = get8 (this_data);
	_Jv_storeLong (&pool_data[index], i);
	pool_tags[index] = JV_CONSTANT_Long;
      }
      break;
	    
    default:
      throw_class_format_error ("erroneous constant pool tag");
    }
}


void
_Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_class)
{
  using namespace java::lang::reflect;

  unsigned char *pool_tags = (unsigned char*) def->constants.tags;
  _Jv_word      *pool_data = def->constants.data;

  check_tag (this_class, JV_CONSTANT_Class);
  _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;

  // was ClassLoader.defineClass called with an expected class name?
  if (def->name == 0)
    {
      jclass orig = def->loader->findLoadedClass(loadedName->toString());

      if (orig == 0)
	{
	  def->name = loadedName;
	}
      else
	{
	  jstring msg = JvNewStringUTF ("anonymous "
					"class data denotes "
					"existing class ");
	  msg = msg->concat (orig->getName ());

	  throw_no_class_def_found_error (msg);
	}
    }

  // assert that the loaded class has the expected name, 5.3.5
  else if (! _Jv_equalUtf8Consts (loadedName, def->name))
    {
      jstring msg = JvNewStringUTF ("loaded class ");
      msg = msg->concat (def->getName ());
      msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
      jstring klass_name = loadedName->toString();
      msg = msg->concat (klass_name);

      throw_no_class_def_found_error (msg);
    }

  def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
  pool_data[this_class].clazz = def;
  pool_tags[this_class] = JV_CONSTANT_ResolvedClass;

  if (super_class == 0 && ! (access_flags & Modifier::INTERFACE))
    {
      // FIXME: Consider this carefully!  
      if (! _Jv_equalUtf8Consts (def->name, java::lang::Object::class$.name))
	throw_no_class_def_found_error ("loading java.lang.Object");
    }

  def->state = JV_STATE_PRELOADING;

  // Register this class with its defining loader as well (despite the
  // name of the function we're calling), so that super class lookups
  // work properly.  If there is an error, our caller will unregister
  // this class from the class loader.  Also, we don't need to hold a
  // lock here, as our caller has acquired it.
  _Jv_RegisterInitiatingLoader (def, def->loader);

  if (super_class != 0)
    {
      // Load the superclass.
      check_tag (super_class, JV_CONSTANT_Class);
      _Jv_Utf8Const* super_name = pool_data[super_class].utf8; 

      // Load the superclass using our defining loader.
      jclass the_super = _Jv_FindClass (super_name,
					def->loader);

      // This will establish that we are allowed to be a subclass,
      // and check for class circularity error.
      checkExtends (def, the_super);

      // Note: for an interface we will find Object as the
      // superclass.  We still check it above to ensure class file
      // validity, but we simply assign `null' to the actual field in
      // this case.
      def->superclass = (((access_flags & Modifier::INTERFACE))
			 ? NULL : the_super);
      pool_data[super_class].clazz = the_super;
      pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
    }

  // Now we've come past the circularity problem, we can 
  // now say that we're loading.

  def->state = JV_STATE_LOADING;
  def->notifyAll ();
}

///// Implements the checks described in sect. 5.3.5.3
void
_Jv_ClassReader::checkExtends (jclass sub, jclass super)
{
  using namespace java::lang::reflect;

  _Jv_Linker::wait_for_state (super, JV_STATE_LOADING);

  // Having an interface or a final class as a superclass is no good.
  if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
    {
      throw_incompatible_class_change_error (sub->getName ());
    }

  // If the super class is not public, we need to check some more.
  if ((super->accflags & Modifier::PUBLIC) == 0)
    {
      // With package scope, the classes must have the same class
      // loader.
      if (   sub->loader != super->loader
	  || !_Jv_ClassNameSamePackage (sub->name, super->name))
	{
	  throw_incompatible_class_change_error (sub->getName ());
	}
    } 

  for (; super != 0; super = super->getSuperclass ())
    {
      if (super == sub)
	throw_class_circularity_error (sub->getName ());
    }
}



void _Jv_ClassReader::handleInterfacesBegin (int count)
{
  def->interfaces = (jclass*) _Jv_AllocBytes (count*sizeof (jclass));
  def->interface_count = count;
}

void _Jv_ClassReader::handleInterface (int if_number, int offset)
{
  _Jv_word       * pool_data = def->constants.data;
  unsigned char  * pool_tags = (unsigned char*) def->constants.tags;

  jclass the_interface;

  if (pool_tags[offset] == JV_CONSTANT_Class)
    {
      _Jv_Utf8Const* name = pool_data[offset].utf8;
      the_interface =  _Jv_FindClass (name, def->loader);
    }
  else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
    {
      the_interface = pool_data[offset].clazz;
    }
  else
    {
      throw_no_class_def_found_error ("erroneous constant pool tag");
    }

  // checks the validity of the_interface, and that we are in fact
  // allowed to implement that interface.
  checkImplements (def, the_interface);
  
  pool_data[offset].clazz = the_interface;
  pool_tags[offset] = JV_CONSTANT_ResolvedClass;
  
  def->interfaces[if_number] = the_interface;
}

void
_Jv_ClassReader::checkImplements (jclass sub, jclass super)
{
  using namespace java::lang::reflect;

  // well, it *must* be an interface
  if ((super->accflags & Modifier::INTERFACE) == 0)
    {
      throw_incompatible_class_change_error (sub->getName ());
    }

  // if it has package scope, it must also be defined by the 
  // same loader.
  if ((super->accflags & Modifier::PUBLIC) == 0)
    {
      if (    sub->loader != super->loader
	  || !_Jv_ClassNameSamePackage (sub->name, super->name))
	{
	  throw_incompatible_class_change_error (sub->getName ());
	}
    } 

  // FIXME: add interface circularity check here
  if (sub == super)
    {
      throw_class_circularity_error (sub->getName ());
    }		
}

void _Jv_ClassReader::handleFieldsBegin (int count)
{
  def->fields = (_Jv_Field*) 
    _Jv_AllocBytes (count * sizeof (_Jv_Field));
  def->field_count = count;
  def_interp->field_initializers = (_Jv_ushort*)
    _Jv_AllocBytes (count * sizeof (_Jv_ushort));
  for (int i = 0; i < count; i++)
    def_interp->field_initializers[i] = (_Jv_ushort) 0;
}

void _Jv_ClassReader::handleField (int field_no,
				   int flags,
				   int name,
				   int desc)
{
  using namespace java::lang::reflect;

  _Jv_word *pool_data = def->constants.data;

  _Jv_Field *field = &def->fields[field_no];
  _Jv_Utf8Const *field_name = pool_data[name].utf8;

  field->name      = field_name;

  // Ignore flags we don't know about.  
  field->flags = flags & Modifier::ALL_FLAGS;

  _Jv_Utf8Const* sig = pool_data[desc].utf8;

  if (verify)
    {
      verify_identifier (field_name);

      for (int i = 0; i < field_no; ++i)
	{
	  if (_Jv_equalUtf8Consts (field_name, def->fields[i].name)
	      && _Jv_equalUtf8Consts (sig,
				      // We know the other fields are
				      // unresolved.
				      (_Jv_Utf8Const *) def->fields[i].type))
	    throw_class_format_error ("duplicate field name");
	}

      // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
      if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
		+((field->flags & Modifier::PRIVATE) ? 1 : 0)
		+((field->flags & Modifier::PROTECTED) ? 1 : 0)))
	throw_class_format_error ("erroneous field access flags");

      // FIXME: JVM spec S4.5: Verify ACC_FINAL and ACC_VOLATILE are not 
      // both set. Verify modifiers for interface fields.
      
    }

  if (verify)
    verify_field_signature (sig);

  // field->type is really a jclass, but while it is still
  // unresolved we keep an _Jv_Utf8Const* instead.
  field->type       = (jclass) sig;
  field->flags     |= _Jv_FIELD_UNRESOLVED_FLAG;
  field->u.boffset  = 0;
}


void _Jv_ClassReader::handleConstantValueAttribute (int field_index, 
						    int value)
{
  using namespace java::lang::reflect;

  _Jv_Field *field = &def->fields[field_index];

  if ((field->flags & (Modifier::STATIC
		       | Modifier::FINAL
		       | Modifier::PRIVATE)) == 0)
    {
      // Ignore, as per vmspec #4.7.2
      return;
    }

  // do not allow multiple constant fields!
  if (field->flags & _Jv_FIELD_CONSTANT_VALUE)
    throw_class_format_error ("field has multiple ConstantValue attributes");

  field->flags |= _Jv_FIELD_CONSTANT_VALUE;
  def_interp->field_initializers[field_index] = value;

  /* type check the initializer */
  
  if (value <= 0 || value >= pool_count)
    throw_class_format_error ("erroneous ConstantValue attribute");

  /* FIXME: do the rest */
}

void _Jv_ClassReader::handleFieldsEnd ()
{
  using namespace java::lang::reflect;

  // We need to reorganize the fields so that the static ones are first,
  // to conform to GCJ class layout.

  int low            = 0;
  int high           = def->field_count-1;
  _Jv_Field  *fields = def->fields;
  _Jv_ushort *inits  = def_interp->field_initializers;

  // this is kind of a raw version of quicksort.
  while (low < high)
    {
      // go forward on low, while it's a static
      while (low < high && (fields[low].flags & Modifier::STATIC) != 0)
	low++;
      
      // go backwards on high, while it's a non-static
      while (low < high && (fields[high].flags & Modifier::STATIC) == 0)
	high--;

      if (low==high)
	break;

      _Jv_Field  tmp  = fields[low];
      _Jv_ushort itmp = inits[low];
	  
      fields[low] = fields[high];
      inits[low]  = inits[high];
	  
      fields[high] = tmp;
      inits[high]  = itmp;
	  
      high -= 1;
      low  += 1;
    }
  
  if ((fields[low].flags & Modifier::STATIC) != 0) 
    low += 1;

  def->static_field_count = low;
}



void
_Jv_ClassReader::handleMethodsBegin (int count)
{
  def->methods = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method) * count);

  def_interp->interpreted_methods
    = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
					  * count);

  for (int i = 0; i < count; i++)
    {
      def_interp->interpreted_methods[i] = 0;
      def->methods[i].index = (_Jv_ushort) -1;
    }

  def->method_count = count;
}


void _Jv_ClassReader::handleMethod 
    (int mth_index, int accflags, int name, int desc)
{ 
  using namespace java::lang::reflect;

  _Jv_word *pool_data = def->constants.data;
  _Jv_Method *method = &def->methods[mth_index];

  check_tag (name, JV_CONSTANT_Utf8);
  prepare_pool_entry (name, JV_CONSTANT_Utf8);
  method->name = pool_data[name].utf8;

  check_tag (desc, JV_CONSTANT_Utf8);
  prepare_pool_entry (desc, JV_CONSTANT_Utf8);
  method->signature = pool_data[desc].utf8;

  // ignore unknown flags
  method->accflags = accflags & Modifier::ALL_FLAGS;

  // Initialize...
  method->ncode = 0;
  method->throws = NULL;
  
  if (verify)
    {
      if (_Jv_equalUtf8Consts (method->name, clinit_name)
	  || _Jv_equalUtf8Consts (method->name, init_name))
	/* ignore */;
      else
	verify_identifier (method->name);

      verify_method_signature (method->signature);

      for (int i = 0; i < mth_index; ++i)
	{
	  if (_Jv_equalUtf8Consts (method->name, def->methods[i].name)
	      && _Jv_equalUtf8Consts (method->signature,
				      def->methods[i].signature))
	    throw_class_format_error ("duplicate method");
	}

      // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
      if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
		+((method->accflags & Modifier::PRIVATE) ? 1 : 0)
		+((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
	throw_class_format_error ("erroneous method access flags");

      // FIXME: JVM spec S4.6: if ABSTRACT modifier is set, verify other 
      // flags are not set. Verify flags for interface methods. Verifiy
      // modifiers for initializers. 
    }
}

void _Jv_ClassReader::handleCodeAttribute
  (int method_index, int max_stack, int max_locals, 
   int code_start, int code_length, int exc_table_length)
{
  int size = _Jv_InterpMethod::size (exc_table_length, code_length);
  _Jv_InterpMethod *method = 
    (_Jv_InterpMethod*) (_Jv_AllocBytes (size));

  method->max_stack      = max_stack;
  method->max_locals     = max_locals;
  method->code_length    = code_length;
  method->exc_count      = exc_table_length;
  method->defining_class = def;
  method->self           = &def->methods[method_index];
  method->prepared       = NULL;

  // grab the byte code!
  memcpy ((void*) method->bytecode (),
	  (void*) (bytes+code_start),
	  code_length);

  def_interp->interpreted_methods[method_index] = method;

  if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
    {
      // Precompute the ncode field for a static method.  This lets us
      // call a static method of an interpreted class from precompiled
      // code without first resolving the class (that will happen
      // during class initialization instead).
      method->self->ncode = method->ncode ();
    }
}

void _Jv_ClassReader::handleExceptionTableEntry
  (int method_index, int exc_index, 
   int start_pc, int end_pc, int handler_pc, int catch_type)
{
  _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
    (def_interp->interpreted_methods[method_index]);
  _Jv_InterpException *exc = method->exceptions ();

  exc[exc_index].start_pc.i     = start_pc;
  exc[exc_index].end_pc.i       = end_pc;
  exc[exc_index].handler_pc.i   = handler_pc;
  exc[exc_index].handler_type.i = catch_type;
}

void _Jv_ClassReader::handleMethodsEnd ()
{
  using namespace java::lang::reflect;

  for (int i = 0; i < def->method_count; i++)
    {
      _Jv_Method *method = &def->methods[i];
      if ((method->accflags & Modifier::NATIVE) != 0)
	{
	  if (def_interp->interpreted_methods[i] != 0)
	    throw_class_format_error ("code provided for native method");
	  else
	    {
	      _Jv_JNIMethod *m = (_Jv_JNIMethod *)
		_Jv_AllocBytes (sizeof (_Jv_JNIMethod));
	      m->defining_class = def;
	      m->self = method;
	      m->function = NULL;
	      def_interp->interpreted_methods[i] = m;

	      if ((method->accflags & Modifier::STATIC))
		{
		  // Precompute the ncode field for a static method.
		  // This lets us call a static method of an
		  // interpreted class from precompiled code without
		  // first resolving the class (that will happen
		  // during class initialization instead).
		  method->ncode = m->ncode ();
		}
	    }
	}
      else if ((method->accflags & Modifier::ABSTRACT) != 0)
	{
	  if (def_interp->interpreted_methods[i] != 0)
	    throw_class_format_error ("code provided for abstract method");
	}
      else
	{
	  if (def_interp->interpreted_methods[i] == 0)
	    throw_class_format_error ("method with no code");
	}
    }
}

void _Jv_ClassReader::throw_class_format_error (char *msg)
{
  jstring str;
  if (def->name != NULL)
    {
      jsize mlen = strlen (msg);
      unsigned char* data = (unsigned char*) def->name->chars();
      int ulen = def->name->len();
      unsigned char* limit = data + ulen;
      jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
      jsize len = nlen + mlen + 3;
      str = JvAllocString(len);
      jchar *chrs = JvGetStringChars(str);
      while (data < limit)
	*chrs++ = UTF8_GET(data, limit);
      *chrs++ = ' ';
      *chrs++ = '(';
      for (;;)
	{
	  char c = *msg++;
	  if (c == 0)
	    break;
	  *chrs++ = c & 0xFFFF;
	}
      *chrs++ = ')';
    }
  else
    str = JvNewStringLatin1 (msg);
  ::throw_class_format_error (str);
}

/** Here we define the exceptions that can be thrown */

static void
throw_no_class_def_found_error (jstring msg)
{
  throw (msg
	 ? new java::lang::NoClassDefFoundError (msg)
	 : new java::lang::NoClassDefFoundError);
}

static void
throw_no_class_def_found_error (char *msg)
{
  throw_no_class_def_found_error (JvNewStringLatin1 (msg));
}

static void
throw_class_format_error (jstring msg)
{
  throw (msg
	 ? new java::lang::ClassFormatError (msg)
	 : new java::lang::ClassFormatError);
}

static void
throw_internal_error (char *msg)
{
  throw new java::lang::InternalError (JvNewStringLatin1 (msg));
}

static void
throw_incompatible_class_change_error (jstring msg)
{
  throw new java::lang::IncompatibleClassChangeError (msg);
}

static void
throw_class_circularity_error (jstring msg)
{
  throw new java::lang::ClassCircularityError (msg);
}

#endif /* INTERPRETER */



/** This section takes care of verifying integrity of identifiers,
    signatures, field ddescriptors, and class names */

#define UTF8_PEEK(PTR, LIMIT) \
  ({ unsigned char* xxkeep = (PTR); \
     int xxch = UTF8_GET(PTR,LIMIT); \
     PTR = xxkeep; xxch; })

/* Verify one element of a type descriptor or signature.  */
static unsigned char*
_Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
{
  if (ptr >= limit)
    return 0;

  int ch = UTF8_GET (ptr, limit);

  switch (ch)
    {
    case 'V':
      if (! void_ok)
	return 0;

    case 'S': case 'B': case 'I': case 'J':
    case 'Z': case 'C': case 'F': case 'D': 
      break;

    case 'L':
      {
	unsigned char *start = ptr, *end;
	do
	  {
	    if (ptr > limit)
	      return 0;

	    end = ptr;

	    if ((ch = UTF8_GET (ptr, limit)) == -1)
	      return 0;

	  }
	while (ch != ';');
	if (! _Jv_VerifyClassName (start, (unsigned short) (end-start)))
	  return 0;
      }
      break;

    case '[':
      return _Jv_VerifyOne (ptr, limit, false);
      break;

    default:
      return 0;
    }

  return ptr;
}

/* Verification and loading procedures.  */
bool
_Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
{
  unsigned char* ptr = (unsigned char*) sig->chars();
  unsigned char* limit = ptr + sig->len();

  ptr = _Jv_VerifyOne (ptr, limit, false);

  return ptr == limit;
}

bool
_Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
{
  unsigned char* ptr = (unsigned char*) sig->chars();
  unsigned char* limit = ptr + sig->len();

  if (ptr == limit || UTF8_GET(ptr,limit) != '(')
    return false;

  while (ptr && UTF8_PEEK (ptr, limit) != ')')
    ptr = _Jv_VerifyOne (ptr, limit, false);

  if (UTF8_GET (ptr, limit) != ')')
    return false;

  // get the return type
  ptr = _Jv_VerifyOne (ptr, limit, true);

  return ptr == limit;
}

/* We try to avoid calling the Character methods all the time, in
   fact, they will only be called for non-standard things. */
static __inline__ int 
is_identifier_start (int c)
{
  unsigned int ch = (unsigned)c;

  if ((ch - 0x41U) < 29U) 		/* A ... Z */
    return 1;
  if ((ch - 0x61U) < 29U) 		/* a ... z */
    return 1;
  if (ch == 0x5FU)       		/* _ */
    return 1;

  return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
}

static __inline__ int 
is_identifier_part (int c)
{
  unsigned int ch = (unsigned)c;

  if ((ch - 0x41U) < 29U) 		/* A ... Z */
    return 1;
  if ((ch - 0x61U) < 29U) 		/* a ... z */
    return 1;
  if ((ch - 0x30) < 10U)       		/* 0 .. 9 */
    return 1;
  if (ch == 0x5FU || ch == 0x24U)       /* _ $ */
    return 1;

  return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
}

bool
_Jv_VerifyIdentifier (_Jv_Utf8Const* name)
{
  unsigned char *ptr   = (unsigned char*) name->chars();
  unsigned char *limit = (unsigned char*) name->limit();
  int ch;

  if ((ch = UTF8_GET (ptr, limit))==-1
      || ! is_identifier_start (ch))
    return false;

  while (ptr != limit)
    {
      if ((ch = UTF8_GET (ptr, limit))==-1
	  || ! is_identifier_part (ch))
	return false;
    }
  return true;
}

bool
_Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
{
  unsigned char *limit = ptr+length;
  int ch;

  if ('[' == UTF8_PEEK (ptr, limit))
    {
      unsigned char *end = _Jv_VerifyOne (++ptr, limit, false);
      // _Jv_VerifyOne must leave us looking at the terminating nul
      // byte.
      if (! end || *end)
	return false;
      else
        return true;
    }

 next_level:
  for (;;) {
    if ((ch = UTF8_GET (ptr, limit))==-1)
      return false;
    if (! is_identifier_start (ch))
      return false;
    for (;;) {
      if (ptr == limit)
	return true;
      else if ((ch = UTF8_GET (ptr, limit))==-1)
	return false;
      else if (ch == '.')
	goto next_level;
      else if (! is_identifier_part (ch))
	return false;
    }
  }
}

bool
_Jv_VerifyClassName (_Jv_Utf8Const *name)
{
  return _Jv_VerifyClassName ((unsigned char*)name->chars(), name->len());
}

/* Returns true, if NAME1 and NAME2 represent classes in the same
   package.  Neither NAME2 nor NAME2 may name an array type.  */
bool
_Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
{
  unsigned char* ptr1 = (unsigned char*) name1->chars();
  unsigned char* limit1 = (unsigned char*) name1->limit();

  unsigned char* last1 = ptr1;

  // scan name1, and find the last occurrence of '.'
  while (ptr1 < limit1) {
    int ch1 = UTF8_GET (ptr1, limit1);

    if (ch1 == '.')
      last1 = ptr1;

    else if (ch1 == -1)
      return false;
  }

  // Now the length of NAME1's package name is LEN.
  int len = last1 - (unsigned char*) name1->chars();

  // If this is longer than NAME2, then we're off.
  if (len > name2->len())
    return false;

  // Then compare the first len bytes for equality.
  if (memcmp ((void*) name1->chars(), (void*) name2->chars(), len) == 0)
    {
      // Check that there are no .'s after position LEN in NAME2.

      unsigned char* ptr2 = (unsigned char*) name2->chars() + len;
      unsigned char* limit2 = (unsigned char*) name2->limit();

      while (ptr2 < limit2)
	{
	  int ch2 = UTF8_GET (ptr2, limit2);
	  if (ch2 == -1 || ch2 == '.')
	    return false;
	}
      return true;
    }
  return false;
}
