NSMachPort.py revision 805f79b15edd61887c26a3f0ea80457790ba5807
1"""
2LLDB AppKit formatters
3
4part of The LLVM Compiler Infrastructure
5This file is distributed under the University of Illinois Open Source
6License. See LICENSE.TXT for details.
7"""
8# summary provider for NSData
9import lldb
10import ctypes
11import objc_runtime
12import metrics
13
14statistics = metrics.Metrics()
15statistics.add_metric('invalid_isa')
16statistics.add_metric('invalid_pointer')
17statistics.add_metric('unknown_class')
18statistics.add_metric('code_notrun')
19
20# despite the similary to synthetic children providers, these classes are not
21# trying to provide anything but the port number of an NSMachPort, so they need not
22# obey the interface specification for synthetic children providers
23class NSMachPortKnown_SummaryProvider:
24	def adjust_for_architecture(self):
25		pass
26
27	def __init__(self, valobj, params):
28		self.valobj = valobj;
29		self.sys_params = params
30		if not(self.sys_params.types_cache.NSUInteger):
31			if self.sys_params.is_64_bit:
32				self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedLong)
33			else:
34				self.sys_params.types_cache.NSUInteger = self.valobj.GetType().GetBasicType(lldb.eBasicTypeUnsignedInt)
35		self.update();
36
37	def update(self):
38		self.adjust_for_architecture();
39
40	# one pointer is the ISA
41	# then we have one other internal pointer, plus
42	# 4 bytes worth of flags. hence, these values
43	def offset(self):
44		if self.sys_params.is_64_bit:
45			return 20
46		else:
47			return 12
48
49	def port(self):
50		vport = self.valobj.CreateChildAtOffset("port",
51							self.offset(),
52							self.sys_params.types_cache.NSUInteger)
53		return vport.GetValueAsUnsigned(0)
54
55
56class NSMachPortUnknown_SummaryProvider:
57	def adjust_for_architecture(self):
58		pass
59
60	def __init__(self, valobj, params):
61		self.valobj = valobj;
62		self.sys_params = params
63		self.update();
64
65	def update(self):
66		self.adjust_for_architecture();
67
68	def port(self):
69		stream = lldb.SBStream()
70		self.valobj.GetExpressionPath(stream)
71		num_children_vo = self.valobj.CreateValueFromExpression("port","(int)[" + stream.GetData() + " machPort]")
72		if num_children_vo.IsValid():
73			return num_children_vo.GetValueAsUnsigned(0)
74		return '<variable is not NSMachPort>'
75
76
77def GetSummary_Impl(valobj):
78	global statistics
79	class_data,wrapper = objc_runtime.Utilities.prepare_class_detection(valobj,statistics)
80	if wrapper:
81		return wrapper
82
83	name_string = class_data.class_name()
84	if name_string == 'NSMachPort':
85		wrapper = NSMachPortKnown_SummaryProvider(valobj, class_data.sys_params)
86		statistics.metric_hit('code_notrun',valobj)
87	else:
88		wrapper = NSMachPortUnknown_SummaryProvider(valobj, class_data.sys_params)
89		statistics.metric_hit('unknown_class',valobj.GetName() + " seen as " + name_string)
90	return wrapper;
91
92def NSMachPort_SummaryProvider (valobj,dict):
93	provider = GetSummary_Impl(valobj);
94	if provider != None:
95		if isinstance(provider,objc_runtime.SpecialSituation_Description):
96			return provider.message()
97		try:
98			summary = provider.port();
99		except:
100			summary = None
101		if summary == None:
102			summary = '<variable is not NSMachPort>'
103		if isinstance(summary, basestring):
104			return summay
105		return 'mach port: ' + str(summary)
106	return 'Summary Unavailable'
107
108def __lldb_init_module(debugger,dict):
109	debugger.HandleCommand("type summary add -F NSMachPort.NSMachPort_SummaryProvider NSMachPort")
110