- reverted most of the last commit after realizing that trying to manage constructing/destructing per variable is not going to work because it'd require some extensive exception management in the compiled VM code.

- instead add a list of SpecialInits to VMScriptFunction so this can be done transparently when setting up and popping the stack frame. The only drawback is that this requires permanent allocation of stack objects for the entire lifetime of a function but this is a relatively small tradeoff for significantly reduced maintenance work throughout.
- removed most #include "vm.h", because nearly all files already pull this in through dobject.h.
This commit is contained in:
Christoph Oelckers 2016-11-17 13:10:19 +01:00
parent 30e6e8e25f
commit d86f03e2e0
30 changed files with 55 additions and 235 deletions

View file

@ -70,7 +70,6 @@
#include "doomerrors.h"
#include "p_effect.h"
#include "serializer.h"
#include "vm.h"
#include "thingdef.h"
#include "info.h"
#include "v_text.h"

View file

@ -109,7 +109,6 @@
#include "p_local.h"
#include "autosegs.h"
#include "fragglescript/t_fs.h"
#include "vm.h"
EXTERN_CVAR(Bool, hud_althud)
void DrawHUD();

View file

@ -77,7 +77,6 @@
#include "r_utility.h"
#include "menu/menu.h"
#include "intermission/intermission.h"
#include "vm.h"
// MACROS ------------------------------------------------------------------

View file

@ -1869,39 +1869,6 @@ void PArray::SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset>
}
}
//==========================================================================
//
// PArray :: InitializeValue
// This is needed for local array variables
//
//==========================================================================
void PArray::InitializeValue(void *addr, const void *def) const
{
char *caddr = (char*)addr;
char *cdef = (char*)def;
for (unsigned i = 0; i < ElementCount; ++i)
{
ElementType->InitializeValue(caddr + i * ElementSize, cdef + i * ElementSize);
}
}
//==========================================================================
//
// PArray :: DestroyValue
// This is needed for local array variables
//
//==========================================================================
void PArray::DestroyValue(void *addr) const
{
char *caddr = (char*)addr;
for (unsigned i = 0; i < ElementCount; ++i)
{
ElementType->DestroyValue(caddr + i * ElementSize);
}
}
//==========================================================================
//
// NewArray
@ -1985,28 +1952,6 @@ void PDynArray::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
id2 = 0;
}
//==========================================================================
//
// PDynArray :: InitializeValue
//
//==========================================================================
void PDynArray::InitializeValue(void *addr, const void *def) const
{
// DynArrays are not implemented yet.
}
//==========================================================================
//
// PDynArray :: DestroyValue
//
//==========================================================================
void PDynArray::DestroyValue(void *addr) const
{
// DynArrays are not implemented yet.
}
//==========================================================================
//
// NewDynArray
@ -2091,28 +2036,6 @@ void PMap::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
id2 = (intptr_t)ValueType;
}
//==========================================================================
//
// PMap :: InitializeValue
//
//==========================================================================
void PMap::InitializeValue(void *addr, const void *def) const
{
// Maps are not implemented yet.
}
//==========================================================================
//
// PMap :: DestroyValue
//
//==========================================================================
void PMap::DestroyValue(void *addr) const
{
// Maps are not implemented yet.
}
//==========================================================================
//
// NewMap
@ -2335,76 +2258,6 @@ size_t PStruct::PropagateMark()
return Fields.Size() * sizeof(void*) + Super::PropagateMark();
}
//==========================================================================
//
// PStruct :: InitializeValue
// This is needed for local array variables
//
//==========================================================================
void PStruct::InitializeValue(void *addr, const void *def) const
{
char *caddr = (char*)addr;
char *cdef = (char*)def;
for (auto tao : SpecialInits)
{
tao.first->InitializeValue(caddr + tao.second, cdef + tao.second);
}
}
//==========================================================================
//
// PStruct :: DestroyValue
// This is needed for local array variables
//
//==========================================================================
void PStruct::DestroyValue(void *addr) const
{
char *caddr = (char*)addr;
for (auto tao : SpecialInits)
{
tao.first->DestroyValue(caddr + tao.second);
}
}
//==========================================================================
//
// PStruct :: InitializeSpecialInits
//
// Initialize special field list.
//
//==========================================================================
void PStruct::InitializeSpecialInits()
{
// and initialize our own special values.
auto it = Symbols.GetIterator();
PSymbolTable::MapType::Pair *pair;
while (it.NextPair(pair))
{
auto field = dyn_cast<PField>(pair->Value);
if (field != nullptr && !(field->Flags & VARF_Native))
{
field->Type->SetDefaultValue(nullptr, unsigned(field->Offset), &SpecialInits);
}
}
}
//==========================================================================
//
// PStruct :: RequireConstruction
//
//==========================================================================
bool PStruct::RequireConstruction() const
{
return SpecialInits.Size() > 0;
}
//==========================================================================
//
// NewStruct

View file

@ -5,10 +5,10 @@
#error You must #include "dobject.h" to get dobjtype.h
#endif
#include "vm.h"
typedef std::pair<const class PType *, unsigned> FTypeAndOffset;
#include "vm.h"
// Variable/parameter/field flags -------------------------------------------
// Making all these different storage types use a common set of flags seems
@ -256,9 +256,6 @@ public:
// Initialize the value, if needed (e.g. strings)
virtual void InitializeValue(void *addr, const void *def) const;
// This is for stack variables that may need construction/destruction at runtime
virtual bool RequireConstruction() const { return false; }
// Destroy the value, if needed (e.g. strings)
virtual void DestroyValue(void *addr) const;
@ -492,7 +489,6 @@ public:
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) const override;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
virtual bool RequireConstruction() const override { return true; }
};
// Variations of integer types ----------------------------------------------
@ -630,9 +626,6 @@ public:
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const override;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
bool RequireConstruction() const override { return ElementType->RequireConstruction(); }
protected:
PArray();
@ -649,9 +642,6 @@ public:
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
bool RequireConstruction() const override { return true; }
protected:
PDynArray();
};
@ -668,9 +658,6 @@ public:
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
bool RequireConstruction() const override { return true; }
protected:
PMap();
};
@ -678,10 +665,6 @@ protected:
class PStruct : public PNamedType
{
DECLARE_CLASS(PStruct, PNamedType);
protected:
TArray<FTypeAndOffset> SpecialInits;
public:
PStruct(FName name, PTypeBase *outer);
@ -699,12 +682,6 @@ public:
static void WriteFields(FSerializer &ar, const void *addr, const TArray<PField *> &fields);
bool ReadFields(FSerializer &ar, void *addr) const;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
bool RequireConstruction() const override;
void InitializeSpecialInits();
protected:
PStruct();
};
@ -771,6 +748,7 @@ class PClass : public PStruct
protected:
// We unravel _WITH_META here just as we did for PType.
enum { MetaClassNum = CLASSREG_PClassClass };
TArray<FTypeAndOffset> SpecialInits;
void Derive(PClass *newclass, FName name);
void InitializeSpecials(void *addr) const;
void SetSuper();

View file

@ -7,7 +7,6 @@
#include "gi.h"
#include "doomstat.h"
#include "gstrings.h"
#include "vm.h"
#include "g_level.h"
#include "p_enemy.h"
#include "a_doomglobal.h"
@ -19,7 +18,6 @@
#include "p_maputl.h"
#include "serializer.h"
#include "g_shared/a_pickups.h"
#include "vm.h"
// Include all the other Doom stuff here to reduce compile time
#include "a_bossbrain.cpp"

View file

@ -6,7 +6,6 @@
#include "p_local.h"
#include "s_sound.h"
#include "gstrings.h"
#include "vm.h"
#include "p_enemy.h"
#include "a_specialspot.h"
#include "g_level.h"
@ -18,7 +17,6 @@
#include "a_morph.h"
#include "p_spec.h"
#include "serializer.h"
#include "vm.h"
// Include all the other Heretic stuff here to reduce compile time
#include "a_chicken.cpp"

View file

@ -7,7 +7,6 @@
#include "a_sharedglobal.h"
#include "a_hexenglobal.h"
#include "i_system.h"
#include "vm.h"
#include "gi.h"
#include "g_level.h"
#include "p_enemy.h"
@ -24,7 +23,6 @@
#include "p_maputl.h"
#include "p_spec.h"
#include "serializer.h"
#include "vm.h"
// Include all the Hexen stuff here to reduce compile time
#include "a_blastradius.cpp"

View file

@ -1,5 +1,4 @@
#include "actor.h"
#include "vm.h"
#include "p_conversation.h"
#include "p_lnspec.h"
#include "a_action.h"

View file

@ -2,7 +2,6 @@
#include "info.h"
#include "gi.h"
#include "m_random.h"
#include "vm.h"
static FRandom pr_orbit ("Orbit");

View file

@ -14,7 +14,6 @@
#include "a_strifeglobal.h"
#include "a_morph.h"
#include "a_specialspot.h"
#include "vm.h"
#include "g_level.h"
#include "g_game.h"
#include "doomstat.h"

View file

@ -14,7 +14,6 @@
#include "statnums.h"
#include "gstrings.h"
#include "a_action.h"
#include "vm.h"
#include "v_text.h"
#include "doomstat.h"
#include "doomdata.h"

View file

@ -37,7 +37,6 @@
#include "p_local.h"
#include "statnums.h"
#include "i_system.h"
#include "vm.h"
#include "doomstat.h"
#include "serializer.h"
#include "a_pickups.h"

View file

@ -13,7 +13,6 @@
#include "cmdlib.h"
#include "templates.h"
#include "sbar.h"
#include "vm.h"
#include "doomstat.h"
#include "g_level.h"
#include "d_net.h"

View file

@ -43,7 +43,6 @@
#include "v_text.h"
#include "gi.h"
#include "vm.h"
#include "actor.h"
#include "r_state.h"
#include "i_system.h"
@ -52,7 +51,6 @@
#include "cmdlib.h"
#include "g_level.h"
#include "stats.h"
#include "vm.h"
#include "thingdef.h"
#include "d_player.h"
#include "doomerrors.h"

View file

@ -43,7 +43,6 @@
#include "dobject.h"
#include "doomdef.h"
#include "vm.h"
#include "s_sound.h"
#include "m_fixed.h"

View file

@ -61,7 +61,6 @@
#include "c_console.h"
#include "doomerrors.h"
#include "a_sharedglobal.h"
#include "vm.h"
#include "v_video.h"
#include "v_font.h"
#include "doomstat.h"
@ -77,7 +76,6 @@
#include "p_maputl.h"
#include "p_spec.h"
#include "templates.h"
#include "vm.h"
#include "v_text.h"
#include "thingdef.h"
#include "math/cmath.h"

View file

@ -43,7 +43,6 @@
#include "p_enemy.h"
#include "a_sharedglobal.h"
#include "a_action.h"
#include "vm.h"
#include "d_dehacked.h"
#include "g_level.h"
#include "r_utility.h"
@ -53,7 +52,6 @@
#include "p_spec.h"
#include "p_checkposition.h"
#include "math/cmath.h"
#include "vm.h"
#include "gi.h"

View file

@ -1,7 +1,7 @@
#ifndef __P_ENEMY_H__
#define __P_ENEMY_H__
#include "vm.h"
#include "dobject.h"
#include "vectors.h"
struct sector_t;

View file

@ -53,7 +53,6 @@
#include "a_action.h"
#include "a_keys.h"
#include "p_conversation.h"
#include "vm.h"
#include "g_game.h"
#include "teaminfo.h"
#include "r_data/r_translate.h"

View file

@ -25,7 +25,6 @@
#include "gi.h"
#include "p_pspr.h"
#include "templates.h"
#include "vm.h"
#include "g_level.h"
#include "d_player.h"
#include "serializer.h"

View file

@ -25,7 +25,6 @@
// Basic data types.
// Needs fixed point, and BAM angles.
//#include "vm.h"
#define WEAPONBOTTOM 128.

View file

@ -39,7 +39,6 @@
#include "i_system.h"
#include "c_dispatch.h"
#include "v_text.h"
#include "vm.h"
#include "thingdef.h"
// stores indices for symbolic state labels for some old-style DECORATE functions.

View file

@ -48,7 +48,6 @@
#include "doomdef.h"
#include "c_dispatch.h"
#include "tarray.h"
#include "vm.h"
#include "g_level.h"
#include "d_net.h"
#include "gstrings.h"

View file

@ -6,7 +6,6 @@
#include "s_sound.h"
#include "sc_man.h"
#include "cmdlib.h"
#include "vm.h"
class FScanner;

View file

@ -2,7 +2,6 @@
#define VM_H
#include "zstring.h"
#include "dobject.h"
#include "autosegs.h"
#include "vectors.h"
@ -815,6 +814,12 @@ public:
VM_UHALF MaxParam; // Maximum number of parameters this function has on the stack at once
VM_UBYTE NumArgs; // Number of arguments this function takes
FString PrintableName; // so that the VM can print meaningful info if something in this function goes wrong.
TArray<FTypeAndOffset> SpecialInits; // list of all contents on the extra stack which require construction and destruction
void InitExtra(void *addr);
void DestroyExtra(void *addr);
void SetExtraSpecial(PType *type, unsigned offset);
int AllocExtraStack(PType *type);
};
class VMFrameStack
@ -822,7 +827,6 @@ class VMFrameStack
public:
VMFrameStack();
~VMFrameStack();
VMFrame *AllocFrame(int numregd, int numregf, int numregs, int numrega);
VMFrame *AllocFrame(VMScriptFunction *func);
VMFrame *PopFrame();
VMFrame *TopFrame()

View file

@ -1,7 +1,7 @@
#ifndef VMUTIL_H
#define VMUTIL_H
#include "vm.h"
#include "dobject.h"
class VMFunctionBuilder
{

View file

@ -31,7 +31,7 @@
**
*/
#include "vm.h"
#include "dobject.h"
#include "c_console.h"
#include "templates.h"

View file

@ -34,7 +34,7 @@
#include <math.h>
#include <v_video.h>
#include <s_sound.h>
#include "vm.h"
#include "dobject.h"
#include "xs_Float.h"
#include "math/cmath.h"

View file

@ -32,7 +32,7 @@
*/
#include <new>
#include "vm.h"
#include "dobject.h"
IMPLEMENT_CLASS(VMException, false, false, false, false)
IMPLEMENT_CLASS(VMFunction, true, true, false, false)
@ -162,6 +162,38 @@ size_t VMScriptFunction::PropagateMark()
return NumKonstA * sizeof(void *) + Super::PropagateMark();
}
void VMScriptFunction::InitExtra(void *addr)
{
char *caddr = (char*)addr;
for (auto tao : SpecialInits)
{
tao.first->InitializeValue(caddr + tao.second, nullptr);
}
}
void VMScriptFunction::DestroyExtra(void *addr)
{
char *caddr = (char*)addr;
for (auto tao : SpecialInits)
{
tao.first->DestroyValue(caddr + tao.second);
}
}
void VMScriptFunction::SetExtraSpecial(PType *type, unsigned offset)
{
type->SetDefaultValue(nullptr, offset, &SpecialInits);
}
int VMScriptFunction::AllocExtraStack(PType *type)
{
int address = ((ExtraSpace + type->Align - 1) / type->Align) * type->Align;
ExtraSpace = address + type->Size;
return address;
}
//===========================================================================
//
// VMFrame :: InitRegS
@ -223,34 +255,6 @@ VMFrameStack::~VMFrameStack()
UnusedBlocks = NULL;
}
//===========================================================================
//
// VMFrameStack :: AllocFrame
//
// Allocates a frame from the stack with the desired number of registers.
//
//===========================================================================
VMFrame *VMFrameStack::AllocFrame(int numregd, int numregf, int numregs, int numrega)
{
assert((unsigned)numregd < 255);
assert((unsigned)numregf < 255);
assert((unsigned)numregs < 255);
assert((unsigned)numrega < 255);
// To keep the arguments to this function simpler, it assumes that every
// register might be used as a parameter for a single call.
int numparam = numregd + numregf + numregs + numrega;
int size = VMFrame::FrameSize(numregd, numregf, numregs, numrega, numparam, 0);
VMFrame *frame = Alloc(size);
frame->NumRegD = numregd;
frame->NumRegF = numregf;
frame->NumRegS = numregs;
frame->NumRegA = numrega;
frame->MaxParam = numparam;
frame->InitRegS();
return frame;
}
//===========================================================================
//
// VMFrameStack :: AllocFrame
@ -273,6 +277,10 @@ VMFrame *VMFrameStack::AllocFrame(VMScriptFunction *func)
frame->MaxParam = func->MaxParam;
frame->Func = func;
frame->InitRegS();
if (func->SpecialInits.Size())
{
func->InitExtra(frame->GetExtra());
}
return frame;
}
@ -358,6 +366,11 @@ VMFrame *VMFrameStack::PopFrame()
{
return NULL;
}
auto Func = static_cast<VMScriptFunction *>(frame->Func);
if (Func->SpecialInits.Size())
{
Func->DestroyExtra(frame->GetExtra());
}
// Free any string registers this frame had.
FString *regs = frame->GetRegS();
for (int i = frame->NumRegS; i != 0; --i)