* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "StackFrame.h"
#include <new>
#include "CpuState.h"
#include "FunctionInstance.h"
#include "Image.h"
#include "StackFrameDebugInfo.h"
#include "StackFrameValueInfos.h"
#include "StackFrameValues.h"
#include "Variable.h"
StackFrame::StackFrame(stack_frame_type type, CpuState* cpuState,
target_addr_t frameAddress, target_addr_t instructionPointer,
StackFrameDebugInfo* debugInfo)
:
fType(type),
fCpuState(cpuState),
fPreviousCpuState(NULL),
fFrameAddress(frameAddress),
fInstructionPointer(instructionPointer),
fReturnAddress(0),
fDebugInfo(debugInfo),
fImage(NULL),
fFunction(NULL),
fValues(NULL),
fValueInfos(NULL)
{
fCpuState->AcquireReference();
fDebugInfo->AcquireReference();
}
StackFrame::~StackFrame()
{
for (int32 i = 0; Variable* variable = fParameters.ItemAt(i); i++)
variable->ReleaseReference();
for (int32 i = 0; Variable* variable = fLocalVariables.ItemAt(i); i++)
variable->ReleaseReference();
SetImage(NULL);
SetFunction(NULL);
SetPreviousCpuState(NULL);
fDebugInfo->ReleaseReference();
fCpuState->ReleaseReference();
if (fValues != NULL)
fValues->ReleaseReference();
if (fValueInfos != NULL)
fValueInfos->ReleaseReference();
}
status_t
StackFrame::Init()
{
fValues = new(std::nothrow) StackFrameValues;
if (fValues == NULL)
return B_NO_MEMORY;
status_t error = fValues->Init();
if (error != B_OK)
return error;
fValueInfos = new(std::nothrow) StackFrameValueInfos;
if (fValueInfos == NULL)
return B_NO_MEMORY;
error = fValueInfos->Init();
if (error != B_OK)
return error;
return B_OK;
}
void
StackFrame::SetPreviousCpuState(CpuState* state)
{
if (fPreviousCpuState != NULL)
fPreviousCpuState->ReleaseReference();
fPreviousCpuState = state;
if (fPreviousCpuState != NULL)
fPreviousCpuState->AcquireReference();
}
void
StackFrame::SetReturnAddress(target_addr_t address)
{
fReturnAddress = address;
}
void
StackFrame::SetImage(Image* image)
{
if (fImage != NULL)
fImage->ReleaseReference();
fImage = image;
if (fImage != NULL)
fImage->AcquireReference();
}
void
StackFrame::SetFunction(FunctionInstance* function)
{
if (fFunction != NULL)
fFunction->ReleaseReference();
fFunction = function;
if (fFunction != NULL)
fFunction->AcquireReference();
}
int32
StackFrame::CountParameters() const
{
return fParameters.CountItems();
}
Variable*
StackFrame::ParameterAt(int32 index) const
{
return fParameters.ItemAt(index);
}
bool
StackFrame::AddParameter(Variable* parameter)
{
if (!fParameters.AddItem(parameter))
return false;
parameter->AcquireReference();
return true;
}
int32
StackFrame::CountLocalVariables() const
{
return fLocalVariables.CountItems();
}
Variable*
StackFrame::LocalVariableAt(int32 index) const
{
return fLocalVariables.ItemAt(index);
}
bool
StackFrame::AddLocalVariable(Variable* variable)
{
if (!fLocalVariables.AddItem(variable))
return false;
variable->AcquireReference();
return true;
}
void
StackFrame::AddListener(Listener* listener)
{
fListeners.Add(listener);
}
void
StackFrame::RemoveListener(Listener* listener)
{
fListeners.Remove(listener);
}
void
StackFrame::NotifyValueRetrieved(Variable* variable, TypeComponentPath* path)
{
for (ListenerList::Iterator it = fListeners.GetIterator();
Listener* listener = it.Next();) {
listener->StackFrameValueRetrieved(this, variable, path);
}
}
StackFrame::Listener::~Listener()
{
}
void
StackFrame::Listener::StackFrameValueRetrieved(StackFrame* stackFrame,
Variable* variable, TypeComponentPath* path)
{
}