- fixed: Stack based local VM object pointers should not be subjected to a read barrier.

This isn't done for register based variables so for consistency it should not be done for stack based variables, too.
This difference in handling made it impossible to check the target of a hitscan attack if it was destroyed by getting damaged.
This commit is contained in:
Christoph Oelckers 2017-02-04 16:23:14 +01:00
parent d3ed83942f
commit 43d759782d
3 changed files with 17 additions and 1 deletions

View file

@ -6553,7 +6553,9 @@ ExpEmit FxStackVariable::Emit(VMFunctionBuilder *build)
if (membervar->BitValue == -1)
{
if (offsetreg == -1) offsetreg = build->GetConstantInt(0);
build->Emit(membervar->Type->GetLoadOp(), loc.RegNum, build->FramePointer.RegNum, offsetreg);
auto op = membervar->Type->GetLoadOp();
if (op == OP_LO) op = OP_LOS;
build->Emit(op, loc.RegNum, build->FramePointer.RegNum, offsetreg);
}
else
{

View file

@ -209,6 +209,18 @@ begin:
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);

View file

@ -44,6 +44,8 @@ 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