1/*
2 * Copyright (c) 1999-2007 Apple Inc.  All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#ifndef _OBJC_MESSAGE_H
25#define _OBJC_MESSAGE_H
26
27#pragma GCC system_header
28
29#include <objc/objc.h>
30#include <objc/runtime.h>
31
32#pragma GCC system_header
33
34#ifndef OBJC_SUPER
35#define OBJC_SUPER
36
37/// Specifies the superclass of an instance.
38struct objc_super {
39    /// Specifies an instance of a class.
40    __unsafe_unretained id receiver;
41
42    /// Specifies the particular superclass of the instance to message.
43#if !defined(__cplusplus)  &&  !__OBJC2__
44    /* For compatibility with old objc-runtime.h header */
45    __unsafe_unretained Class class;
46#else
47    __unsafe_unretained Class super_class;
48#endif
49    /* super_class is the first class to search */
50};
51#endif
52
53
54/* Basic Messaging Primitives
55 *
56 * On some architectures, use objc_msgSend_stret for some struct return types.
57 * On some architectures, use objc_msgSend_fpret for some float return types.
58 * On some architectures, use objc_msgSend_fp2ret for some float return types.
59 *
60 * These functions must be cast to an appropriate function pointer type
61 * before being called.
62 */
63#if !OBJC_OLD_DISPATCH_PROTOTYPES
64OBJC_EXPORT void objc_msgSend(void /* id self, SEL op, ... */ )
65    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
66OBJC_EXPORT void objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )
67    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
68#else
69/**
70 * Sends a message with a simple return value to an instance of a class.
71 *
72 * @param self A pointer to the instance of the class that is to receive the message.
73 * @param op The selector of the method that handles the message.
74 * @param ...
75 *   A variable argument list containing the arguments to the method.
76 *
77 * @return The return value of the method.
78 *
79 * @note When it encounters a method call, the compiler generates a call to one of the
80 *  functions \c objc_msgSend, \c objc_msgSend_stret, \c objc_msgSendSuper, or \c objc_msgSendSuper_stret.
81 *  Messages sent to an object’s superclass (using the \c super keyword) are sent using \c objc_msgSendSuper;
82 *  other messages are sent using \c objc_msgSend. Methods that have data structures as return values
83 *  are sent using \c objc_msgSendSuper_stret and \c objc_msgSend_stret.
84 */
85OBJC_EXPORT id objc_msgSend(id self, SEL op, ...)
86    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
87/**
88 * Sends a message with a simple return value to the superclass of an instance of a class.
89 *
90 * @param super A pointer to an \c objc_super data structure. Pass values identifying the
91 *  context the message was sent to, including the instance of the class that is to receive the
92 *  message and the superclass at which to start searching for the method implementation.
93 * @param op A pointer of type SEL. Pass the selector of the method that will handle the message.
94 * @param ...
95 *   A variable argument list containing the arguments to the method.
96 *
97 * @return The return value of the method identified by \e op.
98 *
99 * @see objc_msgSend
100 */
101OBJC_EXPORT id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
102    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
103#endif
104
105
106/* Struct-returning Messaging Primitives
107 *
108 * Use these functions to call methods that return structs on the stack.
109 * On some architectures, some structures are returned in registers.
110 * Consult your local function call ABI documentation for details.
111 *
112 * These functions must be cast to an appropriate function pointer type
113 * before being called.
114 */
115#if !OBJC_OLD_DISPATCH_PROTOTYPES
116OBJC_EXPORT void objc_msgSend_stret(void /* id self, SEL op, ... */ )
117    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0)
118    OBJC_ARM64_UNAVAILABLE;
119OBJC_EXPORT void objc_msgSendSuper_stret(void /* struct objc_super *super, SEL op, ... */ )
120    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0)
121    OBJC_ARM64_UNAVAILABLE;
122#else
123/**
124 * Sends a message with a data-structure return value to an instance of a class.
125 *
126 * @see objc_msgSend
127 */
128OBJC_EXPORT void objc_msgSend_stret(id self, SEL op, ...)
129    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0)
130    OBJC_ARM64_UNAVAILABLE;
131
132/**
133 * Sends a message with a data-structure return value to the superclass of an instance of a class.
134 *
135 * @see objc_msgSendSuper
136 */
137OBJC_EXPORT void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...)
138    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0)
139    OBJC_ARM64_UNAVAILABLE;
140#endif
141
142
143/* Floating-point-returning Messaging Primitives
144 *
145 * Use these functions to call methods that return floating-point values
146 * on the stack.
147 * Consult your local function call ABI documentation for details.
148 *
149 * arm:    objc_msgSend_fpret not used
150 * i386:   objc_msgSend_fpret used for `float`, `double`, `long double`.
151 * x86-64: objc_msgSend_fpret used for `long double`.
152 *
153 * arm:    objc_msgSend_fp2ret not used
154 * i386:   objc_msgSend_fp2ret not used
155 * x86-64: objc_msgSend_fp2ret used for `_Complex long double`.
156 *
157 * These functions must be cast to an appropriate function pointer type
158 * before being called.
159 */
160#if !OBJC_OLD_DISPATCH_PROTOTYPES
161
162# if defined(__i386__)
163
164OBJC_EXPORT void objc_msgSend_fpret(void /* id self, SEL op, ... */ )
165    __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);
166
167# elif defined(__x86_64__)
168
169OBJC_EXPORT void objc_msgSend_fpret(void /* id self, SEL op, ... */ )
170    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
171OBJC_EXPORT void objc_msgSend_fp2ret(void /* id self, SEL op, ... */ )
172    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
173
174# endif
175
176// !OBJC_OLD_DISPATCH_PROTOTYPES
177#else
178// OBJC_OLD_DISPATCH_PROTOTYPES
179# if defined(__i386__)
180
181/**
182 * Sends a message with a floating-point return value to an instance of a class.
183 *
184 * @see objc_msgSend
185 * @note On the i386 platform, the ABI for functions returning a floating-point value is
186 *  incompatible with that for functions returning an integral type. On the i386 platform, therefore,
187 *  you must use \c objc_msgSend_fpret for functions returning non-integral type. For \c float or
188 *  \c long \c double return types, cast the function to an appropriate function pointer type first.
189 */
190OBJC_EXPORT double objc_msgSend_fpret(id self, SEL op, ...)
191    __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);
192
193/* Use objc_msgSendSuper() for fp-returning messages to super. */
194/* See also objc_msgSendv_fpret() below. */
195
196# elif defined(__x86_64__)
197/**
198 * Sends a message with a floating-point return value to an instance of a class.
199 *
200 * @see objc_msgSend
201 */
202OBJC_EXPORT long double objc_msgSend_fpret(id self, SEL op, ...)
203    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
204
205#  if __STDC_VERSION__ >= 199901L
206OBJC_EXPORT _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
207    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
208#  else
209OBJC_EXPORT void objc_msgSend_fp2ret(id self, SEL op, ...)
210    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
211#  endif
212
213/* Use objc_msgSendSuper() for fp-returning messages to super. */
214/* See also objc_msgSendv_fpret() below. */
215
216# endif
217
218// OBJC_OLD_DISPATCH_PROTOTYPES
219#endif
220
221
222/* Direct Method Invocation Primitives
223 * Use these functions to call the implementation of a given Method.
224 * This is faster than calling method_getImplementation() and method_getName().
225 *
226 * The receiver must not be nil.
227 *
228 * These functions must be cast to an appropriate function pointer type
229 * before being called.
230 */
231#if !OBJC_OLD_DISPATCH_PROTOTYPES
232OBJC_EXPORT void method_invoke(void /* id receiver, Method m, ... */ )
233    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
234OBJC_EXPORT void method_invoke_stret(void /* id receiver, Method m, ... */ )
235    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
236    OBJC_ARM64_UNAVAILABLE;
237#else
238OBJC_EXPORT id method_invoke(id receiver, Method m, ...)
239    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
240OBJC_EXPORT void method_invoke_stret(id receiver, Method m, ...)
241    __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0)
242    OBJC_ARM64_UNAVAILABLE;
243#endif
244
245
246/* Message Forwarding Primitives
247 * Use these functions to forward a message as if the receiver did not
248 * respond to it.
249 *
250 * The receiver must not be nil.
251 *
252 * class_getMethodImplementation() may return (IMP)_objc_msgForward.
253 * class_getMethodImplementation_stret() may return (IMP)_objc_msgForward_stret
254 *
255 * These functions must be cast to an appropriate function pointer type
256 * before being called.
257 *
258 * Before Mac OS X 10.6, _objc_msgForward must not be called directly
259 * but may be compared to other IMP values.
260 */
261#if !OBJC_OLD_DISPATCH_PROTOTYPES
262OBJC_EXPORT void _objc_msgForward(void /* id receiver, SEL sel, ... */ )
263    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
264OBJC_EXPORT void _objc_msgForward_stret(void /* id receiver, SEL sel, ... */ )
265    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
266    OBJC_ARM64_UNAVAILABLE;
267#else
268OBJC_EXPORT id _objc_msgForward(id receiver, SEL sel, ...)
269    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
270OBJC_EXPORT void _objc_msgForward_stret(id receiver, SEL sel, ...)
271    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
272    OBJC_ARM64_UNAVAILABLE;
273#endif
274
275
276/* Variable-argument Messaging Primitives
277 *
278 * Use these functions to call methods with a list of arguments, such
279 * as the one passed to forward:: .
280 *
281 * The contents of the argument list are architecture-specific.
282 * Consult your local function call ABI documentation for details.
283 *
284 * These functions must be cast to an appropriate function pointer type
285 * before being called, except for objc_msgSendv_stret() which must not
286 * be cast to a struct-returning type.
287 */
288
289typedef void* marg_list;
290
291OBJC_EXPORT id objc_msgSendv(id self, SEL op, size_t arg_size, marg_list arg_frame) OBJC2_UNAVAILABLE;
292OBJC_EXPORT void objc_msgSendv_stret(void *stretAddr, id self, SEL op, size_t arg_size, marg_list arg_frame) OBJC2_UNAVAILABLE;
293/* Note that objc_msgSendv_stret() does not return a structure type,
294 * and should not be cast to do so. This is unlike objc_msgSend_stret()
295 * and objc_msgSendSuper_stret().
296 */
297#if defined(__i386__)
298OBJC_EXPORT double objc_msgSendv_fpret(id self, SEL op, unsigned arg_size, marg_list arg_frame) OBJC2_UNAVAILABLE;
299#endif
300
301
302/* The following marg_list macros are of marginal utility. They
303 * are included for compatibility with the old objc-class.h header. */
304
305#if !__OBJC2__
306
307#define marg_prearg_size	0
308
309#define marg_malloc(margs, method) \
310	do { \
311		margs = (marg_list *)malloc (marg_prearg_size + ((7 + method_getSizeOfArguments(method)) & ~7)); \
312	} while (0)
313
314#define marg_free(margs) \
315	do { \
316		free(margs); \
317	} while (0)
318
319#define marg_adjustedOffset(method, offset) \
320	(marg_prearg_size + offset)
321
322#define marg_getRef(margs, offset, type) \
323	( (type *)((char *)margs + marg_adjustedOffset(method,offset) ) )
324
325#define marg_getValue(margs, offset, type) \
326	( *marg_getRef(margs, offset, type) )
327
328#define marg_setValue(margs, offset, type, value) \
329	( marg_getValue(margs, offset, type) = (value) )
330
331#endif
332
333#endif
334