annotate libobjc/methods.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* GNU Objective C Runtime method related functions.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2010-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3 Contributed by Nicola Pero
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 This file is part of GCC.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it under the
kono
parents:
diff changeset
8 terms of the GNU General Public License as published by the Free Software
kono
parents:
diff changeset
9 Foundation; either version 3, or (at your option) any later version.
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
kono
parents:
diff changeset
13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
kono
parents:
diff changeset
14 details.
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 Under Section 7 of GPL version 3, you are granted additional
kono
parents:
diff changeset
17 permissions described in the GCC Runtime Library Exception, version
kono
parents:
diff changeset
18 3.1, as published by the Free Software Foundation.
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 You should have received a copy of the GNU General Public License and
kono
parents:
diff changeset
21 a copy of the GCC Runtime Library Exception along with this program;
kono
parents:
diff changeset
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kono
parents:
diff changeset
23 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
24
kono
parents:
diff changeset
25 #include "objc-private/common.h"
kono
parents:
diff changeset
26 #include "objc/runtime.h"
kono
parents:
diff changeset
27 #include "objc-private/module-abi-8.h" /* For runtime structures. */
kono
parents:
diff changeset
28 #include "objc/thr.h"
kono
parents:
diff changeset
29 #include "objc-private/runtime.h" /* For __objc_runtime_mutex. */
kono
parents:
diff changeset
30 #include <stdlib.h> /* For malloc. */
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 SEL
kono
parents:
diff changeset
33 method_getName (struct objc_method * method)
kono
parents:
diff changeset
34 {
kono
parents:
diff changeset
35 if (method == NULL)
kono
parents:
diff changeset
36 return NULL;
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 return method->method_name;
kono
parents:
diff changeset
39 }
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 const char *
kono
parents:
diff changeset
42 method_getTypeEncoding (struct objc_method * method)
kono
parents:
diff changeset
43 {
kono
parents:
diff changeset
44 if (method == NULL)
kono
parents:
diff changeset
45 return NULL;
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 return method->method_types;
kono
parents:
diff changeset
48 }
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 IMP
kono
parents:
diff changeset
51 method_getImplementation (struct objc_method * method)
kono
parents:
diff changeset
52 {
kono
parents:
diff changeset
53 if (method == NULL)
kono
parents:
diff changeset
54 return NULL;
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 return method->method_imp;
kono
parents:
diff changeset
57 }
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 struct objc_method_description *
kono
parents:
diff changeset
60 method_getDescription (struct objc_method * method)
kono
parents:
diff changeset
61 {
kono
parents:
diff changeset
62 /* Note that the following returns NULL if method is NULL, which is
kono
parents:
diff changeset
63 fine. */
kono
parents:
diff changeset
64 return (struct objc_method_description *)method;
kono
parents:
diff changeset
65 }
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 struct objc_method **
kono
parents:
diff changeset
68 class_copyMethodList (Class class_, unsigned int *numberOfReturnedMethods)
kono
parents:
diff changeset
69 {
kono
parents:
diff changeset
70 unsigned int count = 0;
kono
parents:
diff changeset
71 struct objc_method **returnValue = NULL;
kono
parents:
diff changeset
72 struct objc_method_list* method_list;
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 if (class_ == Nil)
kono
parents:
diff changeset
75 {
kono
parents:
diff changeset
76 if (numberOfReturnedMethods)
kono
parents:
diff changeset
77 *numberOfReturnedMethods = 0;
kono
parents:
diff changeset
78 return NULL;
kono
parents:
diff changeset
79 }
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 /* Lock the runtime mutex because the class methods may be
kono
parents:
diff changeset
82 concurrently modified. */
kono
parents:
diff changeset
83 objc_mutex_lock (__objc_runtime_mutex);
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 /* Count how many methods we have. */
kono
parents:
diff changeset
86 method_list = class_->methods;
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 while (method_list)
kono
parents:
diff changeset
89 {
kono
parents:
diff changeset
90 count = count + method_list->method_count;
kono
parents:
diff changeset
91 method_list = method_list->method_next;
kono
parents:
diff changeset
92 }
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 if (count != 0)
kono
parents:
diff changeset
95 {
kono
parents:
diff changeset
96 unsigned int i = 0;
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 /* Allocate enough memory to hold them. */
kono
parents:
diff changeset
99 returnValue
kono
parents:
diff changeset
100 = (struct objc_method **)(malloc (sizeof (struct objc_method *)
kono
parents:
diff changeset
101 * (count + 1)));
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 /* Copy the methods. */
kono
parents:
diff changeset
104 method_list = class_->methods;
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 while (method_list)
kono
parents:
diff changeset
107 {
kono
parents:
diff changeset
108 int j;
kono
parents:
diff changeset
109 for (j = 0; j < method_list->method_count; j++)
kono
parents:
diff changeset
110 {
kono
parents:
diff changeset
111 returnValue[i] = &(method_list->method_list[j]);
kono
parents:
diff changeset
112 i++;
kono
parents:
diff changeset
113 }
kono
parents:
diff changeset
114 method_list = method_list->method_next;
kono
parents:
diff changeset
115 }
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 returnValue[i] = NULL;
kono
parents:
diff changeset
118 }
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 objc_mutex_unlock (__objc_runtime_mutex);
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 if (numberOfReturnedMethods)
kono
parents:
diff changeset
123 *numberOfReturnedMethods = count;
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 return returnValue;
kono
parents:
diff changeset
126 }
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 IMP
kono
parents:
diff changeset
129 method_setImplementation (struct objc_method * method, IMP implementation)
kono
parents:
diff changeset
130 {
kono
parents:
diff changeset
131 IMP old_implementation;
kono
parents:
diff changeset
132
kono
parents:
diff changeset
133 if (method == NULL || implementation == NULL)
kono
parents:
diff changeset
134 return NULL;
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 /* We lock the runtime mutex so that concurrent calls to change the
kono
parents:
diff changeset
137 same method won't conflict with each other. */
kono
parents:
diff changeset
138 objc_mutex_lock (__objc_runtime_mutex);
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 old_implementation = method->method_imp;
kono
parents:
diff changeset
141 method->method_imp = implementation;
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 /* That was easy :-). But now we need to find all classes that use
kono
parents:
diff changeset
144 this method, and update the IMP in the dispatch tables. */
kono
parents:
diff changeset
145 __objc_update_classes_with_methods (method, NULL);
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 objc_mutex_unlock (__objc_runtime_mutex);
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 return old_implementation;
kono
parents:
diff changeset
150 }
kono
parents:
diff changeset
151
kono
parents:
diff changeset
152 void
kono
parents:
diff changeset
153 method_exchangeImplementations (struct objc_method * method_a, struct objc_method * method_b)
kono
parents:
diff changeset
154 {
kono
parents:
diff changeset
155 IMP old_implementation_a;
kono
parents:
diff changeset
156 IMP old_implementation_b;
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158 if (method_a == NULL || method_b == NULL)
kono
parents:
diff changeset
159 return;
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 /* We lock the runtime mutex so that concurrent calls to exchange
kono
parents:
diff changeset
162 similar methods won't conflict with each other. Each of them
kono
parents:
diff changeset
163 should be atomic. */
kono
parents:
diff changeset
164 objc_mutex_lock (__objc_runtime_mutex);
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 old_implementation_a = method_a->method_imp;
kono
parents:
diff changeset
167 old_implementation_b = method_b->method_imp;
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 method_a->method_imp = old_implementation_b;
kono
parents:
diff changeset
170 method_b->method_imp = old_implementation_a;
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 /* That was easy :-). But now we need to find all classes that use
kono
parents:
diff changeset
173 these methods, and update the IMP in the dispatch tables. */
kono
parents:
diff changeset
174 __objc_update_classes_with_methods (method_a, method_b);
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 objc_mutex_unlock (__objc_runtime_mutex);
kono
parents:
diff changeset
177 }