轉自唐巧的博客
前言
- struct Block_descriptor {
- unsigned long int reserved;
- unsigned long int size;
- void (*copy)(void *dst, void *src);
- void (*dispose)(void *);
- };
- struct Block_layout {
- void *isa;
- int flags;
- int reserved;
- void (*invoke)(void *, ...);
- struct Block_descriptor *descriptor;
- /* Imported variables. */
- };
- struct SampleA {
- int a;
- int b;
- int c;
- };
- struct SampleB {
- int a;
- struct Part1 {
- int b;
- };
- struct Part2 {
- int c;
- };
- };
- clang -rewrite-objc block.c
- #include <stdio.h>
- int main()
- {
- ^{ printf("Hello, World!\n"); } ();
- return 0;
- }
- struct __block_impl {
- void *isa;
- int Flags;
- int Reserved;
- void *FuncPtr;
- };
- struct __main_block_impl_0 {
- struct __block_impl impl;
- struct __main_block_desc_0* Desc;
- __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
- impl.isa = &_NSConcreteStackBlock;
- impl.Flags = flags;
- impl.FuncPtr = fp;
- Desc = desc;
- }
- };
- static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
- printf("Hello, World!\n");
- }
- static struct __main_block_desc_0 {
- size_t reserved;
- size_t Block_size;
- } __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0) };
- int main()
- {
- (void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA) ();
- return 0;
- }
- #include <stdio.h>
- int main() {
- int a = 100;
- void (^block2)(void) = ^{
- printf("%d\n", a);
- };
- block2();
- return 0;
- }
- struct __main_block_impl_0 {
- struct __block_impl impl;
- struct __main_block_desc_0* Desc;
- int a;
- __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _a, int flags=0) : a(_a) {
- impl.isa = &_NSConcreteStackBlock;
- impl.Flags = flags;
- impl.FuncPtr = fp;
- Desc = desc;
- }
- };
- static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
- int a = __cself->a; // bound by copy
- printf("%d\n", a);
- }
- static struct __main_block_desc_0 {
- size_t reserved;
- size_t Block_size;
- } __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};
- int main()
- {
- int a = 100;
- void (*block2)(void) = (void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, a);
- ((void (*)(__block_impl *))((__block_impl *)block2)->FuncPtr)((__block_impl *)block2);
- return 0;
- }
- #include <stdio.h>
- int main()
- {
- __block int i = 1024;
- void (^block1)(void) = ^{
- printf("%d\n", i);
- i = 1023;
- };
- block1();
- return 0;
- }
- struct __Block_byref_i_0 {
- void *__isa;
- __Block_byref_i_0 *__forwarding;
- int __flags;
- int __size;
- int i;
- };
- struct __main_block_impl_0 {
- struct __block_impl impl;
- struct __main_block_desc_0* Desc;
- __Block_byref_i_0 *i; // by ref
- __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_i_0 *_i, int flags=0) : i(_i->__forwarding) {
- impl.isa = &_NSConcreteStackBlock;
- impl.Flags = flags;
- impl.FuncPtr = fp;
- Desc = desc;
- }
- };
- static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
- __Block_byref_i_0 *i = __cself->i; // bound by ref
- printf("%d\n", (i->__forwarding->i));
- (i->__forwarding->i) = 1023;
- }
- static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->i, (void*)src->i, 8/*BLOCK_FIELD_IS_BYREF*/);}
- static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->i, 8/*BLOCK_FIELD_IS_BYREF*/);}
- static struct __main_block_desc_0 {
- size_t reserved;
- size_t Block_size;
- void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);
- void (*dispose)(struct __main_block_impl_0*);
- } __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};
- int main()
- {
- __attribute__((__blocks__(byref))) __Block_byref_i_0 i = {(void*)0,(__Block_byref_i_0 *)&i, 0, sizeof(__Block_byref_i_0), 1024};
- void (*block1)(void) = (void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_i_0 *)&i, 570425344);
- ((void (*)(__block_impl *))((__block_impl *)block1)->FuncPtr)((__block_impl *)block1);
- return 0;
- }
- static void *_Block_copy_internal(const void *arg, const int flags) {
- struct Block_layout *aBlock;
- const bool wantsOne = (WANTS_ONE & flags) == WANTS_ONE;
- // 1
- if (!arg) return NULL;
- // 2
- aBlock = (struct Block_layout *)arg;
- // 3
- if (aBlock->flags & BLOCK_NEEDS_FREE) {
- // latches on high
- latching_incr_int(&aBlock->flags);
- return aBlock;
- }
- // 4
- else if (aBlock->flags & BLOCK_IS_GLOBAL) {
- return aBlock;
- }
- // 5
- struct Block_layout *result = malloc(aBlock->descriptor->size);
- if (!result) return (void *)0;
- // 6
- memmove(result, aBlock, aBlock->descriptor->size); // bitcopy first
- // 7
- result->flags &= ~(BLOCK_REFCOUNT_MASK); // XXX not needed
- result->flags |= BLOCK_NEEDS_FREE | 1;
- // 8
- result->isa = _NSConcreteMallocBlock;
- // 9
- if (result->flags & BLOCK_HAS_COPY_DISPOSE) {
- (*aBlock->descriptor->copy)(result, aBlock); // do fixup
- }
- return result;
- }
- #import <Foundation/Foundation.h>
- int main(int argc, const char * argv[])
- {
- @autoreleasepool {
- int i = 1024;
- void (^block1)(void) = ^{
- printf("%d\n", i);
- };
- block1();
- NSLog(@"%@", block1);
- }
- return 0;
- }