mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
c142716352
commit
0374ee3760
@ -910,6 +910,8 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
|
||||
uintN slot, attrs;
|
||||
|
||||
JS_ASSERT(STOBJ_GET_CLASS(obj) == &js_CallClass);
|
||||
JS_ASSERT(!STOBJ_GET_PROTO(obj));
|
||||
|
||||
if (!JSVAL_IS_STRING(idval))
|
||||
return JS_TRUE;
|
||||
|
||||
@ -921,6 +923,17 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
|
||||
if (!js_ValueToStringId(cx, idval, &id))
|
||||
return JS_FALSE;
|
||||
|
||||
/*
|
||||
* Check whether the id refers to a formal parameter, local variable or
|
||||
* the arguments special name.
|
||||
*
|
||||
* We define all such names using JSDNP_DONT_PURGE to avoid an expensive
|
||||
* shape invalidation in js_DefineNativeProperty. If such an id happens to
|
||||
* shadow a global or upvar of the same name, any inner functions can
|
||||
* never access the outer binding. Thus it cannot invalidate any property
|
||||
* cache entries or derived trace guards for the outer binding. See also
|
||||
* comments in js_PurgeScopeChainHelper from jsobj.cpp.
|
||||
*/
|
||||
localKind = js_LookupLocal(cx, fun, JSID_TO_ATOM(id), &slot);
|
||||
if (localKind != JSLOCAL_NONE && localKind != JSLOCAL_UPVAR) {
|
||||
JS_ASSERT((uint16) slot == slot);
|
||||
@ -944,7 +957,7 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
|
||||
}
|
||||
if (!js_DefineNativeProperty(cx, obj, id, JSVAL_VOID, getter, setter,
|
||||
attrs, SPROP_HAS_SHORTID, (int16) slot,
|
||||
NULL)) {
|
||||
NULL, JSDNP_DONT_PURGE)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
*objp = obj;
|
||||
@ -959,7 +972,7 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
|
||||
if (!js_DefineNativeProperty(cx, obj, id, JSVAL_VOID,
|
||||
GetCallArguments, SetCallArguments,
|
||||
JSPROP_PERMANENT | JSPROP_SHARED,
|
||||
0, 0, NULL)) {
|
||||
0, 0, NULL, JSDNP_DONT_PURGE)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
*objp = obj;
|
||||
|
@ -6430,7 +6430,7 @@ js_Interpret(JSContext *cx)
|
||||
? js_SetPropertyHelper(cx, obj, id, true, &rval)
|
||||
: js_DefineNativeProperty(cx, obj, id, rval, NULL, NULL,
|
||||
JSPROP_ENUMERATE, 0, 0, NULL,
|
||||
true)))
|
||||
JSDNP_CACHE_RESULT)))
|
||||
goto error;
|
||||
} while (0);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -641,11 +641,17 @@ js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
||||
|
||||
#ifdef __cplusplus /* FIXME: bug 442399 removes this LiveConnect requirement. */
|
||||
|
||||
/*
|
||||
* Flags for the defineHow parameter of js_DefineNativeProperty.
|
||||
*/
|
||||
const uintN JSDNP_CACHE_RESULT = 1; /* an interpreter call from JSOP_INITPROP */
|
||||
const uintN JSDNP_DONT_PURGE = 2; /* suppress js_PurgeScopeChain */
|
||||
|
||||
extern 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);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user