From 0ddaed959d4ad77891edc52e24c3609bf20dfe81 Mon Sep 17 00:00:00 2001 From: mwilliams Date: Thu, 28 Mar 2013 10:07:15 -0700 Subject: [PATCH] Fix assert in CodeGenerator::emitTypeCheck The vector translator produced a type that was boxed-array-or-string, which we couldnt guard on. Since applying a SetM to a string will almost always produce a string, change it to report string instead (which will still be guarded on). --- hphp/runtime/vm/translator/hopt/vectortranslator.cpp | 10 +++++++++- hphp/test/vm/setmstr.php | 10 ++++++++++ hphp/test/vm/setmstr.php.exp | 2 ++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 hphp/test/vm/setmstr.php create mode 100644 hphp/test/vm/setmstr.php.exp diff --git a/hphp/runtime/vm/translator/hopt/vectortranslator.cpp b/hphp/runtime/vm/translator/hopt/vectortranslator.cpp index 973840518..719a18675 100644 --- a/hphp/runtime/vm/translator/hopt/vectortranslator.cpp +++ b/hphp/runtime/vm/translator/hopt/vectortranslator.cpp @@ -118,7 +118,15 @@ void VectorEffects::init(Opcode op, const Type origBase, // definitely happen but those cases aren't handled yet. In a perfect world // we would remove Type::Null from baseType here but that can produce types // that are tricky to guard against and doesn't buy us much right now. - baseType = baseType.isNull() ? newBase : (baseType | newBase); + if (!baseBoxed || !baseType.isString()) { + /* + * Uses of boxed types are always guarded, in case the inner + * type was modified. If the base type was String, its extremely + * likely to still be a String, so leave it as such, and we'll + * exit in the rare case that it changed. + */ + baseType = baseType.isNull() ? newBase : (baseType | newBase); + } baseValChanged = true; } if (op == SetElem && baseType.maybe(Type::Arr)) { diff --git a/hphp/test/vm/setmstr.php b/hphp/test/vm/setmstr.php new file mode 100644 index 000000000..7f6507ff7 --- /dev/null +++ b/hphp/test/vm/setmstr.php @@ -0,0 +1,10 @@ +