diff --git a/hphp/runtime/vm/translator/hopt/ir.h b/hphp/runtime/vm/translator/hopt/ir.h index d9d225471..f3ffb0c8f 100644 --- a/hphp/runtime/vm/translator/hopt/ir.h +++ b/hphp/runtime/vm/translator/hopt/ir.h @@ -121,6 +121,7 @@ static const TCA kIRDirectGuardActive = (TCA)0x03; * CStr same as C(StaticStr) * SNumInt same as S(Int,Bool) * SNum same as S(Int,Bool,Dbl) + * SSpills SpillStack's variadic source list * * flags: * @@ -350,7 +351,7 @@ O(StaticLocInitCached, D(BoxedCell), CStr \ S(FramePtr) \ S(Cell) \ C(CacheHandle), PRc|E|N|Mem) \ -O(SpillStack, D(StkPtr), SUnk, CRc) \ +O(SpillStack, D(StkPtr), S(StkPtr) C(Int) SSpills, CRc) \ O(SpillFrame, D(StkPtr), S(StkPtr) \ S(FramePtr) \ S(Func,FuncCls,FuncCtx,Null) \ diff --git a/hphp/runtime/vm/translator/hopt/type.cpp b/hphp/runtime/vm/translator/hopt/type.cpp index b16edd022..e13a5b92c 100644 --- a/hphp/runtime/vm/translator/hopt/type.cpp +++ b/hphp/runtime/vm/translator/hopt/type.cpp @@ -215,6 +215,16 @@ void assertOperandTypes(const IRInstruction* inst) { errorMessage).str()); }; + auto checkSpills = [&] { + for (; curSrc < inst->getNumSrcs(); ++curSrc) { + // SpillStack slots may be stack types or None, if the + // simplifier removed some. + auto const valid = inst->getSrc(curSrc)->getType() + .subtypeOfAny(Type::Gen, Type::Cls, Type::None); + check(valid, "Gen|Cls|None"); + } + }; + #define IRT(name, ...) UNUSED static const Type name = Type::name; IR_TYPES #undef IRT @@ -233,6 +243,7 @@ void assertOperandTypes(const IRInstruction* inst) { #define SNumInt S(Int, Bool) #define SNum S(Int, Bool, Dbl) #define SUnk return; +#define SSpills checkSpills(); #define ND #define DMulti #define DStk(...) @@ -265,6 +276,7 @@ void assertOperandTypes(const IRInstruction* inst) { #undef CStr #undef SNum #undef SUnk +#undef SSpills #undef ND #undef D