mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
- added version checks for function calls and virtual overrides.
- restricted the UI functions in inventory.
This commit is contained in:
parent
8a5daf211c
commit
2b5fea4ea8
5 changed files with 53 additions and 15 deletions
|
@ -388,7 +388,7 @@ bool FxExpression::isConstant() const
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
VMFunction *FxExpression::GetDirectFunction()
|
VMFunction *FxExpression::GetDirectFunction(const VersionInfo &ver)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -6065,6 +6065,7 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PStruct *classct
|
||||||
}
|
}
|
||||||
if ((vsym->Flags & VARF_Deprecated) && sym->mVersion >= ctx.Version)
|
if ((vsym->Flags & VARF_Deprecated) && sym->mVersion >= ctx.Version)
|
||||||
{
|
{
|
||||||
|
ScriptPosition.Message(MSG_WARNING, "Accessing deprecated member variable %s - deprecated since %d.%d.%d", sym->SymbolName.GetChars(), vsym->mVersion.major, vsym->mVersion.minor, vsym->mVersion.revision);
|
||||||
ScriptPosition.Message(MSG_WARNING, "Accessing deprecated member variable %s", vsym->SymbolName.GetChars());
|
ScriptPosition.Message(MSG_WARNING, "Accessing deprecated member variable %s", vsym->SymbolName.GetChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8495,19 +8496,44 @@ PPrototype *FxVMFunctionCall::ReturnProto()
|
||||||
return Function->Variants[0].Proto;
|
return Function->Variants[0].Proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FxVMFunctionCall::CheckAccessibility(const VersionInfo &ver)
|
||||||
|
{
|
||||||
|
if (Function->mVersion > ver && !(Function->Variants[0].Flags & VARF_Deprecated))
|
||||||
|
{
|
||||||
|
FString VersionString;
|
||||||
|
if (ver >= MakeVersion(2, 3))
|
||||||
|
{
|
||||||
|
VersionString.Format("ZScript version %d.%d.%d", ver.major, ver.minor, ver.revision);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VersionString = "DECORATE";
|
||||||
|
}
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "%s not accessible to %s", Function->SymbolName.GetChars(), VersionString.GetChars());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((Function->Variants[0].Flags & VARF_Deprecated) && Function->mVersion >= ver)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_WARNING, "Accessing deprecated function %s - deprecated since %d.%d.%d", Function->SymbolName.GetChars(), Function->mVersion.major, Function->mVersion.minor, Function->mVersion.revision);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
VMFunction *FxVMFunctionCall::GetDirectFunction()
|
VMFunction *FxVMFunctionCall::GetDirectFunction(const VersionInfo &ver)
|
||||||
{
|
{
|
||||||
// If this return statement calls a non-virtual function with no arguments,
|
// If this return statement calls a non-virtual function with no arguments,
|
||||||
// then it can be a "direct" function. That is, the DECORATE
|
// then it can be a "direct" function. That is, the DECORATE
|
||||||
// definition can call that function directly without wrapping
|
// definition can call that function directly without wrapping
|
||||||
// it inside VM code.
|
// it inside VM code.
|
||||||
if (ArgList.Size() == 0 && !(Function->Variants[0].Flags & VARF_Virtual))
|
|
||||||
|
if (ArgList.Size() == 0 && !(Function->Variants[0].Flags & VARF_Virtual) && CheckAccessibility(ver))
|
||||||
{
|
{
|
||||||
unsigned imp = Function->GetImplicitArgs();
|
unsigned imp = Function->GetImplicitArgs();
|
||||||
if (Function->Variants[0].ArgFlags.Size() > imp && !(Function->Variants[0].ArgFlags[imp] & VARF_Optional)) return nullptr;
|
if (Function->Variants[0].ArgFlags.Size() > imp && !(Function->Variants[0].ArgFlags[imp] & VARF_Optional)) return nullptr;
|
||||||
|
@ -8536,6 +8562,11 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
|
|
||||||
int implicit = Function->GetImplicitArgs();
|
int implicit = Function->GetImplicitArgs();
|
||||||
|
|
||||||
|
if (!CheckAccessibility(ctx.Version))
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// This should never happen.
|
// This should never happen.
|
||||||
if (Self == nullptr && (Function->Variants[0].Flags & VARF_Method))
|
if (Self == nullptr && (Function->Variants[0].Flags & VARF_Method))
|
||||||
{
|
{
|
||||||
|
@ -9372,11 +9403,11 @@ ExpEmit FxSequence::Emit(VMFunctionBuilder *build)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
VMFunction *FxSequence::GetDirectFunction()
|
VMFunction *FxSequence::GetDirectFunction(const VersionInfo &ver)
|
||||||
{
|
{
|
||||||
if (Expressions.Size() == 1)
|
if (Expressions.Size() == 1)
|
||||||
{
|
{
|
||||||
return Expressions[0]->GetDirectFunction();
|
return Expressions[0]->GetDirectFunction(ver);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -10358,11 +10389,11 @@ ExpEmit FxReturnStatement::Emit(VMFunctionBuilder *build)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
VMFunction *FxReturnStatement::GetDirectFunction()
|
VMFunction *FxReturnStatement::GetDirectFunction(const VersionInfo &ver)
|
||||||
{
|
{
|
||||||
if (Args.Size() == 1)
|
if (Args.Size() == 1)
|
||||||
{
|
{
|
||||||
return Args[0]->GetDirectFunction();
|
return Args[0]->GetDirectFunction(ver);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,7 +324,7 @@ public:
|
||||||
virtual bool isConstant() const;
|
virtual bool isConstant() const;
|
||||||
virtual bool RequestAddress(FCompileContext &ctx, bool *writable);
|
virtual bool RequestAddress(FCompileContext &ctx, bool *writable);
|
||||||
virtual PPrototype *ReturnProto();
|
virtual PPrototype *ReturnProto();
|
||||||
virtual VMFunction *GetDirectFunction();
|
virtual VMFunction *GetDirectFunction(const VersionInfo &ver);
|
||||||
virtual bool CheckReturn() { return false; }
|
virtual bool CheckReturn() { return false; }
|
||||||
virtual int GetBitValue() { return -1; }
|
virtual int GetBitValue() { return -1; }
|
||||||
bool IsNumeric() const { return ValueType->isNumeric(); }
|
bool IsNumeric() const { return ValueType->isNumeric(); }
|
||||||
|
@ -1714,12 +1714,14 @@ class FxVMFunctionCall : public FxExpression
|
||||||
TArray<ExpEmit> ReturnRegs;
|
TArray<ExpEmit> ReturnRegs;
|
||||||
PFunction *CallingFunction;
|
PFunction *CallingFunction;
|
||||||
|
|
||||||
|
bool CheckAccessibility(const VersionInfo &ver);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FxVMFunctionCall(FxExpression *self, PFunction *func, FArgumentList &args, const FScriptPosition &pos, bool novirtual);
|
FxVMFunctionCall(FxExpression *self, PFunction *func, FArgumentList &args, const FScriptPosition &pos, bool novirtual);
|
||||||
~FxVMFunctionCall();
|
~FxVMFunctionCall();
|
||||||
FxExpression *Resolve(FCompileContext&);
|
FxExpression *Resolve(FCompileContext&);
|
||||||
PPrototype *ReturnProto();
|
PPrototype *ReturnProto();
|
||||||
VMFunction *GetDirectFunction();
|
VMFunction *GetDirectFunction(const VersionInfo &ver);
|
||||||
ExpEmit Emit(VMFunctionBuilder *build);
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
bool CheckEmitCast(VMFunctionBuilder *build, bool returnit, ExpEmit ®);
|
bool CheckEmitCast(VMFunctionBuilder *build, bool returnit, ExpEmit ®);
|
||||||
TArray<PType*> &GetReturnTypes() const
|
TArray<PType*> &GetReturnTypes() const
|
||||||
|
@ -1744,7 +1746,7 @@ public:
|
||||||
FxExpression *Resolve(FCompileContext&);
|
FxExpression *Resolve(FCompileContext&);
|
||||||
ExpEmit Emit(VMFunctionBuilder *build);
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
void Add(FxExpression *expr) { if (expr != NULL) Expressions.Push(expr); expr->NeedResult = false; }
|
void Add(FxExpression *expr) { if (expr != NULL) Expressions.Push(expr); expr->NeedResult = false; }
|
||||||
VMFunction *GetDirectFunction();
|
VMFunction *GetDirectFunction(const VersionInfo &ver);
|
||||||
bool CheckReturn();
|
bool CheckReturn();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1951,7 +1953,7 @@ public:
|
||||||
~FxReturnStatement();
|
~FxReturnStatement();
|
||||||
FxExpression *Resolve(FCompileContext&);
|
FxExpression *Resolve(FCompileContext&);
|
||||||
ExpEmit Emit(VMFunctionBuilder *build);
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
VMFunction *GetDirectFunction();
|
VMFunction *GetDirectFunction(const VersionInfo &ver);
|
||||||
bool CheckReturn() { return true; }
|
bool CheckReturn() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -804,7 +804,7 @@ FFunctionBuildList FunctionBuildList;
|
||||||
|
|
||||||
VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo &ver, PFunction *functype, FxExpression *code, const FString &name, bool fromdecorate, int stateindex, int statecount, int lumpnum)
|
VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo &ver, PFunction *functype, FxExpression *code, const FString &name, bool fromdecorate, int stateindex, int statecount, int lumpnum)
|
||||||
{
|
{
|
||||||
auto func = code->GetDirectFunction();
|
auto func = code->GetDirectFunction(ver);
|
||||||
if (func != nullptr)
|
if (func != nullptr)
|
||||||
{
|
{
|
||||||
delete code;
|
delete code;
|
||||||
|
|
|
@ -611,7 +611,7 @@ void ZCCCompiler::CreateClassTypes()
|
||||||
{
|
{
|
||||||
if (parent->mVersion > mVersion)
|
if (parent->mVersion > mVersion)
|
||||||
{
|
{
|
||||||
Error(c->cls, "Parent class %s of %s not accessible to ZScript version %d.%d.%d", parent->GetClass()->TypeName.GetChars(), c->NodeName().GetChars(), mVersion.major, mVersion.minor, mVersion.revision);
|
Error(c->cls, "Parent class %s of %s not accessible to ZScript version %d.%d.%d", parent->TypeName.GetChars(), c->NodeName().GetChars(), mVersion.major, mVersion.minor, mVersion.revision);
|
||||||
}
|
}
|
||||||
c->cls->Type = parent->CreateDerivedClass(c->NodeName(), TentativeClass);
|
c->cls->Type = parent->CreateDerivedClass(c->NodeName(), TentativeClass);
|
||||||
if (c->Type() == nullptr)
|
if (c->Type() == nullptr)
|
||||||
|
@ -2493,6 +2493,11 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto oldfunc = clstype->Virtuals[vindex];
|
auto oldfunc = clstype->Virtuals[vindex];
|
||||||
|
auto parentfunc = dyn_cast<PFunction>(clstype->ParentClass->Symbols.FindSymbol(sym->SymbolName, true));
|
||||||
|
if (parentfunc && parentfunc->mVersion > mVersion)
|
||||||
|
{
|
||||||
|
Error(f, "Attempt to override function %s which is incompatible with version %d.%d.%d", FName(f->Name).GetChars(), mVersion.major, mVersion.minor, mVersion.revision);
|
||||||
|
}
|
||||||
if (oldfunc->VarFlags & VARF_Final)
|
if (oldfunc->VarFlags & VARF_Final)
|
||||||
{
|
{
|
||||||
Error(f, "Attempt to override final function %s", FName(f->Name).GetChars());
|
Error(f, "Attempt to override final function %s", FName(f->Name).GetChars());
|
||||||
|
|
|
@ -751,7 +751,7 @@ class Inventory : Actor native
|
||||||
virtual bool Use (bool pickup) { return false; }
|
virtual bool Use (bool pickup) { return false; }
|
||||||
virtual double GetSpeedFactor() { return 1; }
|
virtual double GetSpeedFactor() { return 1; }
|
||||||
virtual bool GetNoTeleportFreeze() { return false; }
|
virtual bool GetNoTeleportFreeze() { return false; }
|
||||||
virtual ui void AlterWeaponSprite(VisStyle vis, in out int changed) {}
|
virtual version("2.4") ui void AlterWeaponSprite(VisStyle vis, in out int changed) {}
|
||||||
virtual void OwnerDied() {}
|
virtual void OwnerDied() {}
|
||||||
virtual Color GetBlend () { return 0; }
|
virtual Color GetBlend () { return 0; }
|
||||||
|
|
||||||
|
@ -818,7 +818,7 @@ class Inventory : Actor native
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
virtual ui bool DrawPowerup(int x, int y) { return false; }
|
virtual ui version("2.4") bool DrawPowerup(int x, int y) { return false; }
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue