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