/* APPLE LOCAL file radar 5932809 */
/* Test the __byreg runtime features. */
/* { dg-options "-mmacosx-version-min=10.5 -ObjC -framework Foundation" { target i?86-*-darwin*  } } */
/* { dg-do run { target i?86-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */

#import <Foundation/Foundation.h>

void * _NSConcreteStackBlock;

int CalledRetain = 0;

id objc_msgSend(id target, SEL cmd) {
    printf("[%p %s] called\n", target, sel_getName(cmd));
    if (!strcmp(sel_getName(cmd), "retain")) {
        CalledRetain = 1;
    }
    return target;
}

@interface DumbObject {
@public
    id isa;
}
@end
id newDumbObject() {
    DumbObject *result = (DumbObject *)calloc(sizeof(DumbObject), 1);
    result->isa = objc_getClass("DumbObject");
    return result;
}

@implementation DumbObject
+ new {
    return newDumbObject();
}
+ (void) initialize { }
- forward:(SEL)msg :(long *)params {
    printf("forward:: with %s called\n", sel_getName(msg));
    return self;
}
@end

//#include <Block_private.h>

enum {
    BLOCK_NEEDS_FREE =        (1 << 24),
    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
    BLOCK_NO_COPY =           (1 << 26), // interim byref: no copies allowed
    BLOCK_IS_GC =             (1 << 27),
};

/* APPLE LOCAL begin radar 5847213 - radar 6329245 */
struct Block_basic {
    void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
    int Block_flags;
    int reserved;
    void (*Block_invoke)(void *);

    struct Block_descriptor_1 {
        unsigned long int reserved;     // NULL
        unsigned long int Block_size;  // sizeof(struct Block_literal_1)

        // optional helper functions
        void (*Block_copy)(void *dst, void *src);
        void (*Block_dispose)(void *src);
    } *descriptor;

    // imported variables
};
/* APPLE LOCAL end radar 5847213 - radar 6329245 */

struct Block_byref {
    void* isa;
    struct Block_byref *forwarding;
    int flags;//refcount;
    int size;
    void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
    void (*byref_destroy)(struct Block_byref *);
    // long shared[0];
};


int ByrefAssignCopy = 0;

void _Block_byref_assign_copy(void *destp, void *source) {
    struct Block_byref *src = (struct Block_byref *)source;
    ByrefAssignCopy = 1;
    // lets look at the Block_byref
    if ((src->flags & BLOCK_HAS_COPY_DISPOSE) == 0) {
        printf("byref data block does not have bit saying that copy/dispose helper routines are present\n");
        return;
    }
    printf("calling out to byref copy helper at %p\n", src->byref_keep);
    int junk[100];
    src->byref_keep((struct Block_byref *)junk, src);
}

void _Block_byref_release(void *source) {
    struct Block_byref *src = source;
    src->byref_destroy(src);
}

int main(int argc, char *argv[]) {
    id __block dumbo = newDumbObject(); //[DumbObject new];
    void (^dummy)(void) = ^{ 
        [dumbo self];
    };

    struct Block_basic *aBlock = (struct Block_basic *)(void *)dummy;
    if ((aBlock->Block_flags & BLOCK_HAS_COPY_DISPOSE) == 0) {
        printf("Block should have a NON_POD copy/destroy helpers and flags to say so, but doesn't\n");
        return 1;
    }

    char result[200];
    printf("calling out to copy support helper at %p\n", aBlock->descriptor->Block_copy);
    (*aBlock->descriptor->Block_copy)(result, aBlock); // do fixup

    // The copy/destroy helper should have had a callout  to _Block_byref_assign_copy for its byref block
    if (! ByrefAssignCopy) {
        printf("_Block_copy_assign not called\n");
        return 1;
    }

    // the copy/destroy helper of the byref should have done dst->object = [src->object retain]
    if (! CalledRetain) {
        printf("byref block support helper did not call retain\n");
        return 1;
    }

    (*aBlock->descriptor->Block_dispose)(aBlock);

    return 0;
}
