1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LLVM_LICENSE_HEADER@ 5 */ 6 7/* 8 * import_interim_byref.c 9 * Examples 10 * 11 * Created by Blaine Garst on 2/13/08. 12 * Copyright 2008 __MyCompanyName__. All rights reserved. 13 * 14 */ 15 16 17 18#include "driver.h" 19 20// Interim closure implementation - merely keep addresses of stack until we learn 21// how to move other parameters into byref block 22// 23// 24 25#if __BLOCKS__ 26int import_byref_interim_real(int verbose) { 27 int x = rand(); 28 int y = 15; 29 void (^myClosure)(void) = ^ (void) { | y | setGlobalInt(x+y); ++y;}; 30 x++; 31 callVoidVoid(myClosure); 32 33 int globalValue = getGlobalInt(); 34 int desiredValue = x+y-2; 35 if (error_found("import_byref_interim", globalValue, desiredValue, verbose)) return 1; 36 37#if FULL_CLOSURES 38 void (^myClosureCopy)(void) = Block_copy(myClosure); 39 callVoidVoid(myClosureCopy); 40 41 globalValue = getGlobalInt(); 42 if (error_found("import_byref_interim copy", globalValue, desiredValue, verbose)) return 1; 43 44 Block_release(myClosureCopy); 45#endif 46 return 0; 47} 48 49#endif __BLOCKS__ 50 51 52struct import_byref_interim_struct { 53 struct Block_basic base; 54 const int x; 55 int *py; 56}; 57 58// the "thunks" compiled for the invoke entry point of the import_byref 59 60void invoke_import_byref_interim(struct import_byref_interim_struct *aBlock) { 61 // no return value so just a void invoke 62 // the compound statement rewritten to reference locals via the const copies. 63 { 64 //printf("closure x is %d and y is %d\n", aBlock->x, *aBlock->py); 65 setGlobalInt(aBlock->x + *aBlock->py); 66 ++*aBlock->py; 67 } 68} 69 70 71// The rewritten version of the code above 72 73int import_byref_interim(int verbose) { 74 int x = rand(); 75 int y = 15; 76 77 struct import_byref_interim_struct myClosure = { 78 { 0, BLOCK_NO_COPY, sizeof(struct import_byref_interim_struct), 79 (void (*)(void *))invoke_import_byref_interim, 80 }, 81 x, // capture x 82 &y // capture y 83 }; 84 x++; 85 callVoidVoid(&myClosure.base); 86 87 int globalValue = getGlobalInt(); 88 int desiredValue = x+y-2; 89 if (error_found("import_byref_interim", globalValue, desiredValue, verbose)) return 1; 90 91#if FULL_CLOSURES 92 struct import_byref_interim_struct *myClosureCopy = Block_copy(&myClosure.base); 93 callVoidVoid(&myClosureCopy->base); 94 95 globalValue = getGlobalInt(); 96 if (error_found("import_byref_interim copy", globalValue, desiredValue, verbose)) return 1; 97 Block_release(myClosureCopy); 98#endif 99 100 101 return 0; 102} 103