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
17struct 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
40struct 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
81struct 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
107StackFrameValueInfos::StackFrameValueInfos()
108	:
109	fValues(NULL)
110{
111}
112
113
114StackFrameValueInfos::~StackFrameValueInfos()
115{
116	_Cleanup();
117}
118
119
120status_t
121StackFrameValueInfos::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
131bool
132StackFrameValueInfos::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
155bool
156StackFrameValueInfos::HasInfo(ObjectID* variable,
157	const TypeComponentPath* path) const
158{
159	return fValues->Lookup(Key(variable, (TypeComponentPath*)path)) != NULL;
160}
161
162
163status_t
164StackFrameValueInfos::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
180void
181StackFrameValueInfos::_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