diff --git a/hphp/runtime/vm/jit/vectortranslator.cpp b/hphp/runtime/vm/jit/vectortranslator.cpp index 645ac568d..fa3b33deb 100644 --- a/hphp/runtime/vm/jit/vectortranslator.cpp +++ b/hphp/runtime/vm/jit/vectortranslator.cpp @@ -156,7 +156,7 @@ 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. - if (!baseBoxed || !baseType.isString()) { + if (!baseBoxed && (!baseType.isString() || op == SetProp)) { /* * Uses of boxed types are always guarded, in case the inner * type was modified. If the base type was String, its extremely diff --git a/hphp/runtime/vm/member_operations.h b/hphp/runtime/vm/member_operations.h index 23c41310c..9a0280c36 100644 --- a/hphp/runtime/vm/member_operations.h +++ b/hphp/runtime/vm/member_operations.h @@ -687,7 +687,11 @@ inline StringData* SetElem(TypedValue* base, TypedValue* key, Cell* value) { case KindOfString: { int baseLen = base->m_data.pstr->size(); if (baseLen == 0) { + initScratchKey(scratch, key); SetElemEmptyish(base, key, value); + if (!setResult) { + throw InvalidSetMException(*value); + } } else { // Convert key to string offset. int64_t x = castKeyToInt(key); diff --git a/hphp/test/slow/array/promote_string.php b/hphp/test/slow/array/promote_string.php new file mode 100644 index 000000000..b4f557cdf --- /dev/null +++ b/hphp/test/slow/array/promote_string.php @@ -0,0 +1,11 @@ + + string(1) "x" + ["x"]=> + string(1) "x" + [1]=> + int(1) + ["foo"]=> + string(3) "foo" +}