- implemented direct CVar access.

This commit is contained in:
Christoph Oelckers 2016-11-20 20:24:39 +01:00
parent 159f09105e
commit 1c2c26eb08
4 changed files with 148 additions and 7 deletions

View file

@ -1093,7 +1093,7 @@ BitVal (bitval)
ECVarType FFlagCVar::GetRealType () const ECVarType FFlagCVar::GetRealType () const
{ {
return CVAR_Dummy; return CVAR_DummyBool;
} }
UCVarValue FFlagCVar::GetGenericRep (ECVarType type) const UCVarValue FFlagCVar::GetGenericRep (ECVarType type) const
@ -1197,7 +1197,7 @@ BitVal (bitval)
ECVarType FMaskCVar::GetRealType () const ECVarType FMaskCVar::GetRealType () const
{ {
return CVAR_Dummy; return CVAR_DummyInt;
} }
UCVarValue FMaskCVar::GetGenericRep (ECVarType type) const UCVarValue FMaskCVar::GetGenericRep (ECVarType type) const

View file

@ -81,13 +81,17 @@ enum ECVarType
CVAR_Float, CVAR_Float,
CVAR_String, CVAR_String,
CVAR_Color, // stored as CVAR_Int CVAR_Color, // stored as CVAR_Int
CVAR_Dummy, // just redirects to another cvar CVAR_DummyBool, // just redirects to another cvar
CVAR_DummyInt, // just redirects to another cvar
CVAR_Dummy, // Unknown
CVAR_GUID CVAR_GUID
}; };
class FConfigFile; class FConfigFile;
class AActor; class AActor;
class FxCVar;
class FBaseCVar class FBaseCVar
{ {
public: public:
@ -211,6 +215,7 @@ void C_DeinitConsole();
class FBoolCVar : public FBaseCVar class FBoolCVar : public FBaseCVar
{ {
friend class FxCVar;
public: public:
FBoolCVar (const char *name, bool def, uint32 flags, void (*callback)(FBoolCVar &)=NULL); FBoolCVar (const char *name, bool def, uint32 flags, void (*callback)(FBoolCVar &)=NULL);
@ -236,6 +241,7 @@ protected:
class FIntCVar : public FBaseCVar class FIntCVar : public FBaseCVar
{ {
friend class FxCVar;
public: public:
FIntCVar (const char *name, int def, uint32 flags, void (*callback)(FIntCVar &)=NULL); FIntCVar (const char *name, int def, uint32 flags, void (*callback)(FIntCVar &)=NULL);
@ -263,6 +269,7 @@ protected:
class FFloatCVar : public FBaseCVar class FFloatCVar : public FBaseCVar
{ {
friend class FxCVar;
public: public:
FFloatCVar (const char *name, float def, uint32 flags, void (*callback)(FFloatCVar &)=NULL); FFloatCVar (const char *name, float def, uint32 flags, void (*callback)(FFloatCVar &)=NULL);
@ -289,6 +296,7 @@ protected:
class FStringCVar : public FBaseCVar class FStringCVar : public FBaseCVar
{ {
friend class FxCVar;
public: public:
FStringCVar (const char *name, const char *def, uint32 flags, void (*callback)(FStringCVar &)=NULL); FStringCVar (const char *name, const char *def, uint32 flags, void (*callback)(FStringCVar &)=NULL);
~FStringCVar (); ~FStringCVar ();
@ -315,6 +323,7 @@ protected:
class FColorCVar : public FIntCVar class FColorCVar : public FIntCVar
{ {
friend class FxCVar;
public: public:
FColorCVar (const char *name, int def, uint32 flags, void (*callback)(FColorCVar &)=NULL); FColorCVar (const char *name, int def, uint32 flags, void (*callback)(FColorCVar &)=NULL);
@ -339,6 +348,7 @@ protected:
class FFlagCVar : public FBaseCVar class FFlagCVar : public FBaseCVar
{ {
friend class FxCVar;
public: public:
FFlagCVar (const char *name, FIntCVar &realvar, uint32 bitval); FFlagCVar (const char *name, FIntCVar &realvar, uint32 bitval);
@ -367,6 +377,7 @@ protected:
class FMaskCVar : public FBaseCVar class FMaskCVar : public FBaseCVar
{ {
friend class FxCVar;
public: public:
FMaskCVar (const char *name, FIntCVar &realvar, uint32 bitval); FMaskCVar (const char *name, FIntCVar &realvar, uint32 bitval);

View file

@ -1993,7 +1993,7 @@ ExpEmit FxPreIncrDecr::Emit(VMFunctionBuilder *build)
if (regtype == REGT_INT) if (regtype == REGT_INT)
{ {
build->Emit((Token == TK_Incr) ? OP_ADD_RK : OP_SUB_RK, value.RegNum, value.RegNum, build->GetConstantInt(1)); build->Emit(OP_ADDI, value.RegNum, value.RegNum, (Token == TK_Incr) ? 1 : -1);
} }
else else
{ {
@ -2077,7 +2077,7 @@ ExpEmit FxPostIncrDecr::Emit(VMFunctionBuilder *build)
ExpEmit assign(build, regtype); ExpEmit assign(build, regtype);
if (regtype == REGT_INT) if (regtype == REGT_INT)
{ {
build->Emit((Token == TK_Incr) ? OP_ADD_RK : OP_SUB_RK, assign.RegNum, out.RegNum, build->GetConstantInt(1)); build->Emit(OP_ADDI, assign.RegNum, out.RegNum, (Token == TK_Incr) ? 1 : -1);
} }
else else
{ {
@ -2094,7 +2094,7 @@ ExpEmit FxPostIncrDecr::Emit(VMFunctionBuilder *build)
if (regtype == REGT_INT) if (regtype == REGT_INT)
{ {
build->Emit(OP_MOVE, out.RegNum, pointer.RegNum); build->Emit(OP_MOVE, out.RegNum, pointer.RegNum);
build->Emit((Token == TK_Incr) ? OP_ADD_RK : OP_SUB_RK, pointer.RegNum, pointer.RegNum, build->GetConstantInt(1)); build->Emit(OP_ADDI, pointer.RegNum, pointer.RegNum, (Token == TK_Incr) ? 1 : -1);
} }
else else
{ {
@ -2108,7 +2108,7 @@ ExpEmit FxPostIncrDecr::Emit(VMFunctionBuilder *build)
{ {
if (regtype == REGT_INT) if (regtype == REGT_INT)
{ {
build->Emit((Token == TK_Incr) ? OP_ADD_RK : OP_SUB_RK, pointer.RegNum, pointer.RegNum, build->GetConstantInt(1)); build->Emit(OP_ADDI, pointer.RegNum, pointer.RegNum, (Token == TK_Incr) ? 1 : -1);
} }
else else
{ {
@ -5526,6 +5526,18 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as line special %d\n", Identifier.GetChars(), num); ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as line special %d\n", Identifier.GetChars(), num);
newex = new FxConstant(num, ScriptPosition); newex = new FxConstant(num, ScriptPosition);
} }
auto cvar = FindCVar(Identifier.GetChars(), nullptr);
if (cvar != nullptr)
{
if (cvar->GetFlags() & CVAR_USERINFO)
{
ScriptPosition.Message(MSG_ERROR, "Cannot access userinfo CVARs directly. Use GetCVar() instead.");
delete this;
return nullptr;
}
newex = new FxCVar(cvar, ScriptPosition);
}
if (newex == nullptr) if (newex == nullptr)
{ {
@ -5956,6 +5968,114 @@ ExpEmit FxGlobalVariable::Emit(VMFunctionBuilder *build)
} }
//==========================================================================
//
//
//
//==========================================================================
FxCVar::FxCVar(FBaseCVar *cvar, const FScriptPosition &pos)
: FxExpression(EFX_CVar, pos)
{
CVar = cvar;
}
//==========================================================================
//
//
//
//==========================================================================
FxExpression *FxCVar::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
switch (CVar->GetRealType())
{
case CVAR_Bool:
case CVAR_DummyBool:
ValueType = TypeBool;
break;
case CVAR_Int:
case CVAR_DummyInt:
ValueType = TypeSInt32;
break;
case CVAR_Color:
ValueType = TypeColor;
break;
case CVAR_Float:
ValueType = TypeFloat64;
break;
case CVAR_String:
ValueType = TypeString;
break;
default:
ScriptPosition.Message(MSG_ERROR, "Unknown CVar type for %s", CVar->GetName());
delete this;
return nullptr;
}
return this;
}
ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
{
ExpEmit dest(build, ValueType->GetRegType());
ExpEmit addr(build, REGT_POINTER);
int nul = build->GetConstantInt(0);
switch (CVar->GetRealType())
{
case CVAR_Int:
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FIntCVar *>(CVar)->Value, ATAG_GENERIC));
build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul);
break;
case CVAR_Color:
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FColorCVar *>(CVar)->Value, ATAG_GENERIC));
build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul);
break;
case CVAR_Float:
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FFloatCVar *>(CVar)->Value, ATAG_GENERIC));
build->Emit(OP_LSP, dest.RegNum, addr.RegNum, nul);
break;
case CVAR_Bool:
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FBoolCVar *>(CVar)->Value, ATAG_GENERIC));
build->Emit(OP_LBU, dest.RegNum, addr.RegNum, nul);
break;
case CVAR_String:
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FStringCVar *>(CVar)->Value, ATAG_GENERIC));
build->Emit(OP_LS, dest.RegNum, addr.RegNum, nul);
break;
case CVAR_DummyBool:
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FFlagCVar *>(CVar)->ValueVar.Value, ATAG_GENERIC));
build->Emit(OP_LBIT, dest.RegNum, addr.RegNum, static_cast<FFlagCVar *>(CVar)->BitNum);
break;
case CVAR_DummyInt:
{
auto cv = static_cast<FMaskCVar *>(CVar);
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&cv->ValueVar.Value, ATAG_GENERIC));
build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul);
build->Emit(OP_AND_RK, dest.RegNum, dest.RegNum, build->GetConstantInt(cv->BitVal));
build->Emit(OP_SRL_RI, dest.RegNum, dest.RegNum, cv->BitNum);
break;
}
default:
assert(false && "Unsupported CVar type");
break;
}
return dest;
}
//========================================================================== //==========================================================================
// //
// //

View file

@ -284,6 +284,7 @@ enum EFxType
EFX_MultiAssign, EFX_MultiAssign,
EFX_StaticArray, EFX_StaticArray,
EFX_StaticArrayVariable, EFX_StaticArrayVariable,
EFX_CVar,
EFX_COUNT EFX_COUNT
}; };
@ -1236,6 +1237,15 @@ public:
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
class FxCVar : public FxExpression
{
FBaseCVar *CVar;
public:
FxCVar(FBaseCVar*, const FScriptPosition&);
FxExpression *Resolve(FCompileContext&);
ExpEmit Emit(VMFunctionBuilder *build);
};
//========================================================================== //==========================================================================
// //
// FxClassMember // FxClassMember