- fixed: the restart CCMD must clear out all statically stored pointers to VM functions because they do not survive the shutdown that is needed before loading new data.

This commit is contained in:
Christoph Oelckers 2017-01-31 13:41:23 +01:00
parent f0a325a904
commit 3131c08640
6 changed files with 25 additions and 6 deletions

View file

@ -69,6 +69,7 @@ FNamespaceManager Namespaces;
FTypeTable TypeTable;
TArray<PClass *> PClass::AllClasses;
TArray<VMFunction**> PClass::FunctionPtrList;
bool PClass::bShutdown;
bool PClass::bVMOperational;
@ -2840,6 +2841,12 @@ void PClass::StaticShutdown ()
TArray<size_t *> uniqueFPs(64);
unsigned int i, j;
// delete all variables containing pointers to script functions.
for (auto p : FunctionPtrList)
{
*p = nullptr;
}
FunctionPtrList.Clear();
// Make a full garbage collection here so that all destroyed but uncollected higher level objects that still exist can be properly taken down.
GC::FullGC();
@ -3547,6 +3554,16 @@ VMFunction *PClass::FindFunction(FName clsname, FName funcname)
return func->Variants[0].Implementation;
}
void PClass::FindFunction(VMFunction **pptr, FName clsname, FName funcname)
{
auto cls = PClass::FindActor(clsname);
if (!cls) return;
auto func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(funcname, true));
if (!func) return;
*pptr = func->Variants[0].Implementation;
FunctionPtrList.Push(pptr);
}
/* FTypeTable **************************************************************/

View file

@ -848,9 +848,11 @@ public:
static PClassActor *FindActor(ENamedName name) { return FindActor(FName(name)); }
static PClassActor *FindActor(FName name);
static VMFunction *FindFunction(FName cls, FName func);
static void FindFunction(VMFunction **pptr, FName cls, FName func);
PClass *FindClassTentative(FName name);
static TArray<PClass *> AllClasses;
static TArray<VMFunction**> FunctionPtrList;
static bool bShutdown;
static bool bVMOperational;

View file

@ -522,7 +522,7 @@ DEFINE_ACTION_FUNCTION(AInventory, DoRespawn)
bool AInventory::CallTryPickup(AActor *toucher, AActor **toucher_return)
{
static VMFunction *func = nullptr;
if (func == nullptr) func = PClass::FindFunction(NAME_Inventory, NAME_CallTryPickup);
if (func == nullptr) PClass::FindFunction(&func, NAME_Inventory, NAME_CallTryPickup);
VMValue params[2] = { (DObject*)this, toucher };
VMReturn ret[2];
int res;

View file

@ -1437,7 +1437,7 @@ class CommandDrawNumber : public CommandDrawString
{
// num = statusBar.CPlayer.mo.GetEffectTicsForItem(inventoryItem) / TICRATE + 1;
static VMFunction *func = nullptr;
if (func == nullptr) func = PClass::FindFunction(NAME_PlayerPawn, "GetEffectTicsForItem");
if (func == nullptr) PClass::FindFunction(&func, NAME_PlayerPawn, "GetEffectTicsForItem");
VMValue params[] = { statusBar->CPlayer->mo, inventoryItem };
int retv;
VMReturn ret(&retv);
@ -2830,7 +2830,7 @@ class CommandDrawBar : public SBarInfoCommand
// [value, max] = statusBar.CPlayer.mo.GetEffectTicsForItem(inventoryItem);
// value++; max++;
static VMFunction *func = nullptr;
if (func == nullptr) func = PClass::FindFunction(NAME_PlayerPawn, "GetEffectTicsForItem");
if (func == nullptr) PClass::FindFunction(&func, NAME_PlayerPawn, "GetEffectTicsForItem");
VMValue params[] = { statusBar->CPlayer->mo, data.inventoryItem };
VMReturn ret[2];
int ival;

View file

@ -478,7 +478,7 @@ void cht_DoCheat (player_t *player, int cheat)
if (player->mo != NULL && player->health >= 0)
{
static VMFunction *gsp = nullptr;
if (gsp == nullptr) gsp = PClass::FindFunction(NAME_Sigil, NAME_GiveSigilPiece);
if (gsp == nullptr) PClass::FindFunction(&gsp, NAME_Sigil, NAME_GiveSigilPiece);
if (gsp)
{
VMValue params[1] = { player->mo };

View file

@ -6203,7 +6203,7 @@ static bool CharArrayParms(int &capacity, int &offset, int &a, int *Stack, int &
static void SetMarineWeapon(AActor *marine, int weapon)
{
static VMFunction *smw = nullptr;
if (smw == nullptr) smw = PClass::FindFunction(NAME_ScriptedMarine, NAME_SetWeapon);
if (smw == nullptr) PClass::FindFunction(&smw, NAME_ScriptedMarine, NAME_SetWeapon);
if (smw)
{
VMValue params[2] = { marine, weapon };
@ -6214,7 +6214,7 @@ static void SetMarineWeapon(AActor *marine, int weapon)
static void SetMarineSprite(AActor *marine, PClassActor *source)
{
static VMFunction *sms = nullptr;
if (sms == nullptr) sms = PClass::FindFunction(NAME_ScriptedMarine, NAME_SetSprite);
if (sms == nullptr) PClass::FindFunction(&sms, NAME_ScriptedMarine, NAME_SetSprite);
if (sms)
{
VMValue params[2] = { marine, source };