1fce4895dSRene Gollent /*
2fce4895dSRene Gollent * Copyright 2012-2015, Rene Gollent, rene@gollent.com
3fce4895dSRene Gollent * Distributed under the terms of the MIT License.
4fce4895dSRene Gollent */
5fce4895dSRene Gollent
6fce4895dSRene Gollent
7fce4895dSRene Gollent #include "BListValueNode.h"
8fce4895dSRene Gollent
9fce4895dSRene Gollent #include <new>
10fce4895dSRene Gollent
11fce4895dSRene Gollent #include <AutoDeleter.h>
12fce4895dSRene Gollent
13fce4895dSRene Gollent #include "AddressValueNode.h"
14fce4895dSRene Gollent #include "Architecture.h"
15fce4895dSRene Gollent #include "StringValue.h"
16fce4895dSRene Gollent #include "TeamTypeInformation.h"
17fce4895dSRene Gollent #include "Tracing.h"
18fce4895dSRene Gollent #include "Type.h"
19fce4895dSRene Gollent #include "TypeLookupConstraints.h"
20fce4895dSRene Gollent #include "ValueLoader.h"
21fce4895dSRene Gollent #include "ValueLocation.h"
22fce4895dSRene Gollent #include "ValueNodeContainer.h"
23fce4895dSRene Gollent
24fce4895dSRene Gollent
25fce4895dSRene Gollent // maximum number of array elements to show by default
26fce4895dSRene Gollent static const int64 kMaxArrayElementCount = 20;
27fce4895dSRene Gollent
28fce4895dSRene Gollent
29fce4895dSRene Gollent //#pragma mark - BListValueNode::BListElementNodeChild
30fce4895dSRene Gollent
31fce4895dSRene Gollent
32fce4895dSRene Gollent class BListValueNode::BListElementNodeChild : public ValueNodeChild {
33fce4895dSRene Gollent public:
34fce4895dSRene Gollent BListElementNodeChild(BListValueNode* parent,
35fce4895dSRene Gollent int64 elementIndex, Type* type);
36fce4895dSRene Gollent virtual ~BListElementNodeChild();
37fce4895dSRene Gollent
Name() const38fce4895dSRene Gollent virtual const BString& Name() const { return fName; };
GetType() const39fce4895dSRene Gollent virtual Type* GetType() const { return fType; };
Parent() const40fce4895dSRene Gollent virtual ValueNode* Parent() const { return fParent; };
41fce4895dSRene Gollent
42fce4895dSRene Gollent virtual status_t ResolveLocation(ValueLoader* valueLoader,
43fce4895dSRene Gollent ValueLocation*& _location);
44fce4895dSRene Gollent
45fce4895dSRene Gollent private:
46fce4895dSRene Gollent Type* fType;
47fce4895dSRene Gollent BListValueNode* fParent;
48fce4895dSRene Gollent int64 fElementIndex;
49fce4895dSRene Gollent BString fName;
50fce4895dSRene Gollent };
51fce4895dSRene Gollent
52fce4895dSRene Gollent
BListElementNodeChild(BListValueNode * parent,int64 elementIndex,Type * type)53fce4895dSRene Gollent BListValueNode::BListElementNodeChild::BListElementNodeChild(
54fce4895dSRene Gollent BListValueNode* parent, int64 elementIndex, Type* type)
55fce4895dSRene Gollent :
56fce4895dSRene Gollent ValueNodeChild(),
57fce4895dSRene Gollent fType(type),
58fce4895dSRene Gollent fParent(parent),
59fce4895dSRene Gollent fElementIndex(elementIndex),
60fce4895dSRene Gollent fName()
61fce4895dSRene Gollent {
62fce4895dSRene Gollent fType->AcquireReference();
63fce4895dSRene Gollent fParent->AcquireReference();
64fce4895dSRene Gollent fName.SetToFormat("[%" B_PRId64 "]", fElementIndex);
65fce4895dSRene Gollent }
66fce4895dSRene Gollent
67fce4895dSRene Gollent
~BListElementNodeChild()68fce4895dSRene Gollent BListValueNode::BListElementNodeChild::~BListElementNodeChild()
69fce4895dSRene Gollent {
70fce4895dSRene Gollent fType->ReleaseReference();
71fce4895dSRene Gollent fParent->ReleaseReference();
72fce4895dSRene Gollent }
73fce4895dSRene Gollent
74fce4895dSRene Gollent
75fce4895dSRene Gollent status_t
ResolveLocation(ValueLoader * valueLoader,ValueLocation * & _location)76fce4895dSRene Gollent BListValueNode::BListElementNodeChild::ResolveLocation(
77fce4895dSRene Gollent ValueLoader* valueLoader, ValueLocation*& _location)
78fce4895dSRene Gollent {
79fce4895dSRene Gollent uint8 addressSize = valueLoader->GetArchitecture()->AddressSize();
80fce4895dSRene Gollent ValueLocation* location = new(std::nothrow) ValueLocation();
81fce4895dSRene Gollent if (location == NULL)
82fce4895dSRene Gollent return B_NO_MEMORY;
83fce4895dSRene Gollent
84fce4895dSRene Gollent
85fce4895dSRene Gollent uint64 listAddress = fParent->fDataLocation.ToUInt64();
86fce4895dSRene Gollent listAddress += fElementIndex * addressSize;
87fce4895dSRene Gollent
88fce4895dSRene Gollent ValuePieceLocation piece;
89fce4895dSRene Gollent piece.SetToMemory(listAddress);
90fce4895dSRene Gollent piece.SetSize(addressSize);
91fce4895dSRene Gollent location->AddPiece(piece);
92fce4895dSRene Gollent
93fce4895dSRene Gollent _location = location;
94fce4895dSRene Gollent return B_OK;
95fce4895dSRene Gollent }
96fce4895dSRene Gollent
97fce4895dSRene Gollent
98fce4895dSRene Gollent //#pragma mark - BListItemCountNodeChild
99fce4895dSRene Gollent
100fce4895dSRene Gollent class BListValueNode::BListItemCountNodeChild : public ValueNodeChild {
101fce4895dSRene Gollent public:
102fce4895dSRene Gollent BListItemCountNodeChild(BVariant location,
103fce4895dSRene Gollent BListValueNode* parent, Type* type);
104fce4895dSRene Gollent virtual ~BListItemCountNodeChild();
105fce4895dSRene Gollent
Name() const106fce4895dSRene Gollent virtual const BString& Name() const { return fName; };
GetType() const107fce4895dSRene Gollent virtual Type* GetType() const { return fType; };
Parent() const108fce4895dSRene Gollent virtual ValueNode* Parent() const { return fParent; };
109fce4895dSRene Gollent
110fce4895dSRene Gollent virtual status_t ResolveLocation(ValueLoader* valueLoader,
111fce4895dSRene Gollent ValueLocation*& _location);
112fce4895dSRene Gollent
113fce4895dSRene Gollent private:
114fce4895dSRene Gollent Type* fType;
115fce4895dSRene Gollent BListValueNode* fParent;
116fce4895dSRene Gollent BVariant fLocation;
117fce4895dSRene Gollent BString fName;
118fce4895dSRene Gollent };
119fce4895dSRene Gollent
120fce4895dSRene Gollent
BListItemCountNodeChild(BVariant location,BListValueNode * parent,Type * type)121fce4895dSRene Gollent BListValueNode::BListItemCountNodeChild::BListItemCountNodeChild(
122fce4895dSRene Gollent BVariant location, BListValueNode* parent, Type* type)
123fce4895dSRene Gollent :
124fce4895dSRene Gollent ValueNodeChild(),
125fce4895dSRene Gollent fType(type),
126fce4895dSRene Gollent fParent(parent),
127fce4895dSRene Gollent fLocation(location),
128fce4895dSRene Gollent fName("Capacity")
129fce4895dSRene Gollent {
130fce4895dSRene Gollent fType->AcquireReference();
131fce4895dSRene Gollent fParent->AcquireReference();
132fce4895dSRene Gollent }
133fce4895dSRene Gollent
134fce4895dSRene Gollent
~BListItemCountNodeChild()135fce4895dSRene Gollent BListValueNode::BListItemCountNodeChild::~BListItemCountNodeChild()
136fce4895dSRene Gollent {
137fce4895dSRene Gollent fType->ReleaseReference();
138fce4895dSRene Gollent fParent->ReleaseReference();
139fce4895dSRene Gollent }
140fce4895dSRene Gollent
141fce4895dSRene Gollent
142fce4895dSRene Gollent status_t
ResolveLocation(ValueLoader * valueLoader,ValueLocation * & _location)143fce4895dSRene Gollent BListValueNode::BListItemCountNodeChild::ResolveLocation(
144fce4895dSRene Gollent ValueLoader* valueLoader, ValueLocation*& _location)
145fce4895dSRene Gollent {
146fce4895dSRene Gollent ValueLocation* location = new(std::nothrow) ValueLocation();
147fce4895dSRene Gollent if (location == NULL)
148fce4895dSRene Gollent return B_NO_MEMORY;
149fce4895dSRene Gollent
150fce4895dSRene Gollent ValuePieceLocation piece;
151fce4895dSRene Gollent piece.SetToMemory(fLocation.ToUInt64());
152fce4895dSRene Gollent piece.SetSize(sizeof(int32));
153fce4895dSRene Gollent location->AddPiece(piece);
154fce4895dSRene Gollent
155fce4895dSRene Gollent _location = location;
156fce4895dSRene Gollent return B_OK;
157fce4895dSRene Gollent }
158fce4895dSRene Gollent
159fce4895dSRene Gollent
160fce4895dSRene Gollent //#pragma mark - BListValueNode
161fce4895dSRene Gollent
BListValueNode(ValueNodeChild * nodeChild,Type * type)162fce4895dSRene Gollent BListValueNode::BListValueNode(ValueNodeChild* nodeChild,
163fce4895dSRene Gollent Type* type)
164fce4895dSRene Gollent :
165fce4895dSRene Gollent ValueNode(nodeChild),
166fce4895dSRene Gollent fType(type),
167fce4895dSRene Gollent fItemCountType(NULL),
168fce4895dSRene Gollent fItemCount(0),
169fce4895dSRene Gollent fCountChildCreated(false)
170fce4895dSRene Gollent {
171fce4895dSRene Gollent fType->AcquireReference();
172fce4895dSRene Gollent }
173fce4895dSRene Gollent
174fce4895dSRene Gollent
~BListValueNode()175fce4895dSRene Gollent BListValueNode::~BListValueNode()
176fce4895dSRene Gollent {
177fce4895dSRene Gollent fType->ReleaseReference();
178fce4895dSRene Gollent for (int32 i = 0; i < fChildren.CountItems(); i++)
179fce4895dSRene Gollent fChildren.ItemAt(i)->ReleaseReference();
180fce4895dSRene Gollent
181fce4895dSRene Gollent if (fItemCountType != NULL)
182fce4895dSRene Gollent fItemCountType->ReleaseReference();
183fce4895dSRene Gollent }
184fce4895dSRene Gollent
185fce4895dSRene Gollent
186fce4895dSRene Gollent Type*
GetType() const187fce4895dSRene Gollent BListValueNode::GetType() const
188fce4895dSRene Gollent {
189fce4895dSRene Gollent return fType;
190fce4895dSRene Gollent }
191fce4895dSRene Gollent
192fce4895dSRene Gollent
193fce4895dSRene Gollent status_t
ResolvedLocationAndValue(ValueLoader * valueLoader,ValueLocation * & _location,Value * & _value)194fce4895dSRene Gollent BListValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
195fce4895dSRene Gollent ValueLocation*& _location, Value*& _value)
196fce4895dSRene Gollent {
197fce4895dSRene Gollent // get the location
198fce4895dSRene Gollent ValueLocation* location = NodeChild()->Location();
199fce4895dSRene Gollent if (location == NULL)
200fce4895dSRene Gollent return B_BAD_VALUE;
201fce4895dSRene Gollent
202fce4895dSRene Gollent
203fce4895dSRene Gollent // get the value type
204fce4895dSRene Gollent type_code valueType;
205fce4895dSRene Gollent if (valueLoader->GetArchitecture()->AddressSize() == 4) {
206fce4895dSRene Gollent valueType = B_UINT32_TYPE;
207fce4895dSRene Gollent TRACE_LOCALS(" -> 32 bit\n");
208fce4895dSRene Gollent } else {
209fce4895dSRene Gollent valueType = B_UINT64_TYPE;
210fce4895dSRene Gollent TRACE_LOCALS(" -> 64 bit\n");
211fce4895dSRene Gollent }
212fce4895dSRene Gollent
213fce4895dSRene Gollent // load the value data
214fce4895dSRene Gollent
215fce4895dSRene Gollent status_t error = B_OK;
216fce4895dSRene Gollent
217fce4895dSRene Gollent ValueLocation* memberLocation = NULL;
218fce4895dSRene Gollent CompoundType* baseType = dynamic_cast<CompoundType*>(fType);
219fce4895dSRene Gollent
220fce4895dSRene Gollent if (baseType->CountTemplateParameters() != 0) {
221fce4895dSRene Gollent // for BObjectList we need to walk up
222fce4895dSRene Gollent // the hierarchy: BObjectList -> _PointerList_ -> BList
223fce4895dSRene Gollent if (baseType->CountBaseTypes() == 0)
224fce4895dSRene Gollent return B_BAD_DATA;
225fce4895dSRene Gollent
226fce4895dSRene Gollent baseType = dynamic_cast<CompoundType*>(baseType->BaseTypeAt(0)
227fce4895dSRene Gollent ->GetType());
228fce4895dSRene Gollent if (baseType == NULL || baseType->Name() != "_PointerList_")
229fce4895dSRene Gollent return B_BAD_DATA;
230fce4895dSRene Gollent
231fce4895dSRene Gollent if (baseType->CountBaseTypes() == 0)
232fce4895dSRene Gollent return B_BAD_DATA;
233fce4895dSRene Gollent
234fce4895dSRene Gollent baseType = dynamic_cast<CompoundType*>(baseType->BaseTypeAt(0)
235fce4895dSRene Gollent ->GetType());
236fce4895dSRene Gollent if (baseType == NULL || baseType->Name() != "BList")
237fce4895dSRene Gollent return B_BAD_DATA;
238fce4895dSRene Gollent
239fce4895dSRene Gollent }
240fce4895dSRene Gollent
241fce4895dSRene Gollent for (int32 i = 0; i < baseType->CountDataMembers(); i++) {
242fce4895dSRene Gollent DataMember* member = baseType->DataMemberAt(i);
243fce4895dSRene Gollent if (strcmp(member->Name(), "fObjectList") == 0) {
244fce4895dSRene Gollent error = baseType->ResolveDataMemberLocation(member,
245fce4895dSRene Gollent *location, memberLocation);
246fce4895dSRene Gollent BReference<ValueLocation> locationRef(memberLocation, true);
247fce4895dSRene Gollent if (error != B_OK) {
248fce4895dSRene Gollent TRACE_LOCALS(
249fce4895dSRene Gollent "BListValueNode::ResolvedLocationAndValue(): "
250fce4895dSRene Gollent "failed to resolve location of header member: %s\n",
251fce4895dSRene Gollent strerror(error));
252fce4895dSRene Gollent return error;
253fce4895dSRene Gollent }
254fce4895dSRene Gollent
255fce4895dSRene Gollent error = valueLoader->LoadValue(memberLocation, valueType,
256fce4895dSRene Gollent false, fDataLocation);
257fce4895dSRene Gollent if (error != B_OK)
258fce4895dSRene Gollent return error;
259fce4895dSRene Gollent } else if (strcmp(member->Name(), "fItemCount") == 0) {
260fce4895dSRene Gollent error = baseType->ResolveDataMemberLocation(member,
261fce4895dSRene Gollent *location, memberLocation);
262fce4895dSRene Gollent BReference<ValueLocation> locationRef(memberLocation, true);
263fce4895dSRene Gollent if (error != B_OK) {
264fce4895dSRene Gollent TRACE_LOCALS(
265fce4895dSRene Gollent "BListValueNode::ResolvedLocationAndValue(): "
266fce4895dSRene Gollent "failed to resolve location of header member: %s\n",
267fce4895dSRene Gollent strerror(error));
268fce4895dSRene Gollent return error;
269fce4895dSRene Gollent }
270fce4895dSRene Gollent
271fce4895dSRene Gollent fItemCountType = member->GetType();
272fce4895dSRene Gollent fItemCountType->AcquireReference();
273fce4895dSRene Gollent
274fce4895dSRene Gollent fItemCountLocation = memberLocation->PieceAt(0).address;
275fce4895dSRene Gollent
276fce4895dSRene Gollent BVariant listSize;
277*ffe684b9SRene Gollent error = valueLoader->LoadValue(memberLocation, B_INT32_TYPE,
278fce4895dSRene Gollent false, listSize);
279fce4895dSRene Gollent if (error != B_OK)
280fce4895dSRene Gollent return error;
281fce4895dSRene Gollent
282fce4895dSRene Gollent fItemCount = listSize.ToInt32();
283fce4895dSRene Gollent TRACE_LOCALS(
284fce4895dSRene Gollent "BListValueNode::ResolvedLocationAndValue(): "
285fce4895dSRene Gollent "detected list size %" B_PRId32 "\n",
286fce4895dSRene Gollent fItemCount);
287fce4895dSRene Gollent }
288fce4895dSRene Gollent memberLocation = NULL;
289fce4895dSRene Gollent }
290fce4895dSRene Gollent
2913995592cSRene Gollent location->AcquireReference();
2923995592cSRene Gollent _location = location;
2933995592cSRene Gollent _value = NULL;
2943995592cSRene Gollent
295fce4895dSRene Gollent return B_OK;
296fce4895dSRene Gollent }
297fce4895dSRene Gollent
298fce4895dSRene Gollent
299fce4895dSRene Gollent status_t
CreateChildren(TeamTypeInformation * info)300fce4895dSRene Gollent BListValueNode::CreateChildren(TeamTypeInformation* info)
301fce4895dSRene Gollent {
302fce4895dSRene Gollent return CreateChildrenInRange(info, 0, kMaxArrayElementCount);
303fce4895dSRene Gollent }
304fce4895dSRene Gollent
305fce4895dSRene Gollent
306fce4895dSRene Gollent int32
CountChildren() const307fce4895dSRene Gollent BListValueNode::CountChildren() const
308fce4895dSRene Gollent {
309fce4895dSRene Gollent return fChildren.CountItems();
310fce4895dSRene Gollent }
311fce4895dSRene Gollent
312fce4895dSRene Gollent
313fce4895dSRene Gollent ValueNodeChild*
ChildAt(int32 index) const314fce4895dSRene Gollent BListValueNode::ChildAt(int32 index) const
315fce4895dSRene Gollent {
316fce4895dSRene Gollent return fChildren.ItemAt(index);
317fce4895dSRene Gollent }
318fce4895dSRene Gollent
319fce4895dSRene Gollent
320fce4895dSRene Gollent bool
IsRangedContainer() const321fce4895dSRene Gollent BListValueNode::IsRangedContainer() const
322fce4895dSRene Gollent {
323fce4895dSRene Gollent return true;
324fce4895dSRene Gollent }
325fce4895dSRene Gollent
326fce4895dSRene Gollent
327fce4895dSRene Gollent bool
IsContainerRangeFixed() const328fce4895dSRene Gollent BListValueNode::IsContainerRangeFixed() const
329fce4895dSRene Gollent {
330fce4895dSRene Gollent return true;
331fce4895dSRene Gollent }
332fce4895dSRene Gollent
333fce4895dSRene Gollent
334fce4895dSRene Gollent void
ClearChildren()335fce4895dSRene Gollent BListValueNode::ClearChildren()
336fce4895dSRene Gollent {
337fce4895dSRene Gollent fChildren.MakeEmpty();
338fce4895dSRene Gollent fCountChildCreated = false;
339fce4895dSRene Gollent if (fContainer != NULL)
340fce4895dSRene Gollent fContainer->NotifyValueNodeChildrenDeleted(this);
341fce4895dSRene Gollent }
342fce4895dSRene Gollent
343fce4895dSRene Gollent
344fce4895dSRene Gollent status_t
CreateChildrenInRange(TeamTypeInformation * info,int32 lowIndex,int32 highIndex)345fce4895dSRene Gollent BListValueNode::CreateChildrenInRange(TeamTypeInformation* info,
346fce4895dSRene Gollent int32 lowIndex, int32 highIndex)
347fce4895dSRene Gollent {
348fce4895dSRene Gollent if (fLocationResolutionState != B_OK)
349fce4895dSRene Gollent return fLocationResolutionState;
350fce4895dSRene Gollent
351fce4895dSRene Gollent if (lowIndex < 0)
352fce4895dSRene Gollent lowIndex = 0;
353fce4895dSRene Gollent if (highIndex >= fItemCount)
354fce4895dSRene Gollent highIndex = fItemCount - 1;
355fce4895dSRene Gollent
356fce4895dSRene Gollent if (!fCountChildCreated && fItemCountType != NULL) {
357fce4895dSRene Gollent BListItemCountNodeChild* countChild = new(std::nothrow)
358fce4895dSRene Gollent BListItemCountNodeChild(fItemCountLocation, this, fItemCountType);
359fce4895dSRene Gollent
360fce4895dSRene Gollent if (countChild == NULL)
361fce4895dSRene Gollent return B_NO_MEMORY;
362fce4895dSRene Gollent
363fce4895dSRene Gollent fCountChildCreated = true;
364fce4895dSRene Gollent countChild->SetContainer(fContainer);
365fce4895dSRene Gollent fChildren.AddItem(countChild);
366fce4895dSRene Gollent }
367fce4895dSRene Gollent
368fce4895dSRene Gollent BReference<Type> addressTypeRef;
369fce4895dSRene Gollent Type* type = NULL;
370fce4895dSRene Gollent CompoundType* objectType = dynamic_cast<CompoundType*>(fType);
371fce4895dSRene Gollent if (objectType->CountTemplateParameters() != 0) {
372fce4895dSRene Gollent AddressType* addressType = NULL;
373fce4895dSRene Gollent status_t result = objectType->TemplateParameterAt(0)->GetType()
374fce4895dSRene Gollent ->CreateDerivedAddressType(DERIVED_TYPE_POINTER, addressType);
375fce4895dSRene Gollent if (result != B_OK)
376fce4895dSRene Gollent return result;
377fce4895dSRene Gollent
378fce4895dSRene Gollent type = addressType;
379fce4895dSRene Gollent addressTypeRef.SetTo(type, true);
380fce4895dSRene Gollent } else {
381fce4895dSRene Gollent BString typeName;
382fce4895dSRene Gollent TypeLookupConstraints constraints;
383fce4895dSRene Gollent constraints.SetTypeKind(TYPE_ADDRESS);
384fce4895dSRene Gollent constraints.SetBaseTypeName("void");
385fce4895dSRene Gollent status_t result = info->LookupTypeByName(typeName, constraints,
386fce4895dSRene Gollent type);
387fce4895dSRene Gollent if (result != B_OK)
388fce4895dSRene Gollent return result;
389fce4895dSRene Gollent }
390fce4895dSRene Gollent
391fce4895dSRene Gollent for (int32 i = lowIndex; i <= highIndex; i++)
392fce4895dSRene Gollent {
393fce4895dSRene Gollent BListElementNodeChild* child =
394fce4895dSRene Gollent new(std::nothrow) BListElementNodeChild(this, i, type);
395fce4895dSRene Gollent if (child == NULL)
396fce4895dSRene Gollent return B_NO_MEMORY;
397fce4895dSRene Gollent child->SetContainer(fContainer);
398fce4895dSRene Gollent fChildren.AddItem(child);
399fce4895dSRene Gollent }
400fce4895dSRene Gollent
401fce4895dSRene Gollent fChildrenCreated = true;
402fce4895dSRene Gollent
403fce4895dSRene Gollent if (fContainer != NULL)
404fce4895dSRene Gollent fContainer->NotifyValueNodeChildrenCreated(this);
405fce4895dSRene Gollent
406fce4895dSRene Gollent return B_OK;
407fce4895dSRene Gollent }
408fce4895dSRene Gollent
409fce4895dSRene Gollent
410fce4895dSRene Gollent status_t
SupportedChildRange(int32 & lowIndex,int32 & highIndex) const411fce4895dSRene Gollent BListValueNode::SupportedChildRange(int32& lowIndex, int32& highIndex) const
412fce4895dSRene Gollent {
413fce4895dSRene Gollent lowIndex = 0;
414fce4895dSRene Gollent highIndex = fItemCount - 1;
415fce4895dSRene Gollent
416fce4895dSRene Gollent return B_OK;
417fce4895dSRene Gollent }
418fce4895dSRene Gollent
419