/* 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, 2005
   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, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, 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 HANDLE_SOURCEDEBUGEXTENSION_ATTRIBUTE
  if (MATCH_ATTRIBUTE ("SourceDebugExtension")) /* JSR 45 */
    {
      HANDLE_SOURCEDEBUGEXTENSION_ATTRIBUTE (attribute_length);
    }
  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;
}

