Don't return stale shape in methodShapeChange, bug 690732.

This commit is contained in:
Brian Hackett 2011-10-27 09:22:32 -07:00
parent 418d3ca581
commit 03be78b36d
3 changed files with 30 additions and 23 deletions

View File

@ -0,0 +1,4 @@
var o4 = Object.freeze({
set: function(summary) {}
});

View File

@ -6314,11 +6314,13 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, uintN defineHow,
* cache, as the interpreter has no fast path for these unusual
* cases.
*/
if (shape->isMethod() && obj->nativeGetMethod(shape) == &vp->toObject())
return true;
shape = obj->methodShapeChange(cx, *shape);
if (!shape)
return false;
if (shape->isMethod()) {
if (obj->nativeGetMethod(shape) == &vp->toObject())
return true;
shape = obj->methodShapeChange(cx, *shape);
if (!shape)
return false;
}
if (!CloneFunctionForSetMethod(cx, vp))
return false;
return js_NativeSet(cx, obj, shape, false, strict, vp);

View File

@ -1084,7 +1084,7 @@ JSObject::generateOwnShape(JSContext *cx, Shape *newShape)
const Shape *
JSObject::methodShapeChange(JSContext *cx, const Shape &shape)
{
const Shape *result = &shape;
JS_ASSERT(shape.isMethod());
if (!inDictionaryMode() && !toDictionaryMode(cx))
return NULL;
@ -1093,27 +1093,28 @@ JSObject::methodShapeChange(JSContext *cx, const Shape &shape)
if (!spare)
return NULL;
if (shape.isMethod()) {
#ifdef DEBUG
JS_ASSERT(canHaveMethodBarrier());
JS_ASSERT(!shape.setter());
JS_ASSERT(!shape.hasShortID());
JS_ASSERT(canHaveMethodBarrier());
JS_ASSERT(!shape.setter());
JS_ASSERT(!shape.hasShortID());
#endif
/*
* Clear Shape::METHOD from flags as we are despecializing from a
* method memoized in the property tree to a plain old function-valued
* property.
*/
result = putProperty(cx, shape.propid(), NULL, NULL, shape.slot(),
shape.attrs,
shape.getFlags() & ~Shape::METHOD,
0);
if (!result)
return NULL;
}
/*
* Clear Shape::METHOD from flags as we are despecializing from a
* method memoized in the property tree to a plain old function-valued
* property.
*/
const Shape *result =
putProperty(cx, shape.propid(), NULL, NULL, shape.slot(),
shape.attrs,
shape.getFlags() & ~Shape::METHOD,
0);
if (!result)
return NULL;
if (result != lastProperty())
JS_ALWAYS_TRUE(generateOwnShape(cx, spare));
JS_ALWAYS_TRUE(generateOwnShape(cx, spare));
return result;
}