mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-31 22:00:48 +00:00
- split PPointer into PPointer and PObjectPointer.
A pointer to an object has quite different semantics so let's do this with proper virtual inheritance. This should allow to simplify a lot of pointer related checks in the compiler.
This commit is contained in:
parent
80801d11b1
commit
bc486904cd
2 changed files with 94 additions and 49 deletions
130
src/dobjtype.cpp
130
src/dobjtype.cpp
|
@ -1338,7 +1338,10 @@ PPointer::PPointer()
|
||||||
: PBasicType(sizeof(void *), alignof(void *)), PointedType(nullptr), IsConst(false)
|
: PBasicType(sizeof(void *), alignof(void *)), PointedType(nullptr), IsConst(false)
|
||||||
{
|
{
|
||||||
mDescriptiveName = "NullPointer";
|
mDescriptiveName = "NullPointer";
|
||||||
SetOps();
|
loadOp = OP_LP;
|
||||||
|
storeOp = OP_SP;
|
||||||
|
moveOp = OP_MOVEA;
|
||||||
|
RegType = REGT_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1352,20 +1355,8 @@ PPointer::PPointer(PType *pointsat, bool isconst)
|
||||||
{
|
{
|
||||||
mDescriptiveName.Format("Pointer<%s%s>", pointsat->DescriptiveName(), isconst? "readonly " : "");
|
mDescriptiveName.Format("Pointer<%s%s>", pointsat->DescriptiveName(), isconst? "readonly " : "");
|
||||||
mVersion = pointsat->mVersion;
|
mVersion = pointsat->mVersion;
|
||||||
SetOps();
|
loadOp = OP_LP;
|
||||||
}
|
storeOp = OP_SP;
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// PPointer :: GetStoreOp
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void PPointer::SetOps()
|
|
||||||
{
|
|
||||||
loadOp = (PointedType && PointedType->IsKindOf(RUNTIME_CLASS(PClass))) ? OP_LO : OP_LP;
|
|
||||||
// Non-destroyed thinkers are always guaranteed to be linked into the thinker chain so we don't need the write barrier for them.
|
|
||||||
storeOp = (loadOp == OP_LO && !static_cast<PClass*>(PointedType)->IsDescendantOf(RUNTIME_CLASS(DThinker))) ? OP_SO : OP_SP;
|
|
||||||
moveOp = OP_MOVEA;
|
moveOp = OP_MOVEA;
|
||||||
RegType = REGT_POINTER;
|
RegType = REGT_POINTER;
|
||||||
}
|
}
|
||||||
|
@ -1396,21 +1387,6 @@ void PPointer::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
|
||||||
id2 = 0;
|
id2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// PPointer :: SetPointer
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void PPointer::SetPointer(void *base, unsigned offset, TArray<size_t> *special) const
|
|
||||||
{
|
|
||||||
if (PointedType != nullptr && PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
|
|
||||||
{
|
|
||||||
// Add to the list of pointers for this class.
|
|
||||||
special->Push(offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// PPointer :: WriteValue
|
// PPointer :: WriteValue
|
||||||
|
@ -1419,11 +1395,7 @@ void PPointer::SetPointer(void *base, unsigned offset, TArray<size_t> *special)
|
||||||
|
|
||||||
void PPointer::WriteValue(FSerializer &ar, const char *key,const void *addr) const
|
void PPointer::WriteValue(FSerializer &ar, const char *key,const void *addr) const
|
||||||
{
|
{
|
||||||
if (PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
|
if (writer != nullptr)
|
||||||
{
|
|
||||||
ar(key, *(DObject **)addr);
|
|
||||||
}
|
|
||||||
else if (writer != nullptr)
|
|
||||||
{
|
{
|
||||||
writer(ar, key, addr);
|
writer(ar, key, addr);
|
||||||
}
|
}
|
||||||
|
@ -1441,19 +1413,67 @@ void PPointer::WriteValue(FSerializer &ar, const char *key,const void *addr) con
|
||||||
|
|
||||||
bool PPointer::ReadValue(FSerializer &ar, const char *key, void *addr) const
|
bool PPointer::ReadValue(FSerializer &ar, const char *key, void *addr) const
|
||||||
{
|
{
|
||||||
if (PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
|
if (reader != nullptr)
|
||||||
{
|
|
||||||
bool res;
|
|
||||||
::Serialize(ar, key, *(DObject **)addr, nullptr, &res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
else if (reader != nullptr)
|
|
||||||
{
|
{
|
||||||
return reader(ar, key, addr);
|
return reader(ar, key, addr);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PObjectPointer **********************************************************/
|
||||||
|
|
||||||
|
IMPLEMENT_CLASS(PObjectPointer, false, false)
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// PPointer :: GetStoreOp
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
PObjectPointer::PObjectPointer(PClass *cls, bool isconst)
|
||||||
|
: PPointer(cls, isconst)
|
||||||
|
{
|
||||||
|
loadOp = OP_LO;
|
||||||
|
// Non-destroyed thinkers are always guaranteed to be linked into the thinker chain so we don't need the write barrier for them.
|
||||||
|
if (cls && !cls->IsDescendantOf(RUNTIME_CLASS(DThinker))) storeOp = OP_SO;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// PPointer :: SetPointer
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void PObjectPointer::SetPointer(void *base, unsigned offset, TArray<size_t> *special) const
|
||||||
|
{
|
||||||
|
// Add to the list of pointers for this class.
|
||||||
|
special->Push(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// PPointer :: WriteValue
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void PObjectPointer::WriteValue(FSerializer &ar, const char *key, const void *addr) const
|
||||||
|
{
|
||||||
|
ar(key, *(DObject **)addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// PPointer :: ReadValue
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool PObjectPointer::ReadValue(FSerializer &ar, const char *key, void *addr) const
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
::Serialize(ar, key, *(DObject **)addr, nullptr, &res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// NewPointer
|
// NewPointer
|
||||||
|
@ -1464,14 +1484,28 @@ bool PPointer::ReadValue(FSerializer &ar, const char *key, void *addr) const
|
||||||
|
|
||||||
PPointer *NewPointer(PType *type, bool isconst)
|
PPointer *NewPointer(PType *type, bool isconst)
|
||||||
{
|
{
|
||||||
size_t bucket;
|
if (type->IsKindOf(RUNTIME_CLASS(PClass)))
|
||||||
PType *ptype = TypeTable.FindType(RUNTIME_CLASS(PPointer), (intptr_t)type, isconst ? 1 : 0, &bucket);
|
|
||||||
if (ptype == nullptr)
|
|
||||||
{
|
{
|
||||||
ptype = new PPointer(type, isconst);
|
size_t bucket;
|
||||||
TypeTable.AddType(ptype, RUNTIME_CLASS(PPointer), (intptr_t)type, isconst ? 1 : 0, bucket);
|
PType *ptype = TypeTable.FindType(RUNTIME_CLASS(PObjectPointer), (intptr_t)type, isconst ? 1 : 0, &bucket);
|
||||||
|
if (ptype == nullptr)
|
||||||
|
{
|
||||||
|
ptype = new PObjectPointer(static_cast<PClass*>(type), isconst);
|
||||||
|
TypeTable.AddType(ptype, RUNTIME_CLASS(PObjectPointer), (intptr_t)type, isconst ? 1 : 0, bucket);
|
||||||
|
}
|
||||||
|
return static_cast<PPointer *>(ptype);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t bucket;
|
||||||
|
PType *ptype = TypeTable.FindType(RUNTIME_CLASS(PPointer), (intptr_t)type, isconst ? 1 : 0, &bucket);
|
||||||
|
if (ptype == nullptr)
|
||||||
|
{
|
||||||
|
ptype = new PPointer(type, isconst);
|
||||||
|
TypeTable.AddType(ptype, RUNTIME_CLASS(PPointer), (intptr_t)type, isconst ? 1 : 0, bucket);
|
||||||
|
}
|
||||||
|
return static_cast<PPointer *>(ptype);
|
||||||
}
|
}
|
||||||
return static_cast<PPointer *>(ptype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PStatePointer **********************************************************/
|
/* PStatePointer **********************************************************/
|
||||||
|
|
|
@ -400,7 +400,6 @@ public:
|
||||||
|
|
||||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||||
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override;
|
|
||||||
|
|
||||||
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
||||||
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
||||||
|
@ -420,6 +419,18 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class PObjectPointer : public PPointer
|
||||||
|
{
|
||||||
|
DECLARE_CLASS(PObjectPointer, PPointer);
|
||||||
|
public:
|
||||||
|
PObjectPointer(PClass *pointedtype = nullptr, bool isconst = false);
|
||||||
|
|
||||||
|
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
|
||||||
|
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
|
||||||
|
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class PClassPointer : public PPointer
|
class PClassPointer : public PPointer
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(PClassPointer, PPointer);
|
DECLARE_CLASS(PClassPointer, PPointer);
|
||||||
|
|
Loading…
Reference in a new issue