7 ** Copyright (C) 1997,1999,2000 Bernardo Innocenti <bernie@cosmos.it>
8 ** All rights reserved.
10 ** Using these inline versions of the amiga.lib boopsi support functions
11 ** results in faster and smaller code against their linked library
12 ** counterparts. When debug is active, these functions will also
13 ** validate the parameters you pass in.
17 The USE_BOOPSI_STUBS symbol prevents redefinition of the following stubs
18 with their amiga.lib equivalents. In AmigaOS, this trick works only if you
19 are using patched version of <clib/alib_protos.h>
22 #ifndef USE_BOOPSI_STUBS
23 #define USE_BOOPSI_STUBS
24 #endif /* USE_BOOPSI_STUBS */
27 #ifndef INTUITION_CLASSES_H
28 #include <intuition/classes.h>
29 #endif /* INTUITION_CLASSES_H */
34 #include <aros/debug.h>
35 #endif /* AROS_DEBUG_H */
37 #ifndef AROS_ASMCALL_H
38 #include <aros/asmcall.h>
39 #endif /* AROS_ASMCALL_H */
41 #define _CALL_DISPATCHER(entry, cl, o, msg) \
42 AROS_UFC3(IPTR, entry, \
43 AROS_UFCA(Class *, cl, A0), \
44 AROS_UFCA(Object *, o, A2), \
45 AROS_UFCA(APTR, msg, A1))
48 #define INLINE static inline
53 #ifndef COMPILERSPECIFIC_H
54 #include "CompilerSpecific.h"
55 #endif /* COMPILERSPECIFIC_H */
58 #include "DebugMacros.h"
59 #endif /* DEBUGMACROS_H */
61 /* the _HookPtr type is a shortcut for a pointer to a hook function */
62 typedef ASMCALL
IPTR (*HookPtr
)
63 (REG(a0
, Class
*), REG(a2
, Object
*), REG(a1
, APTR
));
65 #define _CALL_DISPATCHER(entry, cl, o, msg) \
66 ((HookPtr)(entry))(cl, o, msg)
72 /* SAS/C is clever enough to inline these even var-args functions, while gcc and egcs
73 * refuse to do it (yikes!). The GCC versions of these functions are macro blocks
74 * similar to those used in the inline/#?.h headers.
76 #if defined(__SASC) || defined (__STORM__)
78 INLINE ULONG
CoerceMethodA(Class
*cl
, Object
*o
, Msg msg
)
81 ASSERT_VALID_PTR_OR_NULL(o
);
83 return _CALL_DISPATCHER(cl
->cl_Dispatcher
.h_Entry
, cl
, o
, msg
);
86 INLINE ULONG
DoSuperMethodA(Class
*cl
, Object
*o
, Msg msg
)
89 ASSERT_VALID_PTR_OR_NULL(o
);
92 return _CALL_DISPATCHER(cl
->cl_Dispatcher
.h_Entry
, cl
, o
, msg
);
95 INLINE ULONG
DoMethodA(Object
*o
, Msg msg
)
100 ASSERT_VALID_PTR(cl
);
102 return _CALL_DISPATCHER(cl
->cl_Dispatcher
.h_Entry
, cl
, o
, msg
);
105 INLINE ULONG
CoerceMethod(Class
*cl
, Object
*o
, ULONG MethodID
, ...)
107 ASSERT_VALID_PTR(cl
);
108 ASSERT_VALID_PTR_OR_NULL(o
);
110 return ((HookPtr
)cl
->cl_Dispatcher
.h_Entry
) ((APTR
)cl
, (APTR
)o
, (APTR
)&MethodID
);
113 INLINE ULONG
DoSuperMethod(Class
*cl
, Object
*o
, ULONG MethodID
, ...)
115 ASSERT_VALID_PTR(cl
);
116 ASSERT_VALID_PTR_OR_NULL(o
);
119 return ((HookPtr
)cl
->cl_Dispatcher
.h_Entry
) ((APTR
)cl
, (APTR
)o
, (APTR
)&MethodID
);
122 INLINE ULONG
DoMethod(Object
*o
, ULONG MethodID
, ...)
128 ASSERT_VALID_PTR(cl
);
130 return ((HookPtr
)cl
->cl_Dispatcher
.h_Entry
) ((APTR
)cl
, (APTR
)o
, (APTR
)&MethodID
);
133 /* varargs stub for the OM_NOTIFY method */
134 INLINE
void NotifyAttrs(Object
*o
, struct GadgetInfo
*gi
, ULONG flags
, Tag attr1
, ...)
137 ASSERT_VALID_PTR_OR_NULL(gi
);
139 DoMethod(o
, OM_NOTIFY
, &attr1
, gi
, flags
);
142 /* varargs stub for the OM_UPDATE method */
143 INLINE
void UpdateAttrs(Object
*o
, struct GadgetInfo
*gi
, ULONG flags
, Tag attr1
, ...)
146 ASSERT_VALID_PTR_OR_NULL(gi
);
148 DoMethod(o
, OM_UPDATE
, &attr1
, gi
, flags
);
151 /* varargs stub for the OM_SET method. Similar to SetAttrs(), but allows
152 * to pass the GadgetInfo structure
154 INLINE
void SetAttrsGI(Object
*o
, struct GadgetInfo
*gi
, ULONG flags
, Tag attr1
, ...)
157 ASSERT_VALID_PTR_OR_NULL(gi
);
159 DoMethod(o
, OM_SET
, &attr1
, gi
, flags
);
162 #elif defined(__GNUC__)
163 #ifndef CoerceMethodA
164 #define CoerceMethodA(cl, o, msg) \
166 ASSERT_VALID_PTR(cl); \
167 ASSERT_VALID_PTR_OR_NULL(o); \
168 _CALL_DISPATCHER(cl->cl_Dispatcher.h_Entry, cl, o, msg); \
172 #ifndef DoSuperMethodA
173 #define DoSuperMethodA(cl, o, msg) \
176 ASSERT_VALID_PTR(cl); \
177 ASSERT_VALID_PTR_OR_NULL(o); \
178 _cl = cl->cl_Super; \
179 ASSERT_VALID_PTR(_cl); \
180 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, msg); \
185 #define DoMethodA(o, msg) \
188 ASSERT_VALID_PTR(o); \
190 ASSERT_VALID_PTR(_cl); \
191 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, msg); \
196 #define CoerceMethod(cl, o, msg...) \
198 IPTR _msg[] = { msg }; \
199 ASSERT_VALID_PTR(cl); \
200 ASSERT_VALID_PTR_OR_NULL(o); \
201 _CALL_DISPATCHER(cl->cl_Dispatcher.h_Entry, cl, o, _msg); \
205 #ifndef DoSuperMethod
206 #define DoSuperMethod(cl, o, msg...) \
209 IPTR _msg[] = { msg }; \
210 ASSERT_VALID_PTR(cl); \
211 ASSERT_VALID_PTR_OR_NULL(o); \
212 _cl = cl->cl_Super; \
213 ASSERT_VALID_PTR(_cl); \
214 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, _msg); \
219 #define DoMethod(o, msg...) \
222 IPTR _msg[] = { msg }; \
223 ASSERT_VALID_PTR(o); \
225 ASSERT_VALID_PTR_OR_NULL(_cl); \
226 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, _msg); \
231 /* Var-args stub for the OM_NOTIFY method */
232 #define NotifyAttrs(o, gi, flags, attrs...) \
235 IPTR _attrs[] = { attrs }; \
236 IPTR _msg[] = { OM_NOTIFY, (IPTR)_attrs, (IPTR)gi, flags }; \
237 ASSERT_VALID_PTR(o); \
239 ASSERT_VALID_PTR(_cl); \
240 ASSERT_VALID_PTR_OR_NULL(gi); \
241 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, _msg); \
246 /* Var-args stub for the OM_UPDATE method */
247 #define UpdateAttrs(o, gi, flags, attrs...) \
250 IPTR _attrs[] = { attrs }; \
251 IPTR _msg[] = { OM_UPDATE, (IPTR)_attrs, (IPTR)gi, flags }; \
252 ASSERT_VALID_PTR(o); \
254 ASSERT_VALID_PTR(_cl); \
255 ASSERT_VALID_PTR_OR_NULL(gi); \
256 _CALL_DISPATCHER(_cl->cl_Dispatcher.h_Entry, _cl, o, _msg); \
261 #endif /* !BOOPSISTUBS_H */