Preserve types when swapping objects, bug 774953. r=dvander

This commit is contained in:
Brian Hackett 2012-08-13 23:25:16 -06:00
parent 2a269f2751
commit 34ffa9ce1f

View File

@ -2897,6 +2897,14 @@ JSObject::ReserveForTradeGuts(JSContext *cx, JSObject *a, JSObject *b,
* swaps can be performed infallibly.
*/
/*
* Swap prototypes on the two objects, so that TradeGuts can preserve
* the types of the two objects.
*/
RootedObject na(cx, a), aProto(cx, a->getProto()), nb(cx, b), bProto(cx, b->getProto());
if (!SetProto(cx, na, bProto, false) || !SetProto(cx, nb, aProto, false))
return false;
if (a->sizeOfThis() == b->sizeOfThis())
return true;
@ -3111,6 +3119,14 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
a->lastProperty()->listp = &a->shape_;
if (b->inDictionaryMode())
b->lastProperty()->listp = &b->shape_;
/*
* Swap the object's types, to restore their initial type information.
* The prototypes of the objects were swapped in ReserveForTradeGuts.
*/
TypeObject *tmp = a->type_;
a->type_ = b->type_;
b->type_ = tmp;
}
/*
@ -3736,7 +3752,6 @@ bool
SetProto(JSContext *cx, HandleObject obj, HandleObject proto, bool checkForCycles)
{
JS_ASSERT_IF(!checkForCycles, obj != proto);
JS_ASSERT(obj->isExtensible());
#if JS_HAS_XML_SUPPORT
if (proto && proto->isXML()) {