mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 00:21:43 +00:00
Did some cleanup - since FScopeBarrier is not in codegen now, it's possible to include it properly from vm.h
This commit is contained in:
parent
456ac64723
commit
8400961a00
5 changed files with 32 additions and 38 deletions
|
@ -89,37 +89,6 @@ static const FLOP FxFlops[] =
|
||||||
{ NAME_TanH, FLOP_TANH, [](double v) { return g_tanh(v); } },
|
{ NAME_TanH, FLOP_TANH, [](double v) { return g_tanh(v); } },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// [ZZ] Magic methods to be used in vmexec.h for runtime checking of scope
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
// this can be imported in vmexec.h
|
|
||||||
void FScopeBarrier_ValidateNew(PClass* cls, PFunction* callingfunc)
|
|
||||||
{
|
|
||||||
int outerside = callingfunc->Variants.Size() ? FScopeBarrier::SideFromFlags(callingfunc->Variants[0].Flags) : FScopeBarrier::Side_Virtual;
|
|
||||||
if (outerside == FScopeBarrier::Side_Virtual)
|
|
||||||
outerside = FScopeBarrier::SideFromObjectFlags(callingfunc->OwningClass->ObjectFlags);
|
|
||||||
int innerside = FScopeBarrier::SideFromObjectFlags(cls->ObjectFlags);
|
|
||||||
if ((outerside != innerside) && (innerside != FScopeBarrier::Side_PlainData)) // "cannot construct ui class ... from data context"
|
|
||||||
ThrowAbortException(X_OTHER, "Cannot construct %s class %s from %s context", FScopeBarrier::StringFromSide(innerside), cls->TypeName.GetChars(), FScopeBarrier::StringFromSide(outerside));
|
|
||||||
}
|
|
||||||
// this can be imported in vmexec.h
|
|
||||||
void FScopeBarrier_ValidateCall(PFunction* calledfunc, PFunction* callingfunc, PClass* selftype)
|
|
||||||
{
|
|
||||||
// [ZZ] anonymous blocks have 0 variants, so give them Side_Virtual.
|
|
||||||
int outerside = callingfunc->Variants.Size() ? FScopeBarrier::SideFromFlags(callingfunc->Variants[0].Flags) : FScopeBarrier::Side_Virtual;
|
|
||||||
if (outerside == FScopeBarrier::Side_Virtual)
|
|
||||||
outerside = FScopeBarrier::SideFromObjectFlags(callingfunc->OwningClass->ObjectFlags);
|
|
||||||
int innerside = FScopeBarrier::SideFromFlags(calledfunc->Variants[0].Flags);
|
|
||||||
if (innerside == FScopeBarrier::Side_Virtual)
|
|
||||||
innerside = FScopeBarrier::SideFromObjectFlags(selftype->ObjectFlags);
|
|
||||||
if ((outerside != innerside) && (innerside != FScopeBarrier::Side_PlainData))
|
|
||||||
ThrowAbortException(X_OTHER, "Cannot call %s function %s from %s context", FScopeBarrier::StringFromSide(innerside), calledfunc->SymbolName.GetChars(), FScopeBarrier::StringFromSide(outerside));
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FCompileContext
|
// FCompileContext
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "scopebarrier.h"
|
|
||||||
#include "dobject.h"
|
#include "dobject.h"
|
||||||
|
#include "scopebarrier.h"
|
||||||
|
|
||||||
|
|
||||||
// Note: the same object can't be both UI and Play. This is checked explicitly in the field construction and will cause esoteric errors here if found.
|
// Note: the same object can't be both UI and Play. This is checked explicitly in the field construction and will cause esoteric errors here if found.
|
||||||
|
@ -171,3 +171,27 @@ void FScopeBarrier::AddFlags(int flags1, int flags2, const char* name)
|
||||||
if (name) callerror.Format("Can't call %s function %s from %s context", StringFromSide(sideto), name, StringFromSide(sidefrom));
|
if (name) callerror.Format("Can't call %s function %s from %s context", StringFromSide(sideto), name, StringFromSide(sidefrom));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// these are for vmexec.h
|
||||||
|
void FScopeBarrier::ValidateNew(PClass* cls, PFunction* callingfunc)
|
||||||
|
{
|
||||||
|
int outerside = callingfunc->Variants.Size() ? FScopeBarrier::SideFromFlags(callingfunc->Variants[0].Flags) : FScopeBarrier::Side_Virtual;
|
||||||
|
if (outerside == FScopeBarrier::Side_Virtual)
|
||||||
|
outerside = FScopeBarrier::SideFromObjectFlags(callingfunc->OwningClass->ObjectFlags);
|
||||||
|
int innerside = FScopeBarrier::SideFromObjectFlags(cls->ObjectFlags);
|
||||||
|
if ((outerside != innerside) && (innerside != FScopeBarrier::Side_PlainData)) // "cannot construct ui class ... from data context"
|
||||||
|
ThrowAbortException(X_OTHER, "Cannot construct %s class %s from %s context", FScopeBarrier::StringFromSide(innerside), cls->TypeName.GetChars(), FScopeBarrier::StringFromSide(outerside));
|
||||||
|
}
|
||||||
|
// this can be imported in vmexec.h
|
||||||
|
void FScopeBarrier::ValidateCall(PFunction* calledfunc, PFunction* callingfunc, PClass* selftype)
|
||||||
|
{
|
||||||
|
// [ZZ] anonymous blocks have 0 variants, so give them Side_Virtual.
|
||||||
|
int outerside = callingfunc->Variants.Size() ? FScopeBarrier::SideFromFlags(callingfunc->Variants[0].Flags) : FScopeBarrier::Side_Virtual;
|
||||||
|
if (outerside == FScopeBarrier::Side_Virtual)
|
||||||
|
outerside = FScopeBarrier::SideFromObjectFlags(callingfunc->OwningClass->ObjectFlags);
|
||||||
|
int innerside = FScopeBarrier::SideFromFlags(calledfunc->Variants[0].Flags);
|
||||||
|
if (innerside == FScopeBarrier::Side_Virtual)
|
||||||
|
innerside = FScopeBarrier::SideFromObjectFlags(selftype->ObjectFlags);
|
||||||
|
if ((outerside != innerside) && (innerside != FScopeBarrier::Side_PlainData))
|
||||||
|
ThrowAbortException(X_OTHER, "Cannot call %s function %s from %s context", FScopeBarrier::StringFromSide(innerside), calledfunc->SymbolName.GetChars(), FScopeBarrier::StringFromSide(outerside));
|
||||||
|
}
|
|
@ -51,5 +51,9 @@ struct FScopeBarrier
|
||||||
// This is used for comparing a.b.c.d access - if non-allowed field is seen anywhere in the chain, anything after it is non-allowed.
|
// This is used for comparing a.b.c.d access - if non-allowed field is seen anywhere in the chain, anything after it is non-allowed.
|
||||||
// This struct is used so that the logic is in a single place.
|
// This struct is used so that the logic is in a single place.
|
||||||
void AddFlags(int flags1, int flags2, const char* name);
|
void AddFlags(int flags1, int flags2, const char* name);
|
||||||
|
|
||||||
|
// this is called from vmexec.h
|
||||||
|
static void ValidateNew(PClass* cls, PFunction* callingfunc);
|
||||||
|
static void ValidateCall(PFunction* calledfunc, PFunction* callingfunc, PClass* selftype);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,8 @@
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "doomerrors.h"
|
#include "doomerrors.h"
|
||||||
#include "memarena.h"
|
#include "memarena.h"
|
||||||
|
#include "scripting/backend/scopebarrier.h"
|
||||||
|
|
||||||
// [ZZ] there are serious circular references between this and the rest of ZScript code, so it needs to be done like this
|
|
||||||
// these are used in vmexec.h
|
|
||||||
void FScopeBarrier_ValidateNew(PClass* cls, PFunction* callingfunc);
|
|
||||||
void FScopeBarrier_ValidateCall(PFunction* calledfunc, PFunction* callingfunc, PClass* selftype);
|
|
||||||
class DObject;
|
class DObject;
|
||||||
|
|
||||||
extern FMemArena ClassDataAllocator;
|
extern FMemArena ClassDataAllocator;
|
||||||
|
|
|
@ -673,7 +673,7 @@ begin:
|
||||||
PFunction* callingfunc = (PFunction*)(reg.param + f->NumParam - b)[1].a;
|
PFunction* callingfunc = (PFunction*)(reg.param + f->NumParam - b)[1].a;
|
||||||
DObject* dobj = (DObject*)(reg.param + f->NumParam - b)[2].a; // this is the self pointer. it should be in, since Side_Virtual functions are always non-static methods.
|
DObject* dobj = (DObject*)(reg.param + f->NumParam - b)[2].a; // this is the self pointer. it should be in, since Side_Virtual functions are always non-static methods.
|
||||||
PClass* selftype = dobj->GetClass();
|
PClass* selftype = dobj->GetClass();
|
||||||
FScopeBarrier_ValidateCall(calledfunc, callingfunc, selftype);
|
FScopeBarrier::ValidateCall(calledfunc, callingfunc, selftype);
|
||||||
b -= 2;
|
b -= 2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -821,7 +821,7 @@ begin:
|
||||||
if (cls->ObjectFlags & OF_Abstract) ThrowAbortException(X_OTHER, "Cannot instantiate abstract class %s", cls->TypeName.GetChars());
|
if (cls->ObjectFlags & OF_Abstract) ThrowAbortException(X_OTHER, "Cannot instantiate abstract class %s", cls->TypeName.GetChars());
|
||||||
// [ZZ] validate readonly and between scope construction
|
// [ZZ] validate readonly and between scope construction
|
||||||
if (callingfunc)
|
if (callingfunc)
|
||||||
FScopeBarrier_ValidateNew(cls, callingfunc);
|
FScopeBarrier::ValidateNew(cls, callingfunc);
|
||||||
reg.a[a] = cls->CreateNew();
|
reg.a[a] = cls->CreateNew();
|
||||||
reg.atag[a] = ATAG_OBJECT;
|
reg.atag[a] = ATAG_OBJECT;
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
|
|
Loading…
Reference in a new issue