Fix stack offset tracking in emitPrint, caught by zend test

The emitPrint function failed to pop the cell when it decided
to nop out the print.  This led to the stack being off by one when we
got to the RetC in this test.
Esse commit está contido em:
Jordan DeLong
2013-04-20 15:55:13 -07:00
commit de Sara Golemon
commit 04f4f27eba
2 arquivos alterados com 27 adições e 17 exclusões
+25 -17
Ver Arquivo
@@ -175,7 +175,9 @@ void HhbcTranslator::setBcOff(Offset newOff, bool lastBcOff) {
void HhbcTranslator::emitPrint() {
Type type = topC()->getType();
if (type.subtypeOf(Type::Int | Type::Bool | Type::Null | Type::Str)) {
if (type.subtypeOfAny(Type::Int, Type::Bool, Type::Null, Type::Str)) {
auto const cell = popC();
Opcode op;
if (type.isString()) {
op = PrintStr;
@@ -188,7 +190,9 @@ void HhbcTranslator::emitPrint() {
op = Nop;
}
// the print helpers decref their arg, so don't decref pop'ed value
if (op != Nop) m_tb->gen(op, popC());
if (op != Nop) {
m_tb->gen(op, cell);
}
push(m_tb->genDefConst<int64_t>(1));
} else {
emitInterpOne(Type::Int, 1);
@@ -2549,17 +2553,21 @@ void HhbcTranslator::emitMod() {
exitSpillValues.push_back(m_tb->genDefConst(false));
// Generate an exit for the rare case that r is zero
auto exit =
m_tb->ifThenExit(getCurFunc(),
m_stackDeficit,
exitSpillValues,
[&](IRFactory* irf, Trace* t) {
// Dividing by zero. Interpreting will raise a notice and
// produce the boolean false. Punch out here and resume after
// the Mod instruction; this should be rare.
m_tb->genFor(t, RaiseWarning,
cns(StringData::GetStaticString(Strings::DIVISION_BY_ZERO)));
},
getNextSrcKey().offset() /* exitBcOff */, m_bcOff);
m_tb->ifThenExit(
getCurFunc(),
m_stackDeficit,
exitSpillValues,
[&](IRFactory* irf, Trace* t) {
// Dividing by zero. Interpreting will raise a notice and
// produce the boolean false. Punch out here and resume after
// the Mod instruction; this should be rare.
m_tb->genFor(t, RaiseWarning,
cns(StringData::GetStaticString(
Strings::DIVISION_BY_ZERO)));
},
getNextSrcKey().offset() /* exitBcOff */,
m_bcOff
);
m_tb->gen(JmpZero, exit, r);
push(m_tb->gen(OpMod, Type::Int, l, r));
}
@@ -2707,10 +2715,10 @@ Trace* HhbcTranslator::getExitTrace(Offset targetBcOff /* = -1 */) {
std::vector<SSATmp*> stackValues = getSpillValues();
return m_tb->genExitTrace(targetBcOff,
m_stackDeficit,
stackValues.size(),
stackValues.size() ? &stackValues[0] : nullptr,
TraceExitType::Normal);
m_stackDeficit,
stackValues.size(),
stackValues.size() ? &stackValues[0] : nullptr,
TraceExitType::Normal);
}
/*
@@ -51,6 +51,8 @@ TraceBuilder::TraceBuilder(Offset initialBcOffset,
, m_localValues(func->numLocals(), nullptr)
, m_localTypes(func->numLocals(), Type::None)
{
FTRACE(2, "TraceBuilder: initial sp offset {}\n", initialSpOffsetFromFp);
// put a function marker at the start of trace
m_curFunc = genDefConst<const Func*>(func);
if (RuntimeOption::EvalHHIRGenOpts) {