2013-05-23 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libobjc / methods.c
blobff041f7d57ecc5f4b5f2db7b620878eb43478f1d
1 /* GNU Objective C Runtime method related functions.
2 Copyright (C) 2010-2013 Free Software Foundation, Inc.
3 Contributed by Nicola Pero
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation; either version 3, or (at your option) any later version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 details.
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
25 #include "objc-private/common.h"
26 #include "objc/runtime.h"
27 #include "objc-private/module-abi-8.h" /* For runtime structures. */
28 #include "objc/thr.h"
29 #include "objc-private/runtime.h" /* For __objc_runtime_mutex. */
30 #include <stdlib.h> /* For malloc. */
32 SEL
33 method_getName (struct objc_method * method)
35 if (method == NULL)
36 return NULL;
38 return method->method_name;
41 const char *
42 method_getTypeEncoding (struct objc_method * method)
44 if (method == NULL)
45 return NULL;
47 return method->method_types;
50 IMP
51 method_getImplementation (struct objc_method * method)
53 if (method == NULL)
54 return NULL;
56 return method->method_imp;
59 struct objc_method_description *
60 method_getDescription (struct objc_method * method)
62 /* Note that the following returns NULL if method is NULL, which is
63 fine. */
64 return (struct objc_method_description *)method;
67 struct objc_method **
68 class_copyMethodList (Class class_, unsigned int *numberOfReturnedMethods)
70 unsigned int count = 0;
71 struct objc_method **returnValue = NULL;
72 struct objc_method_list* method_list;
74 if (class_ == Nil)
76 if (numberOfReturnedMethods)
77 *numberOfReturnedMethods = 0;
78 return NULL;
81 /* Lock the runtime mutex because the class methods may be
82 concurrently modified. */
83 objc_mutex_lock (__objc_runtime_mutex);
85 /* Count how many methods we have. */
86 method_list = class_->methods;
88 while (method_list)
90 count = count + method_list->method_count;
91 method_list = method_list->method_next;
94 if (count != 0)
96 unsigned int i = 0;
98 /* Allocate enough memory to hold them. */
99 returnValue
100 = (struct objc_method **)(malloc (sizeof (struct objc_method *)
101 * (count + 1)));
103 /* Copy the methods. */
104 method_list = class_->methods;
106 while (method_list)
108 int j;
109 for (j = 0; j < method_list->method_count; j++)
111 returnValue[i] = &(method_list->method_list[j]);
112 i++;
114 method_list = method_list->method_next;
117 returnValue[i] = NULL;
120 objc_mutex_unlock (__objc_runtime_mutex);
122 if (numberOfReturnedMethods)
123 *numberOfReturnedMethods = count;
125 return returnValue;
129 method_setImplementation (struct objc_method * method, IMP implementation)
131 IMP old_implementation;
133 if (method == NULL || implementation == NULL)
134 return NULL;
136 /* We lock the runtime mutex so that concurrent calls to change the
137 same method won't conflict with each other. */
138 objc_mutex_lock (__objc_runtime_mutex);
140 old_implementation = method->method_imp;
141 method->method_imp = implementation;
143 /* That was easy :-). But now we need to find all classes that use
144 this method, and update the IMP in the dispatch tables. */
145 __objc_update_classes_with_methods (method, NULL);
147 objc_mutex_unlock (__objc_runtime_mutex);
149 return old_implementation;
152 void
153 method_exchangeImplementations (struct objc_method * method_a, struct objc_method * method_b)
155 IMP old_implementation_a;
156 IMP old_implementation_b;
158 if (method_a == NULL || method_b == NULL)
159 return;
161 /* We lock the runtime mutex so that concurrent calls to exchange
162 similar methods won't conflict with each other. Each of them
163 should be atomic. */
164 objc_mutex_lock (__objc_runtime_mutex);
166 old_implementation_a = method_a->method_imp;
167 old_implementation_b = method_b->method_imp;
169 method_a->method_imp = old_implementation_b;
170 method_b->method_imp = old_implementation_a;
172 /* That was easy :-). But now we need to find all classes that use
173 these methods, and update the IMP in the dispatch tables. */
174 __objc_update_classes_with_methods (method_a, method_b);
176 objc_mutex_unlock (__objc_runtime_mutex);