From a67ef19b553c8f50485f50075f6a2fec21f14876 Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Sun, 10 Oct 2010 15:46:05 -0700 Subject: [PATCH] bug 580128 - Make e4x anyname etc be per compartment, not in the default compartment. r=mrbkap --- js/src/jscntxt.h | 10 --- js/src/jscompartment.cpp | 3 +- js/src/jscompartment.h | 10 +++ js/src/jsxml.cpp | 128 ++++++++++++++------------------------- 4 files changed, 56 insertions(+), 95 deletions(-) diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index ea9cde12189..c6154f66308 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -1526,16 +1526,6 @@ struct JSRuntime { const char *decimalSeparator; const char *numGrouping; - /* - * Weak references to lazily-created, well-known XML singletons. - * - * NB: Singleton objects must be carefully disconnected from the rest of - * the object graph usually associated with a JSContext's global object, - * including the set of standard class objects. See jsxml.c for details. - */ - JSObject *anynameObject; - JSObject *functionNamespaceObject; - #ifdef JS_THREADSAFE /* Number of threads with active requests and unhandled interrupts. */ volatile int32 interruptCounter; diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index c53d77a42f4..40a06d056eb 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -52,7 +52,8 @@ using namespace js; using namespace js::gc; JSCompartment::JSCompartment(JSRuntime *rt) - : rt(rt), principals(NULL), data(NULL), marked(false), debugMode(false) + : rt(rt), principals(NULL), data(NULL), marked(false), debugMode(false), + anynameObject(NULL), functionNamespaceObject(NULL) { JS_INIT_CLIST(&scripts); } diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 7add238c7d6..d2d17748841 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -77,6 +77,16 @@ struct JS_FRIEND_API(JSCompartment) { /* List all scripts in this compartment. */ JSCList scripts; + /* + * Weak references to lazily-created, well-known XML singletons. + * + * NB: Singleton objects must be carefully disconnected from the rest of + * the object graph usually associated with a JSContext's global object, + * including the set of standard class objects. See jsxml.c for details. + */ + JSObject *anynameObject; + JSObject *functionNamespaceObject; + JSCompartment(JSRuntime *cx); ~JSCompartment(); diff --git a/js/src/jsxml.cpp b/js/src/jsxml.cpp index 1fd25b84142..cfaefd084d2 100644 --- a/js/src/jsxml.cpp +++ b/js/src/jsxml.cpp @@ -232,8 +232,8 @@ DEFINE_GETTER(NameURI_getter, static void namespace_finalize(JSContext *cx, JSObject *obj) { - if (cx->runtime->functionNamespaceObject == obj) - cx->runtime->functionNamespaceObject = NULL; + if (cx->compartment->functionNamespaceObject == obj) + cx->compartment->functionNamespaceObject = NULL; } static JSBool @@ -339,8 +339,8 @@ static void anyname_finalize(JSContext* cx, JSObject* obj) { /* Make sure the next call to js_GetAnyName doesn't try to use obj. */ - if (cx->runtime->anynameObject == obj) - cx->runtime->anynameObject = NULL; + if (cx->compartment->anynameObject == obj) + cx->compartment->anynameObject = NULL; } static JSBool @@ -7148,44 +7148,32 @@ js_InitXMLClasses(JSContext *cx, JSObject *obj) JSBool js_GetFunctionNamespace(JSContext *cx, Value *vp) { - JSRuntime *rt; JSObject *obj; JSString *prefix, *uri; - /* Optimize by avoiding JS_LOCK_GC(rt) for the common case. */ - rt = cx->runtime; - obj = rt->functionNamespaceObject; + obj = cx->compartment->functionNamespaceObject; if (!obj) { - JS_LOCK_GC(rt); - obj = rt->functionNamespaceObject; - if (!obj) { - JS_UNLOCK_GC(rt); + JSRuntime *rt = cx->runtime; + prefix = ATOM_TO_STRING(rt->atomState.typeAtoms[JSTYPE_FUNCTION]); + uri = ATOM_TO_STRING(rt->atomState.functionNamespaceURIAtom); + obj = NewXMLNamespace(cx, prefix, uri, JS_FALSE); + if (!obj) + return false; - prefix = ATOM_TO_STRING(rt->atomState.typeAtoms[JSTYPE_FUNCTION]); - uri = ATOM_TO_STRING(rt->atomState.functionNamespaceURIAtom); - obj = NewXMLNamespace(cx, prefix, uri, JS_FALSE); - if (!obj) - return JS_FALSE; + /* + * Avoid entraining any in-scope Object.prototype. The loss of + * Namespace.prototype is not detectable, as there is no way to + * refer to this instance in scripts. When used to qualify method + * names, its prefix and uri references are copied to the QName. + */ + obj->clearProto(); + obj->clearParent(); - /* - * Avoid entraining any in-scope Object.prototype. The loss of - * Namespace.prototype is not detectable, as there is no way to - * refer to this instance in scripts. When used to qualify method - * names, its prefix and uri references are copied to the QName. - */ - obj->clearProto(); - obj->clearParent(); - - JS_LOCK_GC(rt); - if (!rt->functionNamespaceObject) - rt->functionNamespaceObject = obj; - else - obj = rt->functionNamespaceObject; - } - JS_UNLOCK_GC(rt); + cx->compartment->functionNamespaceObject = obj; } vp->setObject(*obj); - return JS_TRUE; + + return true; } /* @@ -7329,66 +7317,38 @@ anyname_toString(JSContext *cx, uintN argc, jsval *vp) JSBool js_GetAnyName(JSContext *cx, jsid *idp) { - JSRuntime *rt; JSObject *obj; - JSBool ok; - /* Optimize by avoiding JS_LOCK_GC(rt) for the common case. */ - rt = cx->runtime; - obj = rt->anynameObject; + obj = cx->compartment->anynameObject; if (!obj) { - JS_LOCK_GC(rt); - obj = rt->anynameObject; - if (!obj) { - JS_UNLOCK_GC(rt); + JSRuntime *rt = cx->runtime; - /* - * Protect multiple newborns created below, in the do-while(0) - * loop used to ensure that we leave this local root scope. - */ - ok = js_EnterLocalRootScope(cx); - if (!ok) - return JS_FALSE; + obj = NewNonFunction(cx, &js_AnyNameClass, NULL, NULL); + if (!obj) + return false; - do { - obj = NewNonFunction(cx, &js_AnyNameClass, NULL, NULL); - if (!obj) { - ok = JS_FALSE; - break; - } - InitXMLQName(obj, rt->emptyString, rt->emptyString, - ATOM_TO_STRING(rt->atomState.starAtom)); - METER(xml_stats.qname); + InitXMLQName(obj, rt->emptyString, rt->emptyString, + ATOM_TO_STRING(rt->atomState.starAtom)); + METER(xml_stats.qname); - /* - * Avoid entraining any Object.prototype found via cx's scope - * chain or global object. This loses the default toString, - * but no big deal: we want to customize toString anyway for - * clearer diagnostics. - */ - if (!JS_DefineFunction(cx, obj, js_toString_str, - anyname_toString, 0, 0)) { - ok = JS_FALSE; - break; - } - JS_ASSERT(!obj->getProto()); - JS_ASSERT(!obj->getParent()); - } while (0); + /* + * Avoid entraining any Object.prototype found via cx's scope + * chain or global object. This loses the default toString, + * but no big deal: we want to customize toString anyway for + * clearer diagnostics. + */ + if (!JS_DefineFunction(cx, obj, js_toString_str, + anyname_toString, 0, 0)) + return false; - js_LeaveLocalRootScopeWithResult(cx, obj); - if (!ok) - return JS_FALSE; + JS_ASSERT(!obj->getProto()); + JS_ASSERT(!obj->getParent()); - JS_LOCK_GC(rt); - if (!rt->anynameObject) - rt->anynameObject = obj; - else - obj = rt->anynameObject; - } - JS_UNLOCK_GC(rt); + cx->compartment->anynameObject = obj; } + *idp = OBJECT_TO_JSID(obj); - return JS_TRUE; + return true; } JSBool