blob: 0721e76b9f8174bd0c2fcdbd9c131207efeb7e5b [file] [log] [blame]
Enrico Granataeb4a4792012-02-23 23:10:27 +00001# synthetic children provider for NSArray
2import lldb
3import ctypes
4import objc_runtime
5import metrics
6
7statistics = metrics.Metrics()
8statistics.add_metric('invalid_isa')
9statistics.add_metric('invalid_pointer')
10statistics.add_metric('unknown_class')
11statistics.add_metric('code_notrun')
12
13# much less functional than the other two cases below
14# just runs code to get to the count and then returns
15# no children
16class NSArrayKVC_SynthProvider:
17
18 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000019 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000020
Enrico Granatacfdafa32012-03-05 19:56:33 +000021 def __init__(self, valobj, dict, params):
Enrico Granataeb4a4792012-02-23 23:10:27 +000022 self.valobj = valobj;
23 self.update()
24
25 def update(self):
26 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000027
28 def num_children(self):
29 stream = lldb.SBStream()
30 self.valobj.GetExpressionPath(stream)
31 num_children_vo = self.valobj.CreateValueFromExpression("count","(int)[" + stream.GetData() + " count]");
32 return num_children_vo.GetValueAsUnsigned(0)
33
Enrico Granataeb4a4792012-02-23 23:10:27 +000034# much less functional than the other two cases below
35# just runs code to get to the count and then returns
36# no children
37class NSArrayCF_SynthProvider:
38
39 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000040 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000041
Enrico Granatacfdafa32012-03-05 19:56:33 +000042 def __init__(self, valobj, dict, params):
Enrico Granataeb4a4792012-02-23 23:10:27 +000043 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000044 self.sys_params = params
45 if not (self.sys_params.types_cache.ulong):
46 self.sys_params.types_cache.ulong = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
Enrico Granataeb4a4792012-02-23 23:10:27 +000047 self.update()
48
49 def update(self):
50 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000051
52 def num_children(self):
53 num_children_vo = self.valobj.CreateChildAtOffset("count",
Enrico Granatacfdafa32012-03-05 19:56:33 +000054 self.sys_params.cfruntime_size,
55 self.sys_params.types_cache.ulong)
Enrico Granataeb4a4792012-02-23 23:10:27 +000056 return num_children_vo.GetValueAsUnsigned(0)
57
Enrico Granataeb4a4792012-02-23 23:10:27 +000058class NSArrayI_SynthProvider:
Enrico Granataeb4a4792012-02-23 23:10:27 +000059 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000060 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000061
Enrico Granatacfdafa32012-03-05 19:56:33 +000062 def __init__(self, valobj, dict, params):
Enrico Granataeb4a4792012-02-23 23:10:27 +000063 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000064 self.sys_params = params
65 if not(self.sys_params.types_cache.long):
66 self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong)
Enrico Granataeb4a4792012-02-23 23:10:27 +000067 self.update()
68
69 def update(self):
70 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000071
72 # skip the isa pointer and get at the size
73 def num_children(self):
Enrico Granataeb4a4792012-02-23 23:10:27 +000074 count = self.valobj.CreateChildAtOffset("count",
Enrico Granatacfdafa32012-03-05 19:56:33 +000075 self.sys_params.pointer_size,
76 self.sys_params.types_cache.long);
77 return count.GetValueAsUnsigned(0)
Enrico Granataeb4a4792012-02-23 23:10:27 +000078
79class NSArrayM_SynthProvider:
Enrico Granataeb4a4792012-02-23 23:10:27 +000080 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +000081 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +000082
Enrico Granatacfdafa32012-03-05 19:56:33 +000083 def __init__(self, valobj, dict, params):
Enrico Granataeb4a4792012-02-23 23:10:27 +000084 self.valobj = valobj;
Enrico Granatacfdafa32012-03-05 19:56:33 +000085 self.sys_params = params
86 if not(self.sys_params.types_cache.long):
87 self.sys_params.types_cache.long = self.valobj.GetType().GetBasicType(lldb.eBasicTypeLong)
88 self.update()
Enrico Granataeb4a4792012-02-23 23:10:27 +000089
90 def update(self):
91 self.adjust_for_architecture();
Enrico Granataeb4a4792012-02-23 23:10:27 +000092
93 # skip the isa pointer and get at the size
94 def num_children(self):
Enrico Granataeb4a4792012-02-23 23:10:27 +000095 count = self.valobj.CreateChildAtOffset("count",
Enrico Granatacfdafa32012-03-05 19:56:33 +000096 self.sys_params.pointer_size,
97 self.sys_params.types_cache.long);
98 return count.GetValueAsUnsigned(0)
Enrico Granataeb4a4792012-02-23 23:10:27 +000099
100# this is the actual synth provider, but is just a wrapper that checks
101# whether valobj is an instance of __NSArrayI or __NSArrayM and sets up an
102# appropriate backend layer to do the computations
103class NSArray_SynthProvider:
Enrico Granataeb4a4792012-02-23 23:10:27 +0000104 def adjust_for_architecture(self):
Enrico Granatacfdafa32012-03-05 19:56:33 +0000105 pass
Enrico Granataeb4a4792012-02-23 23:10:27 +0000106
107 def __init__(self, valobj, dict):
108 self.valobj = valobj;
109 self.adjust_for_architecture()
110 self.wrapper = self.make_wrapper(valobj,dict)
111 self.invalid = (self.wrapper == None)
112
Enrico Granataeb4a4792012-02-23 23:10:27 +0000113 def num_children(self):
114 if self.wrapper == None:
115 return 0;
116 return self.wrapper.num_children()
117
118 def update(self):
119 if self.wrapper == None:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000120 return
121 self.wrapper.update()
Enrico Granataeb4a4792012-02-23 23:10:27 +0000122
123 # this code acts as our defense against NULL and unitialized
124 # NSArray pointers, which makes it much longer than it would be otherwise
125 def make_wrapper(self,valobj,dict):
126 global statistics
127 class_data = objc_runtime.ObjCRuntime(valobj)
128 if class_data.is_valid() == False:
129 statistics.metric_hit('invalid_pointer',valobj)
130 wrapper = None
131 return
132 class_data = class_data.read_class_data()
133 if class_data.is_valid() == False:
134 statistics.metric_hit('invalid_isa',valobj)
135 wrapper = None
136 return
137 if class_data.is_kvo():
138 class_data = class_data.get_superclass()
139 if class_data.is_valid() == False:
140 statistics.metric_hit('invalid_isa',valobj)
141 wrapper = None
142 return
143
144 name_string = class_data.class_name()
145 if name_string == '__NSArrayI':
Enrico Granatacfdafa32012-03-05 19:56:33 +0000146 wrapper = NSArrayI_SynthProvider(valobj, dict, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000147 statistics.metric_hit('code_notrun',valobj)
148 elif name_string == '__NSArrayM':
Enrico Granatacfdafa32012-03-05 19:56:33 +0000149 wrapper = NSArrayM_SynthProvider(valobj, dict, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000150 statistics.metric_hit('code_notrun',valobj)
151 elif name_string == '__NSCFArray':
Enrico Granatacfdafa32012-03-05 19:56:33 +0000152 wrapper = NSArrayCF_SynthProvider(valobj, dict, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000153 statistics.metric_hit('code_notrun',valobj)
154 else:
Enrico Granatacfdafa32012-03-05 19:56:33 +0000155 wrapper = NSArrayKVC_SynthProvider(valobj, dict, class_data.sys_params)
Enrico Granataeb4a4792012-02-23 23:10:27 +0000156 statistics.metric_hit('unknown_class',str(valobj) + " seen as " + name_string)
157 return wrapper;
158
159def CFArray_SummaryProvider (valobj,dict):
160 provider = NSArray_SynthProvider(valobj,dict);
161 if provider.invalid == False:
162 try:
163 summary = str(provider.num_children());
164 except:
165 summary = None
166 if summary == None:
167 summary = 'no valid array here'
Enrico Granata7bc0ec32012-02-29 03:28:49 +0000168 return summary + " objects"
Enrico Granataeb4a4792012-02-23 23:10:27 +0000169 return ''
170
171def __lldb_init_module(debugger,dict):
172 debugger.HandleCommand("type summary add -F CFArray.CFArray_SummaryProvider NSArray CFArrayRef CFMutableArrayRef")