mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +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)
|
||||
{
|
||||
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 " : "");
|
||||
mVersion = pointsat->mVersion;
|
||||
SetOps();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// 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;
|
||||
loadOp = OP_LP;
|
||||
storeOp = OP_SP;
|
||||
moveOp = OP_MOVEA;
|
||||
RegType = REGT_POINTER;
|
||||
}
|
||||
|
@ -1396,21 +1387,6 @@ void PPointer::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
|
|||
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
|
||||
|
@ -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
|
||||
{
|
||||
if (PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
|
||||
{
|
||||
ar(key, *(DObject **)addr);
|
||||
}
|
||||
else if (writer != nullptr)
|
||||
if (writer != nullptr)
|
||||
{
|
||||
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
|
||||
{
|
||||
if (PointedType->IsKindOf(RUNTIME_CLASS(PClass)))
|
||||
{
|
||||
bool res;
|
||||
::Serialize(ar, key, *(DObject **)addr, nullptr, &res);
|
||||
return res;
|
||||
}
|
||||
else if (reader != nullptr)
|
||||
if (reader != nullptr)
|
||||
{
|
||||
return reader(ar, key, addr);
|
||||
}
|
||||
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
|
||||
|
@ -1464,14 +1484,28 @@ bool PPointer::ReadValue(FSerializer &ar, const char *key, void *addr) const
|
|||
|
||||
PPointer *NewPointer(PType *type, bool isconst)
|
||||
{
|
||||
size_t bucket;
|
||||
PType *ptype = TypeTable.FindType(RUNTIME_CLASS(PPointer), (intptr_t)type, isconst ? 1 : 0, &bucket);
|
||||
if (ptype == nullptr)
|
||||
if (type->IsKindOf(RUNTIME_CLASS(PClass)))
|
||||
{
|
||||
ptype = new PPointer(type, isconst);
|
||||
TypeTable.AddType(ptype, RUNTIME_CLASS(PPointer), (intptr_t)type, isconst ? 1 : 0, bucket);
|
||||
size_t 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 **********************************************************/
|
||||
|
|
|
@ -400,7 +400,6 @@ public:
|
|||
|
||||
virtual bool IsMatch(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;
|
||||
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
|
||||
{
|
||||
DECLARE_CLASS(PClassPointer, PPointer);
|
||||
|
|
Loading…
Reference in a new issue