From efa6ea67c94e1c7e155c082fee41029129ca29b2 Mon Sep 17 00:00:00 2001 From: "brendan%mozilla.org" Date: Sun, 2 Mar 2008 04:06:33 +0000 Subject: [PATCH] Fix property cache fill to recompute protoIndex to handle XBL and other JS_SetPrototype users (418139, r/a=shaver). git-svn-id: svn://10.0.0.236/trunk@246857 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/src/jsinterp.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/mozilla/js/src/jsinterp.c b/mozilla/js/src/jsinterp.c index 68a0fa408c5..49c06ab924a 100644 --- a/mozilla/js/src/jsinterp.c +++ b/mozilla/js/src/jsinterp.c @@ -133,7 +133,32 @@ js_FillPropertyCache(JSContext *cx, JSObject *obj, jsuword kshape, return; } - /* Check for overdeep scope and prototype chain. */ + /* + * Check for overdeep scope and prototype chain. Because resolve, getter, + * and setter hooks can change the prototype chain using JS_SetPrototype + * after js_LookupPropertyWithFlags has returned the nominal protoIndex, + * we have to validate protoIndex if it is non-zero. If it is zero, then + * we know thanks to the SCOPE_HAS_PROPERTY test above, and from the fact + * that obj == pobj, that protoIndex is invariant. + * + * The scopeIndex can't be wrong. We require JS_SetParent calls to happen + * before any running script might consult a parent-linked scope chain. If + * this requirement is not satisfied, the fill in progress will never hit, + * but vcap vs. scope shape tests ensure nothing malfunctions. + */ + JS_ASSERT_IF(scopeIndex == 0 && protoIndex == 0, obj == pobj); + if (protoIndex != 0) { + JSObject *tmp; + + JS_ASSERT(pobj != obj); + protoIndex = 1; + tmp = obj; + while ((tmp = OBJ_GET_PROTO(cx, tmp)) != NULL) { + if (tmp == pobj) + break; + ++protoIndex; + } + } if (scopeIndex > PCVCAP_SCOPEMASK || protoIndex > PCVCAP_PROTOMASK) { PCMETER(cache->longchains++); return;