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 15 struct 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 38 struct 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 58 struct 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 84 StackFrameValues::StackFrameValues() 85 : 86 fValues(NULL) 87 { 88 } 89 90 91 StackFrameValues::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 113 StackFrameValues::~StackFrameValues() 114 { 115 _Cleanup(); 116 } 117 118 119 status_t 120 StackFrameValues::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 130 bool 131 StackFrameValues::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 144 bool 145 StackFrameValues::HasValue(ObjectID* variable, const TypeComponentPath* path) 146 const 147 { 148 return fValues->Lookup(Key(variable, (TypeComponentPath*)path)) != NULL; 149 } 150 151 152 status_t 153 StackFrameValues::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 169 void 170 StackFrameValues::_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