mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-17 09:41:21 +00:00
- All states now use thunk functions to call the action functions. This is the bare
minimum to be able to say that VM is being used. - Added tags for the pointer constants table. SVN r1871 (scripting)
This commit is contained in:
parent
1eb7912bd8
commit
3e7b69a12e
5 changed files with 211 additions and 39 deletions
66
src/info.cpp
66
src/info.cpp
|
@ -51,6 +51,72 @@
|
||||||
|
|
||||||
extern void LoadActors ();
|
extern void LoadActors ();
|
||||||
|
|
||||||
|
int CallDecorateAction(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
|
||||||
|
{
|
||||||
|
assert(numparam == 6);
|
||||||
|
actionf_p action = (actionf_p)param[5].a;
|
||||||
|
action((AActor *)param[0].a, (AActor *)param[1].a, (FState *)param[2].a, param[3].i, (StateCallData *)param[4].a);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FState::SetAction(PSymbolActionFunction *func, bool setdefaultparams)
|
||||||
|
{
|
||||||
|
if (func != NULL)
|
||||||
|
{
|
||||||
|
// All generated functions use this code.
|
||||||
|
static const VM_UBYTE codetemplate[] =
|
||||||
|
{
|
||||||
|
OP_PARAM, 0, REGT_POINTER, 0,
|
||||||
|
OP_PARAM, 0, REGT_POINTER, 1,
|
||||||
|
OP_PARAM, 0, REGT_POINTER, 2,
|
||||||
|
OP_PARAM, 0, REGT_INT, 0,
|
||||||
|
OP_PARAM, 0, REGT_POINTER, 3,
|
||||||
|
OP_PARAM, 0, REGT_POINTER|REGT_KONST, 0,
|
||||||
|
OP_CALL_K, 1, 6, 0,
|
||||||
|
OP_RET, 0, REGT_NIL, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find the CallDecorateAction function. If not found, create it and install it
|
||||||
|
// in Actor.
|
||||||
|
VMFunction *callfunc;
|
||||||
|
PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol("CallDecorateAction", false);
|
||||||
|
if (sym == NULL)
|
||||||
|
{
|
||||||
|
PSymbolVMFunction *symfunc = new PSymbolVMFunction("CallDecorateAction");
|
||||||
|
VMNativeFunction *calldec = new VMNativeFunction(CallDecorateAction);
|
||||||
|
symfunc->Function = calldec;
|
||||||
|
sym = symfunc;
|
||||||
|
RUNTIME_CLASS(AActor)->Symbols.AddSymbol(sym);
|
||||||
|
}
|
||||||
|
assert(sym->SymbolType == SYM_VMFunction);
|
||||||
|
assert(((PSymbolVMFunction *)sym)->Function != NULL);
|
||||||
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
|
||||||
|
// Create a function for this state.
|
||||||
|
VMScriptFunction *vmfunc = new VMScriptFunction;
|
||||||
|
VM_UBYTE *code = vmfunc->AllocCode(sizeof(codetemplate)/VM_OPSIZE);
|
||||||
|
memcpy(code, codetemplate, sizeof(codetemplate));
|
||||||
|
FVoidObj *konsta = vmfunc->AllocKonstA(2);
|
||||||
|
VM_ATAG *atag = vmfunc->KonstATags();
|
||||||
|
konsta[0].v = func->Function;
|
||||||
|
konsta[1].o = callfunc;
|
||||||
|
atag[0] = ATAG_GENERIC;
|
||||||
|
atag[1] = ATAG_OBJECT;
|
||||||
|
vmfunc->NumRegA = 4;
|
||||||
|
vmfunc->NumRegD = 1;
|
||||||
|
vmfunc->MaxParam = 6;
|
||||||
|
vmfunc->NumArgs = 5;
|
||||||
|
ActionFunc = vmfunc;
|
||||||
|
|
||||||
|
if (setdefaultparams) ParameterIndex = func->defaultparameterindex+1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ActionFunc = NULL;
|
||||||
|
if (setdefaultparams) ParameterIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool FState::CallAction(AActor *self, AActor *stateowner, StateCallData *statecall)
|
bool FState::CallAction(AActor *self, AActor *stateowner, StateCallData *statecall)
|
||||||
{
|
{
|
||||||
if (ActionFunc != NULL)
|
if (ActionFunc != NULL)
|
||||||
|
|
16
src/info.h
16
src/info.h
|
@ -92,21 +92,7 @@ struct FState
|
||||||
{
|
{
|
||||||
Frame = (Frame & SF_FULLBRIGHT) | (frame-'A');
|
Frame = (Frame & SF_FULLBRIGHT) | (frame-'A');
|
||||||
}
|
}
|
||||||
void SetAction(PSymbolActionFunction *func, bool setdefaultparams = true)
|
void SetAction(PSymbolActionFunction *func, bool setdefaultparams = true);
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
if (func != NULL)
|
|
||||||
{
|
|
||||||
ActionFunc = func->Function;
|
|
||||||
if (setdefaultparams) ParameterIndex = func->defaultparameterindex+1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
ActionFunc = NULL;
|
|
||||||
if (setdefaultparams) ParameterIndex = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool CallAction(AActor *self, AActor *stateowner, StateCallData *statecall = NULL);
|
bool CallAction(AActor *self, AActor *stateowner, StateCallData *statecall = NULL);
|
||||||
static const PClass *StaticFindStateOwner (const FState *state);
|
static const PClass *StaticFindStateOwner (const FState *state);
|
||||||
static const PClass *StaticFindStateOwner (const FState *state, const FActorInfo *info);
|
static const PClass *StaticFindStateOwner (const FState *state, const FActorInfo *info);
|
||||||
|
|
|
@ -14,8 +14,10 @@ typedef unsigned short VM_UHALF;
|
||||||
typedef signed short VM_SHALF;
|
typedef signed short VM_SHALF;
|
||||||
typedef unsigned int VM_UWORD;
|
typedef unsigned int VM_UWORD;
|
||||||
typedef signed int VM_SWORD;
|
typedef signed int VM_SWORD;
|
||||||
|
typedef VM_UBYTE VM_ATAG;
|
||||||
|
|
||||||
#define VM_EPSILON (1/1024.0)
|
#define VM_EPSILON (1/1024.0)
|
||||||
|
#define VM_OPSIZE 4 // Number of bytes used by one opcode
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -109,7 +111,7 @@ enum
|
||||||
|
|
||||||
class VMFunction : public DObject
|
class VMFunction : public DObject
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(VMFunction, DObject);
|
DECLARE_ABSTRACT_CLASS(VMFunction, DObject);
|
||||||
public:
|
public:
|
||||||
bool Native;
|
bool Native;
|
||||||
};
|
};
|
||||||
|
@ -409,7 +411,7 @@ struct VMValue
|
||||||
Type = REGT_POINTER;
|
Type = REGT_POINTER;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
void SetPointer(void *v, VM_UBYTE atag=ATAG_GENERIC)
|
void SetPointer(void *v, VM_ATAG atag=ATAG_GENERIC)
|
||||||
{
|
{
|
||||||
Kill();
|
Kill();
|
||||||
a = v;
|
a = v;
|
||||||
|
@ -614,9 +616,9 @@ struct VMFrame
|
||||||
return (void **)(GetRegS() + NumRegS);
|
return (void **)(GetRegS() + NumRegS);
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_UBYTE *GetRegATag() const
|
VM_ATAG *GetRegATag() const
|
||||||
{
|
{
|
||||||
return (VM_UBYTE *)(GetRegD() + NumRegD);
|
return (VM_ATAG *)(GetRegD() + NumRegD);
|
||||||
}
|
}
|
||||||
|
|
||||||
VMValue *GetParam() const
|
VMValue *GetParam() const
|
||||||
|
@ -626,12 +628,12 @@ struct VMFrame
|
||||||
|
|
||||||
void *GetExtra() const
|
void *GetExtra() const
|
||||||
{
|
{
|
||||||
VM_UBYTE *ptag = GetRegATag();
|
VM_ATAG *ptag = GetRegATag();
|
||||||
ptrdiff_t ofs = ptag - (VM_UBYTE *)this;
|
ptrdiff_t ofs = ptag - (VM_ATAG *)this;
|
||||||
return (VM_UBYTE *)this + ((ofs + NumRegA + 15) & ~15);
|
return (VM_UBYTE *)this + ((ofs + NumRegA + 15) & ~15);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetAllRegs(int *&d, double *&f, FString *&s, void **&a, VM_UBYTE *&atag, VMValue *¶m) const
|
void GetAllRegs(int *&d, double *&f, FString *&s, void **&a, VM_ATAG *&atag, VMValue *¶m) const
|
||||||
{
|
{
|
||||||
// Calling the individual functions produces suboptimal code. :(
|
// Calling the individual functions produces suboptimal code. :(
|
||||||
param = GetParam();
|
param = GetParam();
|
||||||
|
@ -639,7 +641,7 @@ struct VMFrame
|
||||||
s = (FString *)(f + NumRegF);
|
s = (FString *)(f + NumRegF);
|
||||||
a = (void **)(s + NumRegS);
|
a = (void **)(s + NumRegS);
|
||||||
d = (int *)(a + NumRegA);
|
d = (int *)(a + NumRegA);
|
||||||
atag = (VM_UBYTE *)(d + NumRegD);
|
atag = (VM_ATAG *)(d + NumRegD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitRegS();
|
void InitRegS();
|
||||||
|
@ -660,7 +662,7 @@ struct VMRegisters
|
||||||
double *f;
|
double *f;
|
||||||
FString *s;
|
FString *s;
|
||||||
void **a;
|
void **a;
|
||||||
VM_UBYTE *atag;
|
VM_ATAG *atag;
|
||||||
VMValue *param;
|
VMValue *param;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -669,15 +671,33 @@ struct VMException : public DObject
|
||||||
DECLARE_CLASS(VMFunction, DObject);
|
DECLARE_CLASS(VMFunction, DObject);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union FVoidObj
|
||||||
|
{
|
||||||
|
DObject *o;
|
||||||
|
void *v;
|
||||||
|
};
|
||||||
|
|
||||||
class VMScriptFunction : public VMFunction
|
class VMScriptFunction : public VMFunction
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(VMScriptFunction, VMFunction);
|
DECLARE_CLASS(VMScriptFunction, VMFunction);
|
||||||
public:
|
public:
|
||||||
const VM_UBYTE *Code;
|
VMScriptFunction();
|
||||||
|
~VMScriptFunction();
|
||||||
|
size_t PropagateMark();
|
||||||
|
VM_UBYTE *AllocCode(int numops);
|
||||||
|
int *AllocKonstD(int numkonst);
|
||||||
|
double *AllocKonstF(int numkonst);
|
||||||
|
FString *AllocKonstS(int numkonst);
|
||||||
|
FVoidObj *AllocKonstA(int numkonst);
|
||||||
|
|
||||||
|
VM_ATAG *KonstATags() { return (VM_UBYTE *)(KonstA + NumKonstA); }
|
||||||
|
const VM_ATAG *KonstATags() const { return (VM_UBYTE *)(KonstA + NumKonstA); }
|
||||||
|
|
||||||
|
VM_UBYTE *Code;
|
||||||
int *KonstD;
|
int *KonstD;
|
||||||
double *KonstF;
|
double *KonstF;
|
||||||
FString *KonstS;
|
FString *KonstS;
|
||||||
void **KonstA;
|
FVoidObj *KonstA;
|
||||||
int ExtraSpace;
|
int ExtraSpace;
|
||||||
int NumCodeBytes;
|
int NumCodeBytes;
|
||||||
VM_UBYTE NumRegD;
|
VM_UBYTE NumRegD;
|
||||||
|
@ -724,8 +744,13 @@ class VMNativeFunction : public VMFunction
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(VMNativeFunction, VMFunction);
|
DECLARE_CLASS(VMNativeFunction, VMFunction);
|
||||||
public:
|
public:
|
||||||
|
typedef int (*NativeCallType)(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret);
|
||||||
|
|
||||||
|
VMNativeFunction() : NativeCall(NULL) { Native = true; }
|
||||||
|
VMNativeFunction(NativeCallType call) : NativeCall(call) { Native = true; }
|
||||||
|
|
||||||
// Return value is the number of results.
|
// Return value is the number of results.
|
||||||
int (*NativeCall)(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret);
|
NativeCallType NativeCall;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -762,7 +787,7 @@ public:
|
||||||
RegA++;
|
RegA++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParamPointer(void *ptr, VM_UBYTE atag)
|
void ParamPointer(void *ptr, VM_ATAG atag)
|
||||||
{
|
{
|
||||||
Reg.a[RegA] = ptr;
|
Reg.a[RegA] = ptr;
|
||||||
Reg.atag[RegA] = atag;
|
Reg.atag[RegA] = atag;
|
||||||
|
|
|
@ -20,7 +20,8 @@ static int Exec(VMFrameStack *stack, const VM_UBYTE *pc, VMReturn *ret, int numr
|
||||||
const int *konstd;
|
const int *konstd;
|
||||||
const double *konstf;
|
const double *konstf;
|
||||||
const FString *konsts;
|
const FString *konsts;
|
||||||
void * const *konsta;
|
const FVoidObj *konsta;
|
||||||
|
const VM_ATAG *konstatag;
|
||||||
|
|
||||||
if (f->Func != NULL && !f->Func->Native)
|
if (f->Func != NULL && !f->Func->Native)
|
||||||
{
|
{
|
||||||
|
@ -29,6 +30,7 @@ static int Exec(VMFrameStack *stack, const VM_UBYTE *pc, VMReturn *ret, int numr
|
||||||
konstf = sfunc->KonstF;
|
konstf = sfunc->KonstF;
|
||||||
konsts = sfunc->KonstS;
|
konsts = sfunc->KonstS;
|
||||||
konsta = sfunc->KonstA;
|
konsta = sfunc->KonstA;
|
||||||
|
konstatag = sfunc->KonstATags();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -37,6 +39,7 @@ static int Exec(VMFrameStack *stack, const VM_UBYTE *pc, VMReturn *ret, int numr
|
||||||
konstf = NULL;
|
konstf = NULL;
|
||||||
konsts = NULL;
|
konsts = NULL;
|
||||||
konsta = NULL;
|
konsta = NULL;
|
||||||
|
konstatag = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
@ -72,8 +75,8 @@ begin:
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(LKP):
|
OP(LKP):
|
||||||
ASSERTA(a); ASSERTKA(BC);
|
ASSERTA(a); ASSERTKA(BC);
|
||||||
reg.a[a] = konsta[BC];
|
reg.a[a] = konsta[BC].v;
|
||||||
reg.atag[a] = ATAG_OBJECT;
|
reg.atag[a] = konstatag[BC];
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(LFP):
|
OP(LFP):
|
||||||
ASSERTA(a); assert(sfunc != NULL); assert(sfunc->ExtraSpace > 0);
|
ASSERTA(a); assert(sfunc != NULL); assert(sfunc->ExtraSpace > 0);
|
||||||
|
@ -439,7 +442,7 @@ begin:
|
||||||
break;
|
break;
|
||||||
case REGT_POINTER | REGT_KONST:
|
case REGT_POINTER | REGT_KONST:
|
||||||
assert(C < sfunc->NumKonstA);
|
assert(C < sfunc->NumKonstA);
|
||||||
::new(param) VMValue(konsta[C]);
|
::new(param) VMValue(konsta[C].v, konstatag[C]);
|
||||||
break;
|
break;
|
||||||
case REGT_FLOAT:
|
case REGT_FLOAT:
|
||||||
if (b & REGT_MULTIREG)
|
if (b & REGT_MULTIREG)
|
||||||
|
@ -486,7 +489,8 @@ begin:
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(CALL_K):
|
OP(CALL_K):
|
||||||
ASSERTKA(a);
|
ASSERTKA(a);
|
||||||
ptr = sfunc->KonstA[a];
|
assert(konstatag[a] == ATAG_OBJECT);
|
||||||
|
ptr = konsta[a].o;
|
||||||
goto Do_CALL;
|
goto Do_CALL;
|
||||||
OP(CALL):
|
OP(CALL):
|
||||||
ASSERTA(a);
|
ASSERTA(a);
|
||||||
|
@ -572,7 +576,8 @@ begin:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSERTKA(B);
|
ASSERTKA(B);
|
||||||
throw((VMException *)konsta[B]);
|
assert(konstatag[B] == ATAG_OBJECT);
|
||||||
|
throw((VMException *)konsta[B].o);
|
||||||
}
|
}
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(CATCH):
|
OP(CATCH):
|
||||||
|
@ -1224,7 +1229,7 @@ begin:
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(EQA_K):
|
OP(EQA_K):
|
||||||
ASSERTA(B); ASSERTKA(C);
|
ASSERTA(B); ASSERTKA(C);
|
||||||
CMPJMP(reg.a[B] == konsta[C]);
|
CMPJMP(reg.a[B] == konsta[C].v);
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1254,7 +1259,8 @@ begin:
|
||||||
{
|
{
|
||||||
assert(pc[1] == 3);
|
assert(pc[1] == 3);
|
||||||
ASSERTKA(b);
|
ASSERTKA(b);
|
||||||
type = (PClass *)konsta[b];
|
assert(konstatag[b] == ATAG_OBJECT);
|
||||||
|
type = (PClass *)konsta[b].o;
|
||||||
}
|
}
|
||||||
ASSERTA(pc[3]);
|
ASSERTA(pc[3]);
|
||||||
if (type == extype)
|
if (type == extype)
|
||||||
|
@ -1414,7 +1420,7 @@ static void FillReturns(const VMRegisters ®, VMFrame *frame, VMReturn *return
|
||||||
static void SetReturn(const VMRegisters ®, VMFrame *frame, VMReturn *ret, VM_UBYTE regtype, int regnum)
|
static void SetReturn(const VMRegisters ®, VMFrame *frame, VMReturn *ret, VM_UBYTE regtype, int regnum)
|
||||||
{
|
{
|
||||||
const void *src;
|
const void *src;
|
||||||
VM_UBYTE atag;
|
VM_ATAG atag;
|
||||||
VMScriptFunction *func = static_cast<VMScriptFunction *>(frame->Func);
|
VMScriptFunction *func = static_cast<VMScriptFunction *>(frame->Func);
|
||||||
|
|
||||||
assert(func != NULL && !func->Native);
|
assert(func != NULL && !func->Native);
|
||||||
|
@ -1478,8 +1484,8 @@ static void SetReturn(const VMRegisters ®, VMFrame *frame, VMReturn *ret, VM_
|
||||||
if (regtype & REGT_KONST)
|
if (regtype & REGT_KONST)
|
||||||
{
|
{
|
||||||
assert(regnum < func->NumKonstA);
|
assert(regnum < func->NumKonstA);
|
||||||
ret->SetPointer(func->KonstA[regnum]);
|
ret->SetPointer(func->KonstA[regnum].v);
|
||||||
atag = ATAG_OBJECT;
|
atag = func->KonstATags()[regnum];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,95 @@
|
||||||
#include <new>
|
#include <new>
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
|
|
||||||
|
IMPLEMENT_CLASS(VMException)
|
||||||
|
IMPLEMENT_ABSTRACT_CLASS(VMFunction)
|
||||||
|
IMPLEMENT_CLASS(VMScriptFunction)
|
||||||
|
IMPLEMENT_CLASS(VMNativeFunction)
|
||||||
|
|
||||||
|
VMScriptFunction::VMScriptFunction()
|
||||||
|
{
|
||||||
|
Native = false;
|
||||||
|
Code = NULL;
|
||||||
|
KonstD = NULL;
|
||||||
|
KonstF = NULL;
|
||||||
|
KonstS = NULL;
|
||||||
|
KonstA = NULL;
|
||||||
|
ExtraSpace = 0;
|
||||||
|
NumCodeBytes = 0;
|
||||||
|
NumRegD = 0;
|
||||||
|
NumRegF = 0;
|
||||||
|
NumRegS = 0;
|
||||||
|
NumRegA = 0;
|
||||||
|
NumKonstD = 0;
|
||||||
|
NumKonstF = 0;
|
||||||
|
NumKonstS = 0;
|
||||||
|
NumKonstA = 0;
|
||||||
|
MaxParam = 0;
|
||||||
|
NumArgs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VMScriptFunction::~VMScriptFunction()
|
||||||
|
{
|
||||||
|
if (Code != NULL) M_Free(Code);
|
||||||
|
if (KonstD != NULL) M_Free(KonstD);
|
||||||
|
if (KonstF != NULL) M_Free(KonstF);
|
||||||
|
if (KonstS != NULL) delete[] KonstS;
|
||||||
|
if (KonstA != NULL) M_Free(KonstA);
|
||||||
|
}
|
||||||
|
|
||||||
|
VM_UBYTE *VMScriptFunction::AllocCode(int numops)
|
||||||
|
{
|
||||||
|
assert(Code == NULL && numops > 0);
|
||||||
|
numops *= VM_OPSIZE;
|
||||||
|
NumCodeBytes = numops;
|
||||||
|
return Code = (VM_UBYTE *)M_Malloc(numops);
|
||||||
|
}
|
||||||
|
|
||||||
|
int *VMScriptFunction::AllocKonstD(int numkonst)
|
||||||
|
{
|
||||||
|
assert(KonstD == NULL && numkonst > 0);
|
||||||
|
NumKonstD = numkonst;
|
||||||
|
return KonstD = (int *)M_Malloc(numkonst * sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
double *VMScriptFunction::AllocKonstF(int numkonst)
|
||||||
|
{
|
||||||
|
assert(KonstF == NULL && numkonst > 0);
|
||||||
|
NumKonstF = numkonst;
|
||||||
|
return KonstF = (double *)M_Malloc(numkonst * sizeof(double));
|
||||||
|
}
|
||||||
|
|
||||||
|
FString *VMScriptFunction::AllocKonstS(int numkonst)
|
||||||
|
{
|
||||||
|
assert(KonstS == NULL && numkonst > 0);
|
||||||
|
NumKonstS = numkonst;
|
||||||
|
return KonstS = new FString[numkonst];
|
||||||
|
}
|
||||||
|
|
||||||
|
FVoidObj *VMScriptFunction::AllocKonstA(int numkonst)
|
||||||
|
{
|
||||||
|
assert(KonstA == NULL && numkonst > 0);
|
||||||
|
NumKonstA = numkonst;
|
||||||
|
return KonstA = (FVoidObj *)M_Malloc(numkonst * sizeof(FVoidObj) + numkonst);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t VMScriptFunction::PropagateMark()
|
||||||
|
{
|
||||||
|
if (KonstA != NULL)
|
||||||
|
{
|
||||||
|
FVoidObj *konsta = KonstA;
|
||||||
|
VM_UBYTE *atag = KonstATags();
|
||||||
|
for (int count = NumKonstA; count > 0; --count)
|
||||||
|
{
|
||||||
|
if (*atag++ == ATAG_OBJECT)
|
||||||
|
{
|
||||||
|
GC::Mark(konsta->o);
|
||||||
|
}
|
||||||
|
konsta++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NumKonstA * sizeof(void *) + Super::PropagateMark();
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue