- most ATAG stuff is gone, except for the static storage space in the VMFunction.

This commit is contained in:
Christoph Oelckers 2017-04-10 16:06:18 +02:00
parent 5464336035
commit 60dd58e7d2
5 changed files with 14 additions and 53 deletions

View file

@ -76,7 +76,7 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info,
{
ActionCycles.Clock();
VMValue params[3] = { self, stateowner, VMValue(info, ATAG_GENERIC) };
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.

View file

@ -153,7 +153,7 @@ bool AStateProvider::CallStateChain (AActor *actor, FState *state)
VMReturn *wantret;
FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON };
params[2] = VMValue(&stp, ATAG_GENERIC);
params[2] = VMValue(&stp);
retval = true; // assume success
wantret = NULL; // assume no return value wanted
numret = 0;

View file

@ -176,13 +176,6 @@ enum
#define RET_FINAL (0x80) // Used with RET and RETI in the destination slot: this is the final return value
// Tags for address registers
enum
{
ATAG_GENERIC, // pointer to something; we don't care what
ATAG_OBJECT, // pointer to an object; will be followed by GC
};
enum EVMAbortException
{
X_OTHER,
@ -445,19 +438,11 @@ struct VMValue
VMValue(DObject *v)
{
a = v;
atag = ATAG_OBJECT;
Type = REGT_POINTER;
}
VMValue(void *v)
{
a = v;
atag = ATAG_GENERIC;
Type = REGT_POINTER;
}
VMValue(void *v, int tag)
{
a = v;
atag = tag;
Type = REGT_POINTER;
}
VMValue &operator=(const VMValue &o)
@ -488,7 +473,6 @@ struct VMValue
VMValue &operator=(DObject *v)
{
a = v;
atag = ATAG_OBJECT;
Type = REGT_POINTER;
return *this;
}
@ -640,7 +624,7 @@ struct VMFrame
return (VM_UBYTE *)this + ((ofs + NumRegA + 15) & ~15);
}
void GetAllRegs(int *&d, double *&f, FString *&s, void **&a, VM_ATAG *&atag, VMValue *&param) const
void GetAllRegs(int *&d, double *&f, FString *&s, void **&a, VMValue *&param) const
{
// Calling the individual functions produces suboptimal code. :(
param = GetParam();
@ -648,7 +632,6 @@ struct VMFrame
s = (FString *)(f + NumRegF);
a = (void **)(s + NumRegS);
d = (int *)(a + NumRegA);
atag = (VM_ATAG *)(d + NumRegD);
}
void InitRegS();
@ -658,18 +641,17 @@ struct VMRegisters
{
VMRegisters(const VMFrame *frame)
{
frame->GetAllRegs(d, f, s, a, atag, param);
frame->GetAllRegs(d, f, s, a, param);
}
VMRegisters(const VMRegisters &o)
: d(o.d), f(o.f), s(o.s), a(o.a), atag(o.atag), param(o.param)
: d(o.d), f(o.f), s(o.s), a(o.a), param(o.param)
{ }
int *d;
double *f;
FString *s;
void **a;
VM_ATAG *atag;
VMValue *param;
};
@ -796,14 +778,12 @@ public:
void ParamObject(DObject *obj)
{
Reg.a[RegA] = obj;
Reg.atag[RegA] = ATAG_OBJECT;
RegA++;
}
void ParamPointer(void *ptr, VM_ATAG atag)
void ParamPointer(void *ptr)
{
Reg.a[RegA] = ptr;
Reg.atag[RegA] = atag;
RegA++;
}
@ -1052,7 +1032,7 @@ class AActor;
PARAM_PROLOGUE; \
PARAM_OBJECT(self, type);
// for structs we need to check for ATAG_GENERIC instead of ATAG_OBJECT
// for structs we cannot do a class validation
#define PARAM_SELF_STRUCT_PROLOGUE(type) \
PARAM_PROLOGUE; \
PARAM_POINTER(self, type);

View file

@ -227,8 +227,7 @@ void VMFillParams(VMValue *params, VMFrame *callee, int numparam)
else
{
assert(p.Type == REGT_POINTER);
calleereg.a[rega] = p.a;
calleereg.atag[rega++] = p.atag;
calleereg.a[rega++] = p.a;
}
}
}

View file

@ -101,19 +101,16 @@ begin:
OP(LFP):
ASSERTA(a); assert(sfunc != NULL); assert(sfunc->ExtraSpace > 0);
reg.a[a] = f->GetExtra();
reg.atag[a] = ATAG_GENERIC; // using ATAG_FRAMEPOINTER will cause endless asserts.
NEXTOP;
OP(CLSS):
ASSERTA(a); ASSERTA(B);
reg.a[a] = ((DObject*)reg.a[B])->GetClass(); // I wish this could be done without a special opcode but there's really no good way to guarantee initialization of the Class pointer...
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(META):
ASSERTA(a); ASSERTA(B);
reg.a[a] = ((DObject*)reg.a[B])->GetClass()->Meta; // I wish this could be done without a special opcode but there's really no good way to guarantee initialization of the Class pointer...
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(LB):
@ -212,37 +209,31 @@ begin:
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
GETADDR(PB,KC,X_READ_NIL);
reg.a[a] = GC::ReadBarrier(*(DObject **)ptr);
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(LO_R):
ASSERTA(a); ASSERTA(B); ASSERTD(C);
GETADDR(PB,RC,X_READ_NIL);
reg.a[a] = GC::ReadBarrier(*(DObject **)ptr);
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(LOS):
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
GETADDR(PB,KC,X_READ_NIL);
reg.a[a] = *(DObject **)ptr;
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(LOS_R):
ASSERTA(a); ASSERTA(B); ASSERTD(C);
GETADDR(PB,RC,X_READ_NIL);
reg.a[a] = *(DObject **)ptr;
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(LP):
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
GETADDR(PB,KC,X_READ_NIL);
reg.a[a] = *(void **)ptr;
reg.atag[a] = ATAG_GENERIC;
NEXTOP;
OP(LP_R):
ASSERTA(a); ASSERTA(B); ASSERTD(C);
GETADDR(PB,RC,X_READ_NIL);
reg.a[a] = *(void **)ptr;
reg.atag[a] = ATAG_GENERIC;
NEXTOP;
OP(LV2):
ASSERTF(a+1); ASSERTA(B); ASSERTKD(C);
@ -437,7 +428,6 @@ begin:
ASSERTA(a); ASSERTA(B);
b = B;
reg.a[a] = reg.a[b];
reg.atag[a] = reg.atag[b];
NEXTOP;
}
OP(MOVEV2):
@ -461,25 +451,21 @@ begin:
ASSERTA(a); ASSERTA(B); ASSERTA(C);
b = B;
reg.a[a] = (reg.a[b] && ((DObject*)(reg.a[b]))->IsKindOf((PClass*)(reg.a[C]))) ? reg.a[b] : nullptr;
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(DYNCAST_K) :
ASSERTA(a); ASSERTA(B); ASSERTKA(C);
b = B;
reg.a[a] = (reg.a[b] && ((DObject*)(reg.a[b]))->IsKindOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr;
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(DYNCASTC_R) :
ASSERTA(a); ASSERTA(B); ASSERTA(C);
b = B;
reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(reg.a[C]))) ? reg.a[b] : nullptr;
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(DYNCASTC_K) :
ASSERTA(a); ASSERTA(B); ASSERTKA(C);
b = B;
reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr;
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
OP(CAST):
if (C == CAST_I2F)
@ -570,7 +556,7 @@ begin:
break;
case REGT_INT | REGT_ADDROF:
assert(C < f->NumRegD);
::new(param) VMValue(&reg.d[C], ATAG_GENERIC);
::new(param) VMValue(&reg.d[C]);
break;
case REGT_INT | REGT_KONST:
assert(C < sfunc->NumKonstD);
@ -582,7 +568,7 @@ begin:
break;
case REGT_STRING | REGT_ADDROF:
assert(C < f->NumRegS);
::new(param) VMValue(&reg.s[C], ATAG_GENERIC);
::new(param) VMValue((void*)&reg.s[C]); // Note that this may not use the FString* version of the constructor!
break;
case REGT_STRING | REGT_KONST:
assert(C < sfunc->NumKonstS);
@ -590,15 +576,15 @@ begin:
break;
case REGT_POINTER:
assert(C < f->NumRegA);
::new(param) VMValue(reg.a[C], reg.atag[C]);
::new(param) VMValue(reg.a[C]);
break;
case REGT_POINTER | REGT_ADDROF:
assert(C < f->NumRegA);
::new(param) VMValue(&reg.a[C], ATAG_GENERIC);
::new(param) VMValue(&reg.a[C]);
break;
case REGT_POINTER | REGT_KONST:
assert(C < sfunc->NumKonstA);
::new(param) VMValue(konsta[C].v, ATAG_GENERIC);
::new(param) VMValue(konsta[C].v);
break;
case REGT_FLOAT:
assert(C < f->NumRegF);
@ -621,7 +607,7 @@ begin:
break;
case REGT_FLOAT | REGT_ADDROF:
assert(C < f->NumRegF);
::new(param) VMValue(&reg.f[C], ATAG_GENERIC);
::new(param) VMValue(&reg.f[C]);
break;
case REGT_FLOAT | REGT_KONST:
assert(C < sfunc->NumKonstF);
@ -818,7 +804,6 @@ begin:
c = C;
if (c) FScopeBarrier::ValidateNew(cls, c - 1);
reg.a[a] = cls->CreateNew();
reg.atag[a] = ATAG_OBJECT;
NEXTOP;
}
@ -1651,7 +1636,6 @@ begin:
c = 0;
}
reg.a[a] = (VM_UBYTE *)reg.a[B] + c;
reg.atag[a] = c == 0 ? reg.atag[B] : (int)ATAG_GENERIC;
NEXTOP;
OP(ADDA_RK):
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
@ -1710,7 +1694,6 @@ begin:
// Found a handler. Store the exception in pC, skip the JMP,
// and begin executing its code.
reg.a[pc->c] = exception;
reg.atag[pc->c] = ATAG_OBJECT;
pc += 2;
goto begin;
}
@ -1723,7 +1706,6 @@ begin:
// Catch any type of VMException. This terminates the chain.
ASSERTA(pc->c);
reg.a[pc->c] = exception;
reg.atag[pc->c] = ATAG_OBJECT;
pc += 1;
goto begin;
}