xref: /haiku/src/kits/debugger/model/StackFrameValueInfos.cpp (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "StackFrameValueInfos.h"
8 
9 #include <new>
10 
11 #include "FunctionID.h"
12 #include "Type.h"
13 #include "TypeComponentPath.h"
14 #include "ValueLocation.h"
15 
16 
17 struct StackFrameValueInfos::Key {
18 	ObjectID*			variable;
19 	TypeComponentPath*	path;
20 
21 	Key(ObjectID* variable, TypeComponentPath* path)
22 		:
23 		variable(variable),
24 		path(path)
25 	{
26 	}
27 
28 	uint32 HashValue() const
29 	{
30 		return variable->HashValue() ^ path->HashValue();
31 	}
32 
33 	bool operator==(const Key& other) const
34 	{
35 		return *variable == *other.variable && *path == *other.path;
36 	}
37 };
38 
39 
40 struct StackFrameValueInfos::InfoEntry : Key {
41 	Type*				type;
42 	ValueLocation*		location;
43 	InfoEntry*			next;
44 
45 	InfoEntry(ObjectID* variable, TypeComponentPath* path)
46 		:
47 		Key(variable, path),
48 		type(NULL),
49 		location(NULL)
50 	{
51 		variable->AcquireReference();
52 		path->AcquireReference();
53 	}
54 
55 	~InfoEntry()
56 	{
57 		SetInfo(NULL, NULL);
58 		variable->ReleaseReference();
59 		path->ReleaseReference();
60 	}
61 
62 
63 	void SetInfo(Type* type, ValueLocation* location)
64 	{
65 		if (type != NULL)
66 			type->AcquireReference();
67 		if (location != NULL)
68 			location->AcquireReference();
69 
70 		if (this->type != NULL)
71 			this->type->ReleaseReference();
72 		if (this->location != NULL)
73 			this->location->ReleaseReference();
74 
75 		this->type = type;
76 		this->location = location;
77 	}
78 };
79 
80 
81 struct StackFrameValueInfos::InfoEntryHashDefinition {
82 	typedef Key			KeyType;
83 	typedef	InfoEntry	ValueType;
84 
85 	size_t HashKey(const Key& key) const
86 	{
87 		return key.HashValue();
88 	}
89 
90 	size_t Hash(const InfoEntry* value) const
91 	{
92 		return value->HashValue();
93 	}
94 
95 	bool Compare(const Key& key, const InfoEntry* value) const
96 	{
97 		return key == *value;
98 	}
99 
100 	InfoEntry*& GetLink(InfoEntry* value) const
101 	{
102 		return value->next;
103 	}
104 };
105 
106 
107 StackFrameValueInfos::StackFrameValueInfos()
108 	:
109 	fValues(NULL)
110 {
111 }
112 
113 
114 StackFrameValueInfos::~StackFrameValueInfos()
115 {
116 	_Cleanup();
117 }
118 
119 
120 status_t
121 StackFrameValueInfos::Init()
122 {
123 	fValues = new(std::nothrow) ValueTable;
124 	if (fValues == NULL)
125 		return B_NO_MEMORY;
126 
127 	return fValues->Init();
128 }
129 
130 
131 bool
132 StackFrameValueInfos::GetInfo(ObjectID* variable,
133 	const TypeComponentPath* path, Type** _type,
134 	ValueLocation** _location) const
135 {
136 	InfoEntry* entry = fValues->Lookup(
137 		Key(variable, (TypeComponentPath*)path));
138 	if (entry == NULL)
139 		return false;
140 
141 	if (_type != NULL) {
142 		entry->type->AcquireReference();
143 		*_type = entry->type;
144 	}
145 
146 	if (_location != NULL) {
147 		entry->location->AcquireReference();
148 		*_location = entry->location;
149 	}
150 
151 	return true;
152 }
153 
154 
155 bool
156 StackFrameValueInfos::HasInfo(ObjectID* variable,
157 	const TypeComponentPath* path) const
158 {
159 	return fValues->Lookup(Key(variable, (TypeComponentPath*)path)) != NULL;
160 }
161 
162 
163 status_t
164 StackFrameValueInfos::SetInfo(ObjectID* variable, TypeComponentPath* path,
165 	Type* type, ValueLocation* location)
166 {
167 	InfoEntry* entry = fValues->Lookup(Key(variable, path));
168 	if (entry == NULL) {
169 		entry = new(std::nothrow) InfoEntry(variable, path);
170 		if (entry == NULL)
171 			return B_NO_MEMORY;
172 		fValues->Insert(entry);
173 	}
174 
175 	entry->SetInfo(type, location);
176 	return B_OK;
177 }
178 
179 
180 void
181 StackFrameValueInfos::_Cleanup()
182 {
183 	if (fValues != NULL) {
184 		InfoEntry* entry = fValues->Clear(true);
185 
186 		while (entry != NULL) {
187 			InfoEntry* next = entry->next;
188 			delete entry;
189 			entry = next;
190 		}
191 
192 		delete fValues;
193 		fValues = NULL;
194 	}
195 }
196