186d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst//
286d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst//                     The LLVM Compiler Infrastructure
386d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst//
486d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst// This file is distributed under the University of Illinois Open Source
586d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst// License. See LICENSE.TXT for details.
686d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
786d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst// CONFIG
886d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
986d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
1086d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst#include <stdio.h>
1186d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst#include <stdbool.h>
1286d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst#include <stdlib.h>
1386d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst#include <Block.h>
1486d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
1586d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garstint
1686d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garstmain(int argc, char *argv[])
1786d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst{
1886d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    __block int var = 0;
1986d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    void (^b)(void) = ^{ var++; };
2086d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
2186d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    //sanity(b);
2286d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    b();
2386d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    printf("%s: success!\n", argv[0]);
2486d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    return 0;
2586d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst}
2686d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
2786d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
2886d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst#if 1
2986d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst/* replicated internal data structures: BEWARE, MAY CHANGE!!! */
3086d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
3186d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garstenum {
3286d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    BLOCK_REFCOUNT_MASK =     (0xffff),
3386d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    BLOCK_NEEDS_FREE =        (1 << 24),
3486d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
3586d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    BLOCK_NO_COPY =           (1 << 26), // interim byref: no copies allowed
3686d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    BLOCK_IS_GC =             (1 << 27),
3786d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    BLOCK_IS_GLOBAL =         (1 << 28),
3886d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst};
3986d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
4086d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garststruct byref_id {
4186d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    struct byref_id *forwarding;
4286d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    int flags;//refcount;
4386d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    int size;
4486d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    void (*byref_keep)(struct byref_id *dst, struct byref_id *src);
4586d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    void (*byref_destroy)(struct byref_id *);
4686d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    int var;
4786d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst};
4886d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garststruct Block_basic2 {
4986d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    void *isa;
5086d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    int Block_flags;  // int32_t
5186d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    int Block_size; // XXX should be packed into Block_flags
5286d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    void (*Block_invoke)(void *);
5386d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    void (*Block_copy)(void *dst, void *src);
5486d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    void (*Block_dispose)(void *);
5586d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    struct byref_id *ref;
5686d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst};
5786d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
5886d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garstvoid sanity(void *arg) {
5986d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    struct Block_basic2 *bb = (struct Block_basic2 *)arg;
6086d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    if ( ! (bb->Block_flags & BLOCK_HAS_COPY_DISPOSE)) {
6186d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst        printf("missing copy/dispose helpers for byref data\n");
6286d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst        exit(1);
6386d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    }
6486d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    struct byref_id *ref = bb->ref;
6586d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    if (ref->forwarding != ref) {
6686d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst        printf("forwarding pointer should be %p but is %p\n", ref, ref->forwarding);
6786d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst        exit(1);
6886d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst    }
6986d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst}
7086d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst#endif
7186d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
7286d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
7386d0ba4286ec42dcd055bd22434c7f40009834bdBlaine Garst
74