/* This file read a Java(TM) .class file.
   It is not stand-alone:  It depends on tons of macros, and the
   intent is you #include this file after you've defined the macros.
   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
   Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  

Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
The Free Software Foundation is independent of Sun Microsystems, Inc.  */

#include "jcf.h"
#include "zipfile.h"

static int get_attribute (JCF *);
static int jcf_parse_preamble (JCF *);
static int jcf_parse_constant_pool (JCF *);
static void jcf_parse_class (JCF *);
static int jcf_parse_fields (JCF *);
static int jcf_parse_one_method (JCF *);
static int jcf_parse_methods (JCF *);
static int jcf_parse_final_attributes (JCF *);
#ifdef NEED_PEEK_ATTRIBUTE
static int peek_attribute (JCF *, int, const char *, int);
#endif
#ifdef NEED_SKIP_ATTRIBUTE
static void skip_attribute (JCF *, int);
#endif

/* Go through all available attribute (ATTRIBUTE_NUMER) and try to
   identify PEEKED_NAME.  Return 1 if PEEKED_NAME was found, 0
   otherwise. JCF is restored to its initial position before
   returning.  */

#ifdef NEED_PEEK_ATTRIBUTE	/* Not everyone uses this function */
static int
peek_attribute (JCF *jcf, int attribute_number, const char *peeked_name,
		int peeked_name_length)
{
  int to_return = 0;
  long absolute_offset = (long)JCF_TELL (jcf);
  int i;

  for (i = 0; !to_return && i < attribute_number; i++)
    {
      uint16 attribute_name = (JCF_FILL (jcf, 6), JCF_readu2 (jcf));
      uint32 attribute_length = JCF_readu4 (jcf);
      int name_length;
      const unsigned char *name_data; 

      JCF_FILL (jcf, (long) attribute_length);
      if (attribute_name <= 0 || attribute_name >= JPOOL_SIZE(jcf)
	  || JPOOL_TAG (jcf, attribute_name) != CONSTANT_Utf8)
	continue;

      name_length = JPOOL_UTF_LENGTH (jcf, attribute_name);
      name_data = JPOOL_UTF_DATA (jcf, attribute_name);

      if (name_length == peeked_name_length 
	  && ! memcmp (name_data, peeked_name, peeked_name_length)) 
	{
	  to_return = 1; 
	  break;
	}
      
      JCF_SKIP (jcf, attribute_length);
    }

  JCF_SEEK (jcf, absolute_offset);
  return to_return;
}
#endif

#ifdef NEED_SKIP_ATTRIBUTE	/* Not everyone uses this function */
static void
skip_attribute (JCF *jcf, int number_of_attribute)
{
  while (number_of_attribute--)
    {
      JCF_u4 N;
      JCF_FILL (jcf, 6);
      (void) JCF_readu2 (jcf);
      N = JCF_readu4 (jcf);
      JCF_SKIP (jcf, N);
    }
}
#endif

static int
get_attribute (JCF *jcf)
{
  uint16 attribute_name = (JCF_FILL (jcf, 6), JCF_readu2 (jcf));
  uint32 attribute_length = JCF_readu4 (jcf);
  uint32 start_pos = JCF_TELL(jcf);
  int name_length;
  const unsigned char *name_data;
  JCF_FILL (jcf, (long) attribute_length);
  if (attribute_name <= 0 || attribute_name >= JPOOL_SIZE(jcf))
    return -2;
  if (JPOOL_TAG (jcf, attribute_name) != CONSTANT_Utf8)
    return -2;
  name_length = JPOOL_UTF_LENGTH (jcf, attribute_name);
  name_data = JPOOL_UTF_DATA (jcf, attribute_name);

#define MATCH_ATTRIBUTE(S) \
  (name_length == sizeof (S)-1 && memcmp (name_data, S, sizeof (S)-1) == 0)

#ifdef IGNORE_ATTRIBUTE
   if (IGNORE_ATTRIBUTE (jcf, attribute_name, attribute_length))
     {
       JCF_SKIP (jcf, attribute_length);
     }
   else
#endif
#ifdef HANDLE_SOURCEFILE
  if (MATCH_ATTRIBUTE ("SourceFile"))
    {
      uint16 sourcefile_index = JCF_readu2 (jcf);
      HANDLE_SOURCEFILE(sourcefile_index);
    }
  else
#endif
#ifdef HANDLE_CONSTANTVALUE
  if (MATCH_ATTRIBUTE ("ConstantValue"))
    {
      uint16 constantvalue_index = JCF_readu2 (jcf);
      if (constantvalue_index <= 0 || constantvalue_index >= JPOOL_SIZE(jcf))
	return -2;
      HANDLE_CONSTANTVALUE(constantvalue_index);
    }
  else
#endif
#ifdef HANDLE_CODE_ATTRIBUTE
  if (MATCH_ATTRIBUTE ("Code"))
    {
      uint16 j;
      uint16 max_stack ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
      uint16 max_locals ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
      uint32 code_length = JCF_readu4 (jcf);
      uint16 exception_table_length, attributes_count;
      if (code_length + 12 > attribute_length)
	return -1;
      HANDLE_CODE_ATTRIBUTE(max_stack, max_locals, code_length);
      JCF_SKIP (jcf, code_length);
      exception_table_length = JCF_readu2 (jcf);
      if (code_length + 8 * exception_table_length + 12 > attribute_length)
	return -1;
#ifdef HANDLE_EXCEPTION_TABLE
      HANDLE_EXCEPTION_TABLE (jcf->read_ptr, exception_table_length);
#endif
      JCF_SKIP (jcf, 2 * 4 * exception_table_length);
      attributes_count = JCF_readu2 (jcf);
      for (j = 0; j < attributes_count; j++)
	{
	  int code = get_attribute (jcf);
	  if (code != 0)
	    return code;
	}
    }
  else
#endif /* HANDLE_CODE_ATTRIBUTE */
#ifdef HANDLE_EXCEPTIONS_ATTRIBUTE
  if (MATCH_ATTRIBUTE ("Exceptions"))
    {
      uint16 count = JCF_readu2 (jcf);
      HANDLE_EXCEPTIONS_ATTRIBUTE (count);
    }
  else
#endif
#ifdef HANDLE_LINENUMBERTABLE_ATTRIBUTE
  if (MATCH_ATTRIBUTE ("LineNumberTable"))
    {
      uint16 count = JCF_readu2 (jcf);
      HANDLE_LINENUMBERTABLE_ATTRIBUTE (count);
    }
  else
#endif
#ifdef HANDLE_LOCALVARIABLETABLE_ATTRIBUTE
  if (MATCH_ATTRIBUTE ("LocalVariableTable"))
    {
      uint16 count = JCF_readu2 (jcf);
      HANDLE_LOCALVARIABLETABLE_ATTRIBUTE (count);
    }
  else
#endif
#ifdef HANDLE_INNERCLASSES_ATTRIBUTE
  if (MATCH_ATTRIBUTE ("InnerClasses"))
    {
      uint16 count = JCF_readu2 (jcf);
      HANDLE_INNERCLASSES_ATTRIBUTE (count);
    }
  else
#endif
#ifdef HANDLE_SYNTHETIC_ATTRIBUTE
  if (MATCH_ATTRIBUTE ("Synthetic"))
    {
      HANDLE_SYNTHETIC_ATTRIBUTE ();
    }
  else
#endif
#ifdef HANDLE_GCJCOMPILED_ATTRIBUTE
  if (MATCH_ATTRIBUTE ("gnu.gcj.gcj-compiled"))
    {
      HANDLE_GCJCOMPILED_ATTRIBUTE ();
    }
  else
#endif
#ifdef HANDLE_DEPRECATED_ATTRIBUTE
  if (MATCH_ATTRIBUTE ("Deprecated"))
    {
      HANDLE_DEPRECATED_ATTRIBUTE ();
    }
  else
#endif
    {
#ifdef PROCESS_OTHER_ATTRIBUTE
      PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length);
#else
      JCF_SKIP (jcf, attribute_length);
#endif
    }
  if ((long) (start_pos + attribute_length) != JCF_TELL(jcf))
    return -1;
  return 0;
}

/* Read and handle the pre-amble. */
static int
jcf_parse_preamble (JCF* jcf)
{
  uint32 magic = (JCF_FILL (jcf, 8), JCF_readu4 (jcf));
  uint16 minor_version ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
  uint16 major_version ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
#ifdef HANDLE_MAGIC
  HANDLE_MAGIC (magic, minor_version, major_version);
#endif
  if (magic != 0xcafebabe)
    return -1;
  else
    return 0;
}

/* Read and handle the constant pool.

   Return 0 if OK.
   Return -2 if a bad cross-reference (index of other constant) was seen.
*/
static int
jcf_parse_constant_pool (JCF* jcf)
{
  int i, n;
  JPOOL_SIZE (jcf) = (JCF_FILL (jcf, 2), JCF_readu2 (jcf));
  jcf->cpool.tags = ggc_alloc (JPOOL_SIZE (jcf));
  jcf->cpool.data = ggc_alloc (sizeof (jword) * JPOOL_SIZE (jcf));
  jcf->cpool.tags[0] = 0;
#ifdef HANDLE_START_CONSTANT_POOL
  HANDLE_START_CONSTANT_POOL (JPOOL_SIZE (jcf));
#endif
  for (i = 1; i < (int) JPOOL_SIZE (jcf); i++)
    {
      int constant_kind;
       
      /* Make sure at least 9 bytes are available.  This is enough
	 for all fixed-sized constant pool entries (so we don't need many
	 more JCF_FILL calls below), but is is small enough that
	 we are guaranteed to not hit EOF (in a valid .class file). */
      JCF_FILL (jcf, 9);
      constant_kind = JCF_readu (jcf);
      jcf->cpool.tags[i] = constant_kind;
      switch (constant_kind)
	{
	case CONSTANT_String:
	case CONSTANT_Class:
	  jcf->cpool.data[i].w = JCF_readu2 (jcf);
	  break;
	case CONSTANT_Fieldref:
	case CONSTANT_Methodref:
	case CONSTANT_InterfaceMethodref:
	case CONSTANT_NameAndType:
	  jcf->cpool.data[i].w = JCF_readu2 (jcf);
	  jcf->cpool.data[i].w |= JCF_readu2 (jcf) << 16;
	  break;
	case CONSTANT_Integer:
	case CONSTANT_Float:
	  jcf->cpool.data[i].w = JCF_readu4 (jcf);
	  break;
	case CONSTANT_Long:
	case CONSTANT_Double:
	  jcf->cpool.data[i].w = JCF_readu4 (jcf);
	  i++; /* These take up two spots in the constant pool */
	  jcf->cpool.tags[i] = 0;
	  jcf->cpool.data[i].w = JCF_readu4 (jcf);
	  break;
	case CONSTANT_Utf8:
	  n = JCF_readu2 (jcf);
	  JCF_FILL (jcf, n);
#ifdef HANDLE_CONSTANT_Utf8
	  HANDLE_CONSTANT_Utf8(jcf, i, n);
#else
	  jcf->cpool.data[i].w = JCF_TELL(jcf) - 2;
	  JCF_SKIP (jcf, n);
#endif
	  break;
	default:
	  return i;
	}
    }
  return 0;
}

/* Read various class flags and numbers. */

static void
jcf_parse_class (JCF* jcf)
{
  int i;
  uint16 interfaces_count;
  JCF_FILL (jcf, 8);
  jcf->access_flags = JCF_readu2 (jcf);
  jcf->this_class = JCF_readu2 (jcf);
  jcf->super_class = JCF_readu2 (jcf);
  interfaces_count = JCF_readu2 (jcf);

#ifdef HANDLE_CLASS_INFO
  HANDLE_CLASS_INFO(jcf->access_flags, jcf->this_class, jcf->super_class, interfaces_count);
#endif

  JCF_FILL (jcf, 2 * interfaces_count);

  /* Read interfaces. */
  for (i = 0; i < interfaces_count; i++)
    {
      uint16 index ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
#ifdef HANDLE_CLASS_INTERFACE
      HANDLE_CLASS_INTERFACE (index);
#endif
    }
}

/* Read fields. */
static int
jcf_parse_fields (JCF* jcf)
{
  int i, j;
  uint16 fields_count;
  JCF_FILL (jcf, 2);
  fields_count = JCF_readu2 (jcf);

#ifdef HANDLE_START_FIELDS
  HANDLE_START_FIELDS (fields_count);
#endif
  for (i = 0; i < fields_count; i++)
    {
      uint16 access_flags = (JCF_FILL (jcf, 8), JCF_readu2 (jcf));
      uint16 name_index = JCF_readu2 (jcf);
      uint16 signature_index = JCF_readu2 (jcf);
      uint16 attribute_count = JCF_readu2 (jcf);
#ifdef HANDLE_START_FIELD
      HANDLE_START_FIELD (access_flags, name_index, signature_index,
			  attribute_count);
#endif
      for (j = 0; j < attribute_count; j++)
	{
	  int code = get_attribute (jcf);
	  if (code != 0)
	    return code;
	}
#ifdef HANDLE_END_FIELD
      HANDLE_END_FIELD ();
#endif
    }
#ifdef HANDLE_END_FIELDS
  HANDLE_END_FIELDS ();
#endif
  return 0;
}

/* Read methods. */

static int
jcf_parse_one_method (JCF* jcf)
{
  int i;
  uint16 access_flags = (JCF_FILL (jcf, 8), JCF_readu2 (jcf));
  uint16 name_index = JCF_readu2 (jcf);
  uint16 signature_index = JCF_readu2 (jcf);
  uint16 attribute_count = JCF_readu2 (jcf);
#ifdef HANDLE_METHOD
  HANDLE_METHOD(access_flags, name_index, signature_index, attribute_count);
#endif
  for (i = 0; i < attribute_count; i++)
    {
      int code = get_attribute (jcf);
      if (code != 0)
	return code;
    }
#ifdef HANDLE_END_METHOD
  HANDLE_END_METHOD ();
#endif
  return 0;
}

static int
jcf_parse_methods (JCF* jcf)
{
  int i;
  uint16 methods_count;
  JCF_FILL (jcf, 2);
  methods_count = JCF_readu2 (jcf);
#ifdef HANDLE_START_METHODS
  HANDLE_START_METHODS (methods_count);
#endif
  for (i = 0; i < methods_count; i++)
    {
      int code = jcf_parse_one_method (jcf);
      if (code != 0)
	return code;
    }
#ifdef HANDLE_END_METHODS
  HANDLE_END_METHODS ();
#endif
  return 0;
}

/* Read attributes. */
static int
jcf_parse_final_attributes (JCF *jcf)
{
  int i;
  uint16 attributes_count = (JCF_FILL (jcf, 2), JCF_readu2 (jcf));
#ifdef START_FINAL_ATTRIBUTES
  START_FINAL_ATTRIBUTES (attributes_count)
#endif
  for (i = 0; i < attributes_count; i++)
    {
      int code = get_attribute (jcf);
      if (code != 0)
	return code;
    }
  return 0;
}

