123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- /* GNU Objective C Runtime method related functions.
- Copyright (C) 2010-2015 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);
- }
|