ObjFW  Diff

Differences From Artifact [fd13e3d461]:

To Artifact [7eff738717]:

  • File src/OFObject.m — part of check-in [9713ad857d] at 2013-07-26 15:21:45 on branch trunk — Add support for objc_msg_lookup_stret.

    The assembly implementations of the lookup and forwarding still need to
    be adjusted. Those just alias to the non-stret version for now so that
    linking works, meaning the behaviour is still the same as without
    support for objc_msg_lookup_stret for now. (user: js, size: 25727) [annotate] [blame] [check-ins using]


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76


77
78
79
80
81
82
83
# import "atomic.h"
#elif defined(OF_HAVE_THREADS)
# import "threading.h"
#endif

#if defined(OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR)
extern id of_forward(id, SEL, ...);
# ifdef OF_APPLE_RUNTIME
/*
 * Forwarding for methods returning structs only works with the Apple ABI, as
 * with the GNU ABI, there is no way of knowing if a struct is returned and if
 * so how.
 * As forwardingTargetForSelector: only works for architectures for which
 * assembly has been written anyway, it makes sense to switch to
 * objc_msgSend(_{st,fp}ret) for those architectures to solve this problem.
 */
extern struct stret of_forward_stret(id, SEL, ...);
# endif


#endif

struct pre_ivar {
	int32_t retainCount;
	struct pre_mem *firstMem, *lastMem;
#if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS)
	of_spinlock_t retainCountSpinlock;







<
<
<
<
<
<
<
<
<

|
>
>







59
60
61
62
63
64
65









66
67
68
69
70
71
72
73
74
75
76
# import "atomic.h"
#elif defined(OF_HAVE_THREADS)
# import "threading.h"
#endif

#if defined(OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR)
extern id of_forward(id, SEL, ...);









extern struct stret of_forward_stret(id, SEL, ...);
#else
# define of_forward NULL
# define of_forward_stret NULL
#endif

struct pre_ivar {
	int32_t retainCount;
	struct pre_mem *firstMem, *lastMem;
#if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS)
	of_spinlock_t retainCountSpinlock;
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195














196
197
198
199
200
201
202
	 * never return.
	 */
	abort();
}

#ifdef OF_OBJFW_RUNTIME
static IMP
forward_handler(id obj, SEL sel)
{
	/* Try resolveClassMethod:/resolveInstanceMethod: */
	if (class_isMetaClass(object_getClass(obj))) {
		if ([obj respondsToSelector: @selector(resolveClassMethod:)] &&
		    [obj resolveClassMethod: sel]) {
			if (![obj respondsToSelector: sel]) {
				fprintf(stderr, "Runtime error: [%s "
				    "resolveClassMethod: %s] returned true "
				    "without adding the method!\n",
				    class_getName(obj), sel_getName(sel));
				abort();
			}

			return objc_msg_lookup(obj, sel);
		}
	} else {
		Class c = object_getClass(obj);

		if ([c respondsToSelector: @selector(resolveInstanceMethod:)] &&
		    [c resolveInstanceMethod: sel]) {
			if (![obj respondsToSelector: sel]) {
				fprintf(stderr, "Runtime error: [%s "
				    "resolveInstanceMethod: %s] returned true "
				    "without adding the method!\n",
				    class_getName(object_getClass(obj)),
				    sel_getName(sel));
				abort();
			}

			return objc_msg_lookup(obj, sel);
		}
	}

#ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
	if (class_respondsToSelector(object_getClass(obj),
	    @selector(forwardingTargetForSelector:))) {
		id target = [obj forwardingTargetForSelector: sel];

		if (target != nil && target != obj)
			return (IMP)of_forward;
	}
#endif

	of_method_not_found(obj, sel);
	return NULL;
}














#endif

#ifndef HAVE_OBJC_ENUMERATIONMUTATION
void
objc_enumerationMutation(id object)
{
	enumeration_mutation_handler(object);







|













|















|









|






>
>
>
>
>
>
>
>
>
>
>
>
>
>







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
	 * never return.
	 */
	abort();
}

#ifdef OF_OBJFW_RUNTIME
static IMP
common_forward_handler(id obj, SEL sel, IMP (*lookup)(id, SEL), IMP forward)
{
	/* Try resolveClassMethod:/resolveInstanceMethod: */
	if (class_isMetaClass(object_getClass(obj))) {
		if ([obj respondsToSelector: @selector(resolveClassMethod:)] &&
		    [obj resolveClassMethod: sel]) {
			if (![obj respondsToSelector: sel]) {
				fprintf(stderr, "Runtime error: [%s "
				    "resolveClassMethod: %s] returned true "
				    "without adding the method!\n",
				    class_getName(obj), sel_getName(sel));
				abort();
			}

			return lookup(obj, sel);
		}
	} else {
		Class c = object_getClass(obj);

		if ([c respondsToSelector: @selector(resolveInstanceMethod:)] &&
		    [c resolveInstanceMethod: sel]) {
			if (![obj respondsToSelector: sel]) {
				fprintf(stderr, "Runtime error: [%s "
				    "resolveInstanceMethod: %s] returned true "
				    "without adding the method!\n",
				    class_getName(object_getClass(obj)),
				    sel_getName(sel));
				abort();
			}

			return lookup(obj, sel);
		}
	}

#ifdef OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
	if (class_respondsToSelector(object_getClass(obj),
	    @selector(forwardingTargetForSelector:))) {
		id target = [obj forwardingTargetForSelector: sel];

		if (target != nil && target != obj)
			return forward;
	}
#endif

	of_method_not_found(obj, sel);
	return NULL;
}

static IMP
forward_handler(id obj, SEL sel)
{
	return common_forward_handler(obj, sel,
	    objc_msg_lookup, (IMP)of_forward);
}

static IMP
forward_handler_stret(id obj, SEL sel)
{
	return common_forward_handler(obj, sel,
	    objc_msg_lookup_stret, (IMP)of_forward_stret);
}
#endif

#ifndef HAVE_OBJC_ENUMERATIONMUTATION
void
objc_enumerationMutation(id object)
{
	enumeration_mutation_handler(object);
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
{
#if !defined(OF_APPLE_RUNTIME) || defined(__OBJC2__)
	objc_setUncaughtExceptionHandler(uncaught_exception_handler);
#endif

#if defined(OF_OBJFW_RUNTIME)
	objc_forward_handler = forward_handler;

#elif defined(OF_APPLE_RUNTIME) && !defined(__ppc64__)
	objc_setForwardHandler(of_forward, of_forward_stret);
#endif

#ifdef HAVE_OBJC_ENUMERATIONMUTATION
	objc_setEnumerationMutationHandler(enumeration_mutation_handler);
#endif








>
|







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
{
#if !defined(OF_APPLE_RUNTIME) || defined(__OBJC2__)
	objc_setUncaughtExceptionHandler(uncaught_exception_handler);
#endif

#if defined(OF_OBJFW_RUNTIME)
	objc_forward_handler = forward_handler;
	objc_forward_handler_stret = forward_handler_stret;
#elif defined(OF_APPLE_RUNTIME) && defined(HAVE_FORWARDING_TARGET_FOR_SELECTOR)
	objc_setForwardHandler(of_forward, of_forward_stret);
#endif

#ifdef HAVE_OBJC_ENUMERATIONMUTATION
	objc_setEnumerationMutationHandler(enumeration_mutation_handler);
#endif