bug 490364 - mutating parent chain shapes only for Call objects and only when adding properties that are not parameter or var names. r=brendan

This commit is contained in:
Igor Bukanov
2009-05-15 11:43:19 +02:00
parent 141886515c
commit 3ccda978d4
4 changed files with 43 additions and 14 deletions

View File

@@ -3534,11 +3534,19 @@ void
js_PurgeScopeChainHelper(JSContext *cx, JSObject *obj, jsid id)
{
JS_ASSERT(OBJ_IS_DELEGATE(cx, obj));
PurgeProtoChain(cx, OBJ_GET_PROTO(cx, obj), id);
while ((obj = OBJ_GET_PARENT(cx, obj)) != NULL) {
if (PurgeProtoChain(cx, obj, id))
return;
/*
* We must purge the scope chain only for Call objects as they are the only
* kind of cacheable non-global object that can gain properties after outer
* properties with the same names have been cached or traced. Call objects
* may gain such properties via eval introducing new vars; see bug 490364.
*/
if (STOBJ_GET_CLASS(obj) == &js_CallClass) {
while ((obj = OBJ_GET_PARENT(cx, obj)) != NULL) {
if (PurgeProtoChain(cx, obj, id))
break;
}
}
}
@@ -3626,13 +3634,14 @@ JSBool
js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
uintN flags, intN shortid, JSProperty **propp,
JSBool cacheResult /* = JS_FALSE */)
uintN defineHow /* = 0 */)
{
JSClass *clasp;
JSScope *scope;
JSScopeProperty *sprop;
bool added;
JS_ASSERT((defineHow & ~(JSDNP_CACHE_RESULT | JSDNP_DONT_PURGE)) == 0);
js_LeaveTraceIfGlobalObject(cx, obj);
/* Convert string indices to integers if appropriate. */
@@ -3685,11 +3694,12 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
#endif /* JS_HAS_GETTER_SETTER */
/*
* Purge the property cache of any properties named by id that are about to
* be shadowed in obj's scope chain. We do this before locking obj to avoid
* nesting locks.
* Purge the property cache of any properties named by id that are about
* to be shadowed in obj's scope chain unless it is known a priori that it
* is not possible. We do this before locking obj to avoid nesting locks.
*/
js_PurgeScopeChain(cx, obj, id);
if (!(defineHow & JSDNP_DONT_PURGE))
js_PurgeScopeChain(cx, obj, id);
/*
* Check whether a readonly property or setter is being defined on a known
@@ -3736,7 +3746,7 @@ js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
js_RemoveScopeProperty(cx, scope, id);
goto error);
if (cacheResult) {
if (defineHow & JSDNP_CACHE_RESULT) {
JS_ASSERT_NOT_ON_TRACE(cx);
JSPropCacheEntry *entry;
entry = js_FillPropertyCache(cx, obj, 0, 0, obj, sprop, added);