#ifndef __LIBOBJC_BLOCKS_PRIVATE_H_INCLUDED__
#define __LIBOBJC_BLOCKS_PRIVATE_H_INCLUDED__
#if defined(__clang__) && !defined(__OBJC_RUNTIME_INTERNAL__)
#pragma clang system_header
#endif


/*
 * This header file exposes some implementation details of the blocks runtime
 * that are needed, e.g., by libdispatch.
 */


/**
 * Block descriptor that contains copy and dispose operations.
 */
struct Block_descriptor
{
	/**
	 * Reserved for future use.  Currently always 0.
	 */
	unsigned long int reserved;
	/** Size of the block. */
	unsigned long int size;
	/**
	 * Copy function, generated by the compiler to help copy the block if it
	 * contains nontrivial copy operations.
	 */
	void (*copy_helper)(void *dst, void *src);
	/**
	 * Dispose function, generated by the compiler to help copy the block if it
	 * contains nontrivial destructors.
	 */
	void (*dispose_helper)(void *src);
	/**
	 * Objective-C type encoding of the block.
	 */
	const char *encoding;
};

// Helper structure
struct Block_layout
{
	/**
	 * Class pointer.  Always initialised to &_NSConcreteStackBlock for blocks
	 * that are created on the stack or &_NSConcreteGlobalBlock for blocks that
	 * are created in global storage.
	 */
	void *isa;
	/**
	 * Flags.  See the block_flags enumerated type for possible values.
	 */
	int flags;
	/**
	 * Reserved - always initialised to 0 by the compiler.  Used for the
	 * reference count in this implementation.
	 */
	int reserved;
	/**
	 * The function that implements the block.  The first argument is this
	 * structure, the subsequent arguments are the block's explicit parameters.
	 * If the BLOCK_USE_SRET flag is set, there is an additional hidden
	 * argument, which is a pointer to the space on the stack allocated to hold
	 * the return value.
	 */
	void (*invoke)(void *, ...);
	/**
	 * The block's descriptor.  This is either Block_descriptor_basic or
	 * Block_descriptor, depending on whether the
	 * BLOCK_HAS_COPY_DISPOSE flag is set.
	 */
	struct Block_descriptor *descriptor;
	/**
	 * Block variables are appended to this structure.
	 */
};



#ifndef __OBJC_RUNTIME_INTERNAL__
/*
 * Deprecated Block_basic datastructure needed by libdispatch
 */
struct Block_basic {
	void *isa;
	int Block_flags;
	int Block_size;
	void (*Block_invoke)(void *);
	void (*Block_copy)(void *dst, void *src);
	void (*Block_dispose)(void *);
};
#endif // __OBJC_RUNTIME_INTERNAL__
#endif  //__LIBOBJC_BLOCKS_PRIVATE_H_INCLUDED__

