Remove m_obj from c_Continuation
m_obj in c_Continuation is redundant. It is only used at the time Continuation is created. First, it is set in init() call. Few instructions later, it is read so that $this in the Continuation's ActRec can be populated. Kill it.
Esse commit está contido em:
@@ -46,10 +46,10 @@ static StaticString s___cont__("__cont__");
|
||||
|
||||
c_Continuation::c_Continuation(Class* cb) :
|
||||
ExtObjectData(cb),
|
||||
m_origFunc(nullptr),
|
||||
m_index(-1LL),
|
||||
m_value(Variant::NullInit()),
|
||||
m_received(Variant::NullInit()),
|
||||
m_origFunc(nullptr),
|
||||
m_label(0) {
|
||||
o_subclassData.u16 = 0;
|
||||
}
|
||||
|
||||
@@ -46,17 +46,9 @@ class c_Continuation : public ExtObjectData {
|
||||
|
||||
public:
|
||||
void init(const Func* origFunc,
|
||||
ObjectData* thisPtr,
|
||||
ArrayData* args) noexcept {
|
||||
m_origFunc = const_cast<Func*>(origFunc);
|
||||
assert(m_origFunc);
|
||||
|
||||
if (thisPtr != nullptr) {
|
||||
m_obj = thisPtr;
|
||||
} else {
|
||||
assert(m_obj.isNull());
|
||||
}
|
||||
|
||||
m_args = args;
|
||||
}
|
||||
|
||||
@@ -128,13 +120,11 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
Object m_obj;
|
||||
Func *m_origFunc;
|
||||
Array m_args;
|
||||
int64_t m_index;
|
||||
Variant m_value;
|
||||
Variant m_received;
|
||||
Func *m_origFunc;
|
||||
|
||||
int32_t m_label;
|
||||
int m_localsOffset;
|
||||
ActRec* m_arPtr;
|
||||
|
||||
@@ -7038,7 +7038,7 @@ VMExecutionContext::createContinuationHelper(const Func* origFunc,
|
||||
);
|
||||
cont->incRefCount();
|
||||
cont->setNoDestruct();
|
||||
cont->init(origFunc, thisPtr, args);
|
||||
cont->init(origFunc, args);
|
||||
|
||||
// The ActRec corresponding to the generator body lives as long as the object
|
||||
// does. We set it up once, here, and then just change FP to point to it when
|
||||
@@ -7151,10 +7151,10 @@ VMExecutionContext::fillContinuationVars(ActRec* fp,
|
||||
// If $this is used as a local inside the body and is not provided
|
||||
// by our containing environment, just prefill it here instead of
|
||||
// using InitThisLoc inside the body
|
||||
if (!skipThis && cont->m_obj.get()) {
|
||||
if (!skipThis && fp->hasThis()) {
|
||||
Id id = genFunc->lookupVarId(thisStr);
|
||||
if (id != kInvalidId) {
|
||||
tvAsVariant(&cont->locals()[nLocals - id - 1]) = cont->m_obj;
|
||||
tvAsVariant(&cont->locals()[nLocals - id - 1]) = fp->getThis();
|
||||
}
|
||||
}
|
||||
return cont;
|
||||
|
||||
@@ -5080,17 +5080,14 @@ void CodeGenerator::cgInterpOneCF(IRInstruction* inst) {
|
||||
}
|
||||
|
||||
void CodeGenerator::cgFillContThis(IRInstruction* inst) {
|
||||
SSATmp* cont = inst->src(0);
|
||||
auto thisObj = m_regs[inst->src(0)].reg();
|
||||
auto baseReg = m_regs[inst->src(1)].reg();
|
||||
int64_t offset = inst->src(2)->getValInt();
|
||||
auto scratch = m_rScratch;
|
||||
auto contReg = m_regs[cont].reg();
|
||||
|
||||
m_as.loadq(contReg[CONTOFF(m_obj)], scratch);
|
||||
m_as.testq(scratch, scratch);
|
||||
m_as.testq(thisObj, thisObj);
|
||||
ifThen(m_as, CC_NZ, [&] {
|
||||
m_as.addl(1, scratch[FAST_REFCOUNT_OFFSET]);
|
||||
m_as.storeq(scratch, baseReg[offset + TVOFF(m_data)]);
|
||||
m_as.addl(1, thisObj[FAST_REFCOUNT_OFFSET]);
|
||||
m_as.storeq(thisObj, baseReg[offset + TVOFF(m_data)]);
|
||||
emitStoreTVType(m_as, KindOfObject, baseReg[offset + TVOFF(m_type)]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1046,7 +1046,7 @@ void HhbcTranslator::emitCreateCont(bool getArgs,
|
||||
}
|
||||
if (fillThis) {
|
||||
assert(thisId != kInvalidId);
|
||||
gen(FillContThis, cont, locals,
|
||||
gen(FillContThis, gen(LdThis, m_tb->fp()), locals,
|
||||
cns(cellsToBytes(genLocals - thisId - 1)));
|
||||
}
|
||||
} else {
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário