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

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 3, 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.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include "objc-private/common.h"
#include "objc/runtime.h"
#include "objc/thr.h"
#include "objc-private/hash.h"
#include "objc-private/objc-list.h"
#include "objc-private/module-abi-8.h"
#include "objc-private/runtime.h"
#include "objc-private/sarray.h"
#include "objc-private/selector.h"
#include <stdlib.h>                    /* For malloc.  */

/* 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 */

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

/* Forward-declare an internal function.  */
static SEL
__sel_register_typed_name (const char *name, const char *types,
			   struct objc_selector *orig, BOOL is_const);

void __objc_init_selector_tables (void)
{
  __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0);
  __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0);
  __objc_selector_hash
    = objc_hash_new (SELECTOR_HASH_SIZE,
		     (hash_func_type) objc_hash_string,
		     (compare_func_type) objc_compare_strings);
}  

/* Register a bunch of selectors from the table of selectors in a
   module.  'selectors' should not be NULL.  The list is terminated by
   a selectors with a NULL sel_id.  The selectors are assumed to
   contain the 'name' in the sel_id field; this is replaced with the
   final selector id after they are registered.  */
void
__objc_register_selectors_from_module (struct objc_selector *selectors)
{
  int i;

  for (i = 0; selectors[i].sel_id; ++i)
    {
      const char *name, *type;
      name = (char *) selectors[i].sel_id;
      type = (char *) selectors[i].sel_types;
      /* Constructors are constant static data and we can safely store
	 pointers to them in the runtime structures, so we set
	 is_const == YES.  */
      __sel_register_typed_name (name, type, (struct objc_selector *) &(selectors[i]),
				 /* is_const */ YES);
    }
}

/* 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)
{
  struct objc_method_list * method_list;

  method_list = class->methods;
  while (method_list)
    {
      __objc_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.

   The name and type pointers in the method list must be permanent and
   immutable.  */
void
__objc_register_selectors_from_list (struct objc_method_list *method_list)
{
  int i = 0;

  objc_mutex_lock (__objc_runtime_mutex);
  while (i < method_list->method_count)
    {
      Method method = &method_list->method_list[i];
      if (method->method_name)
	{
	  method->method_name
	    = __sel_register_typed_name ((const char *) method->method_name,
					 method->method_types, 0, YES);
	}
      i += 1;
    }
  objc_mutex_unlock (__objc_runtime_mutex);
}

/* The same as __objc_register_selectors_from_list, but works on a
   struct objc_method_description_list* instead of a struct
   objc_method_list*.  This is only used for protocols, which have
   lists of method descriptions, not methods.  */
void
__objc_register_selectors_from_description_list 
(struct objc_method_description_list *method_list)
{
  int i = 0;
  
  objc_mutex_lock (__objc_runtime_mutex);
  while (i < method_list->count)
    {
      struct objc_method_description *method = &method_list->list[i];
      if (method->name)
	{
	  method->name
	    = __sel_register_typed_name ((const char *) method->name,
					 method->types, 0, YES);
	}
      i += 1;
    }
  objc_mutex_unlock (__objc_runtime_mutex);
}

/* Register instance methods as class methods for root classes.  */
void __objc_register_instance_methods_to_class (Class class)
{
  struct objc_method_list *method_list;
  struct objc_method_list *class_method_list;
  int max_methods_no = 16;
  struct objc_method_list *new_list;
  Method 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 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;
    }
  else
    objc_free(new_list);
  
  __objc_update_dispatch_table_for_class (class->class_pointer);
}

BOOL
sel_isEqual (SEL s1, SEL s2)
{
  if (s1 == 0 || s2 == 0)
    return s1 == s2;
  else
    return s1->sel_id == s2->sel_id;
}

/* Return YES iff t1 and t2 have same method types.  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 ((unsigned char) *t1)) t1++;
      while (isdigit ((unsigned char) *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.  In the Modern API, you'd
   normally use sel_registerTypedName() for this, which does the same
   but would register the selector with the runtime if not registered
   yet (if you only want to check for selectors without registering,
   use sel_copyTypedSelectorList()).  */
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) objc_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_safe (__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.  In the Modern API, sel_getTypedSelector() is similar but
   returns NULL if a typed selector couldn't be found.  */
SEL
sel_get_any_typed_uid (const char *name)
{
  struct objc_list *l;
  sidx i;
  SEL s = NULL;

  objc_mutex_lock (__objc_runtime_mutex);

  i = (sidx) objc_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_safe (__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) objc_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_safe (__objc_selector_array, i);
  objc_mutex_unlock (__objc_runtime_mutex);

  if (l == 0)
    return 0;

  return (SEL) l->head;
}

SEL
sel_getTypedSelector (const char *name)
{
  sidx i;

  if (name == NULL)
    return NULL;
  
  objc_mutex_lock (__objc_runtime_mutex);
  
  /* Look for a typed selector.  */
  i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
  if (i != 0)
    {
      struct objc_list *l;
      SEL returnValue = NULL;

      for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);
	   l; l = l->tail)
	{
	  SEL s = (SEL) l->head;
	  if (s->sel_types)
	    {
	      if (returnValue == NULL)
		{
		  /* First typed selector that we find.  Keep it in
		     returnValue, but keep checking as we want to
		     detect conflicts.  */
		  returnValue = s;
		}
	      else
		{
		  /* We had already found a typed selectors, so we
		     have multiple ones.  Double-check that they have
		     different types, just in case for some reason we
		     got duplicates with the same types.  If so, it's
		     OK, we'll ignore the duplicate.  */
		  if (returnValue->sel_types == s->sel_types)
		    continue;
		  else if (sel_types_match (returnValue->sel_types, s->sel_types))
		    continue;
		  else
		    {
		      /* The types of the two selectors are different;
			 it's a conflict.  Too bad.  Return NULL.  */
		      objc_mutex_unlock (__objc_runtime_mutex);
		      return NULL;
		    }
		}
	    }
	}

      if (returnValue != NULL)
	{
	  objc_mutex_unlock (__objc_runtime_mutex);
	  return returnValue;
	}
    }

  /* No typed selector found.  Return NULL.  */
  objc_mutex_unlock (__objc_runtime_mutex);
  return 0;
}

SEL *
sel_copyTypedSelectorList (const char *name, unsigned int *numberOfReturnedSelectors)
{
  unsigned int count = 0;
  SEL *returnValue = NULL;
  sidx i;
  
  if (name == NULL)
    {
      if (numberOfReturnedSelectors)
	*numberOfReturnedSelectors = 0;
      return NULL;
    }

  objc_mutex_lock (__objc_runtime_mutex);

  /* Count how many selectors we have.  */
  i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
  if (i != 0)
    {
      struct objc_list *selector_list = NULL;
      selector_list = (struct objc_list *) sarray_get_safe (__objc_selector_array, i);

      /* Count how many selectors we have.  */
      {
	struct objc_list *l;
	for (l = selector_list; l; l = l->tail)
	  count++;
      }

      if (count != 0)
	{
	  /* Allocate enough memory to hold them.  */
	  returnValue = (SEL *)(malloc (sizeof (SEL) * (count + 1)));
	  
	  /* Copy the selectors.  */
	  {
	    unsigned int j;
	    for (j = 0; j < count; j++)
	      {
		returnValue[j] = (SEL)(selector_list->head);
		selector_list = selector_list->tail;
	      }
	    returnValue[j] = NULL;
	  }
	}
    }      

  objc_mutex_unlock (__objc_runtime_mutex);
  
  if (numberOfReturnedSelectors)
    *numberOfReturnedSelectors = count;
  
  return returnValue;
}

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

  if (selector == NULL)
    return "<null selector>";
  
  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_safe (__objc_selector_names, (sidx) selector->sel_id);
  else
    ret = 0;
  objc_mutex_unlock (__objc_runtime_mutex);
  return ret;
}

/* Traditional GNU Objective-C Runtime API.  */
const char *sel_get_name (SEL selector)
{
  if (selector == NULL)
    return 0;

  return sel_getName (selector);
}

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_getTypeEncoding (SEL selector)
{
  if (selector)
    return selector->sel_types;
  else
    return 0;
}

/* Traditional GNU Objective-C Runtime API.  */
const char *sel_get_type (SEL selector)
{
  return sel_getTypeEncoding (selector);
}

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

/* __sel_register_typed_name allocates lots of struct objc_selector:s
   of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the
   number of malloc calls and memory lost to malloc overhead, we
   allocate objc_selector:s in blocks here. This is only called from
   __sel_register_typed_name, and __sel_register_typed_name may only
   be called when __objc_runtime_mutex is locked.

   Note that the objc_selector:s allocated from
   __sel_register_typed_name are never freed.

   62 because 62 * sizeof (struct objc_selector) = 496 (992). This
   should let malloc add some overhead and use a nice, round 512
   (1024) byte chunk.  */
#define SELECTOR_POOL_SIZE 62
static struct objc_selector *selector_pool;
static int selector_pool_left;

static struct objc_selector *
pool_alloc_selector(void)
{
  if (!selector_pool_left)
    {
      selector_pool = objc_malloc (sizeof (struct objc_selector)
				   * SELECTOR_POOL_SIZE);
      selector_pool_left = SELECTOR_POOL_SIZE;
    }
  return &selector_pool[--selector_pool_left];
}

/* Store the passed selector name in the selector record and return
   its selector value (value returned by sel_get_uid).  Assume that
   the calling function has locked down __objc_runtime_mutex.  The
   '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.  If the 'orig'
   parameter is not NULL, then we are registering a selector from a
   module, and 'orig' is that selector.  In this case, we can put the
   selector in the tables if needed, and orig->sel_id is updated with
   the selector ID of the registered selector, and 'orig' is
   returned.  */
static 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) objc_hash_value_for_key (__objc_selector_hash, name);
  if (soffset_decode (i) != 0)
    {
      /* There are already selectors with that name.  Examine them to
	 see if the one we're registering already exists.  */
      for (l = (struct objc_list *)sarray_get_safe (__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 (sel_types_match (s->sel_types, types))
	    {
	      if (orig)
		{
		  orig->sel_id = (void *)i;
		  return orig;
		}
	      else
		return s;
	    }
	}
      /* A selector with this specific name/type combination does not
	 exist yet.  We need to register it.  */
      if (orig)
	j = orig;
      else
	j = pool_alloc_selector ();
      
      j->sel_id = (void *)i;
      /* Can we use the pointer or must we copy types ?  Don't copy if
	 NULL.  */
      if ((is_const) || (types == 0))
	j->sel_types = types;
      else
	{
	  j->sel_types = (char *)objc_malloc (strlen (types) + 1);
	  strcpy ((char *)j->sel_types, types);
	}
      l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i);
    }
  else
    {
      /* There are no other selectors with this name registered in the
	 runtime tables.  */
      const char *new_name;

      /* Determine i.  */
      __objc_selector_max_index += 1;
      i = soffset_encode (__objc_selector_max_index);

      /* Prepare the selector.  */
      if (orig)
	j = orig;
      else
	j = pool_alloc_selector ();
      
      j->sel_id = (void *)i;
      /* Can we use the pointer or must we copy types ?  Don't copy if
	 NULL.  */
      if (is_const || (types == 0))
	j->sel_types = types;
      else
	{
	  j->sel_types = (char *)objc_malloc (strlen (types) + 1);
	  strcpy ((char *)j->sel_types, types);
	}

      /* Since this is the first selector with this name, we need to
	 register the correspondence between 'i' (the sel_id) and
	 'name' (the actual string) in __objc_selector_names and
	 __objc_selector_hash.  */
      
      /* Can we use the pointer or must we copy name ?  Don't copy if
	 NULL.  (FIXME: Can the name really be NULL here ?)  */
      if (is_const || (name == 0))
	new_name = name;
      else
	{
	  new_name = (char *)objc_malloc (strlen (name) + 1);
	  strcpy ((char *)new_name, name);
	}
      
      /* This maps the sel_id to the name.  */
      sarray_at_put_safe (__objc_selector_names, i, (void *)new_name);

      /* This maps the name to the sel_id.  */
      objc_hash_add (&__objc_selector_hash, (void *)new_name, (void *)i);

      l = 0;
    }

  DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types, 
		(long)soffset_decode (i));

  /* Now add the selector to the list of selectors with that id.  */
  l = list_cons ((void *)j, l);
  sarray_at_put_safe (__objc_selector_array, i, (void *)l);

  sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1);
  
  return (SEL)j;
}

SEL
sel_registerName (const char *name)
{
  SEL ret;

  if (name == NULL)
    return NULL;
    
  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;
}

/* Traditional GNU Objective-C Runtime API.  */
SEL
sel_register_name (const char *name)
{
  return sel_registerName (name);
}

SEL
sel_registerTypedName (const char *name, const char *type)
{
  SEL ret;

  if (name == NULL)
    return NULL;

  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;
}

SEL
sel_register_typed_name (const char *name, const char *type)
{
  return sel_registerTypedName (name, type);
}

/* Return the selector representing name.  */
SEL
sel_getUid (const char *name)
{
  return sel_registerTypedName (name, 0);
}

/* Traditional GNU Objective-C Runtime API.  */
SEL
sel_get_uid (const char *name)
{
  return sel_getUid (name);
}
