@@ -139,17 +139,108 @@ def run(self, arguments, options):
139
139
command = string .Template (tmpString ).substitute (block = block )
140
140
json = fb .evaluate (command )
141
141
142
+ variables_json = self .getBlockVariables (block )
143
+ if variables_json is not None :
144
+ json .update (variables_json )
145
+
146
+ variablesStrs = []
147
+ for i in range (10 ):
148
+ varKey = 'variables[' + str (i )+ ']'
149
+ if varKey in json :
150
+ variablesStrs .append (json [varKey ])
151
+ variablesStr = '\n ' .join (variablesStrs )
152
+
142
153
signature = json ['signature' ]
143
154
if not signature :
144
- print 'Imp: ' + hex (json ['invoke' ])
155
+ print 'Imp: ' + hex (json ['invoke' ]) + ' Variables : { \n ' + variablesStr + ' \n };'
145
156
return
146
157
147
158
sigStr = '{} ^(' .format (decode (signature [0 ]))
148
159
# the block`s implementation always take the block as it`s first argument, so we ignore it
149
160
sigStr += ', ' .join ([decode (m ) for m in signature [2 :]])
150
- sigStr += '); '
161
+ sigStr += ')'
151
162
152
- print 'Imp: ' + hex (json ['invoke' ]) + ' Signature: ' + sigStr
163
+ print 'Imp: ' + hex (json ['invoke' ]) + ' Signature: ' + sigStr + ' Variables : {\n ' + variablesStr + '\n };'
164
+
165
+ def getBlockVariables (self , block , min_var_count = 1 , max_var_count = 20 ):
166
+ '''
167
+ no __Block_byref_xxx
168
+ '''
169
+
170
+ # http://clang.llvm.org/docs/Block-ABI-Apple.html
171
+ tmpString = """
172
+ #define BLOCK_VARIABLES_COUNT ($variables_count)
173
+ enum {
174
+ BLOCK_HAS_COPY_DISPOSE = (1 << 25),
175
+ BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code
176
+ BLOCK_IS_GLOBAL = (1 << 28),
177
+ BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE
178
+ BLOCK_HAS_SIGNATURE = (1 << 30),
179
+ };
180
+ struct Block_literal_1 {
181
+ void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
182
+ int flags;
183
+ int reserved;
184
+ void (*invoke)(void *, ...);
185
+ struct Block_descriptor_1 {
186
+ unsigned long int reserved; // NULL
187
+ unsigned long int size; // sizeof(struct Block_literal_1)
188
+ // optional helper functions
189
+ void (*copy_helper)(void *dst, void *src); // IFF (1<<25)
190
+ void (*dispose_helper)(void *src); // IFF (1<<25)
191
+ // required ABI.2010.3.16
192
+ const char *signature; // IFF (1<<30)
193
+ } *descriptor;
194
+ // imported variables
195
+ Class *variables[BLOCK_VARIABLES_COUNT];
196
+ };
197
+ struct Block_literal_1 real = *((__bridge struct Block_literal_1 *)$block);
198
+ NSMutableDictionary *dict = (id)[NSMutableDictionary dictionary];
199
+
200
+ // Get the list of classes and look for testPointerClass
201
+ NSInteger numClasses = objc_getClassList(NULL, 0);
202
+ Class *classesList = (Class*)malloc(sizeof(Class) * numClasses);
203
+ numClasses = objc_getClassList(classesList, numClasses);
204
+
205
+ Class **blockVariables = real.variables;
206
+ for (int i = 0; i < BLOCK_VARIABLES_COUNT; i++) {
207
+ Class *obj = (Class*)blockVariables[i];
208
+ if (obj == NULL) {
209
+ break;
210
+ }
211
+
212
+ Class testPointerClass = (Class)(*obj);
213
+ BOOL isClass = NO;
214
+ for (int i = 0; i < numClasses; i++)
215
+ {
216
+ if (classesList[i] == testPointerClass)
217
+ {
218
+ isClass = YES;
219
+ break;
220
+ }
221
+ }
222
+ if (!isClass) {
223
+ break;
224
+ }
225
+
226
+ NSString *key = [NSString stringWithFormat:@"variables[%d]", i];
227
+ NSString *value = [NSString stringWithFormat:@"%@", obj];
228
+ [dict setValue:value forKey:key];
229
+ }
230
+
231
+ free(classesList);
232
+
233
+ RETURN(dict);
234
+ """
235
+ last_json = None
236
+ for i in range (min_var_count , max_var_count ):
237
+ command = string .Template (tmpString ).substitute (block = block , variables_count = i )
238
+ json = fb .evaluate (command , printErrors = False )
239
+ if json is not None :
240
+ last_json = json
241
+ else :
242
+ break
243
+ return last_json
153
244
154
245
# helpers
155
246
def isClassObject (arg ):
@@ -302,20 +393,20 @@ def getProperties(klass):
302
393
NSMutableDictionary *dict = (id)[NSMutableDictionary dictionary];
303
394
304
395
char *name = (char *)property_getName(props[i]);
305
- [dict setObject :(id)[NSString stringWithUTF8String:name] forKey:@"name"];
396
+ [dict setValue :(id)[NSString stringWithUTF8String:name] forKey:@"name"];
306
397
307
398
char *attrstr = (char *)property_getAttributes(props[i]);
308
- [dict setObject :(id)[NSString stringWithUTF8String:attrstr] forKey:@"attributes_string"];
399
+ [dict setValue :(id)[NSString stringWithUTF8String:attrstr] forKey:@"attributes_string"];
309
400
310
401
NSMutableDictionary *attrsDict = (id)[NSMutableDictionary dictionary];
311
402
unsigned int pcount;
312
403
objc_property_attribute_t *attrs = (objc_property_attribute_t *)property_copyAttributeList(props[i], &pcount);
313
404
for (int i = 0; i < pcount; i++) {
314
405
NSString *name = (id)[NSString stringWithUTF8String:(char *)attrs[i].name];
315
406
NSString *value = (id)[NSString stringWithUTF8String:(char *)attrs[i].value];
316
- [attrsDict setObject :value forKey:name];
407
+ [attrsDict setValue :value forKey:name];
317
408
}
318
- [dict setObject :attrsDict forKey:@"attributes"];
409
+ [dict setValue :attrsDict forKey:@"attributes"];
319
410
320
411
[result addObject:dict];
321
412
}
0 commit comments