mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-22 05:13:22 +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*/)
|
void CustomTypeBase::throwIfFiledExist(const std::string &fieldName)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
bool fieldExist = false;
|
bool fieldExist = false;
|
||||||
try
|
try
|
||||||
@ -40,10 +22,71 @@ void CustomStruct::appendField(const std::string &fieldName, TypeInfoPtr fieldTy
|
|||||||
}
|
}
|
||||||
if (fieldExist)
|
if (fieldExist)
|
||||||
throw TypeException(getName(), "duplicate field name: " + fieldName);
|
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();
|
ULONG offset = getSize();
|
||||||
offset += offset % (m_align ? m_align : fieldType->getAlignReq());
|
offset += offset % (m_align ? m_align : fieldType->getAlignReq());
|
||||||
UdtFieldColl::push_back(
|
Base::push_back(
|
||||||
UdtUtils::Field(offset, fieldName, fieldType)
|
UdtUtils::Field(offset, fieldName, fieldType)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -73,20 +116,10 @@ ULONG CustomUnion::getSize()
|
|||||||
|
|
||||||
void CustomUnion::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
|
void CustomUnion::appendField(const std::string &fieldName, TypeInfoPtr fieldType)
|
||||||
{
|
{
|
||||||
bool fieldExist = false;
|
Base::throwIfFiledExist(fieldName);
|
||||||
try
|
Base::throwIfTypeRecursive(fieldType);
|
||||||
{
|
|
||||||
lookupField(fieldName);
|
|
||||||
fieldExist = true;
|
|
||||||
}
|
|
||||||
catch (const TypeException &except)
|
|
||||||
{
|
|
||||||
DBG_UNREFERENCED_PARAMETER(except);
|
|
||||||
}
|
|
||||||
if (fieldExist)
|
|
||||||
throw TypeException(getName(), "duplicate field name: " + fieldName);
|
|
||||||
|
|
||||||
UdtFieldColl::push_back(
|
Base::push_back(
|
||||||
UdtUtils::Field(0, fieldName, fieldType)
|
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:
|
public:
|
||||||
static TypeInfoPtr create(const std::string &name, ULONG align = 0);
|
static TypeInfoPtr create(const std::string &name, ULONG align = 0);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CustomStruct(const std::string &name, ULONG align)
|
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:
|
public:
|
||||||
static TypeInfoPtr create(const std::string &name);
|
static TypeInfoPtr create(const std::string &name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CustomUnion(const std::string &name) : UdtFieldColl(name) {}
|
CustomUnion(const std::string &name) : Base(name) {}
|
||||||
|
|
||||||
virtual ULONG getSize() override;
|
virtual ULONG getSize() override;
|
||||||
|
|
||||||
|
@ -211,6 +211,10 @@ public:
|
|||||||
return m_virtualBaseType;
|
return m_virtualBaseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is(TypeInfo *rhs) const {
|
||||||
|
return this == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
std::string getComplexName();
|
std::string getComplexName();
|
||||||
|
Loading…
Reference in New Issue
Block a user