CFBinaryHeap.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# summary provider for CFBinaryHeap
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# despite the similary to synthetic children providers, these classes are not
22b370df27c76fd875f3312be487868528121a4838Enrico Granata# trying to provide anything but the length for an CFBinaryHeap, so they need not
23b370df27c76fd875f3312be487868528121a4838Enrico Granata# obey the interface specification for synthetic children providers
24b370df27c76fd875f3312be487868528121a4838Enrico Granataclass CFBinaryHeapRef_SummaryProvider:
25b370df27c76fd875f3312be487868528121a4838Enrico Granata	def adjust_for_architecture(self):
26f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		pass
27b370df27c76fd875f3312be487868528121a4838Enrico Granata
28f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata	def __init__(self, valobj, params):
298f18240a09893310c43673901d863892ae7b0611Enrico Granata		logger = Logger.Logger()
30b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.valobj = valobj;
31f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		self.sys_params = params
32f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		if not(self.sys_params.types_cache.NSUInteger):
33f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata			if self.sys_params.is_64_bit:
34f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata				self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
35f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata			else:
36f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata				self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
37b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.update();
38b370df27c76fd875f3312be487868528121a4838Enrico Granata
39b370df27c76fd875f3312be487868528121a4838Enrico Granata	def update(self):
408f18240a09893310c43673901d863892ae7b0611Enrico Granata		logger = Logger.Logger()
41b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.adjust_for_architecture();
42b370df27c76fd875f3312be487868528121a4838Enrico Granata
43b370df27c76fd875f3312be487868528121a4838Enrico Granata	# 8 bytes on i386
44b370df27c76fd875f3312be487868528121a4838Enrico Granata	# 16 bytes on x64
45b370df27c76fd875f3312be487868528121a4838Enrico Granata	# most probably 2 pointers
46b370df27c76fd875f3312be487868528121a4838Enrico Granata	def offset(self):
478f18240a09893310c43673901d863892ae7b0611Enrico Granata		logger = Logger.Logger()
48f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		return 2 * self.sys_params.pointer_size
49b370df27c76fd875f3312be487868528121a4838Enrico Granata
50b370df27c76fd875f3312be487868528121a4838Enrico Granata	def length(self):
518f18240a09893310c43673901d863892ae7b0611Enrico Granata		logger = Logger.Logger()
52b370df27c76fd875f3312be487868528121a4838Enrico Granata		size = self.valobj.CreateChildAtOffset("count",
53b370df27c76fd875f3312be487868528121a4838Enrico Granata							self.offset(),
54f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata							self.sys_params.types_cache.NSUInteger)
55b370df27c76fd875f3312be487868528121a4838Enrico Granata		return size.GetValueAsUnsigned(0)
56b370df27c76fd875f3312be487868528121a4838Enrico Granata
57b370df27c76fd875f3312be487868528121a4838Enrico Granata
58b370df27c76fd875f3312be487868528121a4838Enrico Granataclass CFBinaryHeapUnknown_SummaryProvider:
59b370df27c76fd875f3312be487868528121a4838Enrico Granata	def adjust_for_architecture(self):
60f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		pass
61b370df27c76fd875f3312be487868528121a4838Enrico Granata
62f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata	def __init__(self, valobj, params):
638f18240a09893310c43673901d863892ae7b0611Enrico Granata		logger = Logger.Logger()
64b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.valobj = valobj;
65f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		self.sys_params = params
66f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata		self.update();
67b370df27c76fd875f3312be487868528121a4838Enrico Granata
68b370df27c76fd875f3312be487868528121a4838Enrico Granata	def update(self):
698f18240a09893310c43673901d863892ae7b0611Enrico Granata		logger = Logger.Logger()
70b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.adjust_for_architecture();
71b370df27c76fd875f3312be487868528121a4838Enrico Granata
72b370df27c76fd875f3312be487868528121a4838Enrico Granata	def length(self):
738f18240a09893310c43673901d863892ae7b0611Enrico Granata		logger = Logger.Logger()
74b370df27c76fd875f3312be487868528121a4838Enrico Granata		stream = lldb.SBStream()
75b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.valobj.GetExpressionPath(stream)
76b370df27c76fd875f3312be487868528121a4838Enrico Granata		num_children_vo = self.valobj.CreateValueFromExpression("count","(int)CFBinaryHeapGetCount(" + stream.GetData() + " )");
77579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		if num_children_vo.IsValid():
78579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			return num_children_vo.GetValueAsUnsigned(0)
79579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		return '<variable is not CFBinaryHeap>'
80b370df27c76fd875f3312be487868528121a4838Enrico Granata
81b370df27c76fd875f3312be487868528121a4838Enrico Granata
82b370df27c76fd875f3312be487868528121a4838Enrico Granatadef GetSummary_Impl(valobj):
838f18240a09893310c43673901d863892ae7b0611Enrico Granata	logger = Logger.Logger()
84b370df27c76fd875f3312be487868528121a4838Enrico Granata	global statistics
85579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata	class_data,wrapper = objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
86579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata	if wrapper:
87579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		return wrapper
88b370df27c76fd875f3312be487868528121a4838Enrico Granata
89b370df27c76fd875f3312be487868528121a4838Enrico Granata	name_string = class_data.class_name()
90579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata	actual_name = class_data.class_name()
918f18240a09893310c43673901d863892ae7b0611Enrico Granata
928f18240a09893310c43673901d863892ae7b0611Enrico Granata	logger >> "name string got was " + str(name_string) + " but actual name is " + str(actual_name)
938f18240a09893310c43673901d863892ae7b0611Enrico Granata
94579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata	if class_data.is_cftype():
95b370df27c76fd875f3312be487868528121a4838Enrico Granata		# CFBinaryHeap does not expose an actual NSWrapper type, so we have to check that this is
96b370df27c76fd875f3312be487868528121a4838Enrico Granata		# an NSCFType and then check we are a pointer-to CFBinaryHeap
97b370df27c76fd875f3312be487868528121a4838Enrico Granata		valobj_type = valobj.GetType()
98b370df27c76fd875f3312be487868528121a4838Enrico Granata		if valobj_type.IsValid() and valobj_type.IsPointerType():
99579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			valobj_type = valobj_type.GetPointeeType()
100579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			if valobj_type.IsValid():
101579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata				actual_name = valobj_type.GetName()
102579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		if actual_name == '__CFBinaryHeap':
103579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			wrapper = CFBinaryHeapRef_SummaryProvider(valobj, class_data.sys_params)
104579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			statistics.metric_hit('code_notrun',valobj)
105579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			return wrapper
106f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata	wrapper = CFBinaryHeapUnknown_SummaryProvider(valobj, class_data.sys_params)
107805f79b15edd61887c26a3f0ea80457790ba5807Enrico Granata	statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
108b370df27c76fd875f3312be487868528121a4838Enrico Granata	return wrapper;
109b370df27c76fd875f3312be487868528121a4838Enrico Granata
110b370df27c76fd875f3312be487868528121a4838Enrico Granatadef CFBinaryHeap_SummaryProvider (valobj,dict):
1118f18240a09893310c43673901d863892ae7b0611Enrico Granata	logger = Logger.Logger()
112b370df27c76fd875f3312be487868528121a4838Enrico Granata	provider = GetSummary_Impl(valobj);
113b370df27c76fd875f3312be487868528121a4838Enrico Granata	if provider != None:
114579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		if isinstance(provider,objc_runtime.SpecialSituation_Description):
115579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			return provider.message()
116b370df27c76fd875f3312be487868528121a4838Enrico Granata		try:
117b370df27c76fd875f3312be487868528121a4838Enrico Granata			summary = provider.length();
118b370df27c76fd875f3312be487868528121a4838Enrico Granata		except:
119b370df27c76fd875f3312be487868528121a4838Enrico Granata			summary = None
1208f18240a09893310c43673901d863892ae7b0611Enrico Granata		logger >> "summary got from provider: " + str(summary)
121b370df27c76fd875f3312be487868528121a4838Enrico Granata		# for some reason, one needs to clear some bits for the count
122b370df27c76fd875f3312be487868528121a4838Enrico Granata		# to be correct when using CF(Mutable)BagRef on x64
123b370df27c76fd875f3312be487868528121a4838Enrico Granata		# the bit mask was derived through experimentation
124b370df27c76fd875f3312be487868528121a4838Enrico Granata		# (if counts start looking weird, then most probably
125b370df27c76fd875f3312be487868528121a4838Enrico Granata		#  the mask needs to be changed)
126b370df27c76fd875f3312be487868528121a4838Enrico Granata		if summary == None:
127579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			summary = '<variable is not CFBinaryHeap>'
128579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata		elif isinstance(summary,basestring):
129579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata			pass
130b370df27c76fd875f3312be487868528121a4838Enrico Granata		else:
131f2a84671ff78bee1f82b60698f3ee9791585f8acEnrico Granata			if provider.sys_params.is_64_bit:
132b370df27c76fd875f3312be487868528121a4838Enrico Granata				summary = summary & ~0x1fff000000000000
133323cec97d94bd1836e8c158e7065fdb5ad71ad48Enrico Granata			if summary == 1:
1347b9aacf4a454465af905e505f74245173714b23bEnrico Granata				return '@"1 item"'
135323cec97d94bd1836e8c158e7065fdb5ad71ad48Enrico Granata			else:
1367b9aacf4a454465af905e505f74245173714b23bEnrico Granata				summary = '@"' + str(summary) + ' items"'
137323cec97d94bd1836e8c158e7065fdb5ad71ad48Enrico Granata		return summary
138579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata	return 'Summary Unavailable'
139b370df27c76fd875f3312be487868528121a4838Enrico Granata
140b370df27c76fd875f3312be487868528121a4838Enrico Granatadef __lldb_init_module(debugger,dict):
141b370df27c76fd875f3312be487868528121a4838Enrico Granata	debugger.HandleCommand("type summary add -F CFBinaryHeap.CFBinaryHeap_SummaryProvider CFBinaryHeapRef")
142