mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-25 21:51:09 +00:00
Supposedly implemented a write check between ui/play/data
This commit is contained in:
parent
8b0dee6f66
commit
a7a4406bb1
2 changed files with 46 additions and 5 deletions
|
@ -6706,11 +6706,28 @@ bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable)
|
|||
AddressRequested = true;
|
||||
if (writable != nullptr)
|
||||
{
|
||||
*writable = (AddressWritable && !ctx.CheckWritable(membervar->Flags) &&
|
||||
// [ZZ] original check.
|
||||
bool bWritable = (AddressWritable && !ctx.CheckWritable(membervar->Flags) &&
|
||||
(!classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) || !static_cast<PPointer*>(classx->ValueType)->IsConst));
|
||||
// [ZZ] self in a const function is not writable.
|
||||
if (bWritable) // don't do complex checks on early fail
|
||||
{
|
||||
if ((classx->ExprType == EFX_Self) && (ctx.Function && (ctx.Function->Variants[0].Flags & VARF_ReadOnly)))
|
||||
*writable = false;
|
||||
bWritable = false;
|
||||
}
|
||||
// [ZZ] plain data "inherits" scope of whatever it was defined in.
|
||||
if (bWritable) // don't do complex checks on early fail
|
||||
{
|
||||
if (ctx.Function && FString(ctx.Function->SymbolName) == FString("DrawPowerup"))
|
||||
Printf("field type = %d\n", BarrierSide);
|
||||
int outerflags = 0;
|
||||
if (ctx.Function)
|
||||
outerflags = ctx.Function->Variants[0].Flags;
|
||||
FScopeBarrier scopeBarrier(outerflags, FScopeBarrier::FlagsFromSide(BarrierSide), membervar->SymbolName.GetChars());
|
||||
if (!scopeBarrier.writable)
|
||||
bWritable = false;
|
||||
}
|
||||
*writable = bWritable;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -6741,6 +6758,15 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
|
|||
return x->Resolve(ctx);
|
||||
}
|
||||
|
||||
// [ZZ] support magic
|
||||
BarrierSide = FScopeBarrier::SideFromFlags(membervar->Flags);
|
||||
if (classx->ExprType == EFX_StructMember || classx->ExprType == EFX_ClassMember)
|
||||
{
|
||||
FxStructMember* pmember = (FxStructMember*)classx;
|
||||
if (BarrierSide == FScopeBarrier::Side_PlainData && pmember)
|
||||
BarrierSide = pmember->BarrierSide;
|
||||
}
|
||||
|
||||
if (classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)))
|
||||
{
|
||||
PPointer *ptrtype = dyn_cast<PPointer>(classx->ValueType);
|
||||
|
|
|
@ -93,7 +93,7 @@ struct FScopeBarrier
|
|||
int sidelast;
|
||||
|
||||
// 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.
|
||||
int SideFromFlags(int flags)
|
||||
static int SideFromFlags(int flags)
|
||||
{
|
||||
if (flags & VARF_UI)
|
||||
return Side_UI;
|
||||
|
@ -102,8 +102,22 @@ struct FScopeBarrier
|
|||
return Side_PlainData;
|
||||
}
|
||||
|
||||
//
|
||||
static int FlagsFromSide(int side)
|
||||
{
|
||||
switch (side)
|
||||
{
|
||||
case Side_Play:
|
||||
return VARF_Play;
|
||||
case Side_UI:
|
||||
return VARF_UI;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// used for errors
|
||||
const char* StringFromSide(int side)
|
||||
static const char* StringFromSide(int side)
|
||||
{
|
||||
switch (side)
|
||||
{
|
||||
|
@ -1451,6 +1465,7 @@ public:
|
|||
PField *membervar;
|
||||
bool AddressRequested = false;
|
||||
bool AddressWritable = true;
|
||||
int BarrierSide = -1; // [ZZ] some magic
|
||||
FxMemberBase(EFxType type, PField *f, const FScriptPosition &p);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue