Bug 1338323 - Don't attach SetArrayLength stub if length is not writable. (r=evilpie)

--HG--
extra : rebase_source : bf0328f031bc5b2b178ac59049dd75713960b8be
This commit is contained in:
Shu-yu Guo 2017-02-09 15:25:25 -08:00
Родитель fab3ade2de
Коммит 14f16a831d
2 изменённых файлов: 24 добавлений и 3 удалений

Просмотреть файл

@ -2213,8 +2213,12 @@ bool
SetPropIRGenerator::tryAttachSetArrayLength(HandleObject obj, ObjOperandId objId, HandleId id,
ValOperandId rhsId)
{
if (!obj->is<ArrayObject>() || !JSID_IS_ATOM(id, cx_->names().length))
if (!obj->is<ArrayObject>() ||
!JSID_IS_ATOM(id, cx_->names().length) ||
!obj->as<ArrayObject>().lengthIsWritable())
{
return false;
}
maybeEmitIdGuard(id);
writer.guardClass(objId, GuardClassKind::Array);

Просмотреть файл

@ -401,8 +401,25 @@ SetArrayLength(JSContext* cx, HandleObject obj, HandleValue value, bool strict)
RootedId id(cx, NameToId(cx->names().length));
ObjectOpResult result;
return ArraySetLength(cx, array, id, JSPROP_PERMANENT, value, result) &&
result.checkStrictErrorOrWarning(cx, obj, id, strict);
// SetArrayLength is called by IC stubs for SetProp and SetElem on arrays'
// "length" property.
//
// ArraySetLength below coerces |value| before checking for length being
// writable, and in the case of illegal values, will throw RangeError even
// when "length" is not writable. This is incorrect observable behavior,
// as a regular [[Set]] operation will check for "length" being
// writable before attempting any assignment.
//
// So, perform ArraySetLength if and only if "length" is writable.
if (array->lengthIsWritable()) {
if (!ArraySetLength(cx, array, id, JSPROP_PERMANENT, value, result))
return false;
} else {
MOZ_ALWAYS_TRUE(result.fail(JSMSG_READ_ONLY));
}
return result.checkStrictErrorOrWarning(cx, obj, id, strict);
}
bool