1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 
6 // CONFIG
7 
8 
9 #include <stdio.h>
10 #include <stdbool.h>
11 #include <stdlib.h>
12 #include <Block.h>
13 
14 int
main(int argc,char * argv[])15 main(int argc, char *argv[])
16 {
17     __block int var = 0;
18     void (^b)(void) = ^{ var++; };
19 
20     //sanity(b);
21     b();
22     printf("%s: success!\n", argv[0]);
23     return 0;
24 }
25 
26 
27 #if 1
28 /* replicated internal data structures: BEWARE, MAY CHANGE!!! */
29 
30 enum {
31     BLOCK_REFCOUNT_MASK =     (0xffff),
32     BLOCK_NEEDS_FREE =        (1 << 24),
33     BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
34     BLOCK_NO_COPY =           (1 << 26), // interim byref: no copies allowed
35     BLOCK_IS_GC =             (1 << 27),
36     BLOCK_IS_GLOBAL =         (1 << 28),
37 };
38 
39 struct byref_id {
40     struct byref_id *forwarding;
41     int flags;//refcount;
42     int size;
43     void (*byref_keep)(struct byref_id *dst, struct byref_id *src);
44     void (*byref_destroy)(struct byref_id *);
45     int var;
46 };
47 struct Block_basic2 {
48     void *isa;
49     int Block_flags;  // int32_t
50     int Block_size; // XXX should be packed into Block_flags
51     void (*Block_invoke)(void *);
52     void (*Block_copy)(void *dst, void *src);
53     void (*Block_dispose)(void *);
54     struct byref_id *ref;
55 };
56 
sanity(void * arg)57 void sanity(void *arg) {
58     struct Block_basic2 *bb = (struct Block_basic2 *)arg;
59     if ( ! (bb->Block_flags & BLOCK_HAS_COPY_DISPOSE)) {
60         printf("missing copy/dispose helpers for byref data\n");
61         exit(1);
62     }
63     struct byref_id *ref = bb->ref;
64     if (ref->forwarding != ref) {
65         printf("forwarding pointer should be %p but is %p\n", ref, ref->forwarding);
66         exit(1);
67     }
68 }
69 #endif
70 
71 
72 
73