#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct Block_basic {
void *isa; int Block_flags;
int reserved;
void (*Block_invoke)(void *);
struct Block_descriptor_1 {
unsigned long int reserved; unsigned long int Block_size;
void (*Block_copy)(void *dst, void *src);
void (*Block_dispose)(void *src);
} *descriptor;
};
void
func(void (^b)(void))
{
b();
}
void
func2(void (^b)(void))
{
b();
}
extern char **environ;
int
main(int argc __attribute__((unused)), char *argv[])
{
struct Block_basic *bb;
long bbi_addr, bb_addr;
void (^stage1)(void) = ^{
void (^stage2)(void) = ^{
if (environ == argv) {
fprintf(stdout, "You won the lottery! argv == environ\n");
}
};
func2(stage2);
};
bb = (void *)stage1;
bbi_addr = (long)bb->Block_invoke;
bb_addr = (long)bb;
if (labs(bbi_addr - bb_addr) > (64 * 1024)) {
func(stage1);
exit(EXIT_SUCCESS);
} else {
fprintf(stderr, "Blocks generated code on the stack! Block_copy() is not safe!\n");
exit(EXIT_FAILURE);
}
}