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 17 struct 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 40 struct 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 81 struct 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 107 StackFrameValueInfos::StackFrameValueInfos() 108 : 109 fValues(NULL) 110 { 111 } 112 113 114 StackFrameValueInfos::~StackFrameValueInfos() 115 { 116 _Cleanup(); 117 } 118 119 120 status_t 121 StackFrameValueInfos::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 131 bool 132 StackFrameValueInfos::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 155 bool 156 StackFrameValueInfos::HasInfo(ObjectID* variable, 157 const TypeComponentPath* path) const 158 { 159 return fValues->Lookup(Key(variable, (TypeComponentPath*)path)) != NULL; 160 } 161 162 163 status_t 164 StackFrameValueInfos::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 180 void 181 StackFrameValueInfos::_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