|
|
|
|
@ -38,10 +38,11 @@
|
|
|
|
|
|
|
|
|
|
// Descriptor attributes
|
|
|
|
|
enum {
|
|
|
|
|
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
|
|
|
|
|
BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code
|
|
|
|
|
BLOCK_IS_GLOBAL = (1 << 28),
|
|
|
|
|
BLOCK_HAS_DESCRIPTOR = (1 << 29), // interim until complete world build is accomplished
|
|
|
|
|
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
|
|
|
|
|
BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code
|
|
|
|
|
BLOCK_IS_GLOBAL = (1 << 28),
|
|
|
|
|
BLOCK_HAS_DESCRIPTOR = (1 << 29), // interim until complete world build is accomplished
|
|
|
|
|
BLOCK_HAS_SIGNATURE = (1 << 30)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// _Block_object_assign() and _Block_object_dispose() flag helpers.
|
|
|
|
|
@ -55,20 +56,50 @@ enum {
|
|
|
|
|
BLOCK_BYREF_CALLER = 128, // called from byref copy/dispose helpers
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Block descriptor that contains copy and dispose operations.
|
|
|
|
|
*/
|
|
|
|
|
struct block_descriptor_copydispose
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
/**
|
|
|
|
|
* Block descriptor that does not contain copy and dispose helper functions.
|
|
|
|
|
*/
|
|
|
|
|
struct block_descriptor
|
|
|
|
|
{
|
|
|
|
|
unsigned long int reserved;
|
|
|
|
|
/** Size of the block. */
|
|
|
|
|
unsigned long int size;
|
|
|
|
|
/**
|
|
|
|
|
* Objective-C type encoding of the block.
|
|
|
|
|
*/
|
|
|
|
|
const char *encoding;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Helper structure
|
|
|
|
|
struct psy_block_literal {
|
|
|
|
|
void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
|
|
|
|
|
int flags;
|
|
|
|
|
int reserved;
|
|
|
|
|
void (*invoke)(void *, ...);
|
|
|
|
|
struct {
|
|
|
|
|
unsigned long int reserved; // NULL
|
|
|
|
|
unsigned long int size; // sizeof(struct Block_literal_1)
|
|
|
|
|
// optional helper functions
|
|
|
|
|
void (*copy_helper)(void *dst, void *src);
|
|
|
|
|
void (*dispose_helper)(void *src);
|
|
|
|
|
} *descriptor;
|
|
|
|
|
const char *types;
|
|
|
|
|
struct block_descriptor_copydispose *descriptor;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Helper structure
|
|
|
|
|
@ -81,6 +112,21 @@ struct psy_block_byref_obj {
|
|
|
|
|
void (*byref_dispose)(struct psy_block_byref_obj *);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const char *block_getType_np(void *b)
|
|
|
|
|
{
|
|
|
|
|
struct psy_block_literal *block = b;
|
|
|
|
|
if ((NULL == block) || !(block->flags & BLOCK_HAS_SIGNATURE))
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if (!(block->flags & BLOCK_HAS_COPY_DISPOSE))
|
|
|
|
|
{
|
|
|
|
|
return ((struct block_descriptor*)block->descriptor)->encoding;
|
|
|
|
|
}
|
|
|
|
|
return block->descriptor->encoding;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Certain field types require runtime assistance when being copied to the
|
|
|
|
|
* heap. The following function is used to copy fields of types: blocks,
|
|
|
|
|
* pointers to byref structures, and objects (including
|
|
|
|
|
@ -240,9 +286,3 @@ void _Block_release(void *src)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *_Block_get_types(void *blk)
|
|
|
|
|
{
|
|
|
|
|
struct psy_block_literal *block = blk;
|
|
|
|
|
return block->types;
|
|
|
|
|
}
|
|
|
|
|
|