mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-20 03:23:23 +08:00
[0.2.x] ~ check recursive type building
git-svn-id: https://pykd.svn.codeplex.com/svn@79577 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
13b1676d6f
commit
bd94e142d1
@ -8,25 +8,7 @@ namespace pykd {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypeInfoPtr CustomStruct::create(const std::string &name, ULONG alignReq /*= 0*/)
|
||||
{
|
||||
return TypeInfoPtr( new CustomStruct(name, alignReq) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG CustomStruct::getSize()
|
||||
{
|
||||
if (UdtFieldColl::empty())
|
||||
return 0;
|
||||
|
||||
UdtUtils::Field &field = UdtFieldColl::last();
|
||||
return field.m_offset + field.m_type->getSize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
|
||||
void CustomTypeBase::throwIfFiledExist(const std::string &fieldName)
|
||||
{
|
||||
bool fieldExist = false;
|
||||
try
|
||||
@ -40,10 +22,71 @@ void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldTy
|
||||
}
|
||||
if (fieldExist)
|
||||
throw TypeException(getName(), "duplicate field name: " + fieldName);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CustomTypeBase::throwIfTypeRecursive(TypeInfoPtr type)
|
||||
{
|
||||
if (type->is(this))
|
||||
throw TypeException(getName(), "wrong type of field");
|
||||
|
||||
return throwIfTypeRecursiveImpl(type);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CustomTypeBase::throwIfTypeRecursiveImpl(TypeInfoPtr type)
|
||||
{
|
||||
if (type->isEnum())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
const ULONG fields = type->getFieldCount();
|
||||
for (ULONG i = 0; i < fields; ++i)
|
||||
{
|
||||
TypeInfoPtr fileldType = type->getFieldByIndex(i);
|
||||
if (fileldType->is(this))
|
||||
throw TypeException(getName(), "wrong type of field");
|
||||
|
||||
throwIfTypeRecursiveImpl(fileldType);
|
||||
}
|
||||
}
|
||||
catch (const TypeException &except)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypeInfoPtr CustomStruct::create(const std::string &name, ULONG alignReq /*= 0*/)
|
||||
{
|
||||
return TypeInfoPtr( new CustomStruct(name, alignReq) );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG CustomStruct::getSize()
|
||||
{
|
||||
if (Base::empty())
|
||||
return 0;
|
||||
|
||||
UdtUtils::Field &field = Base::last();
|
||||
return field.m_offset + field.m_type->getSize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
|
||||
{
|
||||
Base::throwIfFiledExist(fieldName);
|
||||
Base::throwIfTypeRecursive(fieldType);
|
||||
|
||||
ULONG offset = getSize();
|
||||
offset += offset % (m_align ? m_align : fieldType->getAlignReq());
|
||||
UdtFieldColl::push_back(
|
||||
Base::push_back(
|
||||
UdtUtils::Field(offset, fieldName, fieldType)
|
||||
);
|
||||
}
|
||||
@ -73,20 +116,10 @@ ULONG CustomUnion::getSize()
|
||||
|
||||
void CustomUnion::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
|
||||
{
|
||||
bool fieldExist = false;
|
||||
try
|
||||
{
|
||||
lookupField(fieldName);
|
||||
fieldExist = true;
|
||||
}
|
||||
catch (const TypeException &except)
|
||||
{
|
||||
DBG_UNREFERENCED_PARAMETER(except);
|
||||
}
|
||||
if (fieldExist)
|
||||
throw TypeException(getName(), "duplicate field name: " + fieldName);
|
||||
Base::throwIfFiledExist(fieldName);
|
||||
Base::throwIfTypeRecursive(fieldType);
|
||||
|
||||
UdtFieldColl::push_back(
|
||||
Base::push_back(
|
||||
UdtUtils::Field(0, fieldName, fieldType)
|
||||
);
|
||||
}
|
||||
|
@ -12,14 +12,30 @@ namespace pykd {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CustomStruct : public UdtFieldColl
|
||||
class CustomTypeBase : public UdtFieldColl
|
||||
{
|
||||
typedef UdtFieldColl Base;
|
||||
protected:
|
||||
CustomTypeBase(const std::string &name) : UdtFieldColl(name) {}
|
||||
|
||||
void throwIfFiledExist(const std::string &fieldName);
|
||||
void throwIfTypeRecursive(TypeInfoPtr type);
|
||||
|
||||
private:
|
||||
void throwIfTypeRecursiveImpl(TypeInfoPtr type);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CustomStruct : public CustomTypeBase
|
||||
{
|
||||
typedef CustomTypeBase Base;
|
||||
public:
|
||||
static TypeInfoPtr create(const std::string &name, ULONG align = 0);
|
||||
|
||||
protected:
|
||||
CustomStruct(const std::string &name, ULONG align)
|
||||
: UdtFieldColl(name), m_name(name), m_align(align)
|
||||
: Base(name), m_name(name), m_align(align)
|
||||
{
|
||||
}
|
||||
|
||||
@ -42,13 +58,14 @@ private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CustomUnion : public UdtFieldColl
|
||||
class CustomUnion : public CustomTypeBase
|
||||
{
|
||||
typedef CustomTypeBase Base;
|
||||
public:
|
||||
static TypeInfoPtr create(const std::string &name);
|
||||
|
||||
protected:
|
||||
CustomUnion(const std::string &name) : UdtFieldColl(name) {}
|
||||
CustomUnion(const std::string &name) : Base(name) {}
|
||||
|
||||
virtual ULONG getSize() override;
|
||||
|
||||
|
@ -211,6 +211,10 @@ public:
|
||||
return m_virtualBaseType;
|
||||
}
|
||||
|
||||
bool is(TypeInfo *rhs) const {
|
||||
return this == rhs;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
std::string getComplexName();
|
||||
|
Loading…
Reference in New Issue
Block a user