bug 580128 - Make e4x anyname etc be per compartment, not in the default compartment. r=mrbkap

This commit is contained in:
Andreas Gal 2010-10-10 15:46:05 -07:00
Родитель d386bcf30f
Коммит a67ef19b55
4 изменённых файлов: 56 добавлений и 95 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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();

Просмотреть файл

@ -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<WithProto::Given>(cx, &js_AnyNameClass, NULL, NULL);
if (!obj)
return false;
do {
obj = NewNonFunction<WithProto::Given>(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