/* GNU Objective C Runtime method related functions.
   Copyright (C) 2010-2022 Free Software Foundation, Inc.
   Contributed by Nicola Pero

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-private/module-abi-8.h" /* For runtime structures.   */
#include "objc/thr.h"
#include "objc-private/runtime.h"      /* For __objc_runtime_mutex.  */
#include <stdlib.h>                    /* For malloc.  */

SEL
method_getName (struct objc_method * method)
{
  if (method == NULL)
    return NULL;

  return method->method_name;
}

const char *
method_getTypeEncoding (struct objc_method * method)
{
  if (method == NULL)
    return NULL;

  return method->method_types;
}

IMP
method_getImplementation (struct objc_method * method)
{
  if (method == NULL)
    return NULL;

  return method->method_imp;
}

struct objc_method_description *
method_getDescription (struct objc_method * method)
{
  /* Note that the following returns NULL if method is NULL, which is
     fine.  */
  return (struct objc_method_description *)method;
}

struct objc_method **
class_copyMethodList (Class class_, unsigned int *numberOfReturnedMethods)
{
  unsigned int count = 0;
  struct objc_method **returnValue = NULL;
  struct objc_method_list* method_list;

  if (class_ == Nil)
    {
      if (numberOfReturnedMethods)
	*numberOfReturnedMethods = 0;
      return NULL;
    }

  /* Lock the runtime mutex because the class methods may be
     concurrently modified.  */
  objc_mutex_lock (__objc_runtime_mutex);

  /* Count how many methods we have.  */
  method_list = class_->methods;

  while (method_list)
    {
      count = count + method_list->method_count;
      method_list = method_list->method_next;
    }

  if (count != 0)
    {
      unsigned int i = 0;
      
      /* Allocate enough memory to hold them.  */
      returnValue 
	= (struct objc_method **)(malloc (sizeof (struct objc_method *) 
					  * (count + 1)));
      
      /* Copy the methods.  */
      method_list = class_->methods;
      
      while (method_list)
	{
	  int j;
	  for (j = 0; j < method_list->method_count; j++)
	    {
	      returnValue[i] = &(method_list->method_list[j]);
	      i++;
	    }
	  method_list = method_list->method_next;
	}
      
      returnValue[i] = NULL;
    }

  objc_mutex_unlock (__objc_runtime_mutex);

  if (numberOfReturnedMethods)
    *numberOfReturnedMethods = count;

  return returnValue;
}

IMP
method_setImplementation (struct objc_method * method, IMP implementation)
{
  IMP old_implementation;

  if (method == NULL  ||  implementation == NULL)
    return NULL;

  /* We lock the runtime mutex so that concurrent calls to change the
     same method won't conflict with each other.  */
  objc_mutex_lock (__objc_runtime_mutex);

  old_implementation = method->method_imp;
  method->method_imp = implementation;

  /* That was easy :-).  But now we need to find all classes that use
     this method, and update the IMP in the dispatch tables.  */
  __objc_update_classes_with_methods (method, NULL);

  objc_mutex_unlock (__objc_runtime_mutex);

  return old_implementation;
}

void
method_exchangeImplementations (struct objc_method * method_a, struct objc_method * method_b)
{
  IMP old_implementation_a;
  IMP old_implementation_b;

  if (method_a == NULL  ||  method_b == NULL)
    return;

  /* We lock the runtime mutex so that concurrent calls to exchange
     similar methods won't conflict with each other.  Each of them
     should be atomic.  */
  objc_mutex_lock (__objc_runtime_mutex);

  old_implementation_a = method_a->method_imp;
  old_implementation_b = method_b->method_imp;

  method_a->method_imp = old_implementation_b;
  method_b->method_imp = old_implementation_a;

  /* That was easy :-).  But now we need to find all classes that use
     these methods, and update the IMP in the dispatch tables.  */
  __objc_update_classes_with_methods (method_a, method_b);

  objc_mutex_unlock (__objc_runtime_mutex);
}
