CFArray.py revision 8f18240a09893310c43673901d863892ae7b0611
1579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata""" 2579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLLDB AppKit formatters 3579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata 4579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granatapart of The LLVM Compiler Infrastructure 5579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataThis file is distributed under the University of Illinois Open Source 6579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLicense. See LICENSE.TXT for details. 7579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata""" 8b370df27c76fd875f3312be487868528121a4838Enrico Granata# synthetic children provider for NSArray 9b370df27c76fd875f3312be487868528121a4838Enrico Granataimport lldb 10b370df27c76fd875f3312be487868528121a4838Enrico Granataimport ctypes 11b370df27c76fd875f3312be487868528121a4838Enrico Granataimport objc_runtime 12b370df27c76fd875f3312be487868528121a4838Enrico Granataimport metrics 138f18240a09893310c43673901d863892ae7b0611Enrico Granataimport Logger 14b370df27c76fd875f3312be487868528121a4838Enrico Granata 15b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics = metrics.Metrics() 16b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_isa') 17b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('invalid_pointer') 18b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('unknown_class') 19b370df27c76fd875f3312be487868528121a4838Enrico Granatastatistics.add_metric('code_notrun') 20b370df27c76fd875f3312be487868528121a4838Enrico Granata 21b370df27c76fd875f3312be487868528121a4838Enrico Granata# much less functional than the other two cases below 22b370df27c76fd875f3312be487868528121a4838Enrico Granata# just runs code to get to the count and then returns 23b370df27c76fd875f3312be487868528121a4838Enrico Granata# no children 24b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSArrayKVC_SynthProvider: 25b370df27c76fd875f3312be487868528121a4838Enrico Granata 26b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 27f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 28b370df27c76fd875f3312be487868528121a4838Enrico Granata 29f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, dict, params): 308f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 31b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 32b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update() 33b370df27c76fd875f3312be487868528121a4838Enrico Granata 34b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 358f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 36b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 37b370df27c76fd875f3312be487868528121a4838Enrico Granata 38b370df27c76fd875f3312be487868528121a4838Enrico Granata def num_children(self): 398f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 40b370df27c76fd875f3312be487868528121a4838Enrico Granata stream = lldb.SBStream() 41b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj.GetExpressionPath(stream) 42b370df27c76fd875f3312be487868528121a4838Enrico Granata num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " count]"); 43579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if num_children_vo.IsValid(): 44579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return num_children_vo.GetValueAsUnsigned(0) 45579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return "<variable is not NSArray>" 46b370df27c76fd875f3312be487868528121a4838Enrico Granata 47b370df27c76fd875f3312be487868528121a4838Enrico Granata# much less functional than the other two cases below 48b370df27c76fd875f3312be487868528121a4838Enrico Granata# just runs code to get to the count and then returns 49b370df27c76fd875f3312be487868528121a4838Enrico Granata# no children 50b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSArrayCF_SynthProvider: 51b370df27c76fd875f3312be487868528121a4838Enrico Granata 52b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 53f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 54b370df27c76fd875f3312be487868528121a4838Enrico Granata 55f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, dict, params): 568f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 57b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 58f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 59f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not (self.sys_params.types_cache.ulong): 60f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong) 61b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update() 62b370df27c76fd875f3312be487868528121a4838Enrico Granata 63b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 648f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 65b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 66b370df27c76fd875f3312be487868528121a4838Enrico Granata 67b370df27c76fd875f3312be487868528121a4838Enrico Granata def num_children(self): 688f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 69b370df27c76fd875f3312be487868528121a4838Enrico Granata num_children_vo = self.valobj.CreateChildAtOffset("count", 70f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.cfruntime_size, 71f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.ulong) 72b370df27c76fd875f3312be487868528121a4838Enrico Granata return num_children_vo.GetValueAsUnsigned(0) 73b370df27c76fd875f3312be487868528121a4838Enrico Granata 74b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSArrayI_SynthProvider: 75b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 76f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 77b370df27c76fd875f3312be487868528121a4838Enrico Granata 78f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, dict, params): 798f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 80b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 81f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 82f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(self.sys_params.types_cache.long): 83f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) 84b370df27c76fd875f3312be487868528121a4838Enrico Granata self.update() 85b370df27c76fd875f3312be487868528121a4838Enrico Granata 86b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 878f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 88b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 89b370df27c76fd875f3312be487868528121a4838Enrico Granata 90b370df27c76fd875f3312be487868528121a4838Enrico Granata # skip the isa pointer and get at the size 91b370df27c76fd875f3312be487868528121a4838Enrico Granata def num_children(self): 928f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 93b370df27c76fd875f3312be487868528121a4838Enrico Granata count = self.valobj.CreateChildAtOffset("count", 94f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.pointer_size, 95f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.long); 96f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return count.GetValueAsUnsigned(0) 97b370df27c76fd875f3312be487868528121a4838Enrico Granata 98b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSArrayM_SynthProvider: 99b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 100f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 101b370df27c76fd875f3312be487868528121a4838Enrico Granata 102f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata def __init__(self, valobj, dict, params): 1038f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 104b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 105f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params = params 106f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata if not(self.sys_params.types_cache.long): 107f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong) 108f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.update() 109b370df27c76fd875f3312be487868528121a4838Enrico Granata 110b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 1118f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 112b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture(); 113b370df27c76fd875f3312be487868528121a4838Enrico Granata 114b370df27c76fd875f3312be487868528121a4838Enrico Granata # skip the isa pointer and get at the size 115b370df27c76fd875f3312be487868528121a4838Enrico Granata def num_children(self): 1168f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 117b370df27c76fd875f3312be487868528121a4838Enrico Granata count = self.valobj.CreateChildAtOffset("count", 118f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.pointer_size, 119f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.sys_params.types_cache.long); 120f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return count.GetValueAsUnsigned(0) 121b370df27c76fd875f3312be487868528121a4838Enrico Granata 122b370df27c76fd875f3312be487868528121a4838Enrico Granata# this is the actual synth provider, but is just a wrapper that checks 123b370df27c76fd875f3312be487868528121a4838Enrico Granata# whether valobj is an instance of __NSArrayI or __NSArrayM and sets up an 124b370df27c76fd875f3312be487868528121a4838Enrico Granata# appropriate backend layer to do the computations 125b370df27c76fd875f3312be487868528121a4838Enrico Granataclass NSArray_SynthProvider: 126b370df27c76fd875f3312be487868528121a4838Enrico Granata def adjust_for_architecture(self): 127f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata pass 128b370df27c76fd875f3312be487868528121a4838Enrico Granata 129b370df27c76fd875f3312be487868528121a4838Enrico Granata def __init__(self, valobj, dict): 1308f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 131b370df27c76fd875f3312be487868528121a4838Enrico Granata self.valobj = valobj; 132b370df27c76fd875f3312be487868528121a4838Enrico Granata self.adjust_for_architecture() 133579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata self.error = False 134579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata self.wrapper = self.make_wrapper() 135b370df27c76fd875f3312be487868528121a4838Enrico Granata self.invalid = (self.wrapper == None) 136b370df27c76fd875f3312be487868528121a4838Enrico Granata 137b370df27c76fd875f3312be487868528121a4838Enrico Granata def num_children(self): 1388f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 139b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.wrapper == None: 140b370df27c76fd875f3312be487868528121a4838Enrico Granata return 0; 141b370df27c76fd875f3312be487868528121a4838Enrico Granata return self.wrapper.num_children() 142b370df27c76fd875f3312be487868528121a4838Enrico Granata 143b370df27c76fd875f3312be487868528121a4838Enrico Granata def update(self): 1448f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 145b370df27c76fd875f3312be487868528121a4838Enrico Granata if self.wrapper == None: 146f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata return 147f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata self.wrapper.update() 148b370df27c76fd875f3312be487868528121a4838Enrico Granata 149b370df27c76fd875f3312be487868528121a4838Enrico Granata # this code acts as our defense against NULL and unitialized 150b370df27c76fd875f3312be487868528121a4838Enrico Granata # NSArray pointers, which makes it much longer than it would be otherwise 151579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata def make_wrapper(self): 1528f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 153579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if self.valobj.GetValueAsUnsigned() == 0: 154579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata self.error = True 155579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return objc_runtime.InvalidPointer_Description(True) 156579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata else: 157579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata global statistics 158579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata class_data,wrapper = objc_runtime.Utilities.prepare_class_detection(self.valobj,statistics) 159579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if wrapper: 160579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata self.error = True 161579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return wrapper 162b370df27c76fd875f3312be487868528121a4838Enrico Granata 163b370df27c76fd875f3312be487868528121a4838Enrico Granata name_string = class_data.class_name() 1648f18240a09893310c43673901d863892ae7b0611Enrico Granata 1658f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "Class name is " + str(name_string) 1668f18240a09893310c43673901d863892ae7b0611Enrico Granata 167b370df27c76fd875f3312be487868528121a4838Enrico Granata if name_string == '__NSArrayI': 168579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = NSArrayI_SynthProvider(self.valobj, dict, class_data.sys_params) 169579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata statistics.metric_hit('code_notrun',self.valobj) 170b370df27c76fd875f3312be487868528121a4838Enrico Granata elif name_string == '__NSArrayM': 171579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = NSArrayM_SynthProvider(self.valobj, dict, class_data.sys_params) 172579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata statistics.metric_hit('code_notrun',self.valobj) 173b370df27c76fd875f3312be487868528121a4838Enrico Granata elif name_string == '__NSCFArray': 174579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = NSArrayCF_SynthProvider(self.valobj, dict, class_data.sys_params) 175579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata statistics.metric_hit('code_notrun',self.valobj) 176b370df27c76fd875f3312be487868528121a4838Enrico Granata else: 177579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata wrapper = NSArrayKVC_SynthProvider(self.valobj, dict, class_data.sys_params) 178579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata statistics.metric_hit('unknown_class',str(self.valobj) + " seen as " + name_string) 179b370df27c76fd875f3312be487868528121a4838Enrico Granata return wrapper; 180b370df27c76fd875f3312be487868528121a4838Enrico Granata 181b370df27c76fd875f3312be487868528121a4838Enrico Granatadef CFArray_SummaryProvider (valobj,dict): 1828f18240a09893310c43673901d863892ae7b0611Enrico Granata logger = Logger.Logger() 183b370df27c76fd875f3312be487868528121a4838Enrico Granata provider = NSArray_SynthProvider(valobj,dict); 184b370df27c76fd875f3312be487868528121a4838Enrico Granata if provider.invalid == False: 185579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if provider.error == True: 186579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return provider.wrapper.message() 187579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata try: 188579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = int(provider.num_children()); 189579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata except: 190579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = None 1918f18240a09893310c43673901d863892ae7b0611Enrico Granata logger >> "provider gave me " + str(summary) 192579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata if summary == None: 193579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '<variable is not NSArray>' 194579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata elif isinstance(summary,basestring): 195579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata pass 196579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata else: 197579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata # we format it like it were a CFString to make it look the same as the summary from Xcode 198579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata summary = '@"' + str(summary) + (" objects" if summary != 1 else " object") + '"' 199579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return summary 200579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata return 'Summary Unavailable' 201b370df27c76fd875f3312be487868528121a4838Enrico Granata 202b370df27c76fd875f3312be487868528121a4838Enrico Granatadef __lldb_init_module(debugger,dict): 203b370df27c76fd875f3312be487868528121a4838Enrico Granata debugger.HandleCommand("type summary add -F CFArray.CFArray_SummaryProvider NSArray CFArrayRef CFMutableArrayRef") 204