Use a single JSContext per JSRuntime.

The long-term plan for SpiderMonkey is to eliminate JSContexts by merging
(most of) it into JSRuntime, so to future-proof our code, we should avoid
creating multiple JSContexts for the same JSRuntime.

However, this implies we'll have to use the same JSContext for objects in
different compartments, so we need to enter compartments. This is done by
using the with_compartment function.
This commit is contained in:
Ms2ger 2014-04-21 12:38:23 +02:00
parent bba4bef106
commit 0016b1839e
5 changed files with 119 additions and 88 deletions

View file

@ -1755,22 +1755,26 @@ def CreateBindingJSObject(descriptor, parent=None):
create = " let mut raw: JS<%s> = JS::from_raw(&mut *aObject);\n" % descriptor.concreteType
if descriptor.proxy:
assert not descriptor.createGlobal
handler = """
create += """
let js_info = aScope.deref().page().js_info();
let handler = js_info.get_ref().dom_static.proxy_handlers.deref().get(&(PrototypeList::id::%s as uint));
""" % descriptor.name
create += handler + """ let obj = NewProxyObject(aCx, *handler,
&PrivateValue(squirrel_away_unique(aObject) as *libc::c_void),
proto, %s,
ptr::null(), ptr::null());
let private = PrivateValue(squirrel_away_unique(aObject) as *libc::c_void);
let obj = with_compartment(aCx, proto, || {
NewProxyObject(aCx, *handler,
&private,
proto, %s,
ptr::null(), ptr::null())
});
assert!(obj.is_not_null());
""" % (parent)
""" % (descriptor.name, parent)
else:
if descriptor.createGlobal:
create += " let obj = CreateDOMGlobal(aCx, &Class.base as *js::Class as *JSClass);\n"
else:
create += " let obj = JS_NewObject(aCx, &Class.base as *js::Class as *JSClass, proto, %s);\n" % parent
create += (" let obj = with_compartment(aCx, proto, || {\n"
" JS_NewObject(aCx, &Class.base as *js::Class as *JSClass, proto, %s)\n"
" });\n" % parent)
create += """ assert!(obj.is_not_null());
JS_SetReservedSlot(obj, DOM_OBJECT_SLOT as u32,
@ -1797,8 +1801,7 @@ class CGWrapMethod(CGAbstractMethod):
assert!(scope.is_not_null());
assert!(((*JS_GetClass(scope)).flags & JSCLASS_IS_GLOBAL) != 0);
//JSAutoCompartment ac(aCx, scope);
let proto = GetProtoObject(aCx, scope, scope);
let proto = with_compartment(aCx, scope, || GetProtoObject(aCx, scope, scope));
assert!(proto.is_not_null());
%s
@ -1809,8 +1812,10 @@ class CGWrapMethod(CGAbstractMethod):
else:
return """
%s
let proto = GetProtoObject(aCx, obj, obj);
JS_SetPrototype(aCx, obj, proto);
with_compartment(aCx, obj, || {
let proto = GetProtoObject(aCx, obj, obj);
JS_SetPrototype(aCx, obj, proto);
});
raw.mut_reflector().set_jsobject(obj);
return raw;""" % CreateBindingJSObject(self.descriptor)
@ -4241,6 +4246,7 @@ class CGBindingRoot(CGThing):
'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps}',
'js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO}',
'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
'js::rust::with_compartment',
'dom::types::*',
'dom::bindings',
'dom::bindings::js::{JS, JSRef, Root, RootedReference, Temporary}',