Fix and reenable test/quick/setprofile_throw.php

Fix a cast from a previous diff, and fix surprise checks that throw
exceptions. I turned the two macros into functions to clean things up; the
important part of the fix is taking out the SYNC() before
EventHook::CheckSurprise(). Before this fix, the saved offset in the ActRec
used for reentry would point at the offset immediate of the Jmp instead of the
Jmp itself.
Esse commit está contido em:
bsimmers
2013-06-25 15:15:02 -07:00
commit de Sara Golemon
commit 4375db0f05
4 arquivos alterados com 41 adições e 39 exclusões
+38 -38
Ver Arquivo
@@ -2019,7 +2019,7 @@ Array VMExecutionContext::debugBacktrace(bool skip /* = false */,
ArrayInit frame(7);
auto const curUnit = fp->m_func->unit();
auto const curOp = *reinterpret_cast<const Opcode*>(curUnit->at(pc));
auto const curOp = toOp(*curUnit->at(pc));
auto const isReturning = curOp == OpRetC || curOp == OpRetV;
// Builtins and generators don't have a file and line number
@@ -3992,58 +3992,58 @@ inline void OPTBLD_INLINE VMExecutionContext::iopFatal(PC& pc) {
}
}
#define JMP_SURPRISE_CHECK() \
if (offset < 0 && UNLIKELY(Transl::TargetCache::loadConditionFlags())) { \
SYNC(); \
EventHook::CheckSurprise(); \
inline void OPTBLD_INLINE VMExecutionContext::jmpSurpriseCheck(Offset offset) {
if (offset < 0 && UNLIKELY(Transl::TargetCache::loadConditionFlags())) {
EventHook::CheckSurprise();
}
}
inline void OPTBLD_INLINE VMExecutionContext::iopJmp(PC& pc) {
NEXT();
DECODE_JMP(Offset, offset);
JMP_SURPRISE_CHECK();
jmpSurpriseCheck(offset);
pc += offset - 1;
}
#define JMPOP(OP, VOP) do { \
Cell* c1 = m_stack.topC(); \
if (c1->m_type == KindOfInt64 || c1->m_type == KindOfBoolean) { \
int64_t n = c1->m_data.num; \
if (n OP 0) { \
NEXT(); \
DECODE_JMP(Offset, offset); \
JMP_SURPRISE_CHECK(); \
pc += offset - 1; \
m_stack.popX(); \
} else { \
pc += 1 + sizeof(Offset); \
m_stack.popX(); \
} \
} else { \
if (VOP(tvCellAsCVarRef(c1))) { \
NEXT(); \
DECODE_JMP(Offset, offset); \
JMP_SURPRISE_CHECK(); \
pc += offset - 1; \
m_stack.popC(); \
} else { \
pc += 1 + sizeof(Offset); \
m_stack.popC(); \
} \
} \
} while (0)
template<Op op>
inline void OPTBLD_INLINE VMExecutionContext::jmpOpImpl(PC& pc) {
static_assert(op == OpJmpZ || op == OpJmpNZ,
"jmpOpImpl should only be used by JmpZ and JmpNZ");
NEXT();
DECODE_JMP(Offset, offset);
jmpSurpriseCheck(offset);
Cell* c1 = m_stack.topC();
if (c1->m_type == KindOfInt64 || c1->m_type == KindOfBoolean) {
int64_t n = c1->m_data.num;
if (op == OpJmpZ ? n == 0 : n != 0) {
pc += offset - 1;
m_stack.popX();
} else {
pc += sizeof(Offset);
m_stack.popX();
}
} else {
auto const condition = toBoolean(tvCellAsCVarRef(c1));
if (op == OpJmpZ ? !condition : condition) {
pc += offset - 1;
m_stack.popC();
} else {
pc += sizeof(Offset);
m_stack.popC();
}
}
}
inline void OPTBLD_INLINE VMExecutionContext::iopJmpZ(PC& pc) {
JMPOP(==, !toBoolean);
jmpOpImpl<OpJmpZ>(pc);
}
inline void OPTBLD_INLINE VMExecutionContext::iopJmpNZ(PC& pc) {
JMPOP(!=, toBoolean);
jmpOpImpl<OpJmpNZ>(pc);
}
#undef JMPOP
#undef JMP_SURPRISE_CHECK
enum class SwitchMatch {
NORMAL, // value was converted to an int: match normally
NONZERO, // can't be converted to an int: match first nonzero case