- moved the VM types into their own file and only include it where really needed.

This commit is contained in:
Christoph Oelckers 2017-04-13 01:12:04 +02:00
parent 3e47f00ba0
commit 6599e2c425
111 changed files with 4284 additions and 4148 deletions

View file

@ -1215,6 +1215,7 @@ set (PCH_SOURCES
r_data/renderstyle.cpp
r_data/r_interpolate.cpp
scripting/symbols.cpp
scripting/types.cpp
scripting/thingdef.cpp
scripting/thingdef_data.cpp
scripting/thingdef_properties.cpp

View file

@ -734,8 +734,6 @@ static int grid = 0;
bool automapactive = false;
DEFINE_GLOBAL(automapactive);
// location of window on screen
static int f_x;
static int f_y;

View file

@ -14,6 +14,7 @@
#include "d_net.h"
#include "serializer.h"
#include "d_player.h"
#include "vm.h"
IMPLEMENT_CLASS(DBot, false, true)

View file

@ -62,6 +62,7 @@ Everything that is changed is marked (maybe commented) with "Added by MC"
#include "d_player.h"
#include "doomerrors.h"
#include "events.h"
#include "vm.h"
static FRandom pr_botspawn ("BotSpawn");

View file

@ -46,6 +46,7 @@
#include "w_wad.h"
#include "templates.h"
#include "dobject.h"
#include "vm.h"
#include <math.h>
#include <stdlib.h>

View file

@ -1147,34 +1147,6 @@ CCMD(currentpos)
}
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
CCMD(vmengine)
{
if (argv.argc() == 2)
{
if (stricmp(argv[1], "default") == 0)
{
VMSelectEngine(VMEngine_Default);
return;
}
else if (stricmp(argv[1], "checked") == 0)
{
VMSelectEngine(VMEngine_Checked);
return;
}
else if (stricmp(argv[1], "unchecked") == 0)
{
VMSelectEngine(VMEngine_Unchecked);
return;
}
}
Printf("Usage: vmengine <default|checked|unchecked>\n");
}
//-----------------------------------------------------------------------------
//
// Print secret info (submitted by Karl Murks)

View file

@ -68,6 +68,7 @@
#include "gstrings.h"
#include "c_consolebuffer.h"
#include "g_levellocals.h"
#include "vm.h"
FString FStringFormat(VM_ARGS); // extern from thingdef_data.cpp

View file

@ -52,6 +52,7 @@
#include "v_video.h"
#include "colormatcher.h"
#include "menu/menu.h"
#include "vm.h"
struct FLatchedValue
{

View file

@ -55,6 +55,7 @@
#include "d_main.h"
#include "serializer.h"
#include "menu/menu.h"
#include "vm.h"
// MACROS ------------------------------------------------------------------

View file

@ -74,6 +74,7 @@
#include "info.h"
#include "v_text.h"
#include "backend/vmbuilder.h"
#include "types.h"
// [SO] Just the way Randy said to do it :)
// [RH] Made this CVAR_SERVERINFO

View file

@ -112,6 +112,8 @@
#include "g_levellocals.h"
#include "events.h"
#include "r_utility.h"
#include "vm.h"
#include "types.h"
EXTERN_CVAR(Bool, hud_althud)
void DrawHUD();

View file

@ -57,6 +57,7 @@
#include "templates.h"
#include "cmdlib.h"
#include "serializer.h"
#include "vm.h"
static FRandom pr_pickteam ("PickRandomTeam");

View file

@ -48,8 +48,9 @@
#include "a_sharedglobal.h"
#include "dsectoreffect.h"
#include "serializer.h"
#include "virtual.h"
#include "vm.h"
#include "g_levellocals.h"
#include "types.h"
//==========================================================================
//
@ -372,7 +373,7 @@ void DObject:: Destroy ()
IFVIRTUAL(DObject, OnDestroy)
{
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0);
VMCall(func, params, 1, nullptr, 0);
}
}
OnDestroy();

View file

@ -247,13 +247,13 @@ public:
void Destroy();
// Add other types as needed.
bool &BoolVar(FName field);
int &IntVar(FName field);
FSoundID &SoundVar(FName field);
PalEntry &ColorVar(FName field);
FName &NameVar(FName field);
double &FloatVar(FName field);
FString &StringVar(FName field);
inline bool &BoolVar(FName field);
inline int &IntVar(FName field);
inline FSoundID &SoundVar(FName field);
inline PalEntry &ColorVar(FName field);
inline FName &NameVar(FName field);
inline double &FloatVar(FName field);
inline FString &StringVar(FName field);
template<class T> T*& PointerVar(FName field);
// If you need to replace one object with another and want to
@ -409,4 +409,40 @@ template<class T> const T *dyn_cast(const DObject *p)
return dyn_cast<T>(const_cast<DObject *>(p));
}
inline bool &DObject::BoolVar(FName field)
{
return *(bool*)ScriptVar(field, nullptr);
}
inline int &DObject::IntVar(FName field)
{
return *(int*)ScriptVar(field, nullptr);
}
inline FSoundID &DObject::SoundVar(FName field)
{
return *(FSoundID*)ScriptVar(field, nullptr);
}
inline PalEntry &DObject::ColorVar(FName field)
{
return *(PalEntry*)ScriptVar(field, nullptr);
}
inline FName &DObject::NameVar(FName field)
{
return *(FName*)ScriptVar(field, nullptr);
}
inline double &DObject::FloatVar(FName field)
{
return *(double*)ScriptVar(field, nullptr);
}
template<class T>
inline T *&DObject::PointerVar(FName field)
{
return *(T**)ScriptVar(field, nullptr); // pointer check is more tricky and for the handful of uses in the DECORATE parser not worth the hassle.
}
#endif //__DOBJECT_H__

File diff suppressed because it is too large Load diff

View file

@ -5,50 +5,17 @@
#error You must #include "dobject.h" to get dobjtype.h
#endif
typedef std::pair<const class PType *, unsigned> FTypeAndOffset;
class PStruct;
#include "memarena.h"
typedef std::pair<const class PType *, unsigned> FTypeAndOffset;
#if 0
// This is intentionally not in vm.h so that this file remains free of DObject pollution.
class VMException : public DObject
{
DECLARE_CLASS(VMException, DObject);
};
#include "vm.h"
// Variable/parameter/field flags -------------------------------------------
// Making all these different storage types use a common set of flags seems
// like the simplest thing to do.
enum
{
VARF_Optional = (1<<0), // func param is optional
VARF_Method = (1<<1), // func has an implied self parameter
VARF_Action = (1<<2), // func has implied owner and state parameters
VARF_Native = (1<<3), // func is native code, field is natively defined
VARF_ReadOnly = (1<<4), // field is read only, do not write to it
VARF_Private = (1<<5), // field is private to containing class
VARF_Protected = (1<<6), // field is only accessible by containing class and children.
VARF_Deprecated = (1<<7), // Deprecated fields should output warnings when used.
VARF_Virtual = (1<<8), // function is virtual
VARF_Final = (1<<9), // Function may not be overridden in subclasses
VARF_In = (1<<10),
VARF_Out = (1<<11),
VARF_Implicit = (1<<12), // implicitly created parameters (i.e. do not compare types when checking function signatures)
VARF_Static = (1<<13),
VARF_InternalAccess = (1<<14), // overrides VARF_ReadOnly for internal script code.
VARF_Override = (1<<15), // overrides a virtual function from the parent class.
VARF_Ref = (1<<16), // argument is passed by reference.
VARF_Transient = (1<<17), // don't auto serialize field.
VARF_Meta = (1<<18), // static class data (by necessity read only.)
VARF_VarArg = (1<<19), // [ZZ] vararg: don't typecheck values after ... in function signature
VARF_UI = (1<<20), // [ZZ] ui: object is ui-scope only (can't modify playsim)
VARF_Play = (1<<21), // [ZZ] play: object is playsim-scope only (can't access ui)
VARF_VirtualScope = (1<<22), // [ZZ] virtualscope: object should use the scope of the particular class it's being used with (methods only)
VARF_ClearScope = (1<<23), // [ZZ] clearscope: this method ignores the member access chain that leads to it and is always plain data.
};
#endif
// An action function -------------------------------------------------------
@ -58,549 +25,16 @@ class VMFrameStack;
struct VMValue;
struct VMReturn;
class VMFunction;
class PClassType;
struct FNamespaceManager;
// Basic information shared by all types ------------------------------------
// Only one copy of a type is ever instantiated at one time.
// - Enums, classes, and structs are defined by their names and outer classes.
// - Pointers are uniquely defined by the type they point at.
// - ClassPointers are also defined by their class restriction.
// - Arrays are defined by their element type and count.
// - DynArrays are defined by their element type.
// - Maps are defined by their key and value types.
// - Prototypes are defined by the argument and return types.
// - Functions are defined by their names and outer objects.
// In table form:
// Outer Name Type Type2 Count
// Enum * *
// Class * *
// Struct * *
// Function * *
// Pointer *
// ClassPointer + *
// Array * *
// DynArray *
// Map * *
// Prototype *+ *+
struct ZCC_ExprConstant;
class PType : public PTypeBase
{
DECLARE_ABSTRACT_CLASS(PType, PTypeBase)
protected:
public:
PClass *TypeTableType; // The type to use for hashing into the type table
unsigned int Size; // this type's size
unsigned int Align; // this type's preferred alignment
PType *HashNext; // next type in this type table
PSymbolTable Symbols;
bool MemberOnly = false; // type may only be used as a struct/class member but not as a local variable or function argument.
FString mDescriptiveName;
VersionInfo mVersion = { 0,0,0 };
uint8_t loadOp, storeOp, moveOp, RegType, RegCount;
PType(unsigned int size = 1, unsigned int align = 1);
virtual ~PType();
virtual bool isNumeric() { return false; }
// Writes the value of a variable of this type at (addr) to an archive, preceded by
// a tag indicating its type. The tag is there so that variable types can be changed
// without completely breaking savegames, provided that the change isn't between
// totally unrelated types.
virtual void WriteValue(FSerializer &ar, const char *key,const void *addr) const;
// Returns true if the stored value was compatible. False otherwise.
// If the value was incompatible, then the memory at *addr is unchanged.
virtual bool ReadValue(FSerializer &ar, const char *key,void *addr) const;
// Sets the default value for this type at (base + offset)
// If the default value is binary 0, then this function doesn't need
// to do anything, because PClass::Extend() takes care of that.
//
// The stroffs array is so that types that need special initialization
// and destruction (e.g. strings) can add their offsets to it for special
// initialization when the object is created and destruction when the
// object is destroyed.
virtual void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL);
virtual void SetPointer(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL);
virtual void SetPointerArray(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) const;
// Initialize the value, if needed (e.g. strings)
virtual void InitializeValue(void *addr, const void *def) const;
// Destroy the value, if needed (e.g. strings)
virtual void DestroyValue(void *addr) const;
// Sets the value of a variable of this type at (addr)
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
// Gets the value of a variable of this type at (addr)
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
// Gets the opcode to store from a register to memory
int GetStoreOp() const
{
return storeOp;
}
// Gets the opcode to load from memory to a register
int GetLoadOp() const
{
return loadOp;
}
// Gets the opcode to move from register to another register
int GetMoveOp() const
{
return moveOp;
}
// Gets the register type for this type
int GetRegType() const
{
return RegType;
}
int GetRegCount() const
{
return RegCount;
}
// Returns true if this type matches the two identifiers. Referring to the
// above table, any type is identified by at most two characteristics. Each
// type that implements this function will cast these to the appropriate type.
// It is up to the caller to make sure they are the correct types. There is
// only one prototype for this function in order to simplify type table
// management.
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
// Get the type IDs used by IsMatch
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
const char *DescriptiveName() const;
static void StaticInit();
};
// Not-really-a-type types --------------------------------------------------
class PErrorType : public PType
{
DECLARE_CLASS(PErrorType, PType);
public:
PErrorType(int which = 1) : PType(0, which) {}
};
class PVoidType : public PType
{
DECLARE_CLASS(PVoidType, PType);
public:
PVoidType() : PType(0, 1) {}
};
// Some categorization typing -----------------------------------------------
class PBasicType : public PType
{
DECLARE_ABSTRACT_CLASS(PBasicType, PType);
public:
PBasicType();
PBasicType(unsigned int size, unsigned int align);
};
class PCompoundType : public PType
{
DECLARE_ABSTRACT_CLASS(PCompoundType, PType);
};
class PContainerType : public PCompoundType
{
DECLARE_ABSTRACT_CLASS(PContainerType, PCompoundType);
public:
PTypeBase *Outer; // object this type is contained within
FName TypeName; // this type's name
PContainerType() : Outer(NULL) {
mDescriptiveName = "NamedType";
}
PContainerType(FName name, PTypeBase *outer) : Outer(outer), TypeName(name) {
mDescriptiveName = name.GetChars();
}
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
virtual PField *AddField(FName name, PType *type, uint32_t flags = 0) = 0;
virtual PField *AddNativeField(FName name, PType *type, size_t address, uint32_t flags = 0, int bitvalue = 0) = 0;
};
// Basic types --------------------------------------------------------------
class PInt : public PBasicType
{
DECLARE_CLASS(PInt, PBasicType);
public:
PInt(unsigned int size, bool unsign, bool compatible = true);
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
virtual bool isNumeric() override { return IntCompatible; }
bool Unsigned;
bool IntCompatible;
protected:
PInt();
void SetOps();
};
class PBool : public PInt
{
DECLARE_CLASS(PBool, PInt);
public:
PBool();
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
};
class PFloat : public PBasicType
{
DECLARE_CLASS(PFloat, PBasicType);
public:
PFloat(unsigned int size);
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
virtual bool isNumeric() override { return true; }
protected:
PFloat();
void SetOps();
private:
struct SymbolInitF
{
ENamedName Name;
double Value;
};
struct SymbolInitI
{
ENamedName Name;
int Value;
};
void SetSingleSymbols();
void SetDoubleSymbols();
void SetSymbols(const SymbolInitF *syminit, size_t count);
void SetSymbols(const SymbolInitI *syminit, size_t count);
};
class PString : public PBasicType
{
DECLARE_CLASS(PString, PBasicType);
public:
PString();
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) override;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
};
// Variations of integer types ----------------------------------------------
class PName : public PInt
{
DECLARE_CLASS(PName, PInt);
public:
PName();
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
};
class PSound : public PInt
{
DECLARE_CLASS(PSound, PInt);
public:
PSound();
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
};
class PSpriteID : public PInt
{
DECLARE_CLASS(PSpriteID, PInt);
public:
PSpriteID();
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
};
class PTextureID : public PInt
{
DECLARE_CLASS(PTextureID, PInt);
public:
PTextureID();
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
};
class PColor : public PInt
{
DECLARE_CLASS(PColor, PInt);
public:
PColor();
};
class PStateLabel : public PInt
{
DECLARE_CLASS(PStateLabel, PInt);
public:
PStateLabel();
};
// Pointers -----------------------------------------------------------------
class PPointer : public PBasicType
{
DECLARE_CLASS(PPointer, PBasicType);
public:
typedef void(*WriteHandler)(FSerializer &ar, const char *key, const void *addr);
typedef bool(*ReadHandler)(FSerializer &ar, const char *key, void *addr);
PPointer();
PPointer(PType *pointsat, bool isconst = false);
PType *PointedType;
bool IsConst;
WriteHandler writer = nullptr;
ReadHandler reader = nullptr;
void InstallHandlers(WriteHandler w, ReadHandler r)
{
writer = w;
reader = r;
}
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
protected:
void SetOps();
};
class PStatePointer : public PPointer
{
DECLARE_CLASS(PStatePointer, PPointer);
public:
PStatePointer();
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
};
class PObjectPointer : public PPointer
{
DECLARE_CLASS(PObjectPointer, PPointer);
public:
PObjectPointer(PClass *pointedtype = nullptr, bool isconst = false);
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) override;
PClass *PointedClass() const;
};
class PClassPointer : public PPointer
{
DECLARE_CLASS(PClassPointer, PPointer);
public:
PClassPointer(class PClass *restrict = nullptr);
class PClass *ClassRestriction;
bool isCompatible(PType *type);
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) override;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
};
// Compound types -----------------------------------------------------------
class PEnum : public PInt
{
DECLARE_CLASS(PEnum, PInt);
public:
PEnum(FName name, PTypeBase *outer);
PTypeBase *Outer;
FName EnumName;
protected:
PEnum();
};
class PArray : public PCompoundType
{
DECLARE_CLASS(PArray, PCompoundType);
public:
PArray(PType *etype, unsigned int ecount);
PType *ElementType;
unsigned int ElementCount;
unsigned int ElementSize;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special) override;
protected:
PArray();
};
class PStaticArray : public PArray
{
DECLARE_CLASS(PStaticArray, PArray);
public:
PStaticArray(PType *etype);
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
protected:
PStaticArray();
};
class PDynArray : public PCompoundType
{
DECLARE_CLASS(PDynArray, PCompoundType);
public:
PDynArray(PType *etype, PStruct *backing);
PType *ElementType;
PStruct *BackingType;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) override;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
void SetPointerArray(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) const override;
protected:
PDynArray();
};
class PMap : public PCompoundType
{
DECLARE_CLASS(PMap, PCompoundType);
public:
PMap(PType *keytype, PType *valtype);
PType *KeyType;
PType *ValueType;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
protected:
PMap();
};
class PStruct : public PContainerType
{
DECLARE_CLASS(PStruct, PContainerType);
public:
PStruct(FName name, PTypeBase *outer, bool isnative = false);
bool isNative;
// Some internal structs require explicit construction and destruction of fields the VM cannot handle directly so use these two functions for it.
VMFunction *mConstructor = nullptr;
VMFunction *mDestructor = nullptr;
virtual PField *AddField(FName name, PType *type, uint32_t flags=0);
virtual PField *AddNativeField(FName name, PType *type, size_t address, uint32_t flags = 0, int bitvalue = 0);
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *specials) override;
protected:
PStruct();
};
class PPrototype : public PCompoundType
{
DECLARE_CLASS(PPrototype, PCompoundType);
public:
PPrototype(const TArray<PType *> &rettypes, const TArray<PType *> &argtypes);
TArray<PType *> ArgumentTypes;
TArray<PType *> ReturnTypes;
size_t PropagateMark();
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
protected:
PPrototype();
};
// Meta-info for every class derived from DObject ---------------------------
extern FMemArena ClassDataAllocator;
enum
{
TentativeClass = UINT_MAX,
};
class PClassType : public PContainerType
{
DECLARE_CLASS(PClassType, PContainerType);
private:
public:
PClass *Descriptor;
PClassType *ParentType;
PClassType(PClass *cls = nullptr);
PField *AddField(FName name, PType *type, uint32_t flags = 0) override;
PField *AddNativeField(FName name, PType *type, size_t address, uint32_t flags = 0, int bitvalue = 0) override;
};
class PClass
{
@ -710,107 +144,4 @@ public:
static bool bVMOperational;
};
// Type tables --------------------------------------------------------------
struct FTypeTable
{
enum { HASH_SIZE = 1021 };
PType *TypeHash[HASH_SIZE];
PType *FindType(PClass *metatype, intptr_t parm1, intptr_t parm2, size_t *bucketnum);
void AddType(PType *type, PClass *metatype, intptr_t parm1, intptr_t parm2, size_t bucket);
void AddType(PType *type);
void Clear();
static size_t Hash(const PClass *p1, intptr_t p2, intptr_t p3);
};
extern FTypeTable TypeTable;
// Returns a type from the TypeTable. Will create one if it isn't present.
PMap *NewMap(PType *keytype, PType *valuetype);
PArray *NewArray(PType *type, unsigned int count);
PStaticArray *NewStaticArray(PType *type);
PDynArray *NewDynArray(PType *type);
PPointer *NewPointer(PType *type, bool isconst = false);
PPointer *NewPointer(PClass *type, bool isconst = false);
PClassPointer *NewClassPointer(PClass *restrict);
PEnum *NewEnum(FName name, PTypeBase *outer);
PStruct *NewStruct(FName name, PTypeBase *outer, bool native = false);
PPrototype *NewPrototype(const TArray<PType *> &rettypes, const TArray<PType *> &argtypes);
PClassType *NewClassType(PClass *cls);
// Built-in types -----------------------------------------------------------
extern PErrorType *TypeError;
extern PErrorType *TypeAuto;
extern PVoidType *TypeVoid;
extern PInt *TypeSInt8, *TypeUInt8;
extern PInt *TypeSInt16, *TypeUInt16;
extern PInt *TypeSInt32, *TypeUInt32;
extern PBool *TypeBool;
extern PFloat *TypeFloat32, *TypeFloat64;
extern PString *TypeString;
extern PName *TypeName;
extern PSound *TypeSound;
extern PColor *TypeColor;
extern PTextureID *TypeTextureID;
extern PSpriteID *TypeSpriteID;
extern PStruct *TypeVector2;
extern PStruct *TypeVector3;
extern PStruct *TypeColorStruct;
extern PStruct *TypeStringStruct;
extern PStatePointer *TypeState;
extern PPointer *TypeFont;
extern PStateLabel *TypeStateLabel;
extern PPointer *TypeNullPtr;
extern PPointer *TypeVoidPtr;
// Enumerations for serializing types in an archive -------------------------
inline bool &DObject::BoolVar(FName field)
{
return *(bool*)ScriptVar(field, TypeBool);
}
inline int &DObject::IntVar(FName field)
{
return *(int*)ScriptVar(field, TypeSInt32);
}
inline FSoundID &DObject::SoundVar(FName field)
{
return *(FSoundID*)ScriptVar(field, TypeSound);
}
inline PalEntry &DObject::ColorVar(FName field)
{
return *(PalEntry*)ScriptVar(field, TypeColor);
}
inline FName &DObject::NameVar(FName field)
{
return *(FName*)ScriptVar(field, TypeName);
}
inline double &DObject::FloatVar(FName field)
{
return *(double*)ScriptVar(field, TypeFloat64);
}
inline FString &DObject::StringVar(FName field)
{
return *(FString*)ScriptVar(field, TypeString);
}
template<class T>
inline T *&DObject::PointerVar(FName field)
{
return *(T**)ScriptVar(field, nullptr); // pointer check is more tricky and for the handful of uses in the DECORATE parser not worth the hassle.
}
void RemoveUnusedSymbols();
#endif

View file

@ -61,7 +61,6 @@ CUSTOM_CVAR (String, language, "auto", CVAR_ARCHIVE)
// [RH] Network arbitrator
int Net_Arbitrator = 0;
DEFINE_GLOBAL(Net_Arbitrator);
int NextSkill = -1;

View file

@ -31,6 +31,7 @@
#include "statnums.h"
#include "serializer.h"
#include "doomstat.h"
#include "vm.h"
IMPLEMENT_CLASS(DSectorEffect, false, false)

View file

@ -40,7 +40,7 @@
#include "doomerrors.h"
#include "serializer.h"
#include "d_player.h"
#include "virtual.h"
#include "vm.h"
static int ThinkCount;
@ -315,7 +315,7 @@ void DThinker::CallPostBeginPlay()
{
// Without the type cast this picks the 'void *' assignment...
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
else
{
@ -560,7 +560,7 @@ void DThinker::CallTick()
{
// Without the type cast this picks the 'void *' assignment...
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
else Tick();
}

View file

@ -1,5 +1,5 @@
#include "events.h"
#include "virtual.h"
#include "vm.h"
#include "r_utility.h"
#include "g_levellocals.h"
#include "gi.h"
@ -7,6 +7,7 @@
#include "actor.h"
#include "c_dispatch.h"
#include "d_net.h"
#include "vm.h"
DStaticEventHandler* E_FirstEventHandler = nullptr;
DStaticEventHandler* E_LastEventHandler = nullptr;
@ -626,7 +627,7 @@ void DStaticEventHandler::OnRegister()
if (func == DStaticEventHandler_OnRegister_VMPtr)
return;
VMValue params[1] = { (DStaticEventHandler*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
@ -638,7 +639,7 @@ void DStaticEventHandler::OnUnregister()
if (func == DStaticEventHandler_OnUnregister_VMPtr)
return;
VMValue params[1] = { (DStaticEventHandler*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
@ -660,7 +661,7 @@ void DStaticEventHandler::WorldLoaded()
return;
FWorldEvent e = E_SetupWorldEvent();
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -673,7 +674,7 @@ void DStaticEventHandler::WorldUnloaded()
return;
FWorldEvent e = E_SetupWorldEvent();
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -687,7 +688,7 @@ void DStaticEventHandler::WorldThingSpawned(AActor* actor)
FWorldEvent e = E_SetupWorldEvent();
e.Thing = actor;
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -702,7 +703,7 @@ void DStaticEventHandler::WorldThingDied(AActor* actor, AActor* inflictor)
e.Thing = actor;
e.Inflictor = inflictor;
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -716,7 +717,7 @@ void DStaticEventHandler::WorldThingRevived(AActor* actor)
FWorldEvent e = E_SetupWorldEvent();
e.Thing = actor;
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -735,7 +736,7 @@ void DStaticEventHandler::WorldThingDamaged(AActor* actor, AActor* inflictor, AA
e.DamageFlags = flags;
e.DamageAngle = angle;
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -749,7 +750,7 @@ void DStaticEventHandler::WorldThingDestroyed(AActor* actor)
FWorldEvent e = E_SetupWorldEvent();
e.Thing = actor;
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -762,7 +763,7 @@ void DStaticEventHandler::WorldLightning()
return;
FWorldEvent e = E_SetupWorldEvent();
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -774,7 +775,7 @@ void DStaticEventHandler::WorldTick()
if (func == DStaticEventHandler_WorldTick_VMPtr)
return;
VMValue params[1] = { (DStaticEventHandler*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
@ -799,7 +800,7 @@ void DStaticEventHandler::RenderFrame()
return;
FRenderEvent e = E_SetupRenderEvent();
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -813,7 +814,7 @@ void DStaticEventHandler::RenderOverlay(EHudState state)
FRenderEvent e = E_SetupRenderEvent();
e.HudState = int(state);
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -826,7 +827,7 @@ void DStaticEventHandler::PlayerEntered(int num, bool fromhub)
return;
FPlayerEvent e = { num, fromhub };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -839,7 +840,7 @@ void DStaticEventHandler::PlayerRespawned(int num)
return;
FPlayerEvent e = { num, false };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -852,7 +853,7 @@ void DStaticEventHandler::PlayerDied(int num)
return;
FPlayerEvent e = { num, false };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -865,7 +866,7 @@ void DStaticEventHandler::PlayerDisconnected(int num)
return;
FPlayerEvent e = { num, false };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
@ -921,7 +922,7 @@ bool DStaticEventHandler::UiProcess(const event_t* ev)
int processed;
VMReturn results[1] = { &processed };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, results, 1, nullptr);
VMCall(func, params, 2, results, 1);
return !!processed;
}
@ -969,7 +970,7 @@ bool DStaticEventHandler::InputProcess(const event_t* ev)
int processed;
VMReturn results[1] = { &processed };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, results, 1, nullptr);
VMCall(func, params, 2, results, 1);
return !!processed;
}
@ -984,7 +985,7 @@ void DStaticEventHandler::UiTick()
if (func == DStaticEventHandler_UiTick_VMPtr)
return;
VMValue params[1] = { (DStaticEventHandler*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
@ -1008,7 +1009,7 @@ void DStaticEventHandler::ConsoleProcess(int player, FString name, int arg1, int
e.IsManual = manual;
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
else
@ -1029,7 +1030,7 @@ void DStaticEventHandler::ConsoleProcess(int player, FString name, int arg1, int
e.IsManual = manual;
VMValue params[2] = { (DStaticEventHandler*)this, &e };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
}
}

View file

@ -85,6 +85,7 @@
#include "serializer.h"
#include "w_zip.h"
#include "resourcefiles/resourcefile.h"
#include "vm.h"
#include <zlib.h>
@ -3010,3 +3011,5 @@ DEFINE_GLOBAL(skyflatnum)
DEFINE_GLOBAL_NAMED(bglobal.freeze, globalfreeze)
DEFINE_GLOBAL(gametic)
DEFINE_GLOBAL(demoplayback)
DEFINE_GLOBAL(automapactive);
DEFINE_GLOBAL(Net_Arbitrator);

View file

@ -43,7 +43,7 @@
#include "w_wad.h"
#include "doomstat.h"
#include "v_font.h"
#include "vm.h"
//===========================================================================
//

View file

@ -19,9 +19,10 @@
#include "d_player.h"
#include "p_spec.h"
#include "serializer.h"
#include "virtual.h"
#include "vm.h"
#include "c_functions.h"
#include "g_levellocals.h"
#include "vm.h"
EXTERN_CVAR(Bool, sv_unlimited_pickup)
@ -237,7 +238,7 @@ double AInventory::GetSpeedFactor()
VMValue params[1] = { (DObject*)self };
double retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr);
VMCall(func, params, 1, &ret, 1);
factor *= retval;
}
self = self->Inventory;
@ -261,7 +262,7 @@ bool AInventory::GetNoTeleportFreeze ()
VMValue params[1] = { (DObject*)self };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr);
VMCall(func, params, 1, &ret, 1);
if (retval) return true;
}
self = self->Inventory;
@ -282,7 +283,7 @@ bool AInventory::CallUse(bool pickup)
VMValue params[2] = { (DObject*)this, pickup };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr);
VMCall(func, params, 2, &ret, 1);
return !!retval;
}
return false;
@ -347,7 +348,7 @@ void AInventory::DepleteOrDestroy ()
IFVIRTUAL(AInventory, DepleteOrDestroy)
{
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
@ -367,7 +368,7 @@ PalEntry AInventory::CallGetBlend()
VMValue params[1] = { (DObject*)this };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr);
VMCall(func, params, 1, &ret, 1);
return retval;
}
else return 0;
@ -479,7 +480,7 @@ bool AInventory::CallTryPickup(AActor *toucher, AActor **toucher_return)
AActor *tret;
ret[0].IntAt(&res);
ret[1].PointerAt((void**)&tret);
GlobalVMStack.Call(func, params, 2, ret, 2);
VMCall(func, params, 2, ret, 2);
if (toucher_return) *toucher_return = tret;
return !!res;
}

View file

@ -52,11 +52,7 @@
#include "g_level.h"
#include "d_net.h"
#include "serializer.h"
#include "thingdef.h"
#include "virtual.h"
extern FFlagDef WeaponFlagDefs[];
#include "vm.h"
IMPLEMENT_CLASS(AWeapon, false, true)
@ -66,7 +62,6 @@ IMPLEMENT_POINTERS_START(AWeapon)
IMPLEMENT_POINTER(SisterWeapon)
IMPLEMENT_POINTERS_END
DEFINE_FIELD(AWeapon, WeaponFlags)
DEFINE_FIELD(AWeapon, AmmoType1)
DEFINE_FIELD(AWeapon, AmmoType2)
DEFINE_FIELD(AWeapon, AmmoGive1)
@ -99,6 +94,7 @@ DEFINE_FIELD(AWeapon, Crosshair)
DEFINE_FIELD(AWeapon, GivenAsMorphWeapon)
DEFINE_FIELD(AWeapon, bAltFire)
DEFINE_FIELD(AWeapon, SlotNumber)
DEFINE_FIELD(AWeapon, WeaponFlags)
DEFINE_FIELD_BIT(AWeapon, WeaponFlags, bDehAmmo, WIF_DEHAMMO)
//===========================================================================
@ -404,7 +400,7 @@ FState *AWeapon::GetUpState ()
VMReturn ret;
FState *retval;
ret.PointerAt((void**)&retval);
GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr);
VMCall(func, params, 1, &ret, 1);
return retval;
}
return nullptr;
@ -424,7 +420,7 @@ FState *AWeapon::GetDownState ()
VMReturn ret;
FState *retval;
ret.PointerAt((void**)&retval);
GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr);
VMCall(func, params, 1, &ret, 1);
return retval;
}
return nullptr;
@ -444,7 +440,7 @@ FState *AWeapon::GetReadyState ()
VMReturn ret;
FState *retval;
ret.PointerAt((void**)&retval);
GlobalVMStack.Call(func, params, 1, &ret, 1, nullptr);
VMCall(func, params, 1, &ret, 1);
return retval;
}
return nullptr;
@ -464,7 +460,7 @@ FState *AWeapon::GetAtkState (bool hold)
VMReturn ret;
FState *retval;
ret.PointerAt((void**)&retval);
GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr);
VMCall(func, params, 2, &ret, 1);
return retval;
}
return nullptr;
@ -484,7 +480,7 @@ FState *AWeapon::GetAltAtkState (bool hold)
VMReturn ret;
FState *retval;
ret.PointerAt((void**)&retval);
GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr);
VMCall(func, params, 2, &ret, 1);
return retval;
}
return nullptr;

View file

@ -84,7 +84,7 @@
#include "r_utility.h"
#include "p_spec.h"
#include "serializer.h"
#include "virtual.h"
#include "vm.h"
#include "events.h"
#include "gi.h"
@ -92,6 +92,7 @@
#include "g_hub.h"
#include "g_levellocals.h"
#include "actorinlines.h"
#include "vm.h"
#include <string.h>
@ -1318,8 +1319,7 @@ void G_FinishTravel ()
IFVIRTUALPTR(inv, AInventory, Travelled)
{
VMValue params[1] = { inv };
VMFrameStack stack;
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
if (ib_compatflags & BCOMPATF_RESETPLAYERSPEED)

View file

@ -11,6 +11,7 @@
#include "templates.h"
#include "serializer.h"
#include "r_data/r_translate.h"
#include "vm.h"
//----------------------------------------------------------------------------
//

View file

@ -60,7 +60,7 @@
#include "p_local.h"
#include "c_dispatch.h"
#include "g_level.h"
#include "scripting/thingdef.h"
#include "thingdef.h"
#include "i_system.h"
#include "templates.h"
#include "doomdata.h"
@ -74,6 +74,7 @@
#include "actorinlines.h"
#include "c_cvars.h"
#include "gl/system//gl_interface.h"
#include "vm.h"
EXTERN_CVAR(Int, vid_renderer)

View file

@ -15,7 +15,8 @@
#include "d_player.h"
#include "r_data/sprites.h"
#include "g_levellocals.h"
#include "virtual.h"
#include "vm.h"
#include "vm.h"
static FRandom pr_morphmonst ("MorphMonster");
@ -612,8 +613,7 @@ void EndAllPowerupEffects(AInventory *item)
IFVIRTUALPTRNAME(item, NAME_Powerup, EndEffect)
{
VMValue params[1] = { item };
VMFrameStack stack;
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
item = item->Inventory;
@ -638,8 +638,7 @@ void InitAllPowerupEffects(AInventory *item)
IFVIRTUALPTRNAME(item, NAME_Powerup, InitEffect)
{
VMValue params[1] = { item };
VMFrameStack stack;
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
item = item->Inventory;

View file

@ -40,6 +40,7 @@
#include "doomstat.h"
#include "serializer.h"
#include "a_pickups.h"
#include "vm.h"
static FRandom pr_spot ("SpecialSpot");
static FRandom pr_spawnmace ("SpawnMace");

View file

@ -54,7 +54,7 @@
#include "r_utility.h"
#include "cmdlib.h"
#include "g_levellocals.h"
#include "virtual.h"
#include "vm.h"
#include <time.h>
@ -1093,7 +1093,7 @@ static void DrawPowerups(player_t *CPlayer)
VMValue param[] = { item };
int rv;
VMReturn ret(&rv);
GlobalVMStack.Call(func, param, 1, &ret, 1);
VMCall(func, param, 1, &ret, 1);
auto tex = FSetTextureID(rv);
if (!tex.isValid()) continue;
auto texture = TexMan(tex);

View file

@ -44,6 +44,7 @@
#include "m_fixed.h"
#include "gstrings.h"
#include "g_levellocals.h"
#include "vm.h"
TArray<FSkillInfo> AllSkills;
int DefaultSkill = -1;

View file

@ -57,7 +57,7 @@
#include "gstrings.h"
#include "cmdlib.h"
#include "g_levellocals.h"
#include "virtual.h"
#include "vm.h"
#define ARTIFLASH_OFFSET (statusBar->invBarOffset+6)
enum

View file

@ -1441,7 +1441,7 @@ class CommandDrawNumber : public CommandDrawString
VMValue params[] = { statusBar->CPlayer->mo, inventoryItem };
int retv;
VMReturn ret(&retv);
GlobalVMStack.Call(func, params, 2, &ret, 1);
VMCall(func, params, 2, &ret, 1);
num = retv < 0? 0 : retv / TICRATE + 1;
break;
}
@ -2738,7 +2738,7 @@ class CommandDrawBar : public SBarInfoCommand
int ival;
ret[0].IntAt(&ival);
ret[1].IntAt(&max);
GlobalVMStack.Call(func, params, 2, ret, 2);
VMCall(func, params, 2, ret, 2);
value = ival + 1;
max++;
break;

View file

@ -57,7 +57,7 @@
#include "r_utility.h"
#include "cmdlib.h"
#include "g_levellocals.h"
#include "virtual.h"
#include "vm.h"
#include "p_acs.h"
#include "r_data/r_translate.h"
#include "sbarinfo.h"
@ -329,7 +329,7 @@ void ST_CreateStatusBar(bool bTitleLevel)
IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init)
{
VMValue params[] = { StatusBar };
GlobalVMStack.Call(func, params, 1, nullptr, 0);
VMCall(func, params, 1, nullptr, 0);
}
GC::WriteBarrier(StatusBar);
@ -560,7 +560,7 @@ void DBaseStatusBar::AttachToPlayer(player_t *player)
IFVIRTUAL(DBaseStatusBar, AttachToPlayer)
{
VMValue params[] = { (DObject*)this, player };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
VMCall(func, params, countof(params), nullptr, 0);
}
}
@ -641,7 +641,7 @@ void DBaseStatusBar::CallTick()
IFVIRTUAL(DBaseStatusBar, Tick)
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
VMCall(func, params, countof(params), nullptr, 0);
}
else Tick();
mugshot.Tick(CPlayer);
@ -973,7 +973,7 @@ void DBaseStatusBar::Draw (EHudState state)
IFVIRTUAL(DBaseStatusBar, DrawMyPos)
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
VMCall(func, params, countof(params), nullptr, 0);
}
V_SetBorderNeedRefresh();
}
@ -990,7 +990,7 @@ void DBaseStatusBar::Draw (EHudState state)
IFVIRTUAL(DBaseStatusBar, DrawAutomapHUD)
{
VMValue params[] = { (DObject*)this, r_viewpoint.TicFrac };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
VMCall(func, params, countof(params), nullptr, 0);
}
}
}
@ -1008,7 +1008,7 @@ void DBaseStatusBar::CallDraw(EHudState state)
IFVIRTUAL(DBaseStatusBar, Draw)
{
VMValue params[] = { (DObject*)this, state, r_viewpoint.TicFrac };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
VMCall(func, params, countof(params), nullptr, 0);
}
else Draw(state);
screen->ClearClipRect(); // make sure the scripts don't leave a valid clipping rect behind.
@ -1073,7 +1073,7 @@ bool DBaseStatusBar::MustDrawLog(EHudState state)
VMValue params[] = { (DObject*)this };
int rv;
VMReturn ret(&rv);
GlobalVMStack.Call(func, params, countof(params), &ret, 1);
VMCall(func, params, countof(params), &ret, 1);
return !!rv;
}
return true;
@ -1095,7 +1095,7 @@ void DBaseStatusBar::SetMugShotState(const char *stateName, bool waitTillDone, b
{
FString statestring = stateName;
VMValue params[] = { (DObject*)this, &statestring, waitTillDone, reset };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
VMCall(func, params, countof(params), nullptr, 0);
}
}
@ -1133,7 +1133,7 @@ void DBaseStatusBar::DrawTopStuff (EHudState state)
IFVIRTUAL(DBaseStatusBar, DrawPowerups)
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0);
VMCall(func, params, 1, nullptr, 0);
}
fullscreenOffsets = saved;
}
@ -1261,7 +1261,7 @@ void DBaseStatusBar::FlashItem (const PClass *itemtype)
IFVIRTUAL(DBaseStatusBar, FlashItem)
{
VMValue params[] = { (DObject*)this, (PClass*)itemtype };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
VMCall(func, params, countof(params), nullptr, 0);
}
}
@ -1270,7 +1270,7 @@ void DBaseStatusBar::NewGame ()
IFVIRTUAL(DBaseStatusBar, NewGame)
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
VMCall(func, params, countof(params), nullptr, 0);
}
mugshot.Reset();
}
@ -1280,7 +1280,7 @@ void DBaseStatusBar::ShowPop(int pop)
IFVIRTUAL(DBaseStatusBar, ShowPop)
{
VMValue params[] = { (DObject*)this, pop };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
VMCall(func, params, countof(params), nullptr, 0);
}
}
@ -1319,7 +1319,7 @@ void DBaseStatusBar::CallScreenSizeChanged()
IFVIRTUAL(DBaseStatusBar, ScreenSizeChanged)
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
VMCall(func, params, countof(params), nullptr, 0);
}
else ScreenSizeChanged();
}

View file

@ -42,6 +42,7 @@
#include "i_system.h"
#include "v_video.h"
#include "g_level.h"
#include "vm.h"
gameinfo_t gameinfo;

View file

@ -33,6 +33,7 @@
#include "c_dispatch.h"
#include "r_state.h"
#include "actor.h"
#include "cmdlib.h"
#ifdef _WIN32
#include "win32gliface.h"
#endif

View file

@ -55,6 +55,8 @@
#include "d_player.h"
#include "doomerrors.h"
#include "events.h"
#include "types.h"
#include "vm.h"
extern void LoadActors ();
extern void InitBotStuff();
@ -128,35 +130,35 @@ void FState::SetAction(const char *name)
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
{
if (ActionFunc != NULL)
if (ActionFunc != nullptr)
{
ActionCycles.Clock();
VMValue params[3] = { self, stateowner, VMValue(info) };
// If the function returns a state, store it at *stateret.
// If it doesn't return a state but stateret is non-NULL, we need
// to set *stateret to NULL.
if (stateret != NULL)
// If it doesn't return a state but stateret is non-nullptr, we need
// to set *stateret to nullptr.
if (stateret != nullptr)
{
*stateret = NULL;
if (ActionFunc->Proto == NULL ||
*stateret = nullptr;
if (ActionFunc->Proto == nullptr ||
ActionFunc->Proto->ReturnTypes.Size() == 0 ||
ActionFunc->Proto->ReturnTypes[0] != TypeState)
{
stateret = NULL;
stateret = nullptr;
}
}
try
{
if (stateret == NULL)
if (stateret == nullptr)
{
GlobalVMStack.Call(ActionFunc, params, ActionFunc->ImplicitArgs, NULL, 0, NULL);
VMCall(ActionFunc, params, ActionFunc->ImplicitArgs, nullptr, 0);
}
else
{
VMReturn ret;
ret.PointerAt((void **)stateret);
GlobalVMStack.Call(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, 1, NULL);
VMCall(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, 1);
}
}
catch (CVMAbortException &err)
@ -331,11 +333,11 @@ void AActor::Finalize(FStateDefinitions &statedef)
}
catch (CRecoverableError &)
{
statedef.MakeStateDefines(NULL);
statedef.MakeStateDefines(nullptr);
throw;
}
statedef.InstallStates(GetClass(), defaults);
statedef.MakeStateDefines(NULL);
statedef.MakeStateDefines(nullptr);
}
//==========================================================================
@ -350,7 +352,7 @@ void PClassActor::RegisterIDs()
{
PClassActor *cls = PClass::FindActor(TypeName);
if (cls == NULL)
if (cls == nullptr)
{
Printf(TEXTCOLOR_RED"The actor '%s' has been hidden by a non-actor of the same name\n", TypeName.GetChars());
return;
@ -381,7 +383,7 @@ void PClassActor::RegisterIDs()
if (DoomEdNum != -1)
{
FDoomEdEntry *oldent = DoomEdMap.CheckKey(DoomEdNum);
if (oldent != NULL && oldent->Special == -2)
if (oldent != nullptr && oldent->Special == -2)
{
Printf(TEXTCOLOR_RED"Editor number %d defined twice for classes '%s' and '%s'\n", DoomEdNum, cls->TypeName.GetChars(), oldent->Type->TypeName.GetChars());
}
@ -411,7 +413,7 @@ PClassActor *PClassActor::GetReplacement(bool lookskill)
if (lookskill && AllSkills.Size() > (unsigned)gameskill)
{
skillrepname = AllSkills[gameskill].GetReplacement(TypeName);
if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == NULL)
if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == nullptr)
{
Printf("Warning: incorrect actor name in definition of skill %s: \n"
"class %s is replaced by non-existent class %s\n"
@ -467,7 +469,7 @@ PClassActor *PClassActor::GetReplacee(bool lookskill)
if (lookskill && AllSkills.Size() > (unsigned)gameskill)
{
skillrepname = AllSkills[gameskill].GetReplacedBy(TypeName);
if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == NULL)
if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == nullptr)
{
Printf("Warning: incorrect actor name in definition of skill %s: \n"
"non-existent class %s is replaced by class %s\n"
@ -488,7 +490,7 @@ PClassActor *PClassActor::GetReplacee(bool lookskill)
// potential infinite recursion.
ActorInfo()->Replacee = nullptr;
PClassActor *rep = savedrep;
if (lookskill && (skillrepname != NAME_None) && (PClass::FindClass(skillrepname) != NULL))
if (lookskill && (skillrepname != NAME_None) && (PClass::FindClass(skillrepname) != nullptr))
{
rep = PClass::FindActor(skillrepname);
}
@ -578,7 +580,7 @@ static void SummonActor (int command, int command2, FCommandLine argv)
if (argv.argc() > 1)
{
PClassActor *type = PClass::FindActor(argv[1]);
if (type == NULL)
if (type == nullptr)
{
Printf ("Unknown actor '%s'\n", argv[1]);
return;

View file

@ -286,6 +286,9 @@ struct FActorInfo
}
};
// This is now merely a wrapper that adds actor-specific functionality to PClass.
// No objects of this type will be created ever - its only use is to static_casr
// PClass to it.
class PClassActor : public PClass
{
protected:
@ -293,9 +296,6 @@ public:
static void StaticInit ();
static void StaticSetActorNums ();
PClassActor();
~PClassActor();
void BuildDefaults();
void ApplyDefaults(uint8_t *defaults);
void RegisterIDs();

View file

@ -48,7 +48,7 @@
#include "r_utility.h"
#include "a_morph.h"
#include "g_levellocals.h"
#include "virtual.h"
#include "vm.h"
#include "events.h"
#include "p_acs.h"
@ -479,7 +479,7 @@ void cht_DoCheat (player_t *player, int cheat)
VMReturn ret;
int oldpieces = 1;
ret.IntAt(&oldpieces);
GlobalVMStack.Call(gsp, params, 1, &ret, 1, nullptr);
VMCall(gsp, params, 1, &ret, 1);
item = player->mo->FindInventory(NAME_Sigil);
if (item != NULL)
@ -604,7 +604,7 @@ void cht_Give (player_t *player, const char *name, int amount)
{
FString namestr = name;
VMValue params[3] = { player->mo, &namestr, amount };
GlobalVMStack.Call(func, params, 3, nullptr, 0);
VMCall(func, params, 3, nullptr, 0);
}
}
@ -616,7 +616,7 @@ void cht_Take (player_t *player, const char *name, int amount)
{
FString namestr = name;
VMValue params[3] = { player->mo, &namestr, amount };
GlobalVMStack.Call(func, params, 3, nullptr, 0);
VMCall(func, params, 3, nullptr, 0);
}
}

View file

@ -50,6 +50,7 @@
#include "d_gui.h"
#include "i_music.h"
#include "m_joy.h"
#include "vm.h"
static TArray<IJoystickConfig *> Joysticks;

View file

@ -48,6 +48,7 @@
#include "d_gui.h"
#include "serializer.h"
#include "resourcefiles/resourcefile.h"
#include "vm.h"
// Save name length limit for old binary formats.
#define OLDSAVESTRINGSIZE 24

View file

@ -55,7 +55,7 @@
#include "r_utility.h"
#include "menu/menu.h"
#include "textures/textures.h"
#include "virtual.h"
#include "vm.h"
#include "events.h"
//
@ -182,7 +182,7 @@ bool DMenu::CallResponder(event_t *ev)
VMValue params[] = { (DObject*)this, &e };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr);
VMCall(func, params, 2, &ret, 1);
return !!retval;
}
}
@ -194,7 +194,7 @@ bool DMenu::CallResponder(event_t *ev)
VMValue params[] = { (DObject*)this, &e };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr);
VMCall(func, params, 2, &ret, 1);
return !!retval;
}
}
@ -214,7 +214,7 @@ bool DMenu::CallMenuEvent(int mkey, bool fromcontroller)
VMValue params[] = { (DObject*)this, mkey, fromcontroller };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr);
VMCall(func, params, 3, &ret, 1);
return !!retval;
}
else return false;
@ -246,7 +246,7 @@ void DMenu::Close ()
IFVIRTUALPTR(CurrentMenu, DMenu, OnReturn)
{
VMValue params[] = { CurrentMenu };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
@ -274,7 +274,7 @@ void DMenu::CallTicker()
IFVIRTUAL(DMenu, Ticker)
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
@ -284,7 +284,7 @@ void DMenu::CallDrawer()
IFVIRTUAL(DMenu, Drawer)
{
VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
screen->ClearClipRect(); // make sure the scripts don't leave a valid clipping rect behind.
}
}
@ -296,7 +296,7 @@ bool DMenu::TranslateKeyboardEvents()
VMValue params[] = { (DObject*)this };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr);
VMCall(func, params, countof(params), &ret, 1);
return !!retval;
}
return true;
@ -472,7 +472,7 @@ void M_SetMenu(FName menu, int param)
IFVIRTUALPTRNAME(newmenu, "ListMenu", Init)
{
VMValue params[3] = { newmenu, CurrentMenu, ld };
GlobalVMStack.Call(func, params, 3, nullptr, 0);
VMCall(func, params, 3, nullptr, 0);
}
M_ActivateMenu(newmenu);
}
@ -488,7 +488,7 @@ void M_SetMenu(FName menu, int param)
IFVIRTUALPTRNAME(newmenu, "OptionMenu", Init)
{
VMValue params[3] = { newmenu, CurrentMenu, ld };
GlobalVMStack.Call(func, params, 3, nullptr, 0);
VMCall(func, params, 3, nullptr, 0);
}
M_ActivateMenu(newmenu);
}
@ -506,7 +506,7 @@ void M_SetMenu(FName menu, int param)
IFVIRTUALPTRNAME(newmenu, "GenericMenu", Init)
{
VMValue params[3] = { newmenu, CurrentMenu };
GlobalVMStack.Call(func, params, 2, nullptr, 0);
VMCall(func, params, 2, nullptr, 0);
}
M_ActivateMenu(newmenu);
return;
@ -1058,7 +1058,7 @@ CCMD(undocolorpic)
IFVIRTUALPTR(CurrentMenu, DMenu, ResetColor)
{
VMValue params[] = { (DObject*)CurrentMenu };
GlobalVMStack.Call(func, params, countof(params), nullptr, 0, nullptr);
VMCall(func, params, countof(params), nullptr, 0);
}
}
}
@ -1128,7 +1128,7 @@ DMenuItemBase * CreateOptionMenuItemStaticText(const char *name, bool v)
FString namestr = name;
VMValue params[] = { p, &namestr, v };
auto f = dyn_cast<PFunction>(c->FindSymbol("Init", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
VMCall(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}
@ -1139,7 +1139,7 @@ DMenuItemBase * CreateOptionMenuItemJoyConfigMenu(const char *label, IJoystickCo
FString namestr = label;
VMValue params[] = { p, &namestr, joy };
auto f = dyn_cast<PFunction>(c->FindSymbol("Init", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
VMCall(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}
@ -1150,7 +1150,7 @@ DMenuItemBase * CreateOptionMenuItemSubmenu(const char *label, FName cmd, int ce
FString namestr = label;
VMValue params[] = { p, &namestr, cmd.GetIndex(), center };
auto f = dyn_cast<PFunction>(c->FindSymbol("Init", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
VMCall(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}
@ -1161,7 +1161,7 @@ DMenuItemBase * CreateOptionMenuItemControl(const char *label, FName cmd, FKeyBi
FString namestr = label;
VMValue params[] = { p, &namestr, cmd.GetIndex(), bindings };
auto f = dyn_cast<PFunction>(c->FindSymbol("Init", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
VMCall(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}
@ -1172,7 +1172,7 @@ DMenuItemBase * CreateListMenuItemPatch(double x, double y, int height, int hotk
FString keystr = FString(char(hotkey));
VMValue params[] = { p, x, y, height, tex.GetIndex(), &keystr, command.GetIndex(), param };
auto f = dyn_cast<PFunction>(c->FindSymbol("InitDirect", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
VMCall(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}
@ -1184,7 +1184,7 @@ DMenuItemBase * CreateListMenuItemText(double x, double y, int height, int hotke
FString textstr = text;
VMValue params[] = { p, x, y, height, &keystr, &textstr, font, int(color1.d), int(color2.d), command.GetIndex(), param };
auto f = dyn_cast<PFunction>(c->FindSymbol("InitDirect", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
VMCall(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenuItemBase*)p;
}
@ -1195,7 +1195,7 @@ bool DMenuItemBase::Activate()
VMValue params[] = { (DObject*)this };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr);
VMCall(func, params, countof(params), &ret, 1);
return !!retval;
}
return false;
@ -1209,7 +1209,7 @@ bool DMenuItemBase::SetString(int i, const char *s)
VMValue params[] = { (DObject*)this, i, &namestr };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr);
VMCall(func, params, countof(params), &ret, 1);
return !!retval;
}
return false;
@ -1223,7 +1223,7 @@ bool DMenuItemBase::GetString(int i, char *s, int len)
int retval;
FString retstr;
VMReturn ret[2]; ret[0].IntAt(&retval); ret[1].StringAt(&retstr);
GlobalVMStack.Call(func, params, countof(params), ret, 2, nullptr);
VMCall(func, params, countof(params), ret, 2);
strncpy(s, retstr, len);
return !!retval;
}
@ -1238,7 +1238,7 @@ bool DMenuItemBase::SetValue(int i, int value)
VMValue params[] = { (DObject*)this, i, value };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr);
VMCall(func, params, countof(params), &ret, 1);
return !!retval;
}
return false;
@ -1251,7 +1251,7 @@ bool DMenuItemBase::GetValue(int i, int *pvalue)
VMValue params[] = { (DObject*)this, i };
int retval[2];
VMReturn ret[2]; ret[0].IntAt(&retval[0]); ret[1].IntAt(&retval[1]);
GlobalVMStack.Call(func, params, countof(params), ret, 2, nullptr);
VMCall(func, params, countof(params), ret, 2);
*pvalue = retval[1];
return !!retval[0];
}

View file

@ -51,6 +51,8 @@
#include "gi.h"
#include "i_sound.h"
#include "cmdlib.h"
#include "vm.h"
#include "types.h"
@ -480,7 +482,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
}
DMenuItemBase *item = (DMenuItemBase*)cls->CreateNew();
params[0] = item;
GlobalVMStack.Call(func->Variants[0].Implementation, &params[0], params.Size(), nullptr, 0);
VMCall(func->Variants[0].Implementation, &params[0], params.Size(), nullptr, 0);
desc->mItems.Push((DMenuItemBase*)item);
if (cls->IsDescendantOf("ListMenuItemSelectable"))
@ -837,7 +839,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc)
DMenuItemBase *item = (DMenuItemBase*)cls->CreateNew();
params[0] = item;
GlobalVMStack.Call(func->Variants[0].Implementation, &params[0], params.Size(), nullptr, 0);
VMCall(func->Variants[0].Implementation, &params[0], params.Size(), nullptr, 0);
desc->mItems.Push((DMenuItemBase*)item);
success = true;

View file

@ -45,6 +45,7 @@
#include "st_start.h"
#include "c_dispatch.h"
#include "g_game.h"
#include "vm.h"
EXTERN_CVAR (Bool, saveloadconfirmation) // [mxd]
@ -71,7 +72,7 @@ DMenu *CreateMessageBoxMenu(DMenu *parent, const char *message, int messagemode,
VMValue params[] = { p, parent, &namestr, messagemode, playsound, action.GetIndex(), reinterpret_cast<void*>(handler) };
auto f = dyn_cast<PFunction>(c->FindSymbol("Init", false));
GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
VMCall(f->Variants[0].Implementation, params, countof(params), nullptr, 0);
return (DMenu*)p;
}

View file

@ -47,6 +47,7 @@
#include "r_state.h"
#include "r_data/r_translate.h"
#include "v_text.h"
#include "vm.h"
EXTERN_CVAR(Int, team)
EXTERN_CVAR(Float, autoaim)

View file

@ -53,6 +53,7 @@
#include "m_joy.h"
#include "sbar.h"
#include "hardware.h"
#include "vm.h"
/*=======================================
*

View file

@ -87,6 +87,8 @@
#include "g_levellocals.h"
#include "actorinlines.h"
#include "stats.h"
#include "types.h"
#include "vm.h"
// P-codes for ACS scripts
enum
@ -5431,7 +5433,7 @@ static int ScriptCall(AActor *activator, unsigned argc, int32_t *args)
// The return value can be the same types as the parameter types, plus void
if (func->Proto->ReturnTypes.Size() == 0)
{
GlobalVMStack.Call(func, &params[0], params.Size(), nullptr, 0);
VMCall(func, &params[0], params.Size(), nullptr, 0);
}
else
{
@ -5439,7 +5441,7 @@ static int ScriptCall(AActor *activator, unsigned argc, int32_t *args)
if (rettype == TypeSInt32 || rettype == TypeBool || rettype == TypeColor || rettype == TypeName || rettype == TypeSound)
{
VMReturn ret(&retval);
GlobalVMStack.Call(func, &params[0], params.Size(), &ret, 1);
VMCall(func, &params[0], params.Size(), &ret, 1);
if (rettype == TypeName)
{
retval = GlobalACSStrings.AddString(FName(ENamedName(retval)));
@ -5453,20 +5455,20 @@ static int ScriptCall(AActor *activator, unsigned argc, int32_t *args)
{
double d;
VMReturn ret(&d);
GlobalVMStack.Call(func, &params[0], params.Size(), &ret, 1);
VMCall(func, &params[0], params.Size(), &ret, 1);
retval = DoubleToACS(d);
}
else if (rettype == TypeString)
{
FString d;
VMReturn ret(&d);
GlobalVMStack.Call(func, &params[0], params.Size(), &ret, 1);
VMCall(func, &params[0], params.Size(), &ret, 1);
retval = GlobalACSStrings.AddString(d);
}
else
{
// All other return values can not be handled so ignore them.
GlobalVMStack.Call(func, &params[0], params.Size(), nullptr, 0);
VMCall(func, &params[0], params.Size(), nullptr, 0);
}
}
}
@ -6910,7 +6912,7 @@ static void SetMarineWeapon(AActor *marine, int weapon)
if (smw)
{
VMValue params[2] = { marine, weapon };
GlobalVMStack.Call(smw, params, 2, nullptr, 0, nullptr);
VMCall(smw, params, 2, nullptr, 0);
}
}
@ -6921,7 +6923,7 @@ static void SetMarineSprite(AActor *marine, PClassActor *source)
if (sms)
{
VMValue params[2] = { marine, source };
GlobalVMStack.Call(sms, params, 2, nullptr, 0, nullptr);
VMCall(sms, params, 2, nullptr, 0);
}
}

View file

@ -82,6 +82,8 @@
#include "r_utility.h"
#include "sbar.h"
#include "actorinlines.h"
#include "vm.h"
#include "types.h"
AActor *SingleActorFromTID(int tid, AActor *defactor);
@ -182,7 +184,7 @@ bool AStateProvider::CallStateChain (AActor *actor, FState *state)
}
try
{
GlobalVMStack.Call(state->ActionFunc, params, state->ActionFunc->ImplicitArgs, wantret, numret);
VMCall(state->ActionFunc, params, state->ActionFunc->ImplicitArgs, wantret, numret);
}
catch (CVMAbortException &err)
{

View file

@ -33,6 +33,7 @@
#include "p_spec.h"
#include "g_levellocals.h"
#include "textures.h"
#include "vm.h"
//============================================================================
//

View file

@ -61,7 +61,7 @@
#include "p_local.h"
#include "menu/menu.h"
#include "g_levellocals.h"
#include "virtual.h"
#include "vm.h"
#include "actorinlines.h"
// The conversations as they exist inside a SCRIPTxx lump.
@ -867,7 +867,7 @@ void P_StartConversation (AActor *npc, AActor *pc, bool facetalker, bool saveang
{
VMValue params[] = { cmenu, CurNode, pc->player, StaticLastReply };
VMReturn ret(&ConversationMenuY);
GlobalVMStack.Call(func, params, countof(params), &ret, 1);
VMCall(func, params, countof(params), &ret, 1);
}
if (CurNode != PrevNode)

View file

@ -54,6 +54,7 @@
#include "d_player.h"
#include "r_utility.h"
#include "g_levellocals.h"
#include "vm.h"
CVAR (Int, cl_rockettrails, 1, CVAR_ARCHIVE);
CVAR (Bool, r_rail_smartspiral, 0, CVAR_ARCHIVE);

View file

@ -52,7 +52,7 @@
#include "p_checkposition.h"
#include "math/cmath.h"
#include "g_levellocals.h"
#include "virtual.h"
#include "vm.h"
#include "actorinlines.h"
#include "gi.h"
@ -3329,7 +3329,7 @@ AInventory *P_DropItem (AActor *source, PClassActor *type, int dropamount, int c
VMValue params[2] = { inv, source };
int retval;
VMReturn ret(&retval);
GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr);
VMCall(func, params, 2, &ret, 1);
if (retval)
{
// The special action indicates that the item should not spawn

View file

@ -33,6 +33,7 @@
#include "p_spec.h"
#include "r_data/r_interpolate.h"
#include "g_levellocals.h"
#include "vm.h"
//==========================================================================
//

View file

@ -58,7 +58,7 @@
#include "d_net.h"
#include "d_netinf.h"
#include "a_morph.h"
#include "virtual.h"
#include "vm.h"
#include "g_levellocals.h"
#include "events.h"
#include "actorinlines.h"
@ -248,7 +248,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf
VMValue params[] = { attacker, self, inflictor, mod.GetIndex(), !!(dmgflags & DMG_PLAYERATTACK) };
FString ret;
VMReturn rett(&ret);
GlobalVMStack.Call(func, params, countof(params), &rett, 1);
VMCall(func, params, countof(params), &rett, 1);
if (ret.IsNotEmpty()) message = ret;
}
}
@ -326,7 +326,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
IFVIRTUALPTR(item, AInventory, OwnerDied)
{
VMValue params[1] = { item };
GlobalVMStack.Call(func, params, 1, nullptr, 0);
VMCall(func, params, 1, nullptr, 0);
}
item = next;
}
@ -367,7 +367,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
{
VMValue params[] = { (DObject*)this };
VMReturn ret(&Height);
GlobalVMStack.Call(func, params, 1, &ret, 1);
VMCall(func, params, 1, &ret, 1);
}
// [RH] If the thing has a special, execute and remove it
@ -733,7 +733,7 @@ void AActor::CallDie(AActor *source, AActor *inflictor, int dmgflags)
IFVIRTUAL(AActor, Die)
{
VMValue params[4] = { (DObject*)this, source, inflictor, dmgflags };
GlobalVMStack.Call(func, params, 4, nullptr, 0, nullptr);
VMCall(func, params, 4, nullptr, 0);
}
else return Die(source, inflictor, dmgflags);
}
@ -1421,7 +1421,7 @@ static int DamageMobj (AActor *target, AActor *inflictor, AActor *source, int da
{
VMValue params[] = { source, target, draindmg, mod.GetIndex() };
VMReturn ret(&draindmg);
GlobalVMStack.Call(func, params, countof(params), &ret, 1);
VMCall(func, params, countof(params), &ret, 1);
}
if (P_GiveBody(source, draindmg))
{
@ -1618,7 +1618,7 @@ int P_DamageMobj(AActor *target, AActor *inflictor, AActor *source, int damage,
VMReturn ret;
int retval;
ret.IntAt(&retval);
GlobalVMStack.Call(func, params, 7, &ret, 1, nullptr);
VMCall(func, params, 7, &ret, 1);
return retval;
}
else
@ -1770,7 +1770,7 @@ bool AActor::CallOkayToSwitchTarget(AActor *other)
VMValue params[] = { (DObject*)this, other };
int retv;
VMReturn ret(&retv);
GlobalVMStack.Call(func, params, 2, &ret, 1);
VMCall(func, params, 2, &ret, 1);
return !!retv;
}
return OkayToSwitchTarget(other);

View file

@ -38,6 +38,7 @@
#include "p_lnspec.h"
#include "p_spec.h"
#include "g_levellocals.h"
#include "vm.h"
enum
{

View file

@ -62,6 +62,7 @@
#include "fragglescript/t_fs.h"
#include "p_spec.h"
#include "g_levellocals.h"
#include "vm.h"
// Remaps EE sector change types to Generic_Floor values. According to the Eternity Wiki:
/*

View file

@ -47,7 +47,7 @@
#include "r_utility.h"
#include "p_blockmap.h"
#include "p_3dmidtex.h"
#include "virtual.h"
#include "vm.h"
#include "s_sound.h"
#include "decallib.h"
@ -154,7 +154,7 @@ bool P_CanCollideWith(AActor *tmthing, AActor *thing)
VMFunction *func = clss->Virtuals.Size() > VIndex ? clss->Virtuals[VIndex] : nullptr;
if (func != nullptr)
{
GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr);
VMCall(func, params, 3, &ret, 1);
if (!retval) return false;
}
std::swap(params[0].a, params[1].a);
@ -165,7 +165,7 @@ bool P_CanCollideWith(AActor *tmthing, AActor *thing)
func = clss->Virtuals.Size() > VIndex ? clss->Virtuals[VIndex] : nullptr;
if (func != nullptr)
{
GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr);
VMCall(func, params, 3, &ret, 1);
if (!retval) return false;
}
return true;
@ -5302,7 +5302,7 @@ bool P_UseTraverse(AActor *usething, const DVector2 &start, const DVector2 &end,
VMValue params[] = { mobj, usething };
int ret;
VMReturn vret(&ret);
GlobalVMStack.Call(func, params, 2, &vret, 1);
VMCall(func, params, 2, &vret, 1);
if (ret) return true;
}
continue;

View file

@ -47,6 +47,7 @@
#include "templates.h"
#include "po_man.h"
#include "g_levellocals.h"
#include "vm.h"
sector_t *P_PointInSectorBuggy(double x, double y);
int P_VanillaPointOnDivlineSide(double x, double y, const divline_t* line);

View file

@ -68,7 +68,7 @@
#include "r_utility.h"
#include "thingdef.h"
#include "d_player.h"
#include "virtual.h"
#include "vm.h"
#include "g_levellocals.h"
#include "a_morph.h"
#include "events.h"
@ -153,9 +153,6 @@ AActor::~AActor ()
// Use Destroy() instead.
}
extern FFlagDef InternalActorFlagDefs[];
extern FFlagDef ActorFlagDefs[];
DEFINE_FIELD(AActor, snext)
DEFINE_FIELD(AActor, player)
DEFINE_FIELD_NAMED(AActor, __Pos, pos)
@ -841,7 +838,7 @@ void AActor::RemoveInventory(AInventory *item)
IFVIRTUALPTR(item, AInventory, DetachFromOwner)
{
VMValue params[1] = { item };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
item->Owner = NULL;
@ -1109,7 +1106,7 @@ AInventory *AActor::DropInventory (AInventory *item, int amt)
{
VMValue params[] = { (DObject*)item, amt };
VMReturn ret((void**)&drop);
GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr);
VMCall(func, params, countof(params), &ret, 1);
}
if (drop == nullptr) return NULL;
drop->SetOrigin(PosPlusZ(10.), false);
@ -1681,7 +1678,7 @@ void AActor::CallTouch(AActor *toucher)
IFVIRTUAL(AActor, Touch)
{
VMValue params[2] = { (DObject*)this, toucher };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
else Touch(toucher);
}
@ -3573,7 +3570,7 @@ int AActor::GetMissileDamage (int mask, int add)
result.IntAt(&amount);
if (GlobalVMStack.Call(DamageFunc, &param, 1, &result, 1) < 1)
if (VMCall(DamageFunc, &param, 1, &result, 1) < 1)
{ // No results
return 0;
}
@ -3638,7 +3635,7 @@ bool AActor::CallSlam(AActor *thing)
VMReturn ret;
int retval;
ret.IntAt(&retval);
GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr);
VMCall(func, params, 2, &ret, 1);
return !!retval;
}
@ -3656,7 +3653,7 @@ int AActor::SpecialMissileHit (AActor *victim)
VMReturn ret;
int retval;
ret.IntAt(&retval);
GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr);
VMCall(func, params, 2, &ret, 1);
return retval;
}
else return -1;
@ -3716,7 +3713,7 @@ int AActor::AbsorbDamage(int damage, FName dmgtype)
IFVIRTUALPTR(item, AInventory, AbsorbDamage)
{
VMValue params[4] = { item, damage, dmgtype.GetIndex(), &damage };
GlobalVMStack.Call(func, params, 4, nullptr, 0, nullptr);
VMCall(func, params, 4, nullptr, 0);
}
}
return damage;
@ -3736,7 +3733,7 @@ void AActor::AlterWeaponSprite(visstyle_t *vis)
IFVIRTUALPTR(items[i], AInventory, AlterWeaponSprite)
{
VMValue params[3] = { items[i], vis, &changed };
GlobalVMStack.Call(func, params, 3, nullptr, 0, nullptr);
VMCall(func, params, 3, nullptr, 0);
}
}
}
@ -3891,7 +3888,7 @@ PClassActor *AActor::GetBloodType(int type) const
VMValue params[] = { (DObject*)this, type };
PClassActor *res;
VMReturn ret((void**)&res);
GlobalVMStack.Call(func, params, countof(params), &ret, 1);
VMCall(func, params, countof(params), &ret, 1);
return res;
}
return nullptr;
@ -4051,7 +4048,7 @@ void AActor::Tick ()
IFVIRTUALPTR(item, AInventory, DoEffect)
{
VMValue params[1] = { item };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
item = item->Inventory;
}
@ -5139,7 +5136,7 @@ void AActor::CallBeginPlay()
{
// Without the type cast this picks the 'void *' assignment...
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
else BeginPlay();
}
@ -5230,7 +5227,7 @@ void AActor::CallActivate(AActor *activator)
{
// Without the type cast this picks the 'void *' assignment...
VMValue params[2] = { (DObject*)this, (DObject*)activator };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
else Activate(activator);
}
@ -5276,7 +5273,7 @@ void AActor::CallDeactivate(AActor *activator)
{
// Without the type cast this picks the 'void *' assignment...
VMValue params[2] = { (DObject*)this, (DObject*)activator };
GlobalVMStack.Call(func, params, 2, nullptr, 0, nullptr);
VMCall(func, params, 2, nullptr, 0);
}
else Deactivate(activator);
}
@ -5582,7 +5579,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
IFVIRTUALPTR(p->mo, APlayerPawn, OnRespawn)
{
VMValue param = p->mo;
GlobalVMStack.Call(func, &param, 1, nullptr, 0);
VMCall(func, &param, 1, nullptr, 0);
}
}
@ -7455,7 +7452,7 @@ int AActor::CallDoSpecialDamage(AActor *target, int damage, FName damagetype)
VMReturn ret;
int retval;
ret.IntAt(&retval);
GlobalVMStack.Call(func, params, 4, &ret, 1, nullptr);
VMCall(func, params, 4, &ret, 1);
return retval;
}
else return DoSpecialDamage(target, damage, damagetype);
@ -7520,7 +7517,7 @@ int AActor::CallTakeSpecialDamage(AActor *inflictor, AActor *source, int damage,
VMReturn ret;
int retval;
ret.IntAt(&retval);
GlobalVMStack.Call(func, params, 5, &ret, 1, nullptr);
VMCall(func, params, 5, &ret, 1);
return retval;
}
else return TakeSpecialDamage(inflictor, source, damage, damagetype);
@ -7664,7 +7661,7 @@ int AActor::GetGibHealth() const
VMValue params[] = { (DObject*)this };
int h;
VMReturn ret(&h);
GlobalVMStack.Call(func, params, 1, &ret, 1);
VMCall(func, params, 1, &ret, 1);
return h;
}
return -SpawnHealth();
@ -7800,7 +7797,7 @@ int AActor::GetModifiedDamage(FName damagetype, int damage, bool passive)
IFVIRTUALPTR(inv, AInventory, ModifyDamage)
{
VMValue params[5] = { (DObject*)inv, damage, int(damagetype), &damage, passive };
GlobalVMStack.Call(func, params, 5, nullptr, 0, nullptr);
VMCall(func, params, 5, nullptr, 0);
}
inv = inv->Inventory;
}

View file

@ -31,6 +31,7 @@
#include "v_text.h"
#include "cmdlib.h"
#include "g_levellocals.h"
#include "vm.h"
// MACROS ------------------------------------------------------------------

View file

@ -36,7 +36,7 @@
#include "r_sky.h"
#include "r_data/colormaps.h"
#include "g_levellocals.h"
#include "virtual.h"
#include "vm.h"
// [RH]
@ -1514,7 +1514,7 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt)
VMReturn ret;
int didit;
ret.IntAt(&didit);
GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr);
VMCall(func, params, 3, &ret, 1);
if (didit)
{

View file

@ -79,6 +79,7 @@
#include "edata.h"
#endif
#include "events.h"
#include "types.h"
#include "fragglescript/t_fs.h"

View file

@ -24,6 +24,7 @@
#include "r_utility.h"
#include "b_bot.h"
#include "p_spec.h"
#include "vm.h"
// State.
#include "r_state.h"

View file

@ -76,6 +76,7 @@
#ifndef NO_EDATA
#include "edata.h"
#endif
#include "vm.h"
// State.
#include "r_state.h"

View file

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

View file

@ -37,6 +37,7 @@
#include "p_tags.h"
#include "c_dispatch.h"
#include "g_levellocals.h"
#include "vm.h"
FTagManager tagManager;

View file

@ -39,6 +39,7 @@
#include "r_utility.h"
#include "p_spec.h"
#include "g_levellocals.h"
#include "vm.h"
#define FUDGEFACTOR 10

View file

@ -47,6 +47,7 @@
#include "p_local.h"
#include "templates.h"
#include "actor.h"
#include "vm.h"
// MACROS ------------------------------------------------------------------

View file

@ -53,6 +53,7 @@
#include "actorptrselect.h"
#include "g_levellocals.h"
#include "actorinlines.h"
#include "vm.h"
// Set of spawnable things for the Thing_Spawn and Thing_Projectile specials.
FClassMap SpawnableThings;

View file

@ -50,6 +50,7 @@
#include "p_terrain.h"
#include "g_levellocals.h"
#include "info.h"
#include "vm.h"
//===========================================================================
//

View file

@ -58,7 +58,7 @@
#include "p_blockmap.h"
#include "a_morph.h"
#include "p_spec.h"
#include "virtual.h"
#include "vm.h"
#include "g_levellocals.h"
#include "actorinlines.h"
#include "r_data/r_translate.h"
@ -1505,7 +1505,7 @@ void APlayerPawn::PlayIdle ()
IFVIRTUAL(APlayerPawn, PlayIdle)
{
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
@ -1514,7 +1514,7 @@ void APlayerPawn::PlayRunning ()
IFVIRTUAL(APlayerPawn, PlayRunning)
{
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
@ -1523,7 +1523,7 @@ void APlayerPawn::PlayAttacking ()
IFVIRTUAL(APlayerPawn, PlayAttacking)
{
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
@ -1532,7 +1532,7 @@ void APlayerPawn::PlayAttacking2 ()
IFVIRTUAL(APlayerPawn, PlayAttacking2)
{
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}
@ -1630,7 +1630,7 @@ void APlayerPawn::MorphPlayerThink ()
IFVIRTUAL(APlayerPawn, MorphPlayerThink)
{
VMValue params[1] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
}

View file

@ -52,6 +52,7 @@
#include "p_checkposition.h"
#include "math/cmath.h"
#include "g_levellocals.h"
#include "vm.h"
// simulation recurions maximum
CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO)

View file

@ -50,6 +50,7 @@
#include "d_player.h"
#include "r_data/sprites.h"
#include "r_state.h"
#include "vm.h"
#include "gi.h"
#include "stats.h"

View file

@ -14,6 +14,7 @@
#include "r_data/sprites.h"
#include "r_data/voxels.h"
#include "textures/textures.h"
#include "vm.h"
void gl_InitModels();

View file

@ -30,6 +30,7 @@
#include "serializer.h"
#include "d_player.h"
#include "g_levellocals.h"
#include "vm.h"
// MACROS ------------------------------------------------------------------

View file

@ -54,7 +54,7 @@
#include "d_player.h"
#include "r_state.h"
#include "g_levellocals.h"
#include "virtual.h"
#include "vm.h"
// MACROS ------------------------------------------------------------------
@ -487,7 +487,7 @@ void S_PrecacheLevel ()
{
// Without the type cast this picks the 'void *' assignment...
VMValue params[1] = { actor };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr);
VMCall(func, params, 1, nullptr, 0);
}
else
{

View file

@ -6620,7 +6620,7 @@ ExpEmit FxClassDefaults::Emit(VMFunctionBuilder *build)
ob.Free(build);
ExpEmit meta(build, REGT_POINTER);
build->Emit(OP_CLSS, meta.RegNum, ob.RegNum);
build->Emit(OP_LOS, meta.RegNum, meta.RegNum, build->GetConstantInt(myoffsetof(PClass, Defaults)));
build->Emit(OP_LP, meta.RegNum, meta.RegNum, build->GetConstantInt(myoffsetof(PClass, Defaults)));
return meta;
}
@ -6878,7 +6878,7 @@ ExpEmit FxStackVariable::Emit(VMFunctionBuilder *build)
if (offsetreg == -1) offsetreg = build->GetConstantInt(0);
auto op = membervar->Type->GetLoadOp();
if (op == OP_LO)
op = OP_LOS;
op = OP_LP;
build->Emit(op, loc.RegNum, build->FramePointer.RegNum, offsetreg);
}
else
@ -9355,7 +9355,7 @@ ExpEmit FxGetParentClass::Emit(VMFunctionBuilder *build)
op.Free(build);
}
ExpEmit to(build, REGT_POINTER);
build->Emit(OP_LOS, to.RegNum, op.RegNum, build->GetConstantInt(myoffsetof(PClass, ParentClass)));
build->Emit(OP_LP, to.RegNum, op.RegNum, build->GetConstantInt(myoffsetof(PClass, ParentClass)));
return to;
}
@ -9427,7 +9427,7 @@ ExpEmit FxGetDefaultByType::Emit(VMFunctionBuilder *build)
build->Emit(OP_LKP, to.RegNum, op.RegNum);
op = to;
}
build->Emit(OP_LOS, to.RegNum, op.RegNum, build->GetConstantInt(myoffsetof(PClass, Defaults)));
build->Emit(OP_LP, to.RegNum, op.RegNum, build->GetConstantInt(myoffsetof(PClass, Defaults)));
return to;
}

View file

@ -46,6 +46,8 @@
#include "actor.h"
#include "vmbuilder.h"
#include "scopebarrier.h"
#include "types.h"
#include "vmintern.h"
#define CHECKRESOLVED() if (isresolved) return this; isresolved=true;

View file

@ -39,7 +39,9 @@
#include "tarray.h"
#include "dobject.h"
#include "thingdef.h"
#include "vm.h"
#include "types.h"
// We need one specific type for each of the 7 integral VM types and instantiate the needed functions for each of them.
// Dynamic arrays cannot hold structs because for every type there'd need to be an internal implementation which is impossible.

View file

@ -1,5 +1,7 @@
#include "dobject.h"
#include "scopebarrier.h"
#include "types.h"
#include "vmintern.h"
// Note: the same object can't be both UI and Play. This is checked explicitly in the field construction and will cause esoteric errors here if found.

View file

@ -35,8 +35,9 @@
#include "codegen.h"
#include "info.h"
#include "m_argv.h"
#include "thingdef.h"
//#include "thingdef.h"
#include "doomerrors.h"
#include "vmintern.h"
struct VMRemap
{

View file

@ -2,6 +2,7 @@
#define VMUTIL_H
#include "dobject.h"
#include "vmintern.h"
class VMFunctionBuilder;
class FxExpression;

View file

@ -34,6 +34,7 @@
#include "dobject.h"
#include "c_console.h"
#include "templates.h"
#include "vmintern.h"
#define NOP MODE_AUNUSED | MODE_BUNUSED | MODE_CUNUSED

View file

@ -38,6 +38,8 @@
#include "i_system.h"
#include "templates.h"
#include "serializer.h"
#include "types.h"
#include "vm.h"
// PUBLIC DATA DEFINITIONS -------------------------------------------------
@ -128,6 +130,80 @@ int PFunction::GetImplicitArgs()
return 0;
}
/* PField *****************************************************************/
IMPLEMENT_CLASS(PField, false, false)
//==========================================================================
//
// PField - Default Constructor
//
//==========================================================================
PField::PField()
: PSymbol(NAME_None), Offset(0), Type(nullptr), Flags(0)
{
}
PField::PField(FName name, PType *type, uint32_t flags, size_t offset, int bitvalue)
: PSymbol(name), Offset(offset), Type(type), Flags(flags)
{
if (bitvalue != 0)
{
BitValue = 0;
unsigned val = bitvalue;
while ((val >>= 1)) BitValue++;
if (type->IsA(RUNTIME_CLASS(PInt)) && unsigned(BitValue) < 8u * type->Size)
{
// map to the single bytes in the actual variable. The internal bit instructions operate on 8 bit values.
#ifndef __BIG_ENDIAN__
Offset += BitValue / 8;
#else
Offset += type->Size - 1 - BitValue / 8;
#endif
BitValue &= 7;
Type = TypeBool;
}
else
{
// Just abort. Bit fields should only be defined internally.
I_Error("Trying to create an invalid bit field element: %s", name.GetChars());
}
}
else BitValue = -1;
}
VersionInfo PField::GetVersion()
{
VersionInfo Highest = { 0,0,0 };
if (!(Flags & VARF_Deprecated)) Highest = mVersion;
if (Type->mVersion > Highest) Highest = Type->mVersion;
return Highest;
}
/* PProperty *****************************************************************/
IMPLEMENT_CLASS(PProperty, false, false)
//==========================================================================
//
// PField - Default Constructor
//
//==========================================================================
PProperty::PProperty()
: PSymbol(NAME_None)
{
}
PProperty::PProperty(FName name, TArray<PField *> &fields)
: PSymbol(name)
{
Variables = std::move(fields);
}
//==========================================================================
//
//

View file

@ -274,5 +274,4 @@ struct FNamespaceManager
};
extern FNamespaceManager Namespaces;
void RemoveUnusedSymbols();

View file

@ -59,7 +59,7 @@
#include "a_weapons.h"
#include "p_conversation.h"
#include "v_text.h"
#include "thingdef.h"
//#include "thingdef.h"
#include "backend/codegen.h"
#include "a_sharedglobal.h"
#include "backend/vmbuilder.h"

View file

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

View file

@ -61,6 +61,8 @@
#include "serializer.h"
#include "wi_stuff.h"
#include "a_dynlight.h"
#include "vm.h"
#include "types.h"
static TArray<FPropertyInfo*> properties;
static TArray<AFuncDesc> AFTable;

View file

@ -70,6 +70,7 @@
#include "a_keys.h"
#include "g_levellocals.h"
#include "d_player.h"
#include "types.h"
//==========================================================================
//

2689
src/scripting/types.cpp Normal file

File diff suppressed because it is too large Load diff

641
src/scripting/types.h Normal file
View file

@ -0,0 +1,641 @@
#pragma once
#include "dobject.h"
#include "serializer.h"
// Variable/parameter/field flags -------------------------------------------
class PStruct;
// Making all these different storage types use a common set of flags seems
// like the simplest thing to do.
enum
{
VARF_Optional = (1<<0), // func param is optional
VARF_Method = (1<<1), // func has an implied self parameter
VARF_Action = (1<<2), // func has implied owner and state parameters
VARF_Native = (1<<3), // func is native code, field is natively defined
VARF_ReadOnly = (1<<4), // field is read only, do not write to it
VARF_Private = (1<<5), // field is private to containing class
VARF_Protected = (1<<6), // field is only accessible by containing class and children.
VARF_Deprecated = (1<<7), // Deprecated fields should output warnings when used.
VARF_Virtual = (1<<8), // function is virtual
VARF_Final = (1<<9), // Function may not be overridden in subclasses
VARF_In = (1<<10),
VARF_Out = (1<<11),
VARF_Implicit = (1<<12), // implicitly created parameters (i.e. do not compare types when checking function signatures)
VARF_Static = (1<<13),
VARF_InternalAccess = (1<<14), // overrides VARF_ReadOnly for internal script code.
VARF_Override = (1<<15), // overrides a virtual function from the parent class.
VARF_Ref = (1<<16), // argument is passed by reference.
VARF_Transient = (1<<17), // don't auto serialize field.
VARF_Meta = (1<<18), // static class data (by necessity read only.)
VARF_VarArg = (1<<19), // [ZZ] vararg: don't typecheck values after ... in function signature
VARF_UI = (1<<20), // [ZZ] ui: object is ui-scope only (can't modify playsim)
VARF_Play = (1<<21), // [ZZ] play: object is playsim-scope only (can't access ui)
VARF_VirtualScope = (1<<22), // [ZZ] virtualscope: object should use the scope of the particular class it's being used with (methods only)
VARF_ClearScope = (1<<23), // [ZZ] clearscope: this method ignores the member access chain that leads to it and is always plain data.
};
// Basic information shared by all types ------------------------------------
// Only one copy of a type is ever instantiated at one time.
// - Enums, classes, and structs are defined by their names and outer classes.
// - Pointers are uniquely defined by the type they point at.
// - ClassPointers are also defined by their class restriction.
// - Arrays are defined by their element type and count.
// - DynArrays are defined by their element type.
// - Maps are defined by their key and value types.
// - Prototypes are defined by the argument and return types.
// - Functions are defined by their names and outer objects.
// In table form:
// Outer Name Type Type2 Count
// Enum * *
// Class * *
// Struct * *
// Function * *
// Pointer *
// ClassPointer + *
// Array * *
// DynArray *
// Map * *
// Prototype *+ *+
struct ZCC_ExprConstant;
class PType : public PTypeBase
{
DECLARE_ABSTRACT_CLASS(PType, PTypeBase)
protected:
public:
PClass *TypeTableType; // The type to use for hashing into the type table
unsigned int Size; // this type's size
unsigned int Align; // this type's preferred alignment
PType *HashNext; // next type in this type table
PSymbolTable Symbols;
bool MemberOnly = false; // type may only be used as a struct/class member but not as a local variable or function argument.
FString mDescriptiveName;
VersionInfo mVersion = { 0,0,0 };
uint8_t loadOp, storeOp, moveOp, RegType, RegCount;
PType(unsigned int size = 1, unsigned int align = 1);
virtual ~PType();
virtual bool isNumeric() { return false; }
// Writes the value of a variable of this type at (addr) to an archive, preceded by
// a tag indicating its type. The tag is there so that variable types can be changed
// without completely breaking savegames, provided that the change isn't between
// totally unrelated types.
virtual void WriteValue(FSerializer &ar, const char *key,const void *addr) const;
// Returns true if the stored value was compatible. False otherwise.
// If the value was incompatible, then the memory at *addr is unchanged.
virtual bool ReadValue(FSerializer &ar, const char *key,void *addr) const;
// Sets the default value for this type at (base + offset)
// If the default value is binary 0, then this function doesn't need
// to do anything, because PClass::Extend() takes care of that.
//
// The stroffs array is so that types that need special initialization
// and destruction (e.g. strings) can add their offsets to it for special
// initialization when the object is created and destruction when the
// object is destroyed.
virtual void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL);
virtual void SetPointer(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL);
virtual void SetPointerArray(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) const;
// Initialize the value, if needed (e.g. strings)
virtual void InitializeValue(void *addr, const void *def) const;
// Destroy the value, if needed (e.g. strings)
virtual void DestroyValue(void *addr) const;
// Sets the value of a variable of this type at (addr)
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
// Gets the value of a variable of this type at (addr)
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
// Gets the opcode to store from a register to memory
int GetStoreOp() const
{
return storeOp;
}
// Gets the opcode to load from memory to a register
int GetLoadOp() const
{
return loadOp;
}
// Gets the opcode to move from register to another register
int GetMoveOp() const
{
return moveOp;
}
// Gets the register type for this type
int GetRegType() const
{
return RegType;
}
int GetRegCount() const
{
return RegCount;
}
// Returns true if this type matches the two identifiers. Referring to the
// above table, any type is identified by at most two characteristics. Each
// type that implements this function will cast these to the appropriate type.
// It is up to the caller to make sure they are the correct types. There is
// only one prototype for this function in order to simplify type table
// management.
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
// Get the type IDs used by IsMatch
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
const char *DescriptiveName() const;
static void StaticInit();
};
// Not-really-a-type types --------------------------------------------------
class PErrorType : public PType
{
DECLARE_CLASS(PErrorType, PType);
public:
PErrorType(int which = 1) : PType(0, which) {}
};
class PVoidType : public PType
{
DECLARE_CLASS(PVoidType, PType);
public:
PVoidType() : PType(0, 1) {}
};
// Some categorization typing -----------------------------------------------
class PBasicType : public PType
{
DECLARE_ABSTRACT_CLASS(PBasicType, PType);
public:
PBasicType();
PBasicType(unsigned int size, unsigned int align);
};
class PCompoundType : public PType
{
DECLARE_ABSTRACT_CLASS(PCompoundType, PType);
};
class PContainerType : public PCompoundType
{
DECLARE_ABSTRACT_CLASS(PContainerType, PCompoundType);
public:
PTypeBase *Outer; // object this type is contained within
FName TypeName; // this type's name
PContainerType() : Outer(NULL) {
mDescriptiveName = "NamedType";
}
PContainerType(FName name, PTypeBase *outer) : Outer(outer), TypeName(name) {
mDescriptiveName = name.GetChars();
}
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
virtual PField *AddField(FName name, PType *type, uint32_t flags = 0) = 0;
virtual PField *AddNativeField(FName name, PType *type, size_t address, uint32_t flags = 0, int bitvalue = 0) = 0;
};
// Basic types --------------------------------------------------------------
class PInt : public PBasicType
{
DECLARE_CLASS(PInt, PBasicType);
public:
PInt(unsigned int size, bool unsign, bool compatible = true);
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
virtual bool isNumeric() override { return IntCompatible; }
bool Unsigned;
bool IntCompatible;
protected:
PInt();
void SetOps();
};
class PBool : public PInt
{
DECLARE_CLASS(PBool, PInt);
public:
PBool();
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
};
class PFloat : public PBasicType
{
DECLARE_CLASS(PFloat, PBasicType);
public:
PFloat(unsigned int size);
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
virtual void SetValue(void *addr, int val);
virtual void SetValue(void *addr, double val);
virtual int GetValueInt(void *addr) const;
virtual double GetValueFloat(void *addr) const;
virtual bool isNumeric() override { return true; }
protected:
PFloat();
void SetOps();
private:
struct SymbolInitF
{
ENamedName Name;
double Value;
};
struct SymbolInitI
{
ENamedName Name;
int Value;
};
void SetSingleSymbols();
void SetDoubleSymbols();
void SetSymbols(const SymbolInitF *syminit, size_t count);
void SetSymbols(const SymbolInitI *syminit, size_t count);
};
class PString : public PBasicType
{
DECLARE_CLASS(PString, PBasicType);
public:
PString();
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) override;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
};
// Variations of integer types ----------------------------------------------
class PName : public PInt
{
DECLARE_CLASS(PName, PInt);
public:
PName();
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
};
class PSound : public PInt
{
DECLARE_CLASS(PSound, PInt);
public:
PSound();
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
};
class PSpriteID : public PInt
{
DECLARE_CLASS(PSpriteID, PInt);
public:
PSpriteID();
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
};
class PTextureID : public PInt
{
DECLARE_CLASS(PTextureID, PInt);
public:
PTextureID();
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
};
class PColor : public PInt
{
DECLARE_CLASS(PColor, PInt);
public:
PColor();
};
class PStateLabel : public PInt
{
DECLARE_CLASS(PStateLabel, PInt);
public:
PStateLabel();
};
// Pointers -----------------------------------------------------------------
class PPointer : public PBasicType
{
DECLARE_CLASS(PPointer, PBasicType);
public:
typedef void(*WriteHandler)(FSerializer &ar, const char *key, const void *addr);
typedef bool(*ReadHandler)(FSerializer &ar, const char *key, void *addr);
PPointer();
PPointer(PType *pointsat, bool isconst = false);
PType *PointedType;
bool IsConst;
WriteHandler writer = nullptr;
ReadHandler reader = nullptr;
void InstallHandlers(WriteHandler w, ReadHandler r)
{
writer = w;
reader = r;
}
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
protected:
void SetOps();
};
class PStatePointer : public PPointer
{
DECLARE_CLASS(PStatePointer, PPointer);
public:
PStatePointer();
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
};
class PObjectPointer : public PPointer
{
DECLARE_CLASS(PObjectPointer, PPointer);
public:
PObjectPointer(PClass *pointedtype = nullptr, bool isconst = false);
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) override;
PClass *PointedClass() const;
};
class PClassPointer : public PPointer
{
DECLARE_CLASS(PClassPointer, PPointer);
public:
PClassPointer(class PClass *restrict = nullptr);
class PClass *ClassRestriction;
bool isCompatible(PType *type);
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) override;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
};
// Compound types -----------------------------------------------------------
class PEnum : public PInt
{
DECLARE_CLASS(PEnum, PInt);
public:
PEnum(FName name, PTypeBase *outer);
PTypeBase *Outer;
FName EnumName;
protected:
PEnum();
};
class PArray : public PCompoundType
{
DECLARE_CLASS(PArray, PCompoundType);
public:
PArray(PType *etype, unsigned int ecount);
PType *ElementType;
unsigned int ElementCount;
unsigned int ElementSize;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *special) override;
protected:
PArray();
};
class PStaticArray : public PArray
{
DECLARE_CLASS(PStaticArray, PArray);
public:
PStaticArray(PType *etype);
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
protected:
PStaticArray();
};
class PDynArray : public PCompoundType
{
DECLARE_CLASS(PDynArray, PCompoundType);
public:
PDynArray(PType *etype, PStruct *backing);
PType *ElementType;
PStruct *BackingType;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) override;
void InitializeValue(void *addr, const void *def) const override;
void DestroyValue(void *addr) const override;
void SetPointerArray(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) const override;
protected:
PDynArray();
};
class PMap : public PCompoundType
{
DECLARE_CLASS(PMap, PCompoundType);
public:
PMap(PType *keytype, PType *valtype);
PType *KeyType;
PType *ValueType;
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
protected:
PMap();
};
class PStruct : public PContainerType
{
DECLARE_CLASS(PStruct, PContainerType);
public:
PStruct(FName name, PTypeBase *outer, bool isnative = false);
bool isNative;
// Some internal structs require explicit construction and destruction of fields the VM cannot handle directly so use these two functions for it.
VMFunction *mConstructor = nullptr;
VMFunction *mDestructor = nullptr;
virtual PField *AddField(FName name, PType *type, uint32_t flags=0);
virtual PField *AddNativeField(FName name, PType *type, size_t address, uint32_t flags = 0, int bitvalue = 0);
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) override;
void SetPointer(void *base, unsigned offset, TArray<size_t> *specials) override;
protected:
PStruct();
};
class PPrototype : public PCompoundType
{
DECLARE_CLASS(PPrototype, PCompoundType);
public:
PPrototype(const TArray<PType *> &rettypes, const TArray<PType *> &argtypes);
TArray<PType *> ArgumentTypes;
TArray<PType *> ReturnTypes;
size_t PropagateMark();
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
protected:
PPrototype();
};
// Meta-info for every class derived from DObject ---------------------------
class PClassType : public PContainerType
{
DECLARE_CLASS(PClassType, PContainerType);
private:
public:
PClass *Descriptor;
PClassType *ParentType;
PClassType(PClass *cls = nullptr);
PField *AddField(FName name, PType *type, uint32_t flags = 0) override;
PField *AddNativeField(FName name, PType *type, size_t address, uint32_t flags = 0, int bitvalue = 0) override;
};
// Returns a type from the TypeTable. Will create one if it isn't present.
PMap *NewMap(PType *keytype, PType *valuetype);
PArray *NewArray(PType *type, unsigned int count);
PStaticArray *NewStaticArray(PType *type);
PDynArray *NewDynArray(PType *type);
PPointer *NewPointer(PType *type, bool isconst = false);
PPointer *NewPointer(PClass *type, bool isconst = false);
PClassPointer *NewClassPointer(PClass *restrict);
PEnum *NewEnum(FName name, PTypeBase *outer);
PStruct *NewStruct(FName name, PTypeBase *outer, bool native = false);
PPrototype *NewPrototype(const TArray<PType *> &rettypes, const TArray<PType *> &argtypes);
PClassType *NewClassType(PClass *cls);
// Built-in types -----------------------------------------------------------
extern PErrorType *TypeError;
extern PErrorType *TypeAuto;
extern PVoidType *TypeVoid;
extern PInt *TypeSInt8, *TypeUInt8;
extern PInt *TypeSInt16, *TypeUInt16;
extern PInt *TypeSInt32, *TypeUInt32;
extern PBool *TypeBool;
extern PFloat *TypeFloat32, *TypeFloat64;
extern PString *TypeString;
extern PName *TypeName;
extern PSound *TypeSound;
extern PColor *TypeColor;
extern PTextureID *TypeTextureID;
extern PSpriteID *TypeSpriteID;
extern PStruct *TypeVector2;
extern PStruct *TypeVector3;
extern PStruct *TypeColorStruct;
extern PStruct *TypeStringStruct;
extern PStatePointer *TypeState;
extern PPointer *TypeFont;
extern PStateLabel *TypeStateLabel;
extern PPointer *TypeNullPtr;
extern PPointer *TypeVoidPtr;
inline FString &DObject::StringVar(FName field)
{
return *(FString*)ScriptVar(field, TypeString);
}
// Type tables --------------------------------------------------------------
struct FTypeTable
{
enum { HASH_SIZE = 1021 };
PType *TypeHash[HASH_SIZE];
PType *FindType(PClass *metatype, intptr_t parm1, intptr_t parm2, size_t *bucketnum);
void AddType(PType *type, PClass *metatype, intptr_t parm1, intptr_t parm2, size_t bucket);
void AddType(PType *type);
void Clear();
static size_t Hash(const PClass *p1, intptr_t p2, intptr_t p3);
};
extern FTypeTable TypeTable;

View file

@ -26,134 +26,6 @@ typedef signed int VM_SWORD;
#define VM_EPSILON (1/65536.0)
#ifdef __BIG_ENDIAN__
#define VM_DEFINE_OP2(TYPE, ARG1, ARG2) TYPE ARG2, ARG1
#define VM_DEFINE_OP4(TYPE, ARG1, ARG2, ARG3, ARG4) TYPE ARG4, ARG3, ARG2, ARG1
#else // little endian
#define VM_DEFINE_OP2(TYPE, ARG1, ARG2) TYPE ARG1, ARG2
#define VM_DEFINE_OP4(TYPE, ARG1, ARG2, ARG3, ARG4) TYPE ARG1, ARG2, ARG3, ARG4
#endif // __BIG_ENDIAN__
union VMOP
{
struct
{
VM_DEFINE_OP4(VM_UBYTE, op, a, b, c);
};
struct
{
VM_DEFINE_OP4(VM_SBYTE, pad0, as, bs, cs);
};
struct
{
VM_DEFINE_OP2(VM_SWORD, pad1:8, i24:24);
};
struct
{
VM_DEFINE_OP2(VM_SWORD, pad2:16, i16:16);
};
struct
{
VM_DEFINE_OP2(VM_UHALF, pad3, i16u);
};
VM_UWORD word;
// Interesting fact: VC++ produces better code for i16 when it's defined
// as a bitfield than when it's defined as two discrete units.
// Compare:
// mov eax,dword ptr [op] ; As two discrete units
// shr eax,10h
// movsx eax,ax
// versus:
// mov eax,dword ptr [op] ; As a bitfield
// sar eax,10h
};
#undef VM_DEFINE_OP4
#undef VM_DEFINE_OP2
enum
{
#include "vmops.h"
NUM_OPS
};
// Flags for A field of CMPS
enum
{
CMP_CHECK = 1,
CMP_EQ = 0,
CMP_LT = 2,
CMP_LE = 4,
CMP_METHOD_MASK = 6,
CMP_BK = 8,
CMP_CK = 16,
CMP_APPROX = 32,
};
// Floating point operations for FLOP
enum
{
FLOP_ABS,
FLOP_NEG,
FLOP_EXP,
FLOP_LOG,
FLOP_LOG10,
FLOP_SQRT,
FLOP_CEIL,
FLOP_FLOOR,
FLOP_ACOS, // This group works with radians
FLOP_ASIN,
FLOP_ATAN,
FLOP_COS,
FLOP_SIN,
FLOP_TAN,
FLOP_ACOS_DEG, // This group works with degrees
FLOP_ASIN_DEG,
FLOP_ATAN_DEG,
FLOP_COS_DEG,
FLOP_SIN_DEG,
FLOP_TAN_DEG,
FLOP_COSH,
FLOP_SINH,
FLOP_TANH,
};
// Cast operations
enum
{
CAST_I2F,
CAST_I2S,
CAST_U2F,
CAST_U2S,
CAST_F2I,
CAST_F2U,
CAST_F2S,
CAST_P2S,
CAST_S2I,
CAST_S2F,
CAST_S2N,
CAST_N2S,
CAST_S2Co,
CAST_S2So,
CAST_Co2S,
CAST_So2S,
CAST_V22S,
CAST_V32S,
CAST_SID2S,
CAST_TID2S,
CASTB_I,
CASTB_F,
CASTB_A,
CASTB_S
};
// Register types for VMParam
enum
{
@ -198,105 +70,6 @@ public:
// This must be a separate function because the VC compiler would otherwise allocate memory on the stack for every separate instance of the exception object that may get thrown.
void ThrowAbortException(EVMAbortException reason, const char *moreinfo, ...);
enum EVMOpMode
{
MODE_ASHIFT = 0,
MODE_BSHIFT = 4,
MODE_CSHIFT = 8,
MODE_BCSHIFT = 12,
MODE_ATYPE = 15 << MODE_ASHIFT,
MODE_BTYPE = 15 << MODE_BSHIFT,
MODE_CTYPE = 15 << MODE_CSHIFT,
MODE_BCTYPE = 31 << MODE_BCSHIFT,
MODE_I = 0,
MODE_F,
MODE_S,
MODE_P,
MODE_V,
MODE_X,
MODE_KI,
MODE_KF,
MODE_KS,
MODE_KP,
MODE_KV,
MODE_UNUSED,
MODE_IMMS,
MODE_IMMZ,
MODE_JOINT,
MODE_CMP,
MODE_PARAM,
MODE_THROW,
MODE_CATCH,
MODE_CAST,
MODE_AI = MODE_I << MODE_ASHIFT,
MODE_AF = MODE_F << MODE_ASHIFT,
MODE_AS = MODE_S << MODE_ASHIFT,
MODE_AP = MODE_P << MODE_ASHIFT,
MODE_AV = MODE_V << MODE_ASHIFT,
MODE_AX = MODE_X << MODE_ASHIFT,
MODE_AKP = MODE_KP << MODE_ASHIFT,
MODE_AUNUSED = MODE_UNUSED << MODE_ASHIFT,
MODE_AIMMS = MODE_IMMS << MODE_ASHIFT,
MODE_AIMMZ = MODE_IMMZ << MODE_ASHIFT,
MODE_ACMP = MODE_CMP << MODE_ASHIFT,
MODE_BI = MODE_I << MODE_BSHIFT,
MODE_BF = MODE_F << MODE_BSHIFT,
MODE_BS = MODE_S << MODE_BSHIFT,
MODE_BP = MODE_P << MODE_BSHIFT,
MODE_BV = MODE_V << MODE_BSHIFT,
MODE_BX = MODE_X << MODE_BSHIFT,
MODE_BKI = MODE_KI << MODE_BSHIFT,
MODE_BKF = MODE_KF << MODE_BSHIFT,
MODE_BKS = MODE_KS << MODE_BSHIFT,
MODE_BKP = MODE_KP << MODE_BSHIFT,
MODE_BKV = MODE_KV << MODE_BSHIFT,
MODE_BUNUSED = MODE_UNUSED << MODE_BSHIFT,
MODE_BIMMS = MODE_IMMS << MODE_BSHIFT,
MODE_BIMMZ = MODE_IMMZ << MODE_BSHIFT,
MODE_CI = MODE_I << MODE_CSHIFT,
MODE_CF = MODE_F << MODE_CSHIFT,
MODE_CS = MODE_S << MODE_CSHIFT,
MODE_CP = MODE_P << MODE_CSHIFT,
MODE_CV = MODE_V << MODE_CSHIFT,
MODE_CX = MODE_X << MODE_CSHIFT,
MODE_CKI = MODE_KI << MODE_CSHIFT,
MODE_CKF = MODE_KF << MODE_CSHIFT,
MODE_CKS = MODE_KS << MODE_CSHIFT,
MODE_CKP = MODE_KP << MODE_CSHIFT,
MODE_CKV = MODE_KV << MODE_CSHIFT,
MODE_CUNUSED = MODE_UNUSED << MODE_CSHIFT,
MODE_CIMMS = MODE_IMMS << MODE_CSHIFT,
MODE_CIMMZ = MODE_IMMZ << MODE_CSHIFT,
MODE_BCJOINT = (MODE_JOINT << MODE_BSHIFT) | (MODE_JOINT << MODE_CSHIFT),
MODE_BCKI = MODE_KI << MODE_BCSHIFT,
MODE_BCKF = MODE_KF << MODE_BCSHIFT,
MODE_BCKS = MODE_KS << MODE_BCSHIFT,
MODE_BCKP = MODE_KP << MODE_BCSHIFT,
MODE_BCIMMS = MODE_IMMS << MODE_BCSHIFT,
MODE_BCIMMZ = MODE_IMMZ << MODE_BCSHIFT,
MODE_BCPARAM = MODE_PARAM << MODE_BCSHIFT,
MODE_BCTHROW = MODE_THROW << MODE_BCSHIFT,
MODE_BCCATCH = MODE_CATCH << MODE_BCSHIFT,
MODE_BCCAST = MODE_CAST << MODE_BCSHIFT,
MODE_ABCJOINT = (MODE_JOINT << MODE_ASHIFT) | MODE_BCJOINT,
};
struct VMOpInfo
{
const char *Name;
int Mode;
};
extern const VMOpInfo OpInfo[NUM_OPS];
struct VMReturn
{
void *Location;
@ -544,186 +317,6 @@ public:
protected:
};
// VM frame layout:
// VMFrame header
// parameter stack - 16 byte boundary, 16 bytes each
// double registers - 8 bytes each
// string registers - 4 or 8 bytes each
// address registers - 4 or 8 bytes each
// data registers - 4 bytes each
// address register tags-1 byte each
// extra space - 16 byte boundary
struct VMFrame
{
VMFrame *ParentFrame;
VMFunction *Func;
VM_UBYTE NumRegD;
VM_UBYTE NumRegF;
VM_UBYTE NumRegS;
VM_UBYTE NumRegA;
VM_UHALF MaxParam;
VM_UHALF NumParam; // current number of parameters
static int FrameSize(int numregd, int numregf, int numregs, int numrega, int numparam, int numextra)
{
int size = (sizeof(VMFrame) + 15) & ~15;
size += numparam * sizeof(VMValue);
size += numregf * sizeof(double);
size += numrega * sizeof(void *);
size += numregs * sizeof(FString);
size += numregd * sizeof(int);
if (numextra != 0)
{
size = (size + 15) & ~15;
size += numextra;
}
return size;
}
VMValue *GetParam() const
{
assert(((size_t)this & 15) == 0 && "VM frame is unaligned");
return (VMValue *)(((size_t)(this + 1) + 15) & ~15);
}
double *GetRegF() const
{
return (double *)(GetParam() + MaxParam);
}
FString *GetRegS() const
{
return (FString *)(GetRegF() + NumRegF);
}
void **GetRegA() const
{
return (void **)(GetRegS() + NumRegS);
}
int *GetRegD() const
{
return (int *)(GetRegA() + NumRegA);
}
void *GetExtra() const
{
uint8_t *pbeg = (uint8_t*)(GetRegD() + NumRegD);
ptrdiff_t ofs = pbeg - (uint8_t *)this;
return (VM_UBYTE *)this + ((ofs + 15) & ~15);
}
void GetAllRegs(int *&d, double *&f, FString *&s, void **&a, VMValue *&param) const
{
// Calling the individual functions produces suboptimal code. :(
param = GetParam();
f = (double *)(param + MaxParam);
s = (FString *)(f + NumRegF);
a = (void **)(s + NumRegS);
d = (int *)(a + NumRegA);
}
void InitRegS();
};
struct VMRegisters
{
VMRegisters(const VMFrame *frame)
{
frame->GetAllRegs(d, f, s, a, param);
}
VMRegisters(const VMRegisters &o)
: d(o.d), f(o.f), s(o.s), a(o.a), param(o.param)
{ }
int *d;
double *f;
FString *s;
void **a;
VMValue *param;
};
union FVoidObj
{
DObject *o;
void *v;
};
struct FStatementInfo
{
uint16_t InstructionIndex;
uint16_t LineNumber;
};
class VMScriptFunction : public VMFunction
{
public:
VMScriptFunction(FName name=NAME_None);
~VMScriptFunction();
void Alloc(int numops, int numkonstd, int numkonstf, int numkonsts, int numkonsta, int numlinenumbers);
VMOP *Code;
FStatementInfo *LineInfo;
FString SourceFileName;
int *KonstD;
double *KonstF;
FString *KonstS;
FVoidObj *KonstA;
int ExtraSpace;
int CodeSize; // Size of code in instructions (not bytes)
unsigned LineInfoCount;
unsigned StackSize;
VM_UBYTE NumRegD;
VM_UBYTE NumRegF;
VM_UBYTE NumRegS;
VM_UBYTE NumRegA;
VM_UHALF NumKonstD;
VM_UHALF NumKonstF;
VM_UHALF NumKonstS;
VM_UHALF NumKonstA;
VM_UHALF MaxParam; // Maximum number of parameters this function has on the stack at once
VM_UBYTE NumArgs; // Number of arguments this function takes
TArray<FTypeAndOffset> SpecialInits; // list of all contents on the extra stack which require construction and destruction
void InitExtra(void *addr);
void DestroyExtra(void *addr);
int AllocExtraStack(PType *type);
int PCToLine(const VMOP *pc);
};
class VMFrameStack
{
public:
VMFrameStack();
~VMFrameStack();
VMFrame *AllocFrame(VMScriptFunction *func);
VMFrame *PopFrame();
VMFrame *TopFrame()
{
assert(Blocks != NULL && Blocks->LastFrame != NULL);
return Blocks->LastFrame;
}
int Call(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults, VMException **trap=NULL);
private:
enum { BLOCK_SIZE = 4096 }; // Default block size
struct BlockHeader
{
BlockHeader *NextBlock;
VMFrame *LastFrame;
VM_UBYTE *FreeSpace;
int BlockSize;
void InitFreeSpace()
{
FreeSpace = (VM_UBYTE *)(((size_t)(this + 1) + 15) & ~15);
}
};
BlockHeader *Blocks;
BlockHeader *UnusedBlocks;
VMFrame *Alloc(int size);
};
class VMNativeFunction : public VMFunction
{
public:
@ -738,66 +331,7 @@ public:
NativeCallType NativeCall;
};
class VMParamFiller
{
public:
VMParamFiller(const VMFrame *frame) : Reg(frame), RegD(0), RegF(0), RegS(0), RegA(0) {}
VMParamFiller(const VMRegisters *reg) : Reg(*reg), RegD(0), RegF(0), RegS(0), RegA(0) {}
void ParamInt(int val)
{
Reg.d[RegD++] = val;
}
void ParamFloat(double val)
{
Reg.f[RegF++] = val;
}
void ParamString(FString &val)
{
Reg.s[RegS++] = val;
}
void ParamString(const char *val)
{
Reg.s[RegS++] = val;
}
void ParamObject(DObject *obj)
{
Reg.a[RegA] = obj;
RegA++;
}
void ParamPointer(void *ptr)
{
Reg.a[RegA] = ptr;
RegA++;
}
private:
const VMRegisters Reg;
int RegD, RegF, RegS, RegA;
};
enum EVMEngine
{
VMEngine_Default,
VMEngine_Unchecked,
VMEngine_Checked
};
extern thread_local VMFrameStack GlobalVMStack;
void VMSelectEngine(EVMEngine engine);
extern int (*VMExec)(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret);
void VMFillParams(VMValue *params, VMFrame *callee, int numparam);
void VMDumpConstants(FILE *out, const VMScriptFunction *func);
void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction *func);
int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults/*, VMException **trap = NULL*/);
// Use this in the prototype for a native function.
#define VM_ARGS VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret
@ -1004,7 +538,7 @@ class AActor;
#define ACTION_CALL_FROM_PSPRITE() (self->player && stateinfo != nullptr && stateinfo->mStateType == STATE_Psprite)
#define ACTION_CALL_FROM_INVENTORY() (stateinfo != nullptr && stateinfo->mStateType == STATE_StateChain)
// Standard parameters for all action functons
// Standard parameters for all action functions
// self - Actor this action is to operate on (player if a weapon)
// stateowner - Actor this action really belongs to (may be an item)
// callingstate - State this action was called from
@ -1033,4 +567,29 @@ VMFunction *FindVMFunction(PClass *cls, const char *name);
FString FStringFormat(VM_ARGS);
unsigned GetVirtualIndex(PClass *cls, const char *funcname);
#define IFVIRTUALPTR(self, cls, funcname) \
static unsigned VIndex = ~0u; \
if (VIndex == ~0u) { \
VIndex = GetVirtualIndex(RUNTIME_CLASS(cls), #funcname); \
assert(VIndex != ~0u); \
} \
auto clss = self->GetClass(); \
VMFunction *func = clss->Virtuals.Size() > VIndex? clss->Virtuals[VIndex] : nullptr; \
if (func != nullptr)
#define IFVIRTUAL(cls, funcname) IFVIRTUALPTR(this, cls, funcname)
#define IFVIRTUALPTRNAME(self, cls, funcname) \
static unsigned VIndex = ~0u; \
if (VIndex == ~0u) { \
VIndex = GetVirtualIndex(PClass::FindClass(cls), #funcname); \
assert(VIndex != ~0u); \
} \
auto clss = self->GetClass(); \
VMFunction *func = clss->Virtuals.Size() > VIndex? clss->Virtuals[VIndex] : nullptr; \
if (func != nullptr)
#endif

View file

@ -40,12 +40,16 @@
#include "textures/textures.h"
#include "math/cmath.h"
#include "stats.h"
#include "vmintern.h"
#include "types.h"
extern cycle_t VMCycles[10];
extern int VMCalls[10];
// intentionally implemented in a different source file to prevent inlining.
#if 0
void ThrowVMException(VMException *x);
#endif
#define IMPLEMENT_VMEXEC

View file

@ -215,16 +215,6 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
GETADDR(PB,RC,X_READ_NIL);
reg.a[a] = GC::ReadBarrier(*(DObject **)ptr);
NEXTOP;
OP(LOS):
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
GETADDR(PB,KC,X_READ_NIL);
reg.a[a] = *(DObject **)ptr;
NEXTOP;
OP(LOS_R):
ASSERTA(a); ASSERTA(B); ASSERTD(C);
GETADDR(PB,RC,X_READ_NIL);
reg.a[a] = *(DObject **)ptr;
NEXTOP;
OP(LP):
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
GETADDR(PB,KC,X_READ_NIL);

View file

@ -36,12 +36,17 @@
#include "dobject.h"
#include "v_text.h"
#include "stats.h"
#include "c_dispatch.h"
#include "templates.h"
#include "vmintern.h"
#include "types.h"
cycle_t VMCycles[10];
int VMCalls[10];
#if 0
IMPLEMENT_CLASS(VMException, false, false)
#endif
TArray<VMFunction *> VMFunction::AllFunctions;
@ -423,9 +428,8 @@ VMFrame *VMFrameStack::PopFrame()
//
//===========================================================================
int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults, VMException **trap)
int VMCall(VMFunction *func, VMValue *params, int numparams, VMReturn *results, int numresults/*, VMException **trap*/)
{
assert(this == &GlobalVMStack); // why would anyone even want to create a local stack?
bool allocated = false;
try
{
@ -452,16 +456,18 @@ int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMRetur
{
VMCycles[0].Clock();
VMCalls[0]++;
AllocFrame(static_cast<VMScriptFunction *>(func));
auto &stack = GlobalVMStack;
stack.AllocFrame(static_cast<VMScriptFunction *>(func));
allocated = true;
VMFillParams(params, TopFrame(), numparams);
int numret = VMExec(this, code, results, numresults);
PopFrame();
VMFillParams(params, stack.TopFrame(), numparams);
int numret = VMExec(&stack, code, results, numresults);
stack.PopFrame();
VMCycles[0].Unclock();
return numret;
}
}
}
#if 0
catch (VMException *exception)
{
if (allocated)
@ -475,11 +481,12 @@ int VMFrameStack::Call(VMFunction *func, VMValue *params, int numparams, VMRetur
}
throw;
}
#endif
catch (...)
{
if (allocated)
{
PopFrame();
GlobalVMStack.PopFrame();
}
throw;
}
@ -576,10 +583,12 @@ void NullParam(const char *varname)
ThrowAbortException(X_READ_NIL, "In function parameter %s", varname);
}
#if 0
void ThrowVMException(VMException *x)
{
throw x;
}
#endif
ADD_STAT(VM)
@ -599,3 +608,32 @@ ADD_STAT(VM)
VMCalls[0] = 0;
return FStringf("VM time in last 10 tics: %f ms, %d calls, peak = %f ms", added, addedc, peak);
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
CCMD(vmengine)
{
if (argv.argc() == 2)
{
if (stricmp(argv[1], "default") == 0)
{
VMSelectEngine(VMEngine_Default);
return;
}
else if (stricmp(argv[1], "checked") == 0)
{
VMSelectEngine(VMEngine_Checked);
return;
}
else if (stricmp(argv[1], "unchecked") == 0)
{
VMSelectEngine(VMEngine_Unchecked);
return;
}
}
Printf("Usage: vmengine <default|checked|unchecked>\n");
}

474
src/scripting/vm/vmintern.h Normal file
View file

@ -0,0 +1,474 @@
#pragma once
#include "vm.h"
class VMScriptFunction;
#ifdef __BIG_ENDIAN__
#define VM_DEFINE_OP2(TYPE, ARG1, ARG2) TYPE ARG2, ARG1
#define VM_DEFINE_OP4(TYPE, ARG1, ARG2, ARG3, ARG4) TYPE ARG4, ARG3, ARG2, ARG1
#else // little endian
#define VM_DEFINE_OP2(TYPE, ARG1, ARG2) TYPE ARG1, ARG2
#define VM_DEFINE_OP4(TYPE, ARG1, ARG2, ARG3, ARG4) TYPE ARG1, ARG2, ARG3, ARG4
#endif // __BIG_ENDIAN__
union VMOP
{
struct
{
VM_DEFINE_OP4(VM_UBYTE, op, a, b, c);
};
struct
{
VM_DEFINE_OP4(VM_SBYTE, pad0, as, bs, cs);
};
struct
{
VM_DEFINE_OP2(VM_SWORD, pad1:8, i24:24);
};
struct
{
VM_DEFINE_OP2(VM_SWORD, pad2:16, i16:16);
};
struct
{
VM_DEFINE_OP2(VM_UHALF, pad3, i16u);
};
VM_UWORD word;
// Interesting fact: VC++ produces better code for i16 when it's defined
// as a bitfield than when it's defined as two discrete units.
// Compare:
// mov eax,dword ptr [op] ; As two discrete units
// shr eax,10h
// movsx eax,ax
// versus:
// mov eax,dword ptr [op] ; As a bitfield
// sar eax,10h
};
#undef VM_DEFINE_OP4
#undef VM_DEFINE_OP2
enum
{
#include "vmops.h"
NUM_OPS
};
// Flags for A field of CMPS
enum
{
CMP_CHECK = 1,
CMP_EQ = 0,
CMP_LT = 2,
CMP_LE = 4,
CMP_METHOD_MASK = 6,
CMP_BK = 8,
CMP_CK = 16,
CMP_APPROX = 32,
};
// Floating point operations for FLOP
enum
{
FLOP_ABS,
FLOP_NEG,
FLOP_EXP,
FLOP_LOG,
FLOP_LOG10,
FLOP_SQRT,
FLOP_CEIL,
FLOP_FLOOR,
FLOP_ACOS, // This group works with radians
FLOP_ASIN,
FLOP_ATAN,
FLOP_COS,
FLOP_SIN,
FLOP_TAN,
FLOP_ACOS_DEG, // This group works with degrees
FLOP_ASIN_DEG,
FLOP_ATAN_DEG,
FLOP_COS_DEG,
FLOP_SIN_DEG,
FLOP_TAN_DEG,
FLOP_COSH,
FLOP_SINH,
FLOP_TANH,
};
// Cast operations
enum
{
CAST_I2F,
CAST_I2S,
CAST_U2F,
CAST_U2S,
CAST_F2I,
CAST_F2U,
CAST_F2S,
CAST_P2S,
CAST_S2I,
CAST_S2F,
CAST_S2N,
CAST_N2S,
CAST_S2Co,
CAST_S2So,
CAST_Co2S,
CAST_So2S,
CAST_V22S,
CAST_V32S,
CAST_SID2S,
CAST_TID2S,
CASTB_I,
CASTB_F,
CASTB_A,
CASTB_S
};
enum EVMOpMode
{
MODE_ASHIFT = 0,
MODE_BSHIFT = 4,
MODE_CSHIFT = 8,
MODE_BCSHIFT = 12,
MODE_ATYPE = 15 << MODE_ASHIFT,
MODE_BTYPE = 15 << MODE_BSHIFT,
MODE_CTYPE = 15 << MODE_CSHIFT,
MODE_BCTYPE = 31 << MODE_BCSHIFT,
MODE_I = 0,
MODE_F,
MODE_S,
MODE_P,
MODE_V,
MODE_X,
MODE_KI,
MODE_KF,
MODE_KS,
MODE_KP,
MODE_KV,
MODE_UNUSED,
MODE_IMMS,
MODE_IMMZ,
MODE_JOINT,
MODE_CMP,
MODE_PARAM,
MODE_THROW,
MODE_CATCH,
MODE_CAST,
MODE_AI = MODE_I << MODE_ASHIFT,
MODE_AF = MODE_F << MODE_ASHIFT,
MODE_AS = MODE_S << MODE_ASHIFT,
MODE_AP = MODE_P << MODE_ASHIFT,
MODE_AV = MODE_V << MODE_ASHIFT,
MODE_AX = MODE_X << MODE_ASHIFT,
MODE_AKP = MODE_KP << MODE_ASHIFT,
MODE_AUNUSED = MODE_UNUSED << MODE_ASHIFT,
MODE_AIMMS = MODE_IMMS << MODE_ASHIFT,
MODE_AIMMZ = MODE_IMMZ << MODE_ASHIFT,
MODE_ACMP = MODE_CMP << MODE_ASHIFT,
MODE_BI = MODE_I << MODE_BSHIFT,
MODE_BF = MODE_F << MODE_BSHIFT,
MODE_BS = MODE_S << MODE_BSHIFT,
MODE_BP = MODE_P << MODE_BSHIFT,
MODE_BV = MODE_V << MODE_BSHIFT,
MODE_BX = MODE_X << MODE_BSHIFT,
MODE_BKI = MODE_KI << MODE_BSHIFT,
MODE_BKF = MODE_KF << MODE_BSHIFT,
MODE_BKS = MODE_KS << MODE_BSHIFT,
MODE_BKP = MODE_KP << MODE_BSHIFT,
MODE_BKV = MODE_KV << MODE_BSHIFT,
MODE_BUNUSED = MODE_UNUSED << MODE_BSHIFT,
MODE_BIMMS = MODE_IMMS << MODE_BSHIFT,
MODE_BIMMZ = MODE_IMMZ << MODE_BSHIFT,
MODE_CI = MODE_I << MODE_CSHIFT,
MODE_CF = MODE_F << MODE_CSHIFT,
MODE_CS = MODE_S << MODE_CSHIFT,
MODE_CP = MODE_P << MODE_CSHIFT,
MODE_CV = MODE_V << MODE_CSHIFT,
MODE_CX = MODE_X << MODE_CSHIFT,
MODE_CKI = MODE_KI << MODE_CSHIFT,
MODE_CKF = MODE_KF << MODE_CSHIFT,
MODE_CKS = MODE_KS << MODE_CSHIFT,
MODE_CKP = MODE_KP << MODE_CSHIFT,
MODE_CKV = MODE_KV << MODE_CSHIFT,
MODE_CUNUSED = MODE_UNUSED << MODE_CSHIFT,
MODE_CIMMS = MODE_IMMS << MODE_CSHIFT,
MODE_CIMMZ = MODE_IMMZ << MODE_CSHIFT,
MODE_BCJOINT = (MODE_JOINT << MODE_BSHIFT) | (MODE_JOINT << MODE_CSHIFT),
MODE_BCKI = MODE_KI << MODE_BCSHIFT,
MODE_BCKF = MODE_KF << MODE_BCSHIFT,
MODE_BCKS = MODE_KS << MODE_BCSHIFT,
MODE_BCKP = MODE_KP << MODE_BCSHIFT,
MODE_BCIMMS = MODE_IMMS << MODE_BCSHIFT,
MODE_BCIMMZ = MODE_IMMZ << MODE_BCSHIFT,
MODE_BCPARAM = MODE_PARAM << MODE_BCSHIFT,
MODE_BCTHROW = MODE_THROW << MODE_BCSHIFT,
MODE_BCCATCH = MODE_CATCH << MODE_BCSHIFT,
MODE_BCCAST = MODE_CAST << MODE_BCSHIFT,
MODE_ABCJOINT = (MODE_JOINT << MODE_ASHIFT) | MODE_BCJOINT,
};
struct VMOpInfo
{
const char *Name;
int Mode;
};
extern const VMOpInfo OpInfo[NUM_OPS];
// VM frame layout:
// VMFrame header
// parameter stack - 16 byte boundary, 16 bytes each
// double registers - 8 bytes each
// string registers - 4 or 8 bytes each
// address registers - 4 or 8 bytes each
// data registers - 4 bytes each
// address register tags-1 byte each
// extra space - 16 byte boundary
struct VMFrame
{
VMFrame *ParentFrame;
VMFunction *Func;
VM_UBYTE NumRegD;
VM_UBYTE NumRegF;
VM_UBYTE NumRegS;
VM_UBYTE NumRegA;
VM_UHALF MaxParam;
VM_UHALF NumParam; // current number of parameters
static int FrameSize(int numregd, int numregf, int numregs, int numrega, int numparam, int numextra)
{
int size = (sizeof(VMFrame) + 15) & ~15;
size += numparam * sizeof(VMValue);
size += numregf * sizeof(double);
size += numrega * sizeof(void *);
size += numregs * sizeof(FString);
size += numregd * sizeof(int);
if (numextra != 0)
{
size = (size + 15) & ~15;
size += numextra;
}
return size;
}
VMValue *GetParam() const
{
assert(((size_t)this & 15) == 0 && "VM frame is unaligned");
return (VMValue *)(((size_t)(this + 1) + 15) & ~15);
}
double *GetRegF() const
{
return (double *)(GetParam() + MaxParam);
}
FString *GetRegS() const
{
return (FString *)(GetRegF() + NumRegF);
}
void **GetRegA() const
{
return (void **)(GetRegS() + NumRegS);
}
int *GetRegD() const
{
return (int *)(GetRegA() + NumRegA);
}
void *GetExtra() const
{
uint8_t *pbeg = (uint8_t*)(GetRegD() + NumRegD);
ptrdiff_t ofs = pbeg - (uint8_t *)this;
return (VM_UBYTE *)this + ((ofs + 15) & ~15);
}
void GetAllRegs(int *&d, double *&f, FString *&s, void **&a, VMValue *&param) const
{
// Calling the individual functions produces suboptimal code. :(
param = GetParam();
f = (double *)(param + MaxParam);
s = (FString *)(f + NumRegF);
a = (void **)(s + NumRegS);
d = (int *)(a + NumRegA);
}
void InitRegS();
};
struct VMRegisters
{
VMRegisters(const VMFrame *frame)
{
frame->GetAllRegs(d, f, s, a, param);
}
VMRegisters(const VMRegisters &o)
: d(o.d), f(o.f), s(o.s), a(o.a), param(o.param)
{ }
int *d;
double *f;
FString *s;
void **a;
VMValue *param;
};
union FVoidObj
{
DObject *o;
void *v;
};
struct FStatementInfo
{
uint16_t InstructionIndex;
uint16_t LineNumber;
};
class VMFrameStack
{
public:
VMFrameStack();
~VMFrameStack();
VMFrame *AllocFrame(VMScriptFunction *func);
VMFrame *PopFrame();
VMFrame *TopFrame()
{
assert(Blocks != NULL && Blocks->LastFrame != NULL);
return Blocks->LastFrame;
}
private:
enum { BLOCK_SIZE = 4096 }; // Default block size
struct BlockHeader
{
BlockHeader *NextBlock;
VMFrame *LastFrame;
VM_UBYTE *FreeSpace;
int BlockSize;
void InitFreeSpace()
{
FreeSpace = (VM_UBYTE *)(((size_t)(this + 1) + 15) & ~15);
}
};
BlockHeader *Blocks;
BlockHeader *UnusedBlocks;
VMFrame *Alloc(int size);
};
class VMParamFiller
{
public:
VMParamFiller(const VMFrame *frame) : Reg(frame), RegD(0), RegF(0), RegS(0), RegA(0) {}
VMParamFiller(const VMRegisters *reg) : Reg(*reg), RegD(0), RegF(0), RegS(0), RegA(0) {}
void ParamInt(int val)
{
Reg.d[RegD++] = val;
}
void ParamFloat(double val)
{
Reg.f[RegF++] = val;
}
void ParamString(FString &val)
{
Reg.s[RegS++] = val;
}
void ParamString(const char *val)
{
Reg.s[RegS++] = val;
}
void ParamObject(DObject *obj)
{
Reg.a[RegA] = obj;
RegA++;
}
void ParamPointer(void *ptr)
{
Reg.a[RegA] = ptr;
RegA++;
}
private:
const VMRegisters Reg;
int RegD, RegF, RegS, RegA;
};
enum EVMEngine
{
VMEngine_Default,
VMEngine_Unchecked,
VMEngine_Checked
};
void VMSelectEngine(EVMEngine engine);
extern int (*VMExec)(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret);
void VMFillParams(VMValue *params, VMFrame *callee, int numparam);
void VMDumpConstants(FILE *out, const VMScriptFunction *func);
void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction *func);
extern thread_local VMFrameStack GlobalVMStack;
typedef std::pair<const class PType *, unsigned> FTypeAndOffset;
class VMScriptFunction : public VMFunction
{
public:
VMScriptFunction(FName name = NAME_None);
~VMScriptFunction();
void Alloc(int numops, int numkonstd, int numkonstf, int numkonsts, int numkonsta, int numlinenumbers);
VMOP *Code;
FStatementInfo *LineInfo;
FString SourceFileName;
int *KonstD;
double *KonstF;
FString *KonstS;
FVoidObj *KonstA;
int ExtraSpace;
int CodeSize; // Size of code in instructions (not bytes)
unsigned LineInfoCount;
unsigned StackSize;
VM_UBYTE NumRegD;
VM_UBYTE NumRegF;
VM_UBYTE NumRegS;
VM_UBYTE NumRegA;
VM_UHALF NumKonstD;
VM_UHALF NumKonstF;
VM_UHALF NumKonstS;
VM_UHALF NumKonstA;
VM_UHALF MaxParam; // Maximum number of parameters this function has on the stack at once
VM_UBYTE NumArgs; // Number of arguments this function takes
TArray<FTypeAndOffset> SpecialInits; // list of all contents on the extra stack which require construction and destruction
void InitExtra(void *addr);
void DestroyExtra(void *addr);
int AllocExtraStack(PType *type);
int PCToLine(const VMOP *pc);
};

View file

@ -45,8 +45,6 @@ xx(LS, ls, RSRPKI, LS_R, 4, REGT_INT), // load string
xx(LS_R, ls, RSRPRI, NOP, 0, 0),
xx(LO, lo, RPRPKI, LO_R, 4, REGT_INT), // load object
xx(LO_R, lo, RPRPRI, NOP, 0, 0),
xx(LOS, los, RPRPKI, LOS_R, 4, REGT_INT), // load object (stack version without read barrier)
xx(LOS_R, lo, RPRPRI, NOP, 0, 0),
xx(LP, lp, RPRPKI, LP_R, 4, REGT_INT), // load pointer
xx(LP_R, lp, RPRPRI, NOP, 0, 0),
xx(LV2, lv2, RVRPKI, LV2_R, 4, REGT_INT), // load vector2

View file

@ -32,6 +32,8 @@
*/
#include "dobject.h"
#include "vmintern.h"
#include "types.h"
#include "sc_man.h"
#include "memarena.h"
#include "zcc_parser.h"

View file

@ -49,6 +49,7 @@
#include "i_system.h"
#include "gdtoa.h"
#include "backend/vmbuilder.h"
#include "types.h"
FSharedStringArena VMStringConstants;
bool isActor(PContainerType *type);

View file

@ -3,6 +3,7 @@
#include "memarena.h"
#include "sc_man.h"
#include "types.h"
struct ZCCToken
{
@ -193,7 +194,7 @@ struct ZCC_NamedNode : ZCC_TreeNode
struct ZCC_Struct : ZCC_NamedNode
{
VM_UWORD Flags;
uint32_t Flags;
ZCC_TreeNode *Body;
PContainerType *Type;
VersionInfo Version;

Some files were not shown because too many files have changed in this diff Show more