#include "driver.h"
#if __BLOCKS__
int import_byref_real(int verbose) {
int x = rand();
int y = 15;
void (^myClosure)(void) = ^ (void) { | y | setGlobalInt(x+y); ++y;};
x++;
callVoidVoid(myClosure);
int globalValue = getGlobalInt();
int desiredValue = x + y - 2;
if (error_found("import byref", globalValue, desiredValue, verbose)) return 1;
#if FULL_CLOSURES
void (^myClosureCopy)(void) = Block_copy(myClosure);
callVoidVoid(myClosureCopy, NULL);
globalValue = getGlobalInt();
if (error_found("import byref copy", globalValue, desiredValue, verbose)) return 1;
Block_release(myClosureCopy);
#endif
return 0;
}
#endif __BLOCKS__
struct import_byref_shared_struct {
struct Block_byref base;
int y;
};
struct import_byref_struct {
struct Block_basic base;
const int x;
struct import_byref_shared_struct *shared_struct;
};
void print_byref_struct(struct import_byref_shared_struct *ibs) {
printf("byref structure @ %p:\n", ibs);
printf("forwarding: %p\nrefcount: %d\nsize: %d\n", ibs->base.forwarding, ibs->base.flags, ibs->base.size);
printf("y: %d\n\n", ibs->y);
}
void invoke_import_byref(struct import_byref_struct *aBlock) {
{
setGlobalInt(aBlock->x + aBlock->shared_struct->y);
++aBlock->shared_struct->y;
}
}
void copy_import_byref(struct import_byref_struct *dst, struct import_byref_struct *src) {
_Block_byref_assign_copy(&dst->shared_struct, src->shared_struct);
}
void destroy_import_byref(struct import_byref_struct *aBlock) {
Block_release_byref(aBlock->shared_struct);
}
int import_byref(int verbose) {
int x = rand();
struct import_byref_shared_struct shared_struct;
shared_struct.base.flags = 0; shared_struct.base.forwarding = &shared_struct;
shared_struct.base.size = sizeof(struct import_byref_shared_struct);
shared_struct.base.byref_destroy = NULL;
shared_struct.base.byref_keep = NULL;
shared_struct.y = 15;
struct import_byref_struct myClosure = {
{ 0, BLOCK_HAS_COPY_DISPOSE, sizeof(struct import_byref_struct),
(void (*)(void *))invoke_import_byref,
(void (*)(void *, void *))copy_import_byref,
(void (*)(void *))destroy_import_byref
},
x, &shared_struct };
x++;
callVoidVoid(&myClosure.base);
int globalValue = getGlobalInt();
int desiredValue = x + ((struct import_byref_shared_struct *)(shared_struct.base.forwarding))->y - 2;
if (error_found("import byref", globalValue, desiredValue, verbose)) return 1;
struct import_byref_struct *myClosureCopy = Block_copy(&myClosure);
callVoidVoid(&myClosureCopy->base);
globalValue = getGlobalInt();
++desiredValue; if (error_found("import byref copy", globalValue, desiredValue, verbose)) return 1;
Block_release(myClosureCopy);
Block_release_byref(shared_struct.base.forwarding);
return 0;
}