1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include "StackFrame.h"
7
8#include <new>
9
10#include "CpuState.h"
11#include "FunctionInstance.h"
12#include "Image.h"
13#include "StackFrameDebugInfo.h"
14#include "StackFrameValueInfos.h"
15#include "StackFrameValues.h"
16#include "Variable.h"
17
18
19// #pragma mark - StackFrame
20
21
22StackFrame::StackFrame(stack_frame_type type, CpuState* cpuState,
23	target_addr_t frameAddress, target_addr_t instructionPointer,
24	StackFrameDebugInfo* debugInfo)
25	:
26	fType(type),
27	fCpuState(cpuState),
28	fPreviousCpuState(NULL),
29	fFrameAddress(frameAddress),
30	fInstructionPointer(instructionPointer),
31	fReturnAddress(0),
32	fDebugInfo(debugInfo),
33	fImage(NULL),
34	fFunction(NULL),
35	fValues(NULL),
36	fValueInfos(NULL)
37{
38	fCpuState->AcquireReference();
39	fDebugInfo->AcquireReference();
40}
41
42
43StackFrame::~StackFrame()
44{
45	for (int32 i = 0; Variable* variable = fParameters.ItemAt(i); i++)
46		variable->ReleaseReference();
47
48	for (int32 i = 0; Variable* variable = fLocalVariables.ItemAt(i); i++)
49		variable->ReleaseReference();
50
51	SetImage(NULL);
52	SetFunction(NULL);
53	SetPreviousCpuState(NULL);
54
55	fDebugInfo->ReleaseReference();
56	fCpuState->ReleaseReference();
57
58	if (fValues != NULL)
59		fValues->ReleaseReference();
60
61	if (fValueInfos != NULL)
62		fValueInfos->ReleaseReference();
63}
64
65
66status_t
67StackFrame::Init()
68{
69	// create values map
70	fValues = new(std::nothrow) StackFrameValues;
71	if (fValues == NULL)
72		return B_NO_MEMORY;
73
74	status_t error = fValues->Init();
75	if (error != B_OK)
76		return error;
77
78	// create value infos map
79	fValueInfos = new(std::nothrow) StackFrameValueInfos;
80	if (fValueInfos == NULL)
81		return B_NO_MEMORY;
82
83	error = fValueInfos->Init();
84	if (error != B_OK)
85		return error;
86
87	return B_OK;
88}
89
90
91void
92StackFrame::SetPreviousCpuState(CpuState* state)
93{
94	if (fPreviousCpuState != NULL)
95		fPreviousCpuState->ReleaseReference();
96
97	fPreviousCpuState = state;
98
99	if (fPreviousCpuState != NULL)
100		fPreviousCpuState->AcquireReference();
101}
102
103void
104StackFrame::SetReturnAddress(target_addr_t address)
105{
106	fReturnAddress = address;
107}
108
109
110void
111StackFrame::SetImage(Image* image)
112{
113	if (fImage != NULL)
114		fImage->ReleaseReference();
115
116	fImage = image;
117
118	if (fImage != NULL)
119		fImage->AcquireReference();
120}
121
122
123void
124StackFrame::SetFunction(FunctionInstance* function)
125{
126	if (fFunction != NULL)
127		fFunction->ReleaseReference();
128
129	fFunction = function;
130
131	if (fFunction != NULL)
132		fFunction->AcquireReference();
133}
134
135
136int32
137StackFrame::CountParameters() const
138{
139	return fParameters.CountItems();
140}
141
142
143Variable*
144StackFrame::ParameterAt(int32 index) const
145{
146	return fParameters.ItemAt(index);
147}
148
149
150bool
151StackFrame::AddParameter(Variable* parameter)
152{
153	if (!fParameters.AddItem(parameter))
154		return false;
155
156	parameter->AcquireReference();
157	return true;
158}
159
160
161int32
162StackFrame::CountLocalVariables() const
163{
164	return fLocalVariables.CountItems();
165}
166
167
168Variable*
169StackFrame::LocalVariableAt(int32 index) const
170{
171	return fLocalVariables.ItemAt(index);
172}
173
174
175bool
176StackFrame::AddLocalVariable(Variable* variable)
177{
178	if (!fLocalVariables.AddItem(variable))
179		return false;
180
181	variable->AcquireReference();
182	return true;
183}
184
185
186void
187StackFrame::AddListener(Listener* listener)
188{
189	fListeners.Add(listener);
190}
191
192
193void
194StackFrame::RemoveListener(Listener* listener)
195{
196	fListeners.Remove(listener);
197}
198
199
200void
201StackFrame::NotifyValueRetrieved(Variable* variable, TypeComponentPath* path)
202{
203	for (ListenerList::Iterator it = fListeners.GetIterator();
204			Listener* listener = it.Next();) {
205		listener->StackFrameValueRetrieved(this, variable, path);
206	}
207}
208
209
210// #pragma mark - StackFrame
211
212
213StackFrame::Listener::~Listener()
214{
215}
216
217
218void
219StackFrame::Listener::StackFrameValueRetrieved(StackFrame* stackFrame,
220	Variable* variable, TypeComponentPath* path)
221{
222}
223