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