mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-29 07:22:07 +00:00
- added version check for member variables.
This commit is contained in:
parent
f9e543bed3
commit
8a5daf211c
7 changed files with 60 additions and 15 deletions
|
@ -1316,6 +1316,7 @@ PPointer::PPointer(PType *pointsat, bool isconst)
|
||||||
: PBasicType(sizeof(void *), alignof(void *)), PointedType(pointsat), IsConst(isconst)
|
: PBasicType(sizeof(void *), alignof(void *)), PointedType(pointsat), IsConst(isconst)
|
||||||
{
|
{
|
||||||
mDescriptiveName.Format("Pointer<%s%s>", pointsat->DescriptiveName(), isconst? "readonly " : "");
|
mDescriptiveName.Format("Pointer<%s%s>", pointsat->DescriptiveName(), isconst? "readonly " : "");
|
||||||
|
mVersion = pointsat->mVersion;
|
||||||
SetOps();
|
SetOps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1518,6 +1519,7 @@ PClassPointer::PClassPointer(PClass *restrict)
|
||||||
// This means we can use the cheapoer non-barriered opcodes here.
|
// This means we can use the cheapoer non-barriered opcodes here.
|
||||||
loadOp = OP_LOS;
|
loadOp = OP_LOS;
|
||||||
storeOp = OP_SP;
|
storeOp = OP_SP;
|
||||||
|
mVersion = restrict->mVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -2522,6 +2524,14 @@ PField::PField(FName name, PType *type, DWORD flags, size_t offset, int bitvalue
|
||||||
else BitValue = -1;
|
else BitValue = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VersionInfo PField::GetVersion()
|
||||||
|
{
|
||||||
|
VersionInfo Highest = { 0,0,0 };
|
||||||
|
if (!(Flags & VARF_Deprecated)) Highest = mVersion;
|
||||||
|
if (Type->mVersion > Highest) Highest = Type->mVersion;
|
||||||
|
return Highest;
|
||||||
|
}
|
||||||
|
|
||||||
/* PProperty *****************************************************************/
|
/* PProperty *****************************************************************/
|
||||||
|
|
||||||
IMPLEMENT_CLASS(PProperty, false, false)
|
IMPLEMENT_CLASS(PProperty, false, false)
|
||||||
|
|
|
@ -89,15 +89,25 @@ static const FLOP FxFlops[] =
|
||||||
{ NAME_TanH, FLOP_TANH, [](double v) { return g_tanh(v); } },
|
{ NAME_TanH, FLOP_TANH, [](double v) { return g_tanh(v); } },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FCompileContext
|
// FCompileContext
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FCompileContext::FCompileContext(PNamespace *cg, PFunction *fnc, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump)
|
FCompileContext::FCompileContext(PNamespace *cg, PFunction *fnc, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump, const VersionInfo &ver)
|
||||||
: ReturnProto(ret), Function(fnc), Class(nullptr), FromDecorate(fromdecorate), StateIndex(stateindex), StateCount(statecount), Lump(lump), CurGlobals(cg)
|
: ReturnProto(ret), Function(fnc), Class(nullptr), FromDecorate(fromdecorate), StateIndex(stateindex), StateCount(statecount), Lump(lump), CurGlobals(cg), Version(ver)
|
||||||
{
|
{
|
||||||
|
if (Version >= MakeVersion(2, 3))
|
||||||
|
{
|
||||||
|
VersionString.Format("ZScript version %d.%d.%d", Version.major, Version.minor, Version.revision);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VersionString = "DECORATE";
|
||||||
|
}
|
||||||
|
|
||||||
if (fnc != nullptr) Class = fnc->OwningClass;
|
if (fnc != nullptr) Class = fnc->OwningClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5955,6 +5965,15 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
|
||||||
}
|
}
|
||||||
else if (sym->IsKindOf(RUNTIME_CLASS(PField)))
|
else if (sym->IsKindOf(RUNTIME_CLASS(PField)))
|
||||||
{
|
{
|
||||||
|
PField *vsym = static_cast<PField*>(sym);
|
||||||
|
|
||||||
|
if (vsym->GetVersion() > ctx.Version)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "%s not accessible to %s", sym->SymbolName.GetChars(), ctx.VersionString.GetChars());
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// internally defined global variable
|
// internally defined global variable
|
||||||
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as global variable\n", Identifier.GetChars());
|
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as global variable\n", Identifier.GetChars());
|
||||||
newex = new FxGlobalVariable(static_cast<PField *>(sym), ScriptPosition);
|
newex = new FxGlobalVariable(static_cast<PField *>(sym), ScriptPosition);
|
||||||
|
@ -6014,7 +6033,8 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PStruct *classct
|
||||||
if (!objtype->IsKindOf(RUNTIME_CLASS(PClassActor)))
|
if (!objtype->IsKindOf(RUNTIME_CLASS(PClassActor)))
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "'Default' requires an actor type.");
|
ScriptPosition.Message(MSG_ERROR, "'Default' requires an actor type.");
|
||||||
delete this;
|
delete object;
|
||||||
|
object = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6036,19 +6056,28 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PStruct *classct
|
||||||
else if (sym->IsKindOf(RUNTIME_CLASS(PField)))
|
else if (sym->IsKindOf(RUNTIME_CLASS(PField)))
|
||||||
{
|
{
|
||||||
PField *vsym = static_cast<PField*>(sym);
|
PField *vsym = static_cast<PField*>(sym);
|
||||||
|
if (vsym->GetVersion() > ctx.Version)
|
||||||
// We have 4 cases to consider here:
|
{
|
||||||
// 1. The symbol is a static/meta member (not implemented yet) which is always accessible.
|
ScriptPosition.Message(MSG_ERROR, "%s not accessible to %s", sym->SymbolName.GetChars(), ctx.VersionString.GetChars());
|
||||||
// 2. This is a static function
|
delete object;
|
||||||
// 3. This is an action function with a restricted self pointer
|
object = nullptr;
|
||||||
// 4. This is a normal member or unrestricted action function.
|
return nullptr;
|
||||||
if (vsym->Flags & VARF_Deprecated && !ctx.FromDecorate)
|
}
|
||||||
|
if ((vsym->Flags & VARF_Deprecated) && sym->mVersion >= ctx.Version)
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_WARNING, "Accessing deprecated member variable %s", vsym->SymbolName.GetChars());
|
ScriptPosition.Message(MSG_WARNING, "Accessing deprecated member variable %s", vsym->SymbolName.GetChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We have 4 cases to consider here:
|
||||||
|
// 1. The symbol is a static/meta member which is always accessible.
|
||||||
|
// 2. This is a static function
|
||||||
|
// 3. This is an action function with a restricted self pointer
|
||||||
|
// 4. This is a normal member or unrestricted action function.
|
||||||
if ((vsym->Flags & VARF_Private) && symtbl != &classctx->Symbols)
|
if ((vsym->Flags & VARF_Private) && symtbl != &classctx->Symbols)
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "Private member %s not accessible", vsym->SymbolName.GetChars());
|
ScriptPosition.Message(MSG_ERROR, "Private member %s not accessible", vsym->SymbolName.GetChars());
|
||||||
|
delete object;
|
||||||
|
object = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
PClass* cls_ctx = dyn_cast<PClass>(classctx);
|
PClass* cls_ctx = dyn_cast<PClass>(classctx);
|
||||||
|
@ -6060,6 +6089,8 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PStruct *classct
|
||||||
if (!cls_ctx || !cls_target)
|
if (!cls_ctx || !cls_target)
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "Protected member %s not accessible", vsym->SymbolName.GetChars());
|
ScriptPosition.Message(MSG_ERROR, "Protected member %s not accessible", vsym->SymbolName.GetChars());
|
||||||
|
delete object;
|
||||||
|
object = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6079,6 +6110,8 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PStruct *classct
|
||||||
if (!cls_ctx->IsDescendantOf(cls_target))
|
if (!cls_ctx->IsDescendantOf(cls_target))
|
||||||
{
|
{
|
||||||
ScriptPosition.Message(MSG_ERROR, "Protected member %s not accessible", vsym->SymbolName.GetChars());
|
ScriptPosition.Message(MSG_ERROR, "Protected member %s not accessible", vsym->SymbolName.GetChars());
|
||||||
|
delete object;
|
||||||
|
object = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,8 +86,10 @@ struct FCompileContext
|
||||||
bool Unsafe = false;
|
bool Unsafe = false;
|
||||||
TDeletingArray<FxLocalVariableDeclaration *> FunctionArgs;
|
TDeletingArray<FxLocalVariableDeclaration *> FunctionArgs;
|
||||||
PNamespace *CurGlobals;
|
PNamespace *CurGlobals;
|
||||||
|
VersionInfo Version;
|
||||||
|
FString VersionString;
|
||||||
|
|
||||||
FCompileContext(PNamespace *spc, PFunction *func, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump);
|
FCompileContext(PNamespace *spc, PFunction *func, PPrototype *ret, bool fromdecorate, int stateindex, int statecount, int lump, const VersionInfo &ver);
|
||||||
FCompileContext(PNamespace *spc, PStruct *cls, bool fromdecorate); // only to be used to resolve constants!
|
FCompileContext(PNamespace *spc, PStruct *cls, bool fromdecorate); // only to be used to resolve constants!
|
||||||
|
|
||||||
PSymbol *FindInClass(FName identifier, PSymbolTable *&symt);
|
PSymbol *FindInClass(FName identifier, PSymbolTable *&symt);
|
||||||
|
|
|
@ -857,7 +857,7 @@ void FFunctionBuildList::Build()
|
||||||
assert(item.Code != NULL);
|
assert(item.Code != NULL);
|
||||||
|
|
||||||
// We don't know the return type in advance for anonymous functions.
|
// We don't know the return type in advance for anonymous functions.
|
||||||
FCompileContext ctx(item.CurGlobals, item.Func, item.Func->SymbolName == NAME_None ? nullptr : item.Func->Variants[0].Proto, item.FromDecorate, item.StateIndex, item.StateCount, item.Lump);
|
FCompileContext ctx(item.CurGlobals, item.Func, item.Func->SymbolName == NAME_None ? nullptr : item.Func->Variants[0].Proto, item.FromDecorate, item.StateIndex, item.StateCount, item.Lump, item.Version);
|
||||||
|
|
||||||
// Allocate registers for the function's arguments and create local variable nodes before starting to resolve it.
|
// Allocate registers for the function's arguments and create local variable nodes before starting to resolve it.
|
||||||
VMFunctionBuilder buildit(item.Func->GetImplicitArgs());
|
VMFunctionBuilder buildit(item.Func->GetImplicitArgs());
|
||||||
|
|
|
@ -77,6 +77,7 @@ class PField : public PSymbol
|
||||||
HAS_OBJECT_POINTERS
|
HAS_OBJECT_POINTERS
|
||||||
public:
|
public:
|
||||||
PField(FName name, PType *type, uint32_t flags = 0, size_t offset = 0, int bitvalue = 0);
|
PField(FName name, PType *type, uint32_t flags = 0, size_t offset = 0, int bitvalue = 0);
|
||||||
|
VersionInfo GetVersion();
|
||||||
|
|
||||||
size_t Offset;
|
size_t Offset;
|
||||||
PType *Type;
|
PType *Type;
|
||||||
|
|
|
@ -1030,7 +1030,7 @@ decl_flags(X) ::= decl_flags(F) DEPRECATED(B) LPAREN STRCONST(A) RPAREN.
|
||||||
X->Version = A.String->GetChars();
|
X->Version = A.String->GetChars();
|
||||||
}
|
}
|
||||||
|
|
||||||
decl_flags(X) ::= decl_flags(F) VERSION(B) LPAREN STRINGCONST(A) RPAREN.
|
decl_flags(X) ::= decl_flags(F) VERSION(B) LPAREN STRCONST(A) RPAREN.
|
||||||
{
|
{
|
||||||
if (F == nullptr)
|
if (F == nullptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -386,8 +386,7 @@ static void DoParse(int lumpnum)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state.ParseVersion.major = 2; // 2.3 is the first version of ZScript.
|
state.ParseVersion = MakeVersion(2, 3); // 2.3 is the first version of ZScript.
|
||||||
state.ParseVersion.minor = 3;
|
|
||||||
sc.RestorePos(saved);
|
sc.RestorePos(saved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue