| 132 | ] |
| 133 | |
| 134 | def run(self, arguments, options): |
| 135 | block = arguments[0] |
| 136 | |
| 137 | # http://clang.llvm.org/docs/Block-ABI-Apple.html |
| 138 | tmpString = """ |
| 139 | enum { |
| 140 | BLOCK_HAS_COPY_DISPOSE = (1 << 25), |
| 141 | BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code |
| 142 | BLOCK_IS_GLOBAL = (1 << 28), |
| 143 | BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE |
| 144 | BLOCK_HAS_SIGNATURE = (1 << 30), |
| 145 | }; |
| 146 | struct Block_literal_1 { |
| 147 | void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock |
| 148 | int flags; |
| 149 | int reserved; |
| 150 | void (*invoke)(void *, ...); |
| 151 | struct Block_descriptor_1 { |
| 152 | unsigned long int reserved; // NULL |
| 153 | unsigned long int size; // sizeof(struct Block_literal_1) |
| 154 | // optional helper functions |
| 155 | void (*copy_helper)(void *dst, void *src); // IFF (1<<25) |
| 156 | void (*dispose_helper)(void *src); // IFF (1<<25) |
| 157 | // required ABI.2010.3.16 |
| 158 | const char *signature; // IFF (1<<30) |
| 159 | } *descriptor; |
| 160 | // imported variables |
| 161 | }; |
| 162 | struct Block_literal_1 real = *((__bridge struct Block_literal_1 *)$block); |
| 163 | NSMutableDictionary *dict = (id)[NSMutableDictionary dictionary]; |
| 164 | |
| 165 | [dict setObject:(id)[NSNumber numberWithLong:(long)real.invoke] forKey:@"invoke"]; |
| 166 | |
| 167 | if (real.flags & BLOCK_HAS_SIGNATURE) { |
| 168 | char *signature; |
| 169 | if (real.flags & BLOCK_HAS_COPY_DISPOSE) { |
| 170 | signature = (char *)(real.descriptor)->signature; |
| 171 | } else { |
| 172 | signature = (char *)(real.descriptor)->copy_helper; |
| 173 | } |
| 174 | |
| 175 | NSMethodSignature *sig = [NSMethodSignature signatureWithObjCTypes:signature]; |
| 176 | NSMutableArray *types = [NSMutableArray array]; |
| 177 | |
| 178 | [types addObject:(id)[NSString stringWithUTF8String:(char *)[sig methodReturnType]]]; |
| 179 | |
| 180 | for (NSUInteger i = 0; i < sig.numberOfArguments; i++) { |
| 181 | char *type = (char *)[sig getArgumentTypeAtIndex:i]; |
| 182 | [types addObject:(id)[NSString stringWithUTF8String:type]]; |
| 183 | } |
| 184 | |
| 185 | [dict setObject:types forKey:@"signature"]; |
| 186 | } |
| 187 | |
| 188 | RETURN(dict); |
| 189 | """ |
| 190 | command = string.Template(tmpString).substitute(block=block) |
| 191 | json = fb.evaluate(command) |