/* GNU Objective C Runtime message lookup 
   Copyright (C) 1993-2014 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/>.  */

/* Uncommented the following line to enable debug logging.  Use this
   only while debugging the runtime.  */
/* #define DEBUG 1 */

/* FIXME: This file has no business including tm.h.  */
/* FIXME: This should be using libffi instead of __builtin_apply
   and friends.  */

#include "objc-private/common.h"
#include "objc-private/error.h"
#include "tconfig.h"
#include "coretypes.h"
#include "tm.h"
#include "objc/runtime.h"
#include "objc/message.h"          /* For objc_msg_lookup(), objc_msg_lookup_super().  */
#include "objc/thr.h"
#include "objc-private/module-abi-8.h"
#include "objc-private/runtime.h"
#include "objc-private/hash.h"
#include "objc-private/sarray.h"
#include "objc-private/selector.h" /* For sel_is_mapped() */
#include "runtime-info.h"
#include <assert.h> /* For assert */
#include <string.h> /* For strlen */

/* This is how we hack STRUCT_VALUE to be 1 or 0.   */
#define gen_rtx(args...) 1
#define gen_rtx_MEM(args...) 1
#define gen_rtx_REG(args...) 1
/* Already defined in gcc/coretypes.h. So prevent double definition warning.  */
#undef rtx
#define rtx int

#if ! defined (STRUCT_VALUE) || STRUCT_VALUE == 0
#define INVISIBLE_STRUCT_RETURN 1
#else
#define INVISIBLE_STRUCT_RETURN 0
#endif

/* The uninstalled dispatch table.  If a class' dispatch table points
   to __objc_uninstalled_dtable then that means it needs its dispatch
   table to be installed.  */
struct sarray *__objc_uninstalled_dtable = 0;   /* !T:MUTEX */

/* Two hooks for method forwarding. If either is set, it is invoked to
 * return a function that performs the real forwarding.  If both are
 * set, the result of __objc_msg_forward2 will be preferred over that
 * of __objc_msg_forward.  If both return NULL or are unset, the
 * libgcc based functions (__builtin_apply and friends) are used.  */
IMP (*__objc_msg_forward) (SEL) = NULL;
IMP (*__objc_msg_forward2) (id, SEL) = NULL;

/* Send +initialize to class.  */
static void __objc_send_initialize (Class);

/* Forward declare some functions */
static void __objc_install_dtable_for_class (Class cls);
static void __objc_prepare_dtable_for_class (Class cls);
static void __objc_install_prepared_dtable_for_class (Class cls);

static struct sarray *__objc_prepared_dtable_for_class (Class cls);
static IMP __objc_get_prepared_imp (Class cls,SEL sel);
  

/* Various forwarding functions that are used based upon the
   return type for the selector.
   __objc_block_forward for structures.
   __objc_double_forward for floats/doubles.
   __objc_word_forward for pointers or types that fit in registers.  */
static double __objc_double_forward (id, SEL, ...);
static id __objc_word_forward (id, SEL, ...);
typedef struct { id many[8]; } __big;
#if INVISIBLE_STRUCT_RETURN 
static __big 
#else
static id
#endif
__objc_block_forward (id, SEL, ...);
static struct objc_method * search_for_method_in_hierarchy (Class class, SEL sel);
struct objc_method * search_for_method_in_list (struct objc_method_list * list, SEL op);
id nil_method (id, SEL);

/* Given a selector, return the proper forwarding implementation.  */
inline
IMP
__objc_get_forward_imp (id rcv, SEL sel)
{
  /* If a custom forwarding hook was registered, try getting a
     forwarding function from it. There are two forward routine hooks,
     one that takes the receiver as an argument and one that does
     not.  */
  if (__objc_msg_forward2)
    {
      IMP result;
      if ((result = __objc_msg_forward2 (rcv, sel)) != NULL)
       return result;
    }
  if (__objc_msg_forward)
    {
      IMP result;
      if ((result = __objc_msg_forward (sel)) != NULL) 
	return result;
    }

  /* In all other cases, use the default forwarding functions built
     using __builtin_apply and friends.  */
    {
      const char *t = sel->sel_types;
      
      if (t && (*t == '[' || *t == '(' || *t == '{')
#ifdef OBJC_MAX_STRUCT_BY_VALUE
          && objc_sizeof_type (t) > OBJC_MAX_STRUCT_BY_VALUE
#endif
          )
        return (IMP)__objc_block_forward;
      else if (t && (*t == 'f' || *t == 'd'))
        return (IMP)__objc_double_forward;
      else
        return (IMP)__objc_word_forward;
    }
}

/* Selectors for +resolveClassMethod: and +resolveInstanceMethod:.
   These are set up at startup.  */
static SEL selector_resolveClassMethod = NULL;
static SEL selector_resolveInstanceMethod = NULL;

/* Internal routines use to resolve a class method using
   +resolveClassMethod:.  'class' is always a non-Nil class (*not* a
   meta-class), and 'sel' is the selector that we are trying to
   resolve.  This must be called when class is not Nil, and the
   dispatch table for class methods has already been installed.

   This routine tries to call +resolveClassMethod: to give an
   opportunity to resolve the method.  If +resolveClassMethod: returns
   YES, it tries looking up the method again, and if found, it returns
   it.  Else, it returns NULL.  */
static inline
IMP
__objc_resolve_class_method (Class class, SEL sel)
{
  /* We need to lookup +resolveClassMethod:.  */
  BOOL (*resolveMethodIMP) (id, SEL, SEL);

  /* The dispatch table for class methods is already installed and we
     don't want any forwarding to happen when looking up this method,
     so we just look it up directly.  Note that if 'sel' is precisely
     +resolveClassMethod:, this would look it up yet again and find
     nothing.  That's no problem and there's no recursion.  */
  resolveMethodIMP = (BOOL (*) (id, SEL, SEL))sarray_get_safe
    (class->class_pointer->dtable, (size_t) selector_resolveClassMethod->sel_id);

  if (resolveMethodIMP && resolveMethodIMP ((id)class, selector_resolveClassMethod, sel))
    {
      /* +resolveClassMethod: returned YES.  Look the method up again.
	 We already know the dtable is installed.  */
      
      /* TODO: There is the case where +resolveClassMethod: is buggy
	 and returned YES without actually adding the method.  We
	 could maybe print an error message.  */
      return sarray_get_safe (class->class_pointer->dtable, (size_t) sel->sel_id);
    }

  return NULL;
}

/* Internal routines use to resolve a instance method using
   +resolveInstanceMethod:.  'class' is always a non-Nil class, and
   'sel' is the selector that we are trying to resolve.  This must be
   called when class is not Nil, and the dispatch table for instance
   methods has already been installed.

   This routine tries to call +resolveInstanceMethod: to give an
   opportunity to resolve the method.  If +resolveInstanceMethod:
   returns YES, it tries looking up the method again, and if found, it
   returns it.  Else, it returns NULL.  */
static inline
IMP
__objc_resolve_instance_method (Class class, SEL sel)
{
  /* We need to lookup +resolveInstanceMethod:.  */
  BOOL (*resolveMethodIMP) (id, SEL, SEL);

  /* The dispatch table for class methods may not be already installed
     so we have to install it if needed.  */
  resolveMethodIMP = sarray_get_safe (class->class_pointer->dtable,
				      (size_t) selector_resolveInstanceMethod->sel_id);
  if (resolveMethodIMP == 0)
    {
      /* Try again after installing the dtable.  */
      if (class->class_pointer->dtable == __objc_uninstalled_dtable)
	{
	  objc_mutex_lock (__objc_runtime_mutex);
	  if (class->class_pointer->dtable == __objc_uninstalled_dtable)
	    __objc_install_dtable_for_class (class->class_pointer);
	  objc_mutex_unlock (__objc_runtime_mutex);
	}
      resolveMethodIMP = sarray_get_safe (class->class_pointer->dtable,
					  (size_t) selector_resolveInstanceMethod->sel_id);	      
    }

  if (resolveMethodIMP && resolveMethodIMP ((id)class, selector_resolveInstanceMethod, sel))
    {
      /* +resolveInstanceMethod: returned YES.  Look the method up
	 again.  We already know the dtable is installed.  */
      
      /* TODO: There is the case where +resolveInstanceMethod: is
	 buggy and returned YES without actually adding the method.
	 We could maybe print an error message.  */
      return sarray_get_safe (class->dtable, (size_t) sel->sel_id);	
    }

  return NULL;
}

/* Given a CLASS and selector, return the implementation corresponding
   to the method of the selector.

   If CLASS is a class, the instance method is returned.
   If CLASS is a meta class, the class method is returned.

   Since this requires the dispatch table to be installed, this function
   will implicitly invoke +initialize for CLASS if it hasn't been
   invoked yet.  This also insures that +initialize has been invoked
   when the returned implementation is called directly.

   The forwarding hooks require the receiver as an argument (if they are to
   perform dynamic lookup in proxy objects etc), so this function has a
   receiver argument to be used with those hooks.  */
static inline
IMP
get_implementation (id receiver, Class class, SEL sel)
{
  void *res;

  if (class->dtable == __objc_uninstalled_dtable)
    {
      /* The dispatch table needs to be installed.  */
      objc_mutex_lock (__objc_runtime_mutex);

      /* Double-checked locking pattern: Check
	 __objc_uninstalled_dtable again in case another thread
	 installed the dtable while we were waiting for the lock to be
	 released.  */
      if (class->dtable == __objc_uninstalled_dtable)
	__objc_install_dtable_for_class (class);

      /* If the dispatch table is not yet installed, we are still in
	 the process of executing +initialize.  But the implementation
	 pointer should be available in the prepared ispatch table if
	 it exists at all.  */
      if (class->dtable == __objc_uninstalled_dtable)
	{
	  assert (__objc_prepared_dtable_for_class (class) != 0);
	  res = __objc_get_prepared_imp (class, sel);
	}
      else
	res = 0;

      objc_mutex_unlock (__objc_runtime_mutex);
      /* Call ourselves with the installed dispatch table and get the
	 real method.  */
      if (!res)
	res = get_implementation (receiver, class, sel);
    }
  else
    {
      /* The dispatch table has been installed.  */
      res = sarray_get_safe (class->dtable, (size_t) sel->sel_id);
      if (res == 0)
	{
	  /* The dispatch table has been installed, and the method is
	     not in the dispatch table.  So the method just doesn't
	     exist for the class.  */

	  /* Try going through the +resolveClassMethod: or
	     +resolveInstanceMethod: process.  */
	  if (CLS_ISMETA (class))
	    {
	      /* We have the meta class, but we need to invoke the
		 +resolveClassMethod: method on the class.  So, we
		 need to obtain the class from the meta class, which
		 we do using the fact that both the class and the
		 meta-class have the same name.  */
	      Class realClass = objc_lookUpClass (class->name);
	      if (realClass)
		res = __objc_resolve_class_method (realClass, sel);
	    }
	  else
	    res = __objc_resolve_instance_method (class, sel);

	  if (res == 0)
	    res = __objc_get_forward_imp (receiver, sel);
	}
    }
  return res;
}

inline
IMP
get_imp (Class class, SEL sel)
{
  /* In a vanilla implementation we would first check if the dispatch
     table is installed.  Here instead, to get more speed in the
     standard case (that the dispatch table is installed) we first try
     to get the imp using brute force.  Only if that fails, we do what
     we should have been doing from the very beginning, that is, check
     if the dispatch table needs to be installed, install it if it's
     not installed, and retrieve the imp from the table if it's
     installed.  */
  void *res = sarray_get_safe (class->dtable, (size_t) sel->sel_id);
  if (res == 0)
    {
      res = get_implementation(nil, class, sel);
    }
  return res;
}

/* The new name of get_imp().  */
IMP
class_getMethodImplementation (Class class_, SEL selector)
{
  if (class_ == Nil  ||  selector == NULL)
    return NULL;

  /* get_imp is inlined, so we're good.  */
  return get_imp (class_, selector);
}

/* Given a method, return its implementation.  This has been replaced
   by method_getImplementation() in the modern API.  */
IMP
method_get_imp (struct objc_method * method)
{
  return (method != (struct objc_method *)0) ? method->method_imp : (IMP)0;
}

/* Query if an object can respond to a selector, returns YES if the
   object implements the selector otherwise NO.  Does not check if the
   method can be forwarded.  Since this requires the dispatch table to
   installed, this function will implicitly invoke +initialize for the
   class of OBJECT if it hasn't been invoked yet.  */
inline
BOOL
__objc_responds_to (id object, SEL sel)
{
  void *res;
  struct sarray *dtable;

  /* Install dispatch table if need be */
  dtable = object->class_pointer->dtable;
  if (dtable == __objc_uninstalled_dtable)
    {
      objc_mutex_lock (__objc_runtime_mutex);
      if (object->class_pointer->dtable == __objc_uninstalled_dtable)
        __objc_install_dtable_for_class (object->class_pointer);

      /* If the dispatch table is not yet installed, we are still in
         the process of executing +initialize.  Yet the dispatch table
         should be available.  */
      if (object->class_pointer->dtable == __objc_uninstalled_dtable)
        {
          dtable = __objc_prepared_dtable_for_class (object->class_pointer);
          assert (dtable);
        }
      else
        dtable = object->class_pointer->dtable;

      objc_mutex_unlock (__objc_runtime_mutex);
    }

  /* Get the method from the dispatch table.  */
  res = sarray_get_safe (dtable, (size_t) sel->sel_id);
  return (res != 0) ? YES : NO;
}

BOOL
class_respondsToSelector (Class class_, SEL selector)
{
  struct sarray *dtable;
  void *res;

  if (class_ == Nil  ||  selector == NULL)
    return NO;

  /* Install dispatch table if need be.  */
  dtable = class_->dtable;
  if (dtable == __objc_uninstalled_dtable)
    {
      objc_mutex_lock (__objc_runtime_mutex);
      if (class_->dtable == __objc_uninstalled_dtable)
	__objc_install_dtable_for_class (class_);

      /* If the dispatch table is not yet installed,
         we are still in the process of executing +initialize.
         Yet the dispatch table should be available.  */
      if (class_->dtable == __objc_uninstalled_dtable)
        {
          dtable = __objc_prepared_dtable_for_class (class_);
          assert (dtable);
        }
      else
        dtable = class_->dtable;

      objc_mutex_unlock (__objc_runtime_mutex);
    }

  /* Get the method from the dispatch table.  */
  res = sarray_get_safe (dtable, (size_t) selector->sel_id);
  return (res != 0) ? YES : NO;
}

/* This is the lookup function.  All entries in the table are either a
   valid method *or* zero.  If zero then either the dispatch table
   needs to be installed or it doesn't exist and forwarding is
   attempted.  */
IMP
objc_msg_lookup (id receiver, SEL op)
{
  IMP result;
  if (receiver)
    {
      /* First try a quick lookup assuming the dispatch table exists.  */
      result = sarray_get_safe (receiver->class_pointer->dtable, 
				(sidx)op->sel_id);
      if (result == 0)
	{
	  /* Not found ... call get_implementation () to install the
             dispatch table and call +initialize as required,
             providing the method implementation or a forwarding
             function.  */
	  result = get_implementation (receiver, receiver->class_pointer, op);
	}
      return result;
    }
  else
    return (IMP)nil_method;
}

IMP
objc_msg_lookup_super (struct objc_super *super, SEL sel)
{
  if (super->self)
    return get_imp (super->super_class, sel);
  else
    return (IMP)nil_method;
}

void
__objc_init_dispatch_tables ()
{
  __objc_uninstalled_dtable = sarray_new (200, 0);

  /* TODO: It would be cool to register typed selectors here.  */
  selector_resolveClassMethod = sel_registerName ("resolveClassMethod:");
  selector_resolveInstanceMethod = sel_registerName ("resolveInstanceMethod:");
}


/* Install dummy table for class which causes the first message to
   that class (or instances hereof) to be initialized properly.  */
void
__objc_install_premature_dtable (Class class)
{
  assert (__objc_uninstalled_dtable);
  class->dtable = __objc_uninstalled_dtable;
}   

/* Send +initialize to class if not already done.  */
static void
__objc_send_initialize (Class class)
{
  /* This *must* be a class object.  */
  assert (CLS_ISCLASS (class));
  assert (! CLS_ISMETA (class));

  /* class_add_method_list/__objc_update_dispatch_table_for_class may
     have reset the dispatch table.  The canonical way to insure that
     we send +initialize just once, is this flag.  */
  if (! CLS_ISINITIALIZED (class))
    {
      DEBUG_PRINTF ("+initialize: need to initialize class '%s'\n", class->name);
      CLS_SETINITIALIZED (class);
      CLS_SETINITIALIZED (class->class_pointer);

      /* Create the garbage collector type memory description.  */
      __objc_generate_gc_type_description (class);

      if (class->super_class)
	__objc_send_initialize (class->super_class);

      {
	SEL op = sel_registerName ("initialize");
        struct objc_method *method = search_for_method_in_hierarchy (class->class_pointer, 
								     op);

	if (method)
	  {
	    DEBUG_PRINTF (" begin of [%s +initialize]\n", class->name);
	    (*method->method_imp) ((id)class, op);
	    DEBUG_PRINTF (" end of [%s +initialize]\n", class->name);
	  }
#ifdef DEBUG
	else
	  {
	    DEBUG_PRINTF (" class '%s' has no +initialize method\n", class->name);	    
	  }
#endif
      }
    }
}

/* Walk on the methods list of class and install the methods in the
   reverse order of the lists.  Since methods added by categories are
   before the methods of class in the methods list, this allows
   categories to substitute methods declared in class.  However if
   more than one category replaces the same method nothing is
   guaranteed about what method will be used.  Assumes that
   __objc_runtime_mutex is locked down.  */
static void
__objc_install_methods_in_dtable (struct sarray *dtable, struct objc_method_list * method_list)
{
  int i;
  
  if (! method_list)
    return;
  
  if (method_list->method_next)
    __objc_install_methods_in_dtable (dtable, method_list->method_next);
  
  for (i = 0; i < method_list->method_count; i++)
    {
      struct objc_method * method = &(method_list->method_list[i]);
      sarray_at_put_safe (dtable,
			  (sidx) method->method_name->sel_id,
			  method->method_imp);
    }
}

void
__objc_update_dispatch_table_for_class (Class class)
{
  Class next;
  struct sarray *arr;

  DEBUG_PRINTF (" _objc_update_dtable_for_class (%s)\n", class->name);

  objc_mutex_lock (__objc_runtime_mutex);

  /* Not yet installed -- skip it unless in +initialize.  */
  if (class->dtable == __objc_uninstalled_dtable) 
    {
      if (__objc_prepared_dtable_for_class (class))
	{
	  /* There is a prepared table so we must be initialising this
	     class ... we must re-do the table preparation.  */
	  __objc_prepare_dtable_for_class (class);
	}
      objc_mutex_unlock (__objc_runtime_mutex);
      return;
    }

  arr = class->dtable;
  __objc_install_premature_dtable (class); /* someone might require it... */
  sarray_free (arr);			   /* release memory */
  
  /* Could have been lazy...  */
  __objc_install_dtable_for_class (class); 

  if (class->subclass_list)	/* Traverse subclasses.  */
    for (next = class->subclass_list; next; next = next->sibling_class)
      __objc_update_dispatch_table_for_class (next);

  objc_mutex_unlock (__objc_runtime_mutex);
}

/* This function adds a method list to a class.  This function is
   typically called by another function specific to the run-time.  As
   such this function does not worry about thread safe issues.

   This one is only called for categories. Class objects have their
   methods installed right away, and their selectors are made into
   SEL's by the function __objc_register_selectors_from_class.  */
void
class_add_method_list (Class class, struct objc_method_list * list)
{
  /* Passing of a linked list is not allowed.  Do multiple calls.  */
  assert (! list->method_next);

  __objc_register_selectors_from_list(list);

  /* Add the methods to the class's method list.  */
  list->method_next = class->methods;
  class->methods = list;

  /* Update the dispatch table of class.  */
  __objc_update_dispatch_table_for_class (class);
}

struct objc_method *
class_getInstanceMethod (Class class_, SEL selector)
{
  struct objc_method *m;

  if (class_ == Nil  ||  selector == NULL)
    return NULL;

  m = search_for_method_in_hierarchy (class_, selector);
  if (m)
    return m;

  /* Try going through +resolveInstanceMethod:, and do the search
     again if successful.  */
  if (__objc_resolve_instance_method (class_, selector))
    return search_for_method_in_hierarchy (class_, selector);

  return NULL;
}

struct objc_method *
class_getClassMethod (Class class_, SEL selector)
{
  struct objc_method *m;

  if (class_ == Nil  ||  selector == NULL)
    return NULL;
  
  m = search_for_method_in_hierarchy (class_->class_pointer, 
				      selector);
  if (m)
    return m;

  /* Try going through +resolveClassMethod:, and do the search again
     if successful.  */
  if (__objc_resolve_class_method (class_, selector))
    return search_for_method_in_hierarchy (class_->class_pointer, 
					   selector);    

  return NULL;
}

BOOL
class_addMethod (Class class_, SEL selector, IMP implementation,
		 const char *method_types)
{
  struct objc_method_list *method_list;
  struct objc_method *method;
  const char *method_name;

  if (class_ == Nil  ||  selector == NULL  ||  implementation == NULL  
      || method_types == NULL  || (strcmp (method_types, "") == 0))
    return NO;

  method_name = sel_getName (selector);
  if (method_name == NULL)
    return NO;

  /* If the method already exists in the class, return NO.  It is fine
     if the method already exists in the superclass; in that case, we
     are overriding it.  */
  if (CLS_IS_IN_CONSTRUCTION (class_))
    {
      /* The class only contains a list of methods; they have not been
	 registered yet, ie, the method_name of each of them is still
	 a string, not a selector.  Iterate manually over them to
	 check if we have already added the method.  */
      struct objc_method_list * method_list = class_->methods;
      while (method_list)
	{
	  int i;
	  
	  /* Search the method list.  */
	  for (i = 0; i < method_list->method_count; ++i)
	    {
	      struct objc_method * method = &method_list->method_list[i];
	      
	      if (method->method_name
		  && strcmp ((char *)method->method_name, method_name) == 0)
		return NO;
	    }
	  
	  /* The method wasn't found.  Follow the link to the next list of
	     methods.  */
	  method_list = method_list->method_next;
	}
      /* The method wasn't found.  It's a new one.  Go ahead and add
	 it.  */
    }
  else
    {
      /* Do the standard lookup.  This assumes the selectors are
	 mapped.  */
      if (search_for_method_in_list (class_->methods, selector))
	return NO;
    }

  method_list = (struct objc_method_list *)objc_calloc (1, sizeof (struct objc_method_list));
  method_list->method_count = 1;

  method = &(method_list->method_list[0]);
  method->method_name = objc_malloc (strlen (method_name) + 1);
  strcpy ((char *)method->method_name, method_name);

  method->method_types = objc_malloc (strlen (method_types) + 1);
  strcpy ((char *)method->method_types, method_types);
  
  method->method_imp = implementation;
  
  if (CLS_IS_IN_CONSTRUCTION (class_))
    {
      /* We only need to add the method to the list.  It will be
	 registered with the runtime when the class pair is registered
	 (if ever).  */
      method_list->method_next = class_->methods;
      class_->methods = method_list;
    }
  else
    {
      /* Add the method to a live class.  */
      objc_mutex_lock (__objc_runtime_mutex);
      class_add_method_list (class_, method_list);
      objc_mutex_unlock (__objc_runtime_mutex);
    }

  return YES;
}

IMP
class_replaceMethod (Class class_, SEL selector, IMP implementation,
		     const char *method_types)
{
  struct objc_method * method;

  if (class_ == Nil  ||  selector == NULL  ||  implementation == NULL
      || method_types == NULL)
    return NULL;

  method = search_for_method_in_hierarchy (class_, selector);

  if (method)
    {
      return method_setImplementation (method, implementation);
    }
  else
    {
      class_addMethod (class_, selector, implementation, method_types);
      return NULL;
    }
}

/* Search for a method starting from the current class up its
   hierarchy.  Return a pointer to the method's method structure if
   found.  NULL otherwise.  */
static struct objc_method *
search_for_method_in_hierarchy (Class cls, SEL sel)
{
  struct objc_method * method = NULL;
  Class class;

  if (! sel_is_mapped (sel))
    return NULL;

  /* Scan the method list of the class.  If the method isn't found in
     the list then step to its super class.  */
  for (class = cls; ((! method) && class); class = class->super_class)
    method = search_for_method_in_list (class->methods, sel);

  return method;
}



/* Given a linked list of method and a method's name.  Search for the
   named method's method structure.  Return a pointer to the method's
   method structure if found.  NULL otherwise.  */  
struct objc_method *
search_for_method_in_list (struct objc_method_list * list, SEL op)
{
  struct objc_method_list * method_list = list;

  if (! sel_is_mapped (op))
    return NULL;

  /* If not found then we'll search the list.  */
  while (method_list)
    {
      int i;

      /* Search the method list.  */
      for (i = 0; i < method_list->method_count; ++i)
        {
          struct objc_method * method = &method_list->method_list[i];

          if (method->method_name)
            if (method->method_name->sel_id == op->sel_id)
              return method;
        }

      /* The method wasn't found.  Follow the link to the next list of
         methods.  */
      method_list = method_list->method_next;
    }

  return NULL;
}

typedef void * retval_t;
typedef void * arglist_t;

static retval_t __objc_forward (id object, SEL sel, arglist_t args);

/* Forwarding pointers/integers through the normal registers.  */
static id
__objc_word_forward (id rcv, SEL op, ...)
{
  void *args, *res;

  args = __builtin_apply_args ();
  res = __objc_forward (rcv, op, args);
  if (res)
    __builtin_return (res);
  else
    return res;
}

/* Specific routine for forwarding floats/double because of
   architectural differences on some processors.  i386s for example
   which uses a floating point stack versus general registers for
   floating point numbers.  This forward routine makes sure that GCC
   restores the proper return values.  */
static double
__objc_double_forward (id rcv, SEL op, ...)
{
  void *args, *res;

  args = __builtin_apply_args ();
  res = __objc_forward (rcv, op, args);
  __builtin_return (res);
}

#if INVISIBLE_STRUCT_RETURN
static __big
#else
static id
#endif
__objc_block_forward (id rcv, SEL op, ...)
{
  void *args, *res;

  args = __builtin_apply_args ();
  res = __objc_forward (rcv, op, args);
  if (res)
    __builtin_return (res);
  else
#if INVISIBLE_STRUCT_RETURN
    return (__big) {{0, 0, 0, 0, 0, 0, 0, 0}};
#else
    return nil;
#endif
}


/* This function is called for methods which are not implemented,
   unless a custom forwarding routine has been installed.  Please note
   that most serious users of libobjc (eg, GNUstep base) do install
   their own forwarding routines, and hence this is never actually
   used.  But, if no custom forwarding routine is installed, this is
   called when a selector is not recognized.  */
static retval_t
__objc_forward (id object, SEL sel, arglist_t args)
{
  IMP imp;
  static SEL frwd_sel = 0;                      /* !T:SAFE2 */
  SEL err_sel;

  /* First try if the object understands forward::.  */
  if (! frwd_sel)
    frwd_sel = sel_get_any_uid ("forward::");

  if (__objc_responds_to (object, frwd_sel))
    {
      imp = get_implementation (object, object->class_pointer, frwd_sel);
      return (*imp) (object, frwd_sel, sel, args);
    }

  /* If the object recognizes the doesNotRecognize: method then we're
     going to send it.  */
  err_sel = sel_get_any_uid ("doesNotRecognize:");
  if (__objc_responds_to (object, err_sel))
    {
      imp = get_implementation (object, object->class_pointer, err_sel);
      return (*imp) (object, err_sel, sel);
    }
  
  /* The object doesn't recognize the method.  Check for responding to
     error:.  If it does then sent it.  */
  {
    char msg[256 + strlen ((const char *) sel_getName (sel))
             + strlen ((const char *) object->class_pointer->name)];

    sprintf (msg, "(%s) %s does not recognize %s",
	     (CLS_ISMETA (object->class_pointer)
	      ? "class"
	      : "instance" ),
             object->class_pointer->name, sel_getName (sel));

    /* The object doesn't respond to doesNotRecognize:.  Therefore, a
       default action is taken.  */
    _objc_abort ("%s\n", msg);

    return 0;
  }
}

void
__objc_print_dtable_stats (void)
{
  int total = 0;

  objc_mutex_lock (__objc_runtime_mutex);

#ifdef OBJC_SPARSE2
  printf ("memory usage: (%s)\n", "2-level sparse arrays");
#else
  printf ("memory usage: (%s)\n", "3-level sparse arrays");
#endif

  printf ("arrays: %d = %ld bytes\n", narrays, 
	  (long) ((size_t) narrays * sizeof (struct sarray)));
  total += narrays * sizeof (struct sarray);
  printf ("buckets: %d = %ld bytes\n", nbuckets, 
	  (long) ((size_t) nbuckets * sizeof (struct sbucket)));
  total += nbuckets * sizeof (struct sbucket);

  printf ("idxtables: %d = %ld bytes\n",
	  idxsize, (long) ((size_t) idxsize * sizeof (void *)));
  total += idxsize * sizeof (void *);
  printf ("-----------------------------------\n");
  printf ("total: %d bytes\n", total);
  printf ("===================================\n");

  objc_mutex_unlock (__objc_runtime_mutex);
}

static cache_ptr prepared_dtable_table = 0;

/* This function is called by: objc_msg_lookup, get_imp and
   __objc_responds_to (and the dispatch table installation functions
   themselves) to install a dispatch table for a class.

   If CLS is a class, it installs instance methods.
   If CLS is a meta class, it installs class methods.

   In either case +initialize is invoked for the corresponding class.

   The implementation must insure that the dispatch table is not
   installed until +initialize completes.  Otherwise it opens a
   potential race since the installation of the dispatch table is used
   as gate in regular method dispatch and we need to guarantee that
   +initialize is the first method invoked an that no other thread my
   dispatch messages to the class before +initialize completes.  */
static void
__objc_install_dtable_for_class (Class cls)
{
  /* If the class has not yet had its class links resolved, we must
     re-compute all class links.  */
  if (! CLS_ISRESOLV (cls))
    __objc_resolve_class_links ();

  /* Make sure the super class has its dispatch table installed or is
     at least preparing.  We do not need to send initialize for the
     super class since __objc_send_initialize will insure that.  */
  if (cls->super_class
      && cls->super_class->dtable == __objc_uninstalled_dtable
      && !__objc_prepared_dtable_for_class (cls->super_class))
    {
      __objc_install_dtable_for_class (cls->super_class);
      /* The superclass initialisation may have also initialised the
         current class, in which case there is no more to do.  */
      if (cls->dtable != __objc_uninstalled_dtable)
	return;
    }

  /* We have already been prepared but +initialize hasn't completed.
     The +initialize implementation is probably sending 'self'
     messages.  We rely on _objc_get_prepared_imp to retrieve the
     implementation pointers.  */
  if (__objc_prepared_dtable_for_class (cls))
    return;

  /* We have this function cache the implementation pointers for
     _objc_get_prepared_imp but the dispatch table won't be initilized
     until __objc_send_initialize completes.  */
  __objc_prepare_dtable_for_class (cls);

  /* We may have already invoked +initialize but
     __objc_update_dispatch_table_for_class invoked by
     class_add_method_list may have reset dispatch table.  */

  /* Call +initialize.  If we are a real class, we are installing
     instance methods.  If we are a meta class, we are installing
     class methods.  The __objc_send_initialize itself will insure
     that the message is called only once per class.  */
  if (CLS_ISCLASS (cls))
    __objc_send_initialize (cls);
  else
    {
      /* Retrieve the class from the meta class.  */
      Class c = objc_getClass (cls->name);
      assert (CLS_ISMETA (cls));
      assert (c);
      __objc_send_initialize (c);
    }

  /* We install the dispatch table correctly when +initialize completed.  */
  __objc_install_prepared_dtable_for_class (cls);
}

/* Builds the dispatch table for the class CLS and stores it in a
   place where it can be retrieved by __objc_get_prepared_imp until
   __objc_install_prepared_dtable_for_class installs it into the
   class.  The dispatch table should not be installed into the class
   until +initialize has completed.  */
static void
__objc_prepare_dtable_for_class (Class cls)
{
  struct sarray *dtable;
  struct sarray *super_dtable;

  /* This table could be initialized in init.c.  We can not use the
     class name since the class maintains the instance methods and the
     meta class maintains the the class methods yet both share the
     same name.  Classes should be unique in any program.  */
  if (! prepared_dtable_table)
    prepared_dtable_table 
      = objc_hash_new (32,
		       (hash_func_type) objc_hash_ptr,
		       (compare_func_type) objc_compare_ptrs);
  
  /* If the class has not yet had its class links resolved, we must
     re-compute all class links.  */
  if (! CLS_ISRESOLV (cls))
    __objc_resolve_class_links ();

  assert (cls);
  assert (cls->dtable == __objc_uninstalled_dtable);

  /* If there is already a prepared dtable for this class, we must
     replace it with a new version (since there must have been methods
     added to or otherwise modified in the class while executing
     +initialize, and the table needs to be recomputed.  */
  dtable = __objc_prepared_dtable_for_class (cls);
  if (dtable != 0)
    {
      objc_hash_remove (prepared_dtable_table, cls);
      sarray_free (dtable);
    }

  /* Now prepare the dtable for population.  */
  assert (cls != cls->super_class);
  if (cls->super_class)
    {
      /* Inherit the method list from the super class.  Yet the super
         class may still be initializing in the case when a class
         cluster sub class initializes its super classes.  */
      if (cls->super_class->dtable == __objc_uninstalled_dtable)
	__objc_install_dtable_for_class (cls->super_class);

      super_dtable = cls->super_class->dtable;
      /* If the dispatch table is not yet installed, we are still in
	 the process of executing +initialize.  Yet the dispatch table
	 should be available.  */
      if (super_dtable == __objc_uninstalled_dtable)
	super_dtable = __objc_prepared_dtable_for_class (cls->super_class);

      assert (super_dtable);
      dtable = sarray_lazy_copy (super_dtable);
    }
  else
    dtable = sarray_new (__objc_selector_max_index, 0);

  __objc_install_methods_in_dtable (dtable, cls->methods);

  objc_hash_add (&prepared_dtable_table,
		 cls,
		 dtable);
}

/* This wrapper only exists to allow an easy replacement of the lookup
   implementation and it is expected that the compiler will optimize
   it away.  */
static struct sarray *
__objc_prepared_dtable_for_class (Class cls)
{
  struct sarray *dtable = 0;
  assert (cls);
  if (prepared_dtable_table)
    dtable = objc_hash_value_for_key (prepared_dtable_table, cls);
  /* dtable my be nil, since we call this to check whether we are
     currently preparing before we start preparing.  */
  return dtable;
}

/* Helper function for messages sent to CLS or implementation pointers
   retrieved from CLS during +initialize before the dtable is
   installed.  When a class implicitly initializes another class which
   in turn implicitly invokes methods in this class, before the
   implementation of +initialize of CLS completes, this returns the
   expected implementation.  Forwarding remains the responsibility of
   objc_msg_lookup.  This function should only be called under the
   global lock.  */
static IMP
__objc_get_prepared_imp (Class cls,SEL sel)
{
  struct sarray *dtable;
  IMP imp;

  assert (cls);
  assert (sel);
  assert (cls->dtable == __objc_uninstalled_dtable);
  dtable = __objc_prepared_dtable_for_class (cls);

  assert (dtable);
  assert (dtable != __objc_uninstalled_dtable);
  imp = sarray_get_safe (dtable, (size_t) sel->sel_id);

  /* imp may be Nil if the method does not exist and we may fallback
     to the forwarding implementation later.  */
  return imp;  
}

/* When this function is called +initialize should be completed.  So
   now we are safe to install the dispatch table for the class so that
   they become available for other threads that may be waiting in the
   lock.  */
static void
__objc_install_prepared_dtable_for_class (Class cls)
{
  assert (cls);
  assert (cls->dtable == __objc_uninstalled_dtable);
  cls->dtable = __objc_prepared_dtable_for_class (cls);

  assert (cls->dtable);
  assert (cls->dtable != __objc_uninstalled_dtable);
  objc_hash_remove (prepared_dtable_table, cls);
}
