184 lines
3.0 KiB
C++
184 lines
3.0 KiB
C++
/*
|
|||
|
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||
|
|
* Distributed under the terms of the MIT License.
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
#include "StackFrameValues.h"
|
||
|
|
|
||
|
|
#include <new>
|
||
|
|
|
||
|
|
#include "FunctionID.h"
|
||
|
|
#include "TypeComponentPath.h"
|
||
|
|
|
||
|
|
|
||
|
|
struct StackFrameValues::Key {
|
||
|
|
ObjectID* variable;
|
||
|
|
TypeComponentPath* path;
|
||
|
|
|
||
|
|
Key(ObjectID* variable, TypeComponentPath* path)
|
||
|
|
:
|
||
|
|
variable(variable),
|
||
|
|
path(path)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
uint32 HashValue() const
|
||
|
|
{
|
||
|
|
return variable->HashValue() ^ path->HashValue();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool operator==(const Key& other) const
|
||
|
|
{
|
||
|
|
return *variable == *other.variable && *path == *other.path;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
struct StackFrameValues::ValueEntry : Key, HashTableLink<ValueEntry> {
|
||
|
|
BVariant value;
|
||
|
|
|
||
|
|
ValueEntry(ObjectID* variable, TypeComponentPath* path)
|
||
|
|
:
|
||
|
|
Key(variable, path)
|
||
|
|
{
|
||
|
|
variable->AcquireReference();
|
||
|
|
path->AcquireReference();
|
||
|
|
}
|
||
|
|
|
||
|
|
~ValueEntry()
|
||
|
|
{
|
||
|
|
variable->ReleaseReference();
|
||
|
|
path->ReleaseReference();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
struct StackFrameValues::ValueEntryHashDefinition {
|
||
|
|
typedef Key KeyType;
|
||
|
|
typedef ValueEntry ValueType;
|
||
|
|
|
||
|
|
size_t HashKey(const Key& key) const
|
||
|
|
{
|
||
|
|
return key.HashValue();
|
||
|
|
}
|
||
|
|
|
||
|
|
size_t Hash(const ValueEntry* value) const
|
||
|
|
{
|
||
|
|
return value->HashValue();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool Compare(const Key& key, const ValueEntry* value) const
|
||
|
|
{
|
||
|
|
return key == *value;
|
||
|
|
}
|
||
|
|
|
||
|
|
HashTableLink<ValueEntry>* GetLink(ValueEntry* value) const
|
||
|
|
{
|
||
|
|
return value;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
StackFrameValues::StackFrameValues()
|
||
|
|
:
|
||
|
|
fValues(NULL)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
StackFrameValues::StackFrameValues(const StackFrameValues& other)
|
||
|
|
:
|
||
|
|
fValues(NULL)
|
||
|
|
{
|
||
|
|
try {
|
||
|
|
// init
|
||
|
|
if (Init() != B_OK)
|
||
|
|
throw std::bad_alloc();
|
||
|
|
|
||
|
|
// clone all values
|
||
|
|
for (ValueTable::Iterator it = other.fValues->GetIterator();
|
||
|
|
ValueEntry* entry = it.Next();) {
|
||
|
|
if (SetValue(entry->variable, entry->path, entry->value) != B_OK)
|
||
|
|
throw std::bad_alloc();
|
||
|
|
}
|
||
|
|
} catch (...) {
|
||
|
|
_Cleanup();
|
||
|
|
throw;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
StackFrameValues::~StackFrameValues()
|
||
|
|
{
|
||
|
|
_Cleanup();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
status_t
|
||
|
|
StackFrameValues::Init()
|
||
|
|
{
|
||
|
|
fValues = new(std::nothrow) ValueTable;
|
||
|
|
if (fValues == NULL)
|
||
|
|
return B_NO_MEMORY;
|
||
|
|
|
||
|
|
return fValues->Init();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
bool
|
||
|
|
StackFrameValues::GetValue(ObjectID* variable, const TypeComponentPath* path,
|
||
|
|
BVariant& _value) const
|
||
|
|
{
|
||
|
|
ValueEntry* entry = fValues->Lookup(
|
||
|
|
Key(variable, (TypeComponentPath*)path));
|
||
|
|
if (entry == NULL)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
_value = entry->value;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
bool
|
||
|
|
StackFrameValues::HasValue(ObjectID* variable, const TypeComponentPath* path)
|
||
|
|
const
|
||
|
|
{
|
||
|
|
return fValues->Lookup(Key(variable, (TypeComponentPath*)path)) != NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
status_t
|
||
|
|
StackFrameValues::SetValue(ObjectID* variable, TypeComponentPath* path,
|
||
|
|
const BVariant& value)
|
||
|
|
{
|
||
|
|
ValueEntry* entry = fValues->Lookup(Key(variable, path));
|
||
|
|
if (entry == NULL) {
|
||
|
|
entry = new(std::nothrow) ValueEntry(variable, path);
|
||
|
|
if (entry == NULL)
|
||
|
|
return B_NO_MEMORY;
|
||
|
|
fValues->Insert(entry);
|
||
|
|
}
|
||
|
|
|
||
|
|
entry->value = value;
|
||
|
|
return B_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void
|
||
|
|
StackFrameValues::_Cleanup()
|
||
|
|
{
|
||
|
|
if (fValues != NULL) {
|
||
|
|
ValueEntry* entry = fValues->Clear(true);
|
||
|
|
|
||
|
|
while (entry != NULL) {
|
||
|
|
ValueEntry* next = entry->fNext;
|
||
|
|
delete entry;
|
||
|
|
entry = next;
|
||
|
|
}
|
||
|
|
|
||
|
|
delete fValues;
|
||
|
|
fValues = NULL;
|
||
|
|
}
|
||
|
|
}
|