1 /* GNU Objective C Runtime method related functions.
2 Copyright (C) 2010-2018 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
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. */
29 #include "objc-private/runtime.h" /* For __objc_runtime_mutex. */
30 #include <stdlib.h> /* For malloc. */
33 method_getName (struct objc_method
* method
)
38 return method
->method_name
;
42 method_getTypeEncoding (struct objc_method
* method
)
47 return method
->method_types
;
51 method_getImplementation (struct objc_method
* method
)
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
64 return (struct objc_method_description
*)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
;
76 if (numberOfReturnedMethods
)
77 *numberOfReturnedMethods
= 0;
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
;
90 count
= count
+ method_list
->method_count
;
91 method_list
= method_list
->method_next
;
98 /* Allocate enough memory to hold them. */
100 = (struct objc_method
**)(malloc (sizeof (struct objc_method
*)
103 /* Copy the methods. */
104 method_list
= class_
->methods
;
109 for (j
= 0; j
< method_list
->method_count
; j
++)
111 returnValue
[i
] = &(method_list
->method_list
[j
]);
114 method_list
= method_list
->method_next
;
117 returnValue
[i
] = NULL
;
120 objc_mutex_unlock (__objc_runtime_mutex
);
122 if (numberOfReturnedMethods
)
123 *numberOfReturnedMethods
= count
;
129 method_setImplementation (struct objc_method
* method
, IMP implementation
)
131 IMP old_implementation
;
133 if (method
== NULL
|| implementation
== 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
;
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
)
161 /* We lock the runtime mutex so that concurrent calls to exchange
162 similar methods won't conflict with each other. Each of them
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
);