]> git.ipfire.org Git - thirdparty/gcc.git/blame - libobjc/methods.c
In libobjc/: 2011-06-07 Nicola Pero <nicola.pero@meta-innovation.com>
[thirdparty/gcc.git] / libobjc / methods.c
CommitLineData
ad9eef11
NP
1/* GNU Objective C Runtime method related functions.
2 Copyright (C) 2010 Free Software Foundation, Inc.
3 Contributed by Nicola Pero
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under the
8terms of the GNU General Public License as published by the Free Software
9Foundation; either version 3, or (at your option) any later version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14details.
15
16Under Section 7 of GPL version 3, you are granted additional
17permissions described in the GCC Runtime Library Exception, version
183.1, as published by the Free Software Foundation.
19
20You should have received a copy of the GNU General Public License and
21a copy of the GCC Runtime Library Exception along with this program;
22see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23<http://www.gnu.org/licenses/>. */
24
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. */
31
ad49efbd
NP
32SEL
33method_getName (struct objc_method * method)
ad9eef11
NP
34{
35 if (method == NULL)
36 return NULL;
37
38 return method->method_name;
39}
40
ad49efbd
NP
41const char *
42method_getTypeEncoding (struct objc_method * method)
ad9eef11
NP
43{
44 if (method == NULL)
45 return NULL;
46
47 return method->method_types;
48}
49
ad49efbd
NP
50IMP
51method_getImplementation (struct objc_method * method)
ad9eef11
NP
52{
53 if (method == NULL)
54 return NULL;
55
56 return method->method_imp;
57}
58
ad49efbd
NP
59struct objc_method_description *
60method_getDescription (struct objc_method * method)
61{
62 /* Note that the following returns NULL if method is NULL, which is
63 fine. */
64 return (struct objc_method_description *)method;
65}
66
67struct objc_method **
68class_copyMethodList (Class class_, unsigned int *numberOfReturnedMethods)
ad9eef11
NP
69{
70 unsigned int count = 0;
71 struct objc_method **returnValue = NULL;
72 struct objc_method_list* method_list;
73
74 if (class_ == Nil)
75 {
76 if (numberOfReturnedMethods)
77 *numberOfReturnedMethods = 0;
78 return NULL;
79 }
80
81 /* Lock the runtime mutex because the class methods may be
82 concurrently modified. */
83 objc_mutex_lock (__objc_runtime_mutex);
84
85 /* Count how many methods we have. */
86 method_list = class_->methods;
87
88 while (method_list)
89 {
90 count = count + method_list->method_count;
91 method_list = method_list->method_next;
92 }
93
94 if (count != 0)
95 {
96 unsigned int i = 0;
97
98 /* Allocate enough memory to hold them. */
99 returnValue
100 = (struct objc_method **)(malloc (sizeof (struct objc_method *)
101 * (count + 1)));
102
103 /* Copy the methods. */
104 method_list = class_->methods;
105
106 while (method_list)
107 {
108 int j;
109 for (j = 0; j < method_list->method_count; j++)
110 {
111 returnValue[i] = &(method_list->method_list[j]);
112 i++;
113 }
114 method_list = method_list->method_next;
115 }
116
117 returnValue[i] = NULL;
118 }
119
120 objc_mutex_unlock (__objc_runtime_mutex);
121
122 if (numberOfReturnedMethods)
123 *numberOfReturnedMethods = count;
124
125 return returnValue;
126}
51194e8e
NP
127
128IMP
129method_setImplementation (struct objc_method * method, IMP implementation)
130{
131 IMP old_implementation;
132
133 if (method == NULL || implementation == NULL)
134 return NULL;
135
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);
139
140 old_implementation = method->method_imp;
141 method->method_imp = implementation;
142
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);
146
147 objc_mutex_unlock (__objc_runtime_mutex);
148
149 return old_implementation;
150}
151
152void
153method_exchangeImplementations (struct objc_method * method_a, struct objc_method * method_b)
154{
155 IMP old_implementation_a;
156 IMP old_implementation_b;
157
158 if (method_a == NULL || method_b == NULL)
159 return;
160
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);
165
166 old_implementation_a = method_a->method_imp;
167 old_implementation_b = method_b->method_imp;
168
169 method_a->method_imp = old_implementation_b;
170 method_b->method_imp = old_implementation_a;
171
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);
175
176 objc_mutex_unlock (__objc_runtime_mutex);
177}