146cdc140SDavid Chisnall /*- 246cdc140SDavid Chisnall * Copyright (c) 2014 David T Chisnall 346cdc140SDavid Chisnall * All rights reserved. 446cdc140SDavid Chisnall * 546cdc140SDavid Chisnall * Redistribution and use in source and binary forms, with or without 646cdc140SDavid Chisnall * modification, are permitted provided that the following conditions 746cdc140SDavid Chisnall * are met: 846cdc140SDavid Chisnall * 1. Redistributions of source code must retain the above copyright 946cdc140SDavid Chisnall * notice, this list of conditions and the following disclaimer. 1046cdc140SDavid Chisnall * 2. Redistributions in binary form must reproduce the above copyright 1146cdc140SDavid Chisnall * notice, this list of conditions and the following disclaimer in the 1246cdc140SDavid Chisnall * documentation and/or other materials provided with the distribution. 1346cdc140SDavid Chisnall * 1446cdc140SDavid Chisnall * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1546cdc140SDavid Chisnall * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1646cdc140SDavid Chisnall * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1746cdc140SDavid Chisnall * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1846cdc140SDavid Chisnall * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1946cdc140SDavid Chisnall * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2046cdc140SDavid Chisnall * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2146cdc140SDavid Chisnall * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2246cdc140SDavid Chisnall * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2346cdc140SDavid Chisnall * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2446cdc140SDavid Chisnall * SUCH DAMAGE. 2546cdc140SDavid Chisnall */ 2646cdc140SDavid Chisnall 2746cdc140SDavid Chisnall #ifdef __BLOCKS__ 2846cdc140SDavid Chisnall /** 2946cdc140SDavid Chisnall * Declares a block variable. This macro is defined in the trivial way for 3046cdc140SDavid Chisnall * compilers that support blocks and exposing the ABI in the source for other 3146cdc140SDavid Chisnall * compilers. 3246cdc140SDavid Chisnall */ 3346cdc140SDavid Chisnall #define DECLARE_BLOCK(retTy, name, argTys, ...)\ 3446cdc140SDavid Chisnall retTy(^name)(argTys, ## __VA_ARGS__) 3546cdc140SDavid Chisnall /** 3646cdc140SDavid Chisnall * Calls a block variable. This macro is defined in the trivial way for 3746cdc140SDavid Chisnall * compilers that support blocks and exposing the ABI in the source for other 3846cdc140SDavid Chisnall * compilers. 3946cdc140SDavid Chisnall */ 40*680f1a39SJessica Clarke #define CALL_BLOCK(name, ...) (name)(__VA_ARGS__) 4146cdc140SDavid Chisnall #else // !__BLOCKS__ 4246cdc140SDavid Chisnall #define DECLARE_BLOCK(retTy, name, argTys, ...)\ 4346cdc140SDavid Chisnall struct {\ 4446cdc140SDavid Chisnall void *isa;\ 4546cdc140SDavid Chisnall int flags;\ 4646cdc140SDavid Chisnall int reserved;\ 4746cdc140SDavid Chisnall retTy (*invoke)(void *, ...);\ 4846cdc140SDavid Chisnall } *name 4946cdc140SDavid Chisnall #define CALL_BLOCK(name, ...) (name)->invoke(name, __VA_ARGS__) 5046cdc140SDavid Chisnall #endif // __BLOCKS__ 5146cdc140SDavid Chisnall /** 5246cdc140SDavid Chisnall * Returns the pointer to the block-invoke function. This is used for passing 5346cdc140SDavid Chisnall * blocks to functions that want a function pointer and a data pointer. 5446cdc140SDavid Chisnall */ 5546cdc140SDavid Chisnall #define GET_BLOCK_FUNCTION(x) \ 5646cdc140SDavid Chisnall (((struct {\ 5746cdc140SDavid Chisnall void *isa;\ 5846cdc140SDavid Chisnall int flags;\ 5946cdc140SDavid Chisnall int reserved;\ 6046cdc140SDavid Chisnall void (*invoke)(void *, ...);\ 6102da4cb4SDavid Chisnall }*)(void*)x)->invoke) 62