/* Handle the constant pool of the Java(TM) Virtual Machine.
   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004
   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 "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "jcf.h"
#include "tree.h"
#include "java-tree.h"
#include "toplev.h"
#include "ggc.h"

static void set_constant_entry (CPool *, int, int, jword);
static int find_tree_constant (CPool *, int, tree);
static int find_class_or_string_constant (CPool *, int, tree);
static int find_name_and_type_constant (CPool *, tree, tree);
static tree get_tag_node (int);
static tree build_constant_data_ref (void);
static CPool *cpool_for_class (tree);

/* Set the INDEX'th constant in CPOOL to have the given TAG and VALUE. */

static void
set_constant_entry (CPool *cpool, int index, int tag, jword value)
{
  if (cpool->data == NULL)
    {
      cpool->capacity = 100;
      cpool->tags = ggc_alloc_cleared (sizeof(uint8) * cpool->capacity);
      cpool->data = ggc_alloc_cleared (sizeof(union cpool_entry)
				       * cpool->capacity);
      cpool->count = 1;
    }
  if (index >= cpool->capacity)
    {
      int old_cap = cpool->capacity;
      cpool->capacity *= 2;
      if (index >= cpool->capacity)
	cpool->capacity = index + 10;
      cpool->tags = ggc_realloc (cpool->tags, 
				 sizeof(uint8) * cpool->capacity);
      cpool->data = ggc_realloc (cpool->data,
				 sizeof(union cpool_entry) * cpool->capacity);

      /* Make sure GC never sees uninitialized tag values.  */
      memset (cpool->tags + old_cap, 0, cpool->capacity - old_cap);
      memset (cpool->data + old_cap, 0,
	      (cpool->capacity - old_cap) * sizeof (union cpool_entry));
    }
  if (index >= cpool->count)
    cpool->count = index + 1;
  cpool->tags[index] = tag;
  cpool->data[index].w = value;
}

/* Find (or create) a constant pool entry matching TAG and VALUE. */

int
find_constant1 (CPool *cpool, int tag, jword value)
{
  int i;
  for (i = cpool->count;  --i > 0; )
    {
      if (cpool->tags[i] == tag && cpool->data[i].w == value)
	return i;
    }
  i = cpool->count == 0 ? 1 : cpool->count;
  set_constant_entry (cpool, i, tag, value);
  return i;
}

/* Find a double-word constant pool entry matching TAG and WORD1/WORD2. */

int
find_constant2 (CPool *cpool, int tag, jword word1, jword word2)
{
  int i;
  for (i = cpool->count - 1;  --i > 0; )
    {
      if (cpool->tags[i] == tag
	  && cpool->data[i].w == word1
	  && cpool->data[i+1].w == word2)
	return i;
    }
  i = cpool->count == 0 ? 1 : cpool->count;
  set_constant_entry (cpool, i, tag, word1);
  set_constant_entry (cpool, i+1, 0, word2);
  return i;
}

static int
find_tree_constant (CPool *cpool, int tag, tree value)
{
  int i;
  for (i = cpool->count;  --i > 0; )
    {
      if (cpool->tags[i] == tag && cpool->data[i].t == value)
	return i;
    }
  i = cpool->count == 0 ? 1 : cpool->count;
  set_constant_entry (cpool, i, tag, 0);
  cpool->data[i].t = value;
  return i;
}


int
find_utf8_constant (CPool *cpool, tree name)
{
  if (name == NULL_TREE)
    return 0;
  return find_tree_constant (cpool, CONSTANT_Utf8, name);
}

static int
find_class_or_string_constant (CPool *cpool, int tag, tree name)
{
  jword j = find_utf8_constant (cpool, name);
  int i;
  for (i = cpool->count;  --i > 0; )
    {
      if (cpool->tags[i] == tag && cpool->data[i].w == j)
	return i;
    }
  i = cpool->count;
  set_constant_entry (cpool, i, tag, j);
  return i;
}

int
find_class_constant (CPool *cpool, tree type)
{
  return find_class_or_string_constant (cpool, CONSTANT_Class,
					build_internal_class_name (type));
}

/* Allocate a CONSTANT_string entry given a STRING_CST. */

int
find_string_constant (CPool *cpool, tree string)
{
  string = get_identifier (TREE_STRING_POINTER (string));
  return find_class_or_string_constant (cpool, CONSTANT_String, string);

}

/* Find (or create) a CONSTANT_NameAndType matching NAME and TYPE.
   Return its index in the constant pool CPOOL. */

static int
find_name_and_type_constant (CPool *cpool, tree name, tree type)
{
  int name_index = find_utf8_constant (cpool, name);
  int type_index = find_utf8_constant (cpool, build_java_signature (type));
  return find_constant1 (cpool, CONSTANT_NameAndType,
			 (name_index << 16) | type_index);
}

/* Find (or create) a CONSTANT_Fieldref for DECL (a FIELD_DECL or VAR_DECL).
   Return its index in the constant pool CPOOL. */

int
find_fieldref_index (CPool *cpool, tree decl)
{
  int class_index = find_class_constant (cpool, DECL_CONTEXT (decl));
  int name_type_index
    = find_name_and_type_constant (cpool, DECL_NAME (decl), TREE_TYPE (decl));
  return find_constant1 (cpool, CONSTANT_Fieldref,
			 (class_index << 16) | name_type_index);
}

/* Find (or create) a CONSTANT_Methodref for DECL (a FUNCTION_DECL).
   Return its index in the constant pool CPOOL. */

int
find_methodref_index (CPool *cpool, tree decl)
{
  return find_methodref_with_class_index (cpool, decl, DECL_CONTEXT (decl));
}

int
find_methodref_with_class_index (CPool *cpool, tree decl, tree mclass)
{
  int class_index = find_class_constant (cpool, mclass);
  tree name = DECL_CONSTRUCTOR_P (decl) ? init_identifier_node
    : DECL_NAME (decl);
  int name_type_index;
  name_type_index = 
      find_name_and_type_constant (cpool, name, TREE_TYPE (decl));
  return find_constant1 (cpool,
			 CLASS_INTERFACE (TYPE_NAME (mclass))
			 ? CONSTANT_InterfaceMethodref
			 : CONSTANT_Methodref,
			 (class_index << 16) | name_type_index);
}

#define PUT1(X)  (*ptr++ = (X))
#define PUT2(X)  (PUT1((X) >> 8), PUT1(X))
#define PUT4(X)  (PUT2((X) >> 16), PUT2(X))
#define PUTN(P, N)  (memcpy(ptr, (P), (N)), ptr += (N))

/* Give the number of bytes needed in a .class file for the CPOOL
   constant pool.  Includes the 2-byte constant_pool_count. */

int
count_constant_pool_bytes (CPool *cpool)
{
  int size = 2;
  int i = 1;
  for ( ;  i < cpool->count;  i++)
    {
      size++;
      switch (cpool->tags[i])
	{
	case CONSTANT_NameAndType:
	case CONSTANT_Fieldref:
	case CONSTANT_Methodref:
	case CONSTANT_InterfaceMethodref:
	case CONSTANT_Float:
	case CONSTANT_Integer:
	  size += 4;
	  break;
	case CONSTANT_Class:
	case CONSTANT_String:
	  size += 2;
	  break;
	case CONSTANT_Long:
	case CONSTANT_Double:
	  size += 8;
	  i++;
	  break;
	case CONSTANT_Utf8:
	  {
	    tree t = cpool->data[i].t;
	    int len = IDENTIFIER_LENGTH (t);
	    size += len + 2;
	  }
	  break;
	default:
	  /* Second word of CONSTANT_Long and  CONSTANT_Double. */
	  size--;
	}
    }
  return size;
}

/* Write the constant pool CPOOL into BUFFER.
   The length of BUFFER is LENGTH, which must match the needed length. */

void
write_constant_pool (CPool *cpool, unsigned char *buffer, int length)
{
  unsigned char *ptr = buffer;
  int i = 1;
  union cpool_entry *datap = &cpool->data[1];
  PUT2 (cpool->count);
  for ( ;  i < cpool->count;  i++, datap++)
    {
      int tag = cpool->tags[i];
      PUT1 (tag);
      switch (tag)
	{
	case CONSTANT_NameAndType:
	case CONSTANT_Fieldref:
	case CONSTANT_Methodref:
	case CONSTANT_InterfaceMethodref:
	case CONSTANT_Float:
	case CONSTANT_Integer:
	  PUT4 (datap->w);
	  break;
	case CONSTANT_Class:
	case CONSTANT_String:
	  PUT2 (datap->w);
	  break;
	  break;
	case CONSTANT_Long:
	case CONSTANT_Double:
	  PUT4(datap->w);
	  i++;
	  datap++;
	  PUT4 (datap->w);
	  break;
	case CONSTANT_Utf8:
	  {
	    tree t = datap->t;
	    int len = IDENTIFIER_LENGTH (t);
	    PUT2 (len);
	    PUTN (IDENTIFIER_POINTER (t), len);
	  }
	  break;
	}
    }

  if (ptr != buffer + length)
    abort ();
}

static GTY(()) tree tag_nodes[13];
static tree
get_tag_node (int tag)
{
  /* A Cache for build_int_cst (CONSTANT_XXX, 0). */

  if (tag_nodes[tag] == NULL_TREE)
    tag_nodes[tag] = build_int_cst (NULL_TREE, tag);
  return tag_nodes[tag];
}

/* Given a class, return its constant pool, creating one if necessary.  */

static CPool *
cpool_for_class (tree class)
{
  CPool *cpool = TYPE_CPOOL (class);

  if (cpool == NULL)
    {
      cpool = ggc_alloc_cleared (sizeof (struct CPool));
      TYPE_CPOOL (class) = cpool;
    }
  return cpool;
}

/* Look for a constant pool entry that matches TAG and NAME.
   Creates a new entry if not found.
   TAG is one of CONSTANT_Utf8, CONSTANT_String or CONSTANT_Class.
   NAME is an IDENTIFIER_NODE naming the Utf8 constant, string, or class.
   Returns the index of the entry. */

int
alloc_name_constant (int tag, tree name)
{
  CPool *outgoing_cpool = cpool_for_class (output_class);
  return find_tree_constant (outgoing_cpool, tag, name);
}

/* Create a cinstant pool entry for a name_and_type.  This one has '.'
   rather than '/' because it isn't going into a class file, it's
   going into a compiled object.  We don't use the '/' separator in
   compiled objects.  */

static int
find_name_and_type_constant_tree (CPool *cpool, tree name, tree type)
{
  int name_index = find_utf8_constant (cpool, name);
  int type_index 
    = find_utf8_constant (cpool, 
			  identifier_subst (build_java_signature (type), 
					    "", '/', '.', ""));
  return find_constant1 (cpool, CONSTANT_NameAndType,
			 (name_index << 16) | type_index);
}

/* Look for a field ref that matches DECL in the constant pool of
   CLASS.  
   Return the index of the entry.  */

int
alloc_constant_fieldref (tree class, tree decl)
{
  CPool *outgoing_cpool = cpool_for_class (class);
  int class_index 
    = find_tree_constant (outgoing_cpool, CONSTANT_Class, 
			  DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
  int name_type_index
    = find_name_and_type_constant_tree (outgoing_cpool, DECL_NAME (decl), 
					TREE_TYPE (decl));
  return find_constant1 (outgoing_cpool, CONSTANT_Fieldref,
			 (class_index << 16) | name_type_index);
}

/* Build an identifier for the internal name of reference type TYPE. */

tree
build_internal_class_name (tree type)
{
  tree name;
  if (TYPE_ARRAY_P (type))
    name = build_java_signature (type);
  else
    {
      name = TYPE_NAME (type);
      if (TREE_CODE (name) != IDENTIFIER_NODE)
	name = DECL_NAME (name);
      name = identifier_subst (name, "", '.', '/', "");
    }
  return name;
}

/* Look for a CONSTANT_Class entry for CLAS, creating a new one if needed. */

int
alloc_class_constant (tree clas)
{
  tree class_name = build_internal_class_name (clas);
  
  return alloc_name_constant (CONSTANT_Class,
			      (unmangle_classname 
			       (IDENTIFIER_POINTER(class_name),
				IDENTIFIER_LENGTH(class_name))));
}

/* Return the decl of the data array of the current constant pool. */

static tree
build_constant_data_ref (void)
{
  tree decl = TYPE_CPOOL_DATA_REF (output_class);

  if (decl == NULL_TREE)
    {
      tree type;
      tree decl_name = mangled_classname ("_CD_", output_class);

      /* Build a type with unspecified bounds.  The will make sure
	 that targets do the right thing with whatever size we end
	 up with at the end.  Using bounds that are too small risks
	 assuming the data is in the small data section.  */
      type = build_array_type (ptr_type_node, NULL_TREE);

      /* We need to lay out the type ourselves, since build_array_type
	 thinks the type is incomplete.  */
      layout_type (type);

      decl = build_decl (VAR_DECL, decl_name, type);
      TREE_STATIC (decl) = 1;
      make_decl_rtl (decl);
      TYPE_CPOOL_DATA_REF (output_class) = decl;
    }

  return decl;
}

/* Get the pointer value at the INDEX'th element of the constant pool. */

tree
build_ref_from_constant_pool (int index)
{
  tree d = build_constant_data_ref ();
  tree i = build_int_cst (NULL_TREE, index);
  return build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i,
		 NULL_TREE, NULL_TREE);
}

/* Build an initializer for the constants field of the current constant pool.
   Should only be called at top-level, since it may emit declarations. */

tree
build_constants_constructor (void)
{
  CPool *outgoing_cpool = cpool_for_class (current_class);
  tree tags_value, data_value;
  tree cons;
  tree tags_list = NULL_TREE;
  tree data_list = NULL_TREE;
  int i;
  for (i = outgoing_cpool->count;  --i > 0; )
    switch (outgoing_cpool->tags[i])
      {
      case CONSTANT_Fieldref:
      case CONSTANT_NameAndType:
	{
	  jword temp = outgoing_cpool->data[i].w;

	  tags_list
	    = tree_cons (NULL_TREE, 
			 build_int_cst (NULL_TREE, outgoing_cpool->tags[i]),
			 tags_list);
	  data_list
	    = tree_cons (NULL_TREE, 
			 fold_convert (ptr_type_node, 
				       (build_int_cst (NULL_TREE, temp))),
			 data_list);
	}
	break;
      default:
	tags_list
	  = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
		       tags_list);
	data_list
	  = tree_cons (NULL_TREE, build_utf8_ref (outgoing_cpool->data[i].t),
		       data_list);
	break;
      }
  if (outgoing_cpool->count > 0)
    {
      tree data_decl, tags_decl, tags_type;
      tree max_index = build_int_cst (sizetype, outgoing_cpool->count - 1);
      tree index_type = build_index_type (max_index);

      /* Add dummy 0'th element of constant pool. */
      tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list);
      data_list = tree_cons (NULL_TREE, null_pointer_node, data_list);
  
      data_decl = build_constant_data_ref ();
      TREE_TYPE (data_decl) = build_array_type (ptr_type_node, index_type);
      DECL_INITIAL (data_decl) = build_constructor (TREE_TYPE (data_decl),
						    data_list);
      DECL_SIZE (data_decl) = TYPE_SIZE (TREE_TYPE (data_decl));
      DECL_SIZE_UNIT (data_decl) = TYPE_SIZE_UNIT (TREE_TYPE (data_decl));
      rest_of_decl_compilation (data_decl, 1, 0);
      data_value = build_address_of (data_decl);

      tags_type = build_array_type (unsigned_byte_type_node, index_type);
      tags_decl = build_decl (VAR_DECL, mangled_classname ("_CT_", 
							   current_class),
			      tags_type);
      TREE_STATIC (tags_decl) = 1;
      DECL_INITIAL (tags_decl) = build_constructor (tags_type, tags_list);
      rest_of_decl_compilation (tags_decl, 1, 0);
      tags_value = build_address_of (tags_decl);
    }
  else
    {
      data_value = null_pointer_node;
      tags_value = null_pointer_node;
    }
  START_RECORD_CONSTRUCTOR (cons, constants_type_node);
  PUSH_FIELD_VALUE (cons, "size",
		    build_int_cst (NULL_TREE, outgoing_cpool->count));
  PUSH_FIELD_VALUE (cons, "tags", tags_value);
  PUSH_FIELD_VALUE (cons, "data", data_value);
  FINISH_RECORD_CONSTRUCTOR (cons);
  return cons;
}

#include "gt-java-constants.h"
