From e209a2f20809ba6a2bfa617fa0edec59fc60f86d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 17 Oct 2009 01:38:54 +0000 Subject: [PATCH] - Stop aliasing strings onto names for function parameters. SVN r1923 (scripting) --- src/thingdef/thingdef_exp.h | 63 ++++++++++++++++++++++++++++ src/thingdef/thingdef_expression.cpp | 11 +++++ src/thingdef/thingdef_parse.cpp | 13 +++++- src/thingdef/thingdef_type.h | 3 +- src/zscript/vmdisasm.cpp | 4 +- wadsrc/static/actors/actor.txt | 2 +- 6 files changed, 90 insertions(+), 6 deletions(-) diff --git a/src/thingdef/thingdef_exp.h b/src/thingdef/thingdef_exp.h index 719c1c66f..bcf08f175 100644 --- a/src/thingdef/thingdef_exp.h +++ b/src/thingdef/thingdef_exp.h @@ -97,6 +97,57 @@ struct ExpVal void *pointer; }; + ExpVal() + { + Type = VAL_Int; + Int = 0; + } + + ~ExpVal() + { + if (Type == VAL_String) + { + ((FString *)&pointer)->~FString(); + } + } + + ExpVal(const FString &str) + { + Type = VAL_String; + ::new(&pointer) FString(str); + } + + ExpVal(const ExpVal &o) + { + Type = o.Type; + if (o.Type == VAL_String) + { + ::new(&pointer) FString(*(FString *)&o.pointer); + } + else + { + memcpy(&Float, &o.Float, 8); + } + } + + ExpVal &operator=(const ExpVal &o) + { + if (Type == VAL_String) + { + ((FString *)&pointer)->~FString(); + } + Type = o.Type; + if (o.Type == VAL_String) + { + ::new(&pointer) FString(*(FString *)&o.pointer); + } + else + { + memcpy(&Float, &o.Float, 8); + } + return *this; + } + int GetInt() const { return Type == VAL_Int? Int : Type == VAL_Float? int(Float) : 0; @@ -107,6 +158,11 @@ struct ExpVal return Type == VAL_Int? double(Int) : Type == VAL_Float? Float : 0; } + const FString GetString() const + { + return Type == VAL_String ? *(FString *)&pointer : Type == VAL_Name ? FString(FName(ENamedName(Int)).GetChars()) : ""; + } + bool GetBool() const { return (Type == VAL_Int || Type == VAL_Sound) ? !!Int : Type == VAL_Float? Float!=0. : false; @@ -286,6 +342,13 @@ public: isresolved = true; } + FxConstant(const char *str, const FScriptPosition &pos) : FxExpression(pos) + { + ValueType = VAL_String; + value = ExpVal(FString(str)); + isresolved = true; + } + FxConstant(ExpVal cv, const FScriptPosition &pos) : FxExpression(pos) { value = cv; diff --git a/src/thingdef/thingdef_expression.cpp b/src/thingdef/thingdef_expression.cpp index a4f076ae2..7b32a132f 100644 --- a/src/thingdef/thingdef_expression.cpp +++ b/src/thingdef/thingdef_expression.cpp @@ -37,6 +37,7 @@ ** */ +#include #include "actor.h" #include "sc_man.h" #include "tarray.h" @@ -404,8 +405,13 @@ ExpEmit FxParameter::Emit(VMFunctionBuilder *build) { build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(val.pointer, ATAG_STATE)); } + else if (val.Type == VAL_String) + { + build->Emit(OP_PARAM, 0, REGT_STRING | REGT_KONST, build->GetConstantString(val.GetString())); + } else { + build->Emit(OP_PARAM, 0, REGT_NIL, 0); ScriptPosition.Message(MSG_ERROR, "Cannot emit needed constant"); } } @@ -498,6 +504,11 @@ ExpEmit FxConstant::Emit(VMFunctionBuilder *build) out.RegType = REGT_POINTER; out.RegNum = build->GetConstantAddress(value.pointer, ATAG_STATE); } + else if (value.Type == VAL_String) + { + out.RegType = REGT_STRING; + out.RegNum = build->GetConstantString(value.GetString()); + } else { ScriptPosition.Message(MSG_ERROR, "Cannot emit needed constant"); diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index 02fb125d6..fa2b1beec 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -85,12 +85,21 @@ FxExpression *ParseParameter(FScanner &sc, PClass *cls, char type, bool constant x = new FxClassTypeCast(RUNTIME_CLASS(AActor), new FxConstant(FName(sc.String), sc)); break; + case 'N': + case 'n': // name case 'T': case 't': // String sc.SetEscape(true); sc.MustGetString(); sc.SetEscape(false); - x = new FxConstant(sc.String[0]? FName(sc.String) : NAME_None, sc); + if (type == 'n' || type == 'N') + { + x = new FxConstant(sc.String[0] ? FName(sc.String) : NAME_None, sc); + } + else + { + x = new FxConstant(strbin1(sc.String), sc); + } break; case 'C': @@ -855,7 +864,7 @@ static void ParseActionDef (FScanner &sc, PClass *cls) case TK_Sound: type = 's'; break; case TK_String: type = 't'; break; - case TK_Name: type = 't'; break; + case TK_Name: type = 'n'; break; case TK_State: type = 'l'; break; case TK_Color: type = 'c'; break; case TK_Class: diff --git a/src/thingdef/thingdef_type.h b/src/thingdef/thingdef_type.h index 721cab61f..a89c80749 100644 --- a/src/thingdef/thingdef_type.h +++ b/src/thingdef/thingdef_type.h @@ -17,7 +17,8 @@ enum ExpValType VAL_Pointer, // Dereferenced variable (only used for addressing arrays for now.) VAL_Sound, // Sound identifier. Internally it's an int. VAL_Name, // A Name - VAL_Color, // A color. + VAL_String, // A string + VAL_Color, // A color VAL_State, // A State pointer // only used for accessing external variables to ensure proper conversion diff --git a/src/zscript/vmdisasm.cpp b/src/zscript/vmdisasm.cpp index e8217815d..9175cc096 100644 --- a/src/zscript/vmdisasm.cpp +++ b/src/zscript/vmdisasm.cpp @@ -166,7 +166,7 @@ void VMDumpConstants(FILE *out, const VMScriptFunction *func) printf_wrapper(out, "\nConstant strings:\n"); for (i = 0; i < func->NumKonstS; ++i) { - printf_wrapper(out, "%3d. %s\n", func->KonstS[k].GetChars()); + printf_wrapper(out, "%3d. %s\n", i, func->KonstS[i].GetChars()); } } } @@ -353,7 +353,7 @@ static int print_reg(FILE *out, int col, int arg, int mode, int immshift, const case MODE_KS: if (func != NULL) { - return col+printf_wrapper(out, "\"%s\"", func->KonstS[arg].GetChars()); + return col+printf_wrapper(out, "\"%.27s\"", func->KonstS[arg].GetChars()); } return col+printf_wrapper(out, "ks%d", arg); case MODE_KP: diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index b644b3511..8f66780ff 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -186,7 +186,7 @@ ACTOR Actor native //: Thinker action native A_JumpIfHealthLower(int health, state label); action native A_JumpIfCloser(float distance, state label); action native A_JumpIfInventory(class itemtype, int itemamount, state label); - action native A_JumpIfArmorType(string Type, state label, int amount = 1); + action native A_JumpIfArmorType(name Type, state label, int amount = 1); action native A_GiveInventory(class itemtype, int amount = 0); action native A_TakeInventory(class itemtype, int amount = 0); action native A_SpawnItem(class itemtype = "Unknown", float distance = 0, float zheight = 0, bool useammo = true, bool transfer_translation = false);