/* GNU Objective C Runtime selector related functions
   Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
   Contributed by Kresten Krab Thorup

This file is part of GNU CC.

GNU CC 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.

GNU CC 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
GNU CC; see the file COPYING.  If not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

/* As a special exception, if you link this library with files compiled with
   GCC to produce an executable, this does not cause the resulting executable
   to be covered by the GNU General Public License. This exception does not
   however invalidate any other reasons why the executable file might be
   covered by the GNU General Public License.  */

#include "runtime.h"
#include "objc/sarray.h"
#include "encoding.h"

/* Initial selector hash table size. Value doesn't matter much */
#define SELECTOR_HASH_SIZE 128

/* Tables mapping selector names to uid and opposite */
static struct sarray* __objc_selector_array = 0; /* uid -> sel  !T:MUTEX */
static struct sarray* __objc_selector_names = 0; /* uid -> name !T:MUTEX */
static cache_ptr      __objc_selector_hash  = 0; /* name -> uid !T:MUTEX */

static void register_selectors_from_list(MethodList_t);

/* Number of selectors stored in each of the above tables */
int __objc_selector_max_index = 0;              /* !T:MUTEX */

void __objc_init_selector_tables()
{
  __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0);
  __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0);
  __objc_selector_hash
    = hash_new (SELECTOR_HASH_SIZE,
		(hash_func_type) hash_string,
		(compare_func_type) compare_strings);
}  

/* This routine is given a class and records all of the methods in its class
   structure in the record table.  */
void
__objc_register_selectors_from_class (Class class)
{
  MethodList_t method_list;

  method_list = class->methods;
  while (method_list)
    {
      register_selectors_from_list (method_list);
      method_list = method_list->method_next;
    }
}


/* This routine is given a list of methods and records each of the methods in
   the record table.  This is the routine that does the actual recording
   work.

   This one is only called for Class objects.  For categories,
   class_add_method_list is called.
   */
static void
register_selectors_from_list (MethodList_t method_list)
{
  int i = 0;
  while (i < method_list->method_count)
    {
      Method_t method = &method_list->method_list[i];
      method->method_name 
	= sel_register_typed_name ((const char*)method->method_name, 
				     method->method_types);
      i += 1;
    }
}


/* Register instance methods as class methods for root classes */
void __objc_register_instance_methods_to_class(Class class)
{
  MethodList_t method_list;
  MethodList_t class_method_list;
  int max_methods_no = 16;
  MethodList_t new_list;
  Method_t curr_method;

  /* Only if a root class. */
  if(class->super_class)
    return;

  /* Allocate a method list to hold the new class methods */
  new_list = objc_calloc(sizeof(struct objc_method_list)
			    + sizeof(struct objc_method[max_methods_no]), 1);
  method_list = class->methods;
  class_method_list = class->class_pointer->methods;
  curr_method = &new_list->method_list[0];

  /* Iterate through the method lists for the class */
  while (method_list)
    {
      int i;

      /* Iterate through the methods from this method list */
      for (i = 0; i < method_list->method_count; i++)
	{
	  Method_t mth = &method_list->method_list[i];
	  if (mth->method_name
	      && !search_for_method_in_list (class_method_list,
					      mth->method_name))
	    {
	      /* This instance method isn't a class method. 
		  Add it into the new_list. */
	      *curr_method = *mth;
  
	      /* Reallocate the method list if necessary */
	      if(++new_list->method_count == max_methods_no)
		new_list =
		  objc_realloc(new_list, sizeof(struct objc_method_list)
				+ sizeof(struct 
					objc_method[max_methods_no += 16]));
	      curr_method = &new_list->method_list[new_list->method_count];
	    }
	}

      method_list = method_list->method_next;
    }

  /* If we created any new class methods
     then attach the method list to the class */
  if (new_list->method_count)
    {
      new_list =
 	objc_realloc(new_list, sizeof(struct objc_method_list)
		     + sizeof(struct objc_method[new_list->method_count]));
      new_list->method_next = class->class_pointer->methods;
      class->class_pointer->methods = new_list;
    }

    __objc_update_dispatch_table_for_class (class->class_pointer);
}


/* Returns YES iff t1 and t2 have same method types, but we ignore
   the argframe layout */
BOOL
sel_types_match (const char* t1, const char* t2)
{
  if (!t1 || !t2)
    return NO;
  while (*t1 && *t2)
    {
      if (*t1 == '+') t1++;
      if (*t2 == '+') t2++;
      while (isdigit(*t1)) t1++;
      while (isdigit(*t2)) t2++;
      /* xxx Remove these next two lines when qualifiers are put in
	 all selectors, not just Protocol selectors. */
      t1 = objc_skip_type_qualifiers(t1);
      t2 = objc_skip_type_qualifiers(t2);
      if (!*t1 && !*t2)
	return YES;
      if (*t1 != *t2)
	return NO;
      t1++;
      t2++;
    }
  return NO;
}

/* return selector representing name */
SEL
sel_get_typed_uid (const char *name, const char *types)
{
  struct objc_list *l;
  sidx i;

  objc_mutex_lock(__objc_runtime_mutex);

  i = (sidx) hash_value_for_key (__objc_selector_hash, name);
  if (i == 0)
    {
      objc_mutex_unlock(__objc_runtime_mutex);
      return 0;
    }

  for (l = (struct objc_list*)sarray_get (__objc_selector_array, i);
       l; l = l->tail)
    {
      SEL s = (SEL)l->head;
      if (types == 0 || s->sel_types == 0)
	{
	  if (s->sel_types == types)
	    {
	      objc_mutex_unlock(__objc_runtime_mutex);
	      return s;
	    }
	}
      else if (sel_types_match (s->sel_types, types))
	{
	  objc_mutex_unlock(__objc_runtime_mutex);
	  return s;
	}
    }

  objc_mutex_unlock(__objc_runtime_mutex);
  return 0;
}

/* Return selector representing name; prefer a selector with non-NULL type */
SEL
sel_get_any_typed_uid (const char *name)
{
  struct objc_list *l;
  sidx i;
  SEL s;

  objc_mutex_lock(__objc_runtime_mutex);

  i = (sidx) hash_value_for_key (__objc_selector_hash, name);
  if (i == 0)
    {
      objc_mutex_unlock(__objc_runtime_mutex);
      return 0;
    }

  for (l = (struct objc_list*)sarray_get (__objc_selector_array, i);
       l; l = l->tail)
    {
      s = (SEL) l->head;
      if (s->sel_types)
	{
	    objc_mutex_unlock(__objc_runtime_mutex);
	    return s;
	}
    }

  objc_mutex_unlock(__objc_runtime_mutex);
  return s;
}

/* return selector representing name */
SEL
sel_get_any_uid (const char *name)
{
  struct objc_list *l;
  sidx i;

  objc_mutex_lock(__objc_runtime_mutex);

  i = (sidx) hash_value_for_key (__objc_selector_hash, name);
  if (soffset_decode (i) == 0)
    {
      objc_mutex_unlock(__objc_runtime_mutex);
      return 0;
    }

  l = (struct objc_list*)sarray_get (__objc_selector_array, i);
  objc_mutex_unlock(__objc_runtime_mutex);

  if (l == 0)
    return 0;

  return (SEL)l->head;
}

/* return selector representing name */
SEL
sel_get_uid (const char *name)
{
  return sel_register_typed_name (name, 0);
}

/* Get name of selector.  If selector is unknown, the empty string "" 
   is returned */ 
const char*
sel_get_name (SEL selector)
{
  const char *ret;

  objc_mutex_lock(__objc_runtime_mutex);
  if ((soffset_decode((sidx)selector->sel_id) > 0)
      && (soffset_decode((sidx)selector->sel_id) <= __objc_selector_max_index))
    ret = sarray_get (__objc_selector_names, (sidx) selector->sel_id);
  else
    ret = 0;
  objc_mutex_unlock(__objc_runtime_mutex);
  return ret;
}

BOOL
sel_is_mapped (SEL selector)
{
  unsigned int idx = soffset_decode ((sidx)selector->sel_id);
  return ((idx > 0) && (idx <= __objc_selector_max_index));
}


const char*
sel_get_type (SEL selector)
{
  if (selector)
    return selector->sel_types;
  else
    return 0;
}

/* The uninstalled dispatch table */
extern struct sarray* __objc_uninstalled_dtable;

/* Store the passed selector name in the selector record and return its
   selector value (value returned by sel_get_uid).
   Assumes that the calling function has locked down __objc_runtime_mutex. */
/* is_const parameter tells us if the name and types parameters
   are really constant or not.  If YES then they are constant and
   we can just store the pointers.  If NO then we need to copy
   name and types because the pointers may disappear later on. */
SEL
__sel_register_typed_name (const char *name, const char *types, 
			   struct objc_selector *orig, BOOL is_const)
{
  struct objc_selector* j;
  sidx i;
  struct objc_list *l;

  i = (sidx) hash_value_for_key (__objc_selector_hash, name);
  if (soffset_decode (i) != 0)
    {
      for (l = (struct objc_list*)sarray_get (__objc_selector_array, i);
	   l; l = l->tail)
	{
	  SEL s = (SEL)l->head;
	  if (types == 0 || s->sel_types == 0)
	    {
	      if (s->sel_types == types)
		{
		  if (orig)
		    {
		      orig->sel_id = (void*)i;
		      return orig;
		    }
		  else
		    return s;
		}
	    }
	  else if (!strcmp (s->sel_types, types))
	    {
	      if (orig)
		{
		  orig->sel_id = (void*)i;
		  return orig;
		}
	      else
		return s;
	    }
	}
      if (orig)
	j = orig;
      else
	j = objc_malloc (sizeof (struct objc_selector));

      j->sel_id = (void*)i;
      /* Can we use the pointer or must copy types?  Don't copy if NULL */
      if ((is_const) || (types == 0))
	j->sel_types = (const char*)types;
      else {
	j->sel_types = (char *) objc_malloc(strlen(types)+1);
	strcpy((char *)j->sel_types, types);
      }
      l = (struct objc_list*)sarray_get (__objc_selector_array, i);
    }
  else
    {
      __objc_selector_max_index += 1;
      i = soffset_encode(__objc_selector_max_index);
      if (orig)
	j = orig;
      else
	j = objc_malloc (sizeof (struct objc_selector));
	
      j->sel_id = (void*)i;
      /* Can we use the pointer or must copy types?  Don't copy if NULL */
      if ((is_const) || (types == 0))
	j->sel_types = (const char*)types;
      else {
	j->sel_types = (char *) objc_malloc(strlen(types)+1);
	strcpy((char *)j->sel_types, types);
      }
      l = 0;
    }

  DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types, 
		soffset_decode (i));
  
  {
    int is_new = (l == 0);
    const char *new_name;

    /* Can we use the pointer or must copy name?  Don't copy if NULL */
    if ((is_const) || (name == 0))
      new_name = name;
    else {
      new_name = (char *) objc_malloc(strlen(name)+1);
      strcpy((char *)new_name, name);
    }

    l = list_cons ((void*)j, l);
    sarray_at_put_safe (__objc_selector_names, i, (void *) new_name);
    sarray_at_put_safe (__objc_selector_array, i, (void *) l);
    if (is_new)
      hash_add (&__objc_selector_hash, (void *) new_name, (void *) i);
  }

  sarray_realloc(__objc_uninstalled_dtable, __objc_selector_max_index+1);

  return (SEL) j;
}

SEL
sel_register_name (const char *name)
{
  SEL ret;
    
  objc_mutex_lock(__objc_runtime_mutex);
  /* Assume that name is not constant static memory and needs to be
     copied before put into a runtime structure.  is_const == NO */
  ret = __sel_register_typed_name (name, 0, 0, NO);
  objc_mutex_unlock(__objc_runtime_mutex);
  
  return ret;
}

SEL
sel_register_typed_name (const char *name, const char *type)
{
  SEL ret;
    
  objc_mutex_lock(__objc_runtime_mutex);
  /* Assume that name and type are not constant static memory and need to
     be copied before put into a runtime structure.  is_const == NO */
  ret = __sel_register_typed_name (name, type, 0, NO);
  objc_mutex_unlock(__objc_runtime_mutex);
  
  return ret;
}

