4 ** $Id: boopsistubs.h,v 1.2 2000/07/15 20:45:32 stegerg Exp $
6 ** Copyright (C) 1997,1999,2000 Bernardo Innocenti <bernie@cosmos.it>
7 ** All rights reserved.
9 ** Using these inline versions of the amiga.lib boopsi support functions
10 ** results in faster and smaller code against their linked library
11 ** counterparts. When debug is active, these functions will also
12 ** validate the parameters you pass in.
15 /* The USE_BOOPSI_STUBS symbol prevents redefinition of the following stubs with
16 * their amiga.lib equivalents. In AmigaOS, this trick works only if you are using
17 * a patched version of <clib/alib_protos.h>
19 #ifndef USE_BOOPSI_STUBS
20 #define USE_BOOPSI_STUBS
21 #endif /* USE_BOOPSI_STUBS */
24 #ifndef INTUITION_CLASSES_H
25 #include <intuition/classes.h>
26 #endif /* INTUITION_CLASSES_H */
31 #include <aros/debug.h>
32 #endif /* AROS_DEBUG_H */
34 #ifndef AROS_ASMCALL_H
35 #include <aros/asmcall.h>
36 #endif /* AROS_ASMCALL_H */
38 #define _CALL_DISPATCHER(entry, cl, o, msg) \
39 AROS_UFC3(IPTR, entry, \
40 AROS_UFCA(Class *, cl, A0), \
41 AROS_UFCA(Object *, o, A2), \
42 AROS_UFCA(APTR, msg, A1))
45 #define INLINE static inline
50 #ifndef COMPILERSPECIFIC_H
51 #include "CompilerSpecific.h"
52 #endif /* COMPILERSPECIFIC_H */
55 #include "DebugMacros.h"
56 #endif /* DEBUGMACROS_H */
58 /* the _HookPtr type is a shortcut for a pointer to a hook function */
59 typedef ASMCALL IPTR (*HookPtr)
60 (REG(a0, Class *), REG(a2, Object *), REG(a1, APTR));
62 #define _CALL_DISPATCHER(entry, cl, o, msg) \
63 ((HookPtr)(entry))(cl, o, msg)
69 /* SAS/C is clever enough to inline these even var-args functions, while gcc and egcs
70 * refuse to do it (yikes!). The GCC versions of these functions are macro blocks
71 * similar to those used in the inline/#?.h headers.
73 #if defined(__SASC) || defined (__STORM__)
75 INLINE ULONG CoerceMethodA(Class *cl, Object *o, Msg msg)
78 ASSERT_VALID_PTR_OR_NULL(o);
80 return _CALL_DISPATCHER(cl->cl_Dispatcher.h_Entry, cl, o, msg);
83 INLINE ULONG DoSuperMethodA(Class *cl, Object *o, Msg msg)
86 ASSERT_VALID_PTR_OR_NULL(o);
89 return _CALL_DISPATCHER(cl->cl_Dispatcher.h_Entry, cl, o, msg);
92 INLINE ULONG DoMethodA(Object *o, Msg msg)
99 return _CALL_DISPATCHER(cl->cl_Dispatcher.h_Entry, cl, o, msg);
102 INLINE ULONG CoerceMethod(Class *cl, Object *o, ULONG MethodID, ...)
104 ASSERT_VALID_PTR(cl);
105 ASSERT_VALID_PTR_OR_NULL(o);
107 return ((HookPtr)cl->cl_Dispatcher.h_Entry) ((APTR)cl, (APTR)o, (APTR)&MethodID);
110 INLINE ULONG DoSuperMethod(Class *cl, Object *o, ULONG MethodID, ...)
112 ASSERT_VALID_PTR(cl);
113 ASSERT_VALID_PTR_OR_NULL(o);
116 return ((HookPtr)cl->cl_Dispatcher.h_Entry) ((APTR)cl, (APTR)o, (APTR)&MethodID);
119 INLINE ULONG DoMethod(Object *o, ULONG MethodID, ...)
125 ASSERT_VALID_PTR(cl);
127 return ((HookPtr)cl->cl_Dispatcher.h_Entry) ((APTR)cl, (APTR)o, (APTR)&MethodID);
130 /* varargs stub for the OM_NOTIFY method */
131 INLINE void NotifyAttrs(Object *o, struct GadgetInfo *gi, ULONG flags, Tag attr1, ...)
134 ASSERT_VALID_PTR_OR_NULL(gi);
136 DoMethod(o, OM_NOTIFY, &attr1, gi, flags);
139 /* varargs stub for the OM_UPDATE method */
140 INLINE void UpdateAttrs(Object *o, struct GadgetInfo *gi, ULONG flags, Tag attr1, ...)
143 ASSERT_VALID_PTR_OR_NULL(gi);
145 DoMethod(o, OM_UPDATE, &attr1, gi, flags);
148 /* varargs stub for the OM_SET method. Similar to SetAttrs(), but allows
149 * to pass the GadgetInfo structure
151 INLINE void SetAttrsGI(Object *o, struct GadgetInfo *gi, ULONG flags, Tag attr1, ...)
154 ASSERT_VALID_PTR_OR_NULL(gi);
156 DoMethod(o, OM_SET, &attr1, gi, flags);
159 #elif defined(__GNUC__)
161 #define CoerceMethodA(cl, o, msg) \
163 ASSERT_VALID_PTR(cl); \
164 ASSERT_VALID_PTR_OR_NULL(o); \
165 _CALL_DISPATCHER(cl->cl_Dispatcher.h_Entry, cl, o, msg); \
168 #define DoSuperMethodA(cl, o, msg) \
171 ASSERT_VALID_PTR(cl); \
172 ASSERT_VALID_PTR_OR_NULL(o); \
173 _cl = cl->cl_Super; \
174 ASSERT_VALID_PTR(_cl); \
175 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, msg); \
178 #define DoMethodA(o, msg) \
181 ASSERT_VALID_PTR(o); \
183 ASSERT_VALID_PTR(_cl); \
184 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, msg); \
187 #define CoerceMethod(cl, o, msg...) \
189 IPTR _msg[] = { msg }; \
190 ASSERT_VALID_PTR(cl); \
191 ASSERT_VALID_PTR_OR_NULL(o); \
192 _CALL_DISPATCHER(cl->cl_Dispatcher.h_Entry, cl, o, _msg); \
195 #define DoSuperMethod(cl, o, msg...) \
198 IPTR _msg[] = { msg }; \
199 ASSERT_VALID_PTR(cl); \
200 ASSERT_VALID_PTR_OR_NULL(o); \
201 _cl = cl->cl_Super; \
202 ASSERT_VALID_PTR(_cl); \
203 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, _msg); \
206 #define DoMethod(o, msg...) \
209 IPTR _msg[] = { msg }; \
210 ASSERT_VALID_PTR(o); \
212 ASSERT_VALID_PTR_OR_NULL(_cl); \
213 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, _msg); \
216 /* Var-args stub for the OM_NOTIFY method */
217 #define NotifyAttrs(o, gi, flags, attrs...) \
220 IPTR _attrs[] = { attrs }; \
221 IPTR _msg[] = { OM_NOTIFY, (IPTR)_attrs, (IPTR)gi, flags }; \
222 ASSERT_VALID_PTR(o); \
224 ASSERT_VALID_PTR(_cl); \
225 ASSERT_VALID_PTR_OR_NULL(gi); \
226 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, _msg); \
229 /* Var-args stub for the OM_UPDATE method */
230 #define UpdateAttrs(o, gi, flags, attrs...) \
233 IPTR _attrs[] = { attrs }; \
234 IPTR _msg[] = { OM_UPDATE, (IPTR)_attrs, (IPTR)gi, flags }; \
235 ASSERT_VALID_PTR(o); \
237 ASSERT_VALID_PTR(_cl); \
238 ASSERT_VALID_PTR_OR_NULL(gi); \
239 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, _msg); \
243 #endif /* !BOOPSISTUBS_H */