Dynamic virtualscope checking. May yet be buggy.
This commit is contained in:
parent
b5ab011bb9
commit
e0ae0fdb2e
6 changed files with 92 additions and 20 deletions
|
|
@ -8,6 +8,11 @@
|
|||
#include "doomerrors.h"
|
||||
#include "memarena.h"
|
||||
|
||||
// [ZZ] there are serious circular references between this and the rest of ZScript code, so it needs to be done like this
|
||||
// these are used in vmexec.h
|
||||
void FScopeBarrier_ValidateNew(PClass* cls, PFunction* callingfunc);
|
||||
void FScopeBarrier_ValidateCall(PFunction* calledfunc, PFunction* callingfunc, PClass* selftype);
|
||||
|
||||
extern FMemArena ClassDataAllocator;
|
||||
|
||||
#define MAX_RETURNS 8 // Maximum number of results a function called by script code can return
|
||||
|
|
@ -712,7 +717,7 @@ public:
|
|||
|
||||
class PPrototype *Proto;
|
||||
|
||||
VMFunction(FName name = NAME_None) : Native(false), ImplicitArgs(0), Name(name), Proto(NULL)
|
||||
VMFunction(FName name = NAME_None) : Native(false), ImplicitArgs(0), Name(name), Proto(NULL)
|
||||
{
|
||||
AllFunctions.Push(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -648,13 +648,25 @@ begin:
|
|||
VMReturn returns[MAX_RETURNS];
|
||||
int numret;
|
||||
|
||||
// [ZZ] hax!
|
||||
b = B;
|
||||
if (call->BarrierSide == 3) // :( - this is Side_Virtual. Side_Virtual should receive special arguments.
|
||||
{
|
||||
PFunction* calledfunc = (PFunction*)(reg.param + f->NumParam - b)[0].a;
|
||||
PFunction* callingfunc = (PFunction*)(reg.param + f->NumParam - b)[1].a;
|
||||
DObject* dobj = (DObject*)(reg.param + f->NumParam - b)[2].a; // this is the self pointer. it should be in, since Side_Virtual functions are always non-static methods.
|
||||
PClass* selftype = dobj->GetClass();
|
||||
FScopeBarrier_ValidateCall(calledfunc, callingfunc, selftype);
|
||||
b -= 2;
|
||||
}
|
||||
|
||||
FillReturns(reg, f, returns, pc+1, C);
|
||||
if (call->Native)
|
||||
{
|
||||
try
|
||||
{
|
||||
VMCycles[0].Unclock();
|
||||
numret = static_cast<VMNativeFunction *>(call)->NativeCall(reg.param + f->NumParam - B, call->DefaultArgs, B, returns, C);
|
||||
numret = static_cast<VMNativeFunction *>(call)->NativeCall(reg.param + f->NumParam - b, call->DefaultArgs, b, returns, C);
|
||||
VMCycles[0].Clock();
|
||||
}
|
||||
catch (CVMAbortException &err)
|
||||
|
|
@ -670,7 +682,7 @@ begin:
|
|||
VMCalls[0]++;
|
||||
VMScriptFunction *script = static_cast<VMScriptFunction *>(call);
|
||||
VMFrame *newf = stack->AllocFrame(script);
|
||||
VMFillParams(reg.param + f->NumParam - B, newf, B);
|
||||
VMFillParams(reg.param + f->NumParam - b, newf, b);
|
||||
try
|
||||
{
|
||||
numret = Exec(stack, script->Code, returns, C);
|
||||
|
|
@ -801,6 +813,9 @@ begin:
|
|||
if (!callingfunc || pcls != callingfunc->OwningClass)
|
||||
ThrowAbortException(X_OTHER, "Cannot instantiate class %s directly", cls->TypeName.GetChars());
|
||||
}
|
||||
// [ZZ] validate readonly and between scope construction
|
||||
if (callingfunc)
|
||||
FScopeBarrier_ValidateNew(cls, callingfunc);
|
||||
reg.a[a] = cls->CreateNew();
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue