ivars.c revision 1.1.1.1.4.2 1 1.1.1.1.4.2 yamt /* GNU Objective C Runtime ivar related functions.
2 1.1.1.1.4.2 yamt Copyright (C) 2010-2013 Free Software Foundation, Inc.
3 1.1.1.1.4.2 yamt Contributed by Nicola Pero
4 1.1.1.1.4.2 yamt
5 1.1.1.1.4.2 yamt This file is part of GCC.
6 1.1.1.1.4.2 yamt
7 1.1.1.1.4.2 yamt GCC is free software; you can redistribute it and/or modify it under the
8 1.1.1.1.4.2 yamt terms of the GNU General Public License as published by the Free Software
9 1.1.1.1.4.2 yamt Foundation; either version 3, or (at your option) any later version.
10 1.1.1.1.4.2 yamt
11 1.1.1.1.4.2 yamt GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 1.1.1.1.4.2 yamt WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 1.1.1.1.4.2 yamt FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 1.1.1.1.4.2 yamt details.
15 1.1.1.1.4.2 yamt
16 1.1.1.1.4.2 yamt Under Section 7 of GPL version 3, you are granted additional
17 1.1.1.1.4.2 yamt permissions described in the GCC Runtime Library Exception, version
18 1.1.1.1.4.2 yamt 3.1, as published by the Free Software Foundation.
19 1.1.1.1.4.2 yamt
20 1.1.1.1.4.2 yamt You should have received a copy of the GNU General Public License and
21 1.1.1.1.4.2 yamt a copy of the GCC Runtime Library Exception along with this program;
22 1.1.1.1.4.2 yamt see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 1.1.1.1.4.2 yamt <http://www.gnu.org/licenses/>. */
24 1.1.1.1.4.2 yamt
25 1.1.1.1.4.2 yamt #include "objc-private/common.h"
26 1.1.1.1.4.2 yamt #include "objc/runtime.h"
27 1.1.1.1.4.2 yamt #include "objc-private/module-abi-8.h" /* For runtime structures */
28 1.1.1.1.4.2 yamt #include "objc/thr.h"
29 1.1.1.1.4.2 yamt #include "objc-private/runtime.h" /* the kitchen sink */
30 1.1.1.1.4.2 yamt #include <string.h> /* For strcmp. */
31 1.1.1.1.4.2 yamt #include <stdlib.h> /* For malloc. */
32 1.1.1.1.4.2 yamt
33 1.1.1.1.4.2 yamt struct objc_ivar *
34 1.1.1.1.4.2 yamt class_getInstanceVariable (Class class_, const char *name)
35 1.1.1.1.4.2 yamt {
36 1.1.1.1.4.2 yamt if (class_ != Nil && name != NULL && ! CLS_IS_IN_CONSTRUCTION (class_))
37 1.1.1.1.4.2 yamt {
38 1.1.1.1.4.2 yamt while (class_ != Nil)
39 1.1.1.1.4.2 yamt {
40 1.1.1.1.4.2 yamt struct objc_ivar_list *ivars = class_->ivars;
41 1.1.1.1.4.2 yamt if (ivars != NULL)
42 1.1.1.1.4.2 yamt {
43 1.1.1.1.4.2 yamt int i;
44 1.1.1.1.4.2 yamt
45 1.1.1.1.4.2 yamt for (i = 0; i < ivars->ivar_count; i++)
46 1.1.1.1.4.2 yamt {
47 1.1.1.1.4.2 yamt struct objc_ivar *ivar = &(ivars->ivar_list[i]);
48 1.1.1.1.4.2 yamt
49 1.1.1.1.4.2 yamt if (!strcmp (ivar->ivar_name, name))
50 1.1.1.1.4.2 yamt return ivar;
51 1.1.1.1.4.2 yamt }
52 1.1.1.1.4.2 yamt }
53 1.1.1.1.4.2 yamt class_ = class_getSuperclass (class_);
54 1.1.1.1.4.2 yamt }
55 1.1.1.1.4.2 yamt }
56 1.1.1.1.4.2 yamt return NULL;
57 1.1.1.1.4.2 yamt }
58 1.1.1.1.4.2 yamt
59 1.1.1.1.4.2 yamt struct objc_ivar *
60 1.1.1.1.4.2 yamt class_getClassVariable (Class class_, const char *name)
61 1.1.1.1.4.2 yamt {
62 1.1.1.1.4.2 yamt if (class_ == Nil)
63 1.1.1.1.4.2 yamt return NULL;
64 1.1.1.1.4.2 yamt
65 1.1.1.1.4.2 yamt /* Logically, since a class is an instance of its meta-class, and
66 1.1.1.1.4.2 yamt since its class methods are the instance methods of the
67 1.1.1.1.4.2 yamt meta-class, class variables should be instance variables of the
68 1.1.1.1.4.2 yamt meta-class. That is different from the normal use of having
69 1.1.1.1.4.2 yamt 'static' variables in the class implementation file, because
70 1.1.1.1.4.2 yamt every class would have its own variables.
71 1.1.1.1.4.2 yamt
72 1.1.1.1.4.2 yamt Anyway, it is all speculative at this stage, but if we get class
73 1.1.1.1.4.2 yamt variables in Objective-C, it is conceivable that this
74 1.1.1.1.4.2 yamt implementation should work. */
75 1.1.1.1.4.2 yamt return class_getInstanceVariable (class_->class_pointer, name);
76 1.1.1.1.4.2 yamt }
77 1.1.1.1.4.2 yamt
78 1.1.1.1.4.2 yamt void *
79 1.1.1.1.4.2 yamt object_getIndexedIvars (id object)
80 1.1.1.1.4.2 yamt {
81 1.1.1.1.4.2 yamt if (object == nil)
82 1.1.1.1.4.2 yamt return NULL;
83 1.1.1.1.4.2 yamt else
84 1.1.1.1.4.2 yamt return (void *)(((char *)object)
85 1.1.1.1.4.2 yamt + object->class_pointer->instance_size);
86 1.1.1.1.4.2 yamt }
87 1.1.1.1.4.2 yamt
88 1.1.1.1.4.2 yamt struct objc_ivar *
89 1.1.1.1.4.2 yamt object_getInstanceVariable (id object, const char *name, void **returnValue)
90 1.1.1.1.4.2 yamt {
91 1.1.1.1.4.2 yamt if (object == nil || name == NULL)
92 1.1.1.1.4.2 yamt return NULL;
93 1.1.1.1.4.2 yamt else
94 1.1.1.1.4.2 yamt {
95 1.1.1.1.4.2 yamt struct objc_ivar * variable = class_getInstanceVariable (object->class_pointer, name);
96 1.1.1.1.4.2 yamt
97 1.1.1.1.4.2 yamt if (variable != NULL && returnValue != NULL)
98 1.1.1.1.4.2 yamt {
99 1.1.1.1.4.2 yamt char *location = (char *)object + variable->ivar_offset;
100 1.1.1.1.4.2 yamt
101 1.1.1.1.4.2 yamt *returnValue = *((id *)location);
102 1.1.1.1.4.2 yamt }
103 1.1.1.1.4.2 yamt
104 1.1.1.1.4.2 yamt return variable;
105 1.1.1.1.4.2 yamt }
106 1.1.1.1.4.2 yamt }
107 1.1.1.1.4.2 yamt
108 1.1.1.1.4.2 yamt struct objc_ivar *
109 1.1.1.1.4.2 yamt object_setInstanceVariable (id object, const char *name, void *newValue)
110 1.1.1.1.4.2 yamt {
111 1.1.1.1.4.2 yamt if (object == nil || name == NULL)
112 1.1.1.1.4.2 yamt return NULL;
113 1.1.1.1.4.2 yamt else
114 1.1.1.1.4.2 yamt {
115 1.1.1.1.4.2 yamt struct objc_ivar * variable = class_getInstanceVariable (object->class_pointer, name);
116 1.1.1.1.4.2 yamt
117 1.1.1.1.4.2 yamt if (variable != NULL)
118 1.1.1.1.4.2 yamt {
119 1.1.1.1.4.2 yamt char *location = (char *)object + variable->ivar_offset;
120 1.1.1.1.4.2 yamt
121 1.1.1.1.4.2 yamt *((id *)location) = (id)newValue;
122 1.1.1.1.4.2 yamt }
123 1.1.1.1.4.2 yamt
124 1.1.1.1.4.2 yamt return variable;
125 1.1.1.1.4.2 yamt }
126 1.1.1.1.4.2 yamt }
127 1.1.1.1.4.2 yamt
128 1.1.1.1.4.2 yamt id object_getIvar (id object, struct objc_ivar * variable)
129 1.1.1.1.4.2 yamt {
130 1.1.1.1.4.2 yamt if (object == nil || variable == NULL)
131 1.1.1.1.4.2 yamt return nil;
132 1.1.1.1.4.2 yamt else
133 1.1.1.1.4.2 yamt {
134 1.1.1.1.4.2 yamt char *location = (char *)object + variable->ivar_offset;
135 1.1.1.1.4.2 yamt
136 1.1.1.1.4.2 yamt return *((id *)location);
137 1.1.1.1.4.2 yamt }
138 1.1.1.1.4.2 yamt }
139 1.1.1.1.4.2 yamt
140 1.1.1.1.4.2 yamt void object_setIvar (id object, struct objc_ivar * variable, id value)
141 1.1.1.1.4.2 yamt {
142 1.1.1.1.4.2 yamt if (object == nil || variable == NULL)
143 1.1.1.1.4.2 yamt return;
144 1.1.1.1.4.2 yamt else
145 1.1.1.1.4.2 yamt {
146 1.1.1.1.4.2 yamt char *location = (char *)object + variable->ivar_offset;
147 1.1.1.1.4.2 yamt
148 1.1.1.1.4.2 yamt *((id *)location) = value;
149 1.1.1.1.4.2 yamt }
150 1.1.1.1.4.2 yamt }
151 1.1.1.1.4.2 yamt
152 1.1.1.1.4.2 yamt const char * ivar_getName (struct objc_ivar * variable)
153 1.1.1.1.4.2 yamt {
154 1.1.1.1.4.2 yamt if (variable == NULL)
155 1.1.1.1.4.2 yamt return NULL;
156 1.1.1.1.4.2 yamt
157 1.1.1.1.4.2 yamt return variable->ivar_name;
158 1.1.1.1.4.2 yamt }
159 1.1.1.1.4.2 yamt
160 1.1.1.1.4.2 yamt ptrdiff_t ivar_getOffset (struct objc_ivar * variable)
161 1.1.1.1.4.2 yamt {
162 1.1.1.1.4.2 yamt if (variable == NULL)
163 1.1.1.1.4.2 yamt return 0;
164 1.1.1.1.4.2 yamt
165 1.1.1.1.4.2 yamt return (ptrdiff_t)(variable->ivar_offset);
166 1.1.1.1.4.2 yamt }
167 1.1.1.1.4.2 yamt
168 1.1.1.1.4.2 yamt const char * ivar_getTypeEncoding (struct objc_ivar * variable)
169 1.1.1.1.4.2 yamt {
170 1.1.1.1.4.2 yamt if (variable == NULL)
171 1.1.1.1.4.2 yamt return NULL;
172 1.1.1.1.4.2 yamt
173 1.1.1.1.4.2 yamt return variable->ivar_type;
174 1.1.1.1.4.2 yamt }
175 1.1.1.1.4.2 yamt
176 1.1.1.1.4.2 yamt struct objc_ivar ** class_copyIvarList (Class class_, unsigned int *numberOfReturnedIvars)
177 1.1.1.1.4.2 yamt {
178 1.1.1.1.4.2 yamt unsigned int count = 0;
179 1.1.1.1.4.2 yamt struct objc_ivar **returnValue = NULL;
180 1.1.1.1.4.2 yamt struct objc_ivar_list* ivar_list;
181 1.1.1.1.4.2 yamt
182 1.1.1.1.4.2 yamt if (class_ == Nil || CLS_IS_IN_CONSTRUCTION (class_))
183 1.1.1.1.4.2 yamt {
184 1.1.1.1.4.2 yamt if (numberOfReturnedIvars)
185 1.1.1.1.4.2 yamt *numberOfReturnedIvars = 0;
186 1.1.1.1.4.2 yamt return NULL;
187 1.1.1.1.4.2 yamt }
188 1.1.1.1.4.2 yamt
189 1.1.1.1.4.2 yamt /* Count how many ivars we have. */
190 1.1.1.1.4.2 yamt ivar_list = class_->ivars;
191 1.1.1.1.4.2 yamt count = ivar_list->ivar_count;
192 1.1.1.1.4.2 yamt
193 1.1.1.1.4.2 yamt if (count != 0)
194 1.1.1.1.4.2 yamt {
195 1.1.1.1.4.2 yamt unsigned int i = 0;
196 1.1.1.1.4.2 yamt
197 1.1.1.1.4.2 yamt /* Allocate enough memory to hold them. */
198 1.1.1.1.4.2 yamt returnValue = (struct objc_ivar **)(malloc (sizeof (struct objc_ivar *) * (count + 1)));
199 1.1.1.1.4.2 yamt
200 1.1.1.1.4.2 yamt /* Copy the ivars. */
201 1.1.1.1.4.2 yamt for (i = 0; i < count; i++)
202 1.1.1.1.4.2 yamt returnValue[i] = &(ivar_list->ivar_list[i]);
203 1.1.1.1.4.2 yamt
204 1.1.1.1.4.2 yamt returnValue[i] = NULL;
205 1.1.1.1.4.2 yamt }
206 1.1.1.1.4.2 yamt
207 1.1.1.1.4.2 yamt if (numberOfReturnedIvars)
208 1.1.1.1.4.2 yamt *numberOfReturnedIvars = count;
209 1.1.1.1.4.2 yamt
210 1.1.1.1.4.2 yamt return returnValue;
211 1.1.1.1.4.2 yamt }
212 1.1.1.1.4.2 yamt
213 1.1.1.1.4.2 yamt BOOL
214 1.1.1.1.4.2 yamt class_addIvar (Class class_, const char * ivar_name, size_t size,
215 1.1.1.1.4.2 yamt unsigned char log_2_of_alignment, const char *type)
216 1.1.1.1.4.2 yamt {
217 1.1.1.1.4.2 yamt struct objc_ivar_list *ivars;
218 1.1.1.1.4.2 yamt
219 1.1.1.1.4.2 yamt if (class_ == Nil
220 1.1.1.1.4.2 yamt || (! CLS_IS_IN_CONSTRUCTION (class_))
221 1.1.1.1.4.2 yamt || ivar_name == NULL
222 1.1.1.1.4.2 yamt || (strcmp (ivar_name, "") == 0)
223 1.1.1.1.4.2 yamt || size == 0
224 1.1.1.1.4.2 yamt || type == NULL)
225 1.1.1.1.4.2 yamt return NO;
226 1.1.1.1.4.2 yamt
227 1.1.1.1.4.2 yamt /* Check if the class has an instance variable with that name
228 1.1.1.1.4.2 yamt already. */
229 1.1.1.1.4.2 yamt ivars = class_->ivars;
230 1.1.1.1.4.2 yamt
231 1.1.1.1.4.2 yamt if (ivars != NULL)
232 1.1.1.1.4.2 yamt {
233 1.1.1.1.4.2 yamt int i;
234 1.1.1.1.4.2 yamt
235 1.1.1.1.4.2 yamt for (i = 0; i < ivars->ivar_count; i++)
236 1.1.1.1.4.2 yamt {
237 1.1.1.1.4.2 yamt struct objc_ivar *ivar = &(ivars->ivar_list[i]);
238 1.1.1.1.4.2 yamt
239 1.1.1.1.4.2 yamt if (strcmp (ivar->ivar_name, ivar_name) == 0)
240 1.1.1.1.4.2 yamt return NO;
241 1.1.1.1.4.2 yamt }
242 1.1.1.1.4.2 yamt }
243 1.1.1.1.4.2 yamt
244 1.1.1.1.4.2 yamt /* Ok, no direct ivars. Check superclasses. */
245 1.1.1.1.4.2 yamt if (class_getInstanceVariable (objc_getClass ((char *)(class_->super_class)),
246 1.1.1.1.4.2 yamt ivar_name))
247 1.1.1.1.4.2 yamt return NO;
248 1.1.1.1.4.2 yamt
249 1.1.1.1.4.2 yamt /* Good. Create space for the new instance variable. */
250 1.1.1.1.4.2 yamt if (ivars)
251 1.1.1.1.4.2 yamt {
252 1.1.1.1.4.2 yamt int ivar_count = ivars->ivar_count + 1;
253 1.1.1.1.4.2 yamt int new_size = sizeof (struct objc_ivar_list)
254 1.1.1.1.4.2 yamt + (ivar_count - 1) * sizeof (struct objc_ivar);
255 1.1.1.1.4.2 yamt
256 1.1.1.1.4.2 yamt ivars = (struct objc_ivar_list*) objc_realloc (ivars, new_size);
257 1.1.1.1.4.2 yamt ivars->ivar_count = ivar_count;
258 1.1.1.1.4.2 yamt class_->ivars = ivars;
259 1.1.1.1.4.2 yamt }
260 1.1.1.1.4.2 yamt else
261 1.1.1.1.4.2 yamt {
262 1.1.1.1.4.2 yamt int new_size = sizeof (struct objc_ivar_list);
263 1.1.1.1.4.2 yamt
264 1.1.1.1.4.2 yamt ivars = (struct objc_ivar_list*) objc_malloc (new_size);
265 1.1.1.1.4.2 yamt ivars->ivar_count = 1;
266 1.1.1.1.4.2 yamt class_->ivars = ivars;
267 1.1.1.1.4.2 yamt }
268 1.1.1.1.4.2 yamt
269 1.1.1.1.4.2 yamt /* Now ivars is set to a list of instance variables of the right
270 1.1.1.1.4.2 yamt size. */
271 1.1.1.1.4.2 yamt {
272 1.1.1.1.4.2 yamt struct objc_ivar *ivar = &(ivars->ivar_list[ivars->ivar_count - 1]);
273 1.1.1.1.4.2 yamt unsigned int alignment = 1 << log_2_of_alignment;
274 1.1.1.1.4.2 yamt int misalignment;
275 1.1.1.1.4.2 yamt
276 1.1.1.1.4.2 yamt ivar->ivar_name = objc_malloc (strlen (ivar_name) + 1);
277 1.1.1.1.4.2 yamt strcpy ((char *)ivar->ivar_name, ivar_name);
278 1.1.1.1.4.2 yamt
279 1.1.1.1.4.2 yamt ivar->ivar_type = objc_malloc (strlen (type) + 1);
280 1.1.1.1.4.2 yamt strcpy ((char *)ivar->ivar_type, type);
281 1.1.1.1.4.2 yamt
282 1.1.1.1.4.2 yamt /* The new instance variable is placed at the end of the existing
283 1.1.1.1.4.2 yamt instance_size, at the first byte that is aligned with
284 1.1.1.1.4.2 yamt alignment. */
285 1.1.1.1.4.2 yamt misalignment = class_->instance_size % alignment;
286 1.1.1.1.4.2 yamt
287 1.1.1.1.4.2 yamt if (misalignment == 0)
288 1.1.1.1.4.2 yamt ivar->ivar_offset = class_->instance_size;
289 1.1.1.1.4.2 yamt else
290 1.1.1.1.4.2 yamt ivar->ivar_offset = class_->instance_size - misalignment + alignment;
291 1.1.1.1.4.2 yamt
292 1.1.1.1.4.2 yamt class_->instance_size = ivar->ivar_offset + size;
293 1.1.1.1.4.2 yamt }
294 1.1.1.1.4.2 yamt
295 1.1.1.1.4.2 yamt return YES;
296 1.1.1.1.4.2 yamt }
297 1.1.1.1.4.2 yamt
298 1.1.1.1.4.2 yamt
299 1.1.1.1.4.2 yamt const char *
300 1.1.1.1.4.2 yamt property_getName (struct objc_property * property __attribute__ ((__unused__)))
301 1.1.1.1.4.2 yamt {
302 1.1.1.1.4.2 yamt if (property == NULL)
303 1.1.1.1.4.2 yamt return NULL;
304 1.1.1.1.4.2 yamt
305 1.1.1.1.4.2 yamt /* TODO: New ABI. */
306 1.1.1.1.4.2 yamt /* The current ABI does not have any information on properties. */
307 1.1.1.1.4.2 yamt return NULL;
308 1.1.1.1.4.2 yamt }
309 1.1.1.1.4.2 yamt
310 1.1.1.1.4.2 yamt const char *
311 1.1.1.1.4.2 yamt property_getAttributes (struct objc_property * property __attribute__ ((__unused__)))
312 1.1.1.1.4.2 yamt {
313 1.1.1.1.4.2 yamt if (property == NULL)
314 1.1.1.1.4.2 yamt return NULL;
315 1.1.1.1.4.2 yamt
316 1.1.1.1.4.2 yamt /* TODO: New ABI. */
317 1.1.1.1.4.2 yamt /* The current ABI does not have any information on properties. */
318 1.1.1.1.4.2 yamt return NULL;
319 1.1.1.1.4.2 yamt }
320 1.1.1.1.4.2 yamt
321 1.1.1.1.4.2 yamt struct objc_property *
322 1.1.1.1.4.2 yamt class_getProperty (Class class_ __attribute__ ((__unused__)),
323 1.1.1.1.4.2 yamt const char *propertyName __attribute__ ((__unused__)))
324 1.1.1.1.4.2 yamt {
325 1.1.1.1.4.2 yamt if (class_ == NULL || propertyName == NULL)
326 1.1.1.1.4.2 yamt return NULL;
327 1.1.1.1.4.2 yamt
328 1.1.1.1.4.2 yamt /* TODO: New ABI. */
329 1.1.1.1.4.2 yamt /* The current ABI does not have any information on class properties. */
330 1.1.1.1.4.2 yamt return NULL;
331 1.1.1.1.4.2 yamt }
332 1.1.1.1.4.2 yamt
333 1.1.1.1.4.2 yamt struct objc_property **
334 1.1.1.1.4.2 yamt class_copyPropertyList (Class class_ __attribute__ ((__unused__)),
335 1.1.1.1.4.2 yamt unsigned int *numberOfReturnedProperties __attribute__ ((__unused__)))
336 1.1.1.1.4.2 yamt {
337 1.1.1.1.4.2 yamt if (class_ == Nil)
338 1.1.1.1.4.2 yamt {
339 1.1.1.1.4.2 yamt if (numberOfReturnedProperties)
340 1.1.1.1.4.2 yamt *numberOfReturnedProperties = 0;
341 1.1.1.1.4.2 yamt return NULL;
342 1.1.1.1.4.2 yamt }
343 1.1.1.1.4.2 yamt
344 1.1.1.1.4.2 yamt /* TODO: New ABI. */
345 1.1.1.1.4.2 yamt /* The current ABI does not have any information on class properties. */
346 1.1.1.1.4.2 yamt if (numberOfReturnedProperties)
347 1.1.1.1.4.2 yamt *numberOfReturnedProperties = 0;
348 1.1.1.1.4.2 yamt
349 1.1.1.1.4.2 yamt return NULL;
350 1.1.1.1.4.2 yamt }
351 1.1.1.1.4.2 yamt
352 1.1.1.1.4.2 yamt const char *
353 1.1.1.1.4.2 yamt class_getIvarLayout (Class class_ __attribute__ ((__unused__)))
354 1.1.1.1.4.2 yamt {
355 1.1.1.1.4.2 yamt return NULL;
356 1.1.1.1.4.2 yamt }
357 1.1.1.1.4.2 yamt
358 1.1.1.1.4.2 yamt const char *
359 1.1.1.1.4.2 yamt class_getWeakIvarLayout (Class class_ __attribute__ ((__unused__)))
360 1.1.1.1.4.2 yamt {
361 1.1.1.1.4.2 yamt return NULL;
362 1.1.1.1.4.2 yamt }
363 1.1.1.1.4.2 yamt
364 1.1.1.1.4.2 yamt void
365 1.1.1.1.4.2 yamt class_setIvarLayout (Class class_ __attribute__ ((__unused__)),
366 1.1.1.1.4.2 yamt const char *layout __attribute__ ((__unused__)))
367 1.1.1.1.4.2 yamt {
368 1.1.1.1.4.2 yamt return;
369 1.1.1.1.4.2 yamt }
370 1.1.1.1.4.2 yamt
371 1.1.1.1.4.2 yamt void
372 1.1.1.1.4.2 yamt class_setWeakIvarLayout (Class class_ __attribute__ ((__unused__)),
373 1.1.1.1.4.2 yamt const char *layout __attribute__ ((__unused__)))
374 1.1.1.1.4.2 yamt {
375 1.1.1.1.4.2 yamt return;
376 1.1.1.1.4.2 yamt }
377