Fixed various virtualscope oddities; set scope for DECORATE classes to play.

This commit is contained in:
ZZYZX 2017-03-12 04:44:22 +02:00 committed by Christoph Oelckers
parent 23130678a1
commit bd889cc8f1
4 changed files with 14 additions and 11 deletions

View file

@ -8815,11 +8815,8 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
if (outerside == FScopeBarrier::Side_Virtual)
outerside = FScopeBarrier::SideFromObjectFlags(CallingFunction->OwningClass->ObjectFlags);
if (selfside != outerside && (selfside == FScopeBarrier::Side_Play || selfside == FScopeBarrier::Side_UI)) // if the self pointer and the calling functions have the same scope the check here is not needed.
{
// Check the self object against the calling function's flags at run time
build->Emit(OP_SCOPE, selfemit.RegNum, outerside + 1, build->GetConstantAddress(vmfunc, ATAG_OBJECT));
}
// Check the self object against the calling function's flags at run time
build->Emit(OP_SCOPE, selfemit.RegNum, outerside + 1, build->GetConstantAddress(vmfunc, ATAG_OBJECT));
}
if (selfemit.Fixed && selfemit.Target)

View file

@ -97,6 +97,12 @@ PClassActor *DecoDerivedClass(const FScriptPosition &sc, PClassActor *parent, FN
sc.Message(MSG_FATAL, "Tried to define class '%s' more than twice in the same file.", typeName.GetChars());
}
}
else
{
// [ZZ] DECORATE classes are always play
type->ObjectFlags = FScopeBarrier::ChangeSideInObjectFlags(type->ObjectFlags, FScopeBarrier::Side_Play);
}
return type;
}

View file

@ -648,10 +648,10 @@ begin:
reg.a[a] = p->Virtuals[C];
}
NEXTOP;
OP(SCOPE) :
{
ASSERTA(a); ASSERTA(C);
FScopeBarrier::ValidateCall(((DObject*)konsta[a].v)->GetClass(), (VMFunction*)konsta[C].v, B - 1);
OP(SCOPE):
{
ASSERTA(a); ASSERTKA(C);
FScopeBarrier::ValidateCall(((DObject*)reg.a[a])->GetClass(), (VMFunction*)konsta[C].v, B - 1);
}
NEXTOP;

View file

@ -658,12 +658,12 @@ void ZCCCompiler::CreateClassTypes()
{
Error(c->cls, "Can't change class scope in class %s", c->NodeName().GetChars());
}
c->Type()->ObjectFlags = (c->Type()->ObjectFlags & ~(OF_UI | OF_Play)) | (parent->ObjectFlags & (OF_UI | OF_Play));
c->Type()->ObjectFlags = FScopeBarrier::ChangeSideInObjectFlags(c->Type()->ObjectFlags, FScopeBarrier::SideFromObjectFlags(parent->ObjectFlags));
}
}
else
{
c->Type()->ObjectFlags = (c->Type()->ObjectFlags&~OF_UI) | OF_Play;
c->Type()->ObjectFlags = FScopeBarrier::ChangeSideInObjectFlags(c->Type()->ObjectFlags, FScopeBarrier::Side_Play);
}
c->Type()->bExported = true; // this class is accessible to script side type casts. (The reason for this flag is that types like PInt need to be skipped.)