mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
auto merge of #2331 : Ms2ger/servo/global-cx-3, r=jdm
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:
commit
d66197ae40
5 changed files with 145 additions and 96 deletions
|
@ -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}',
|
||||
|
@ -4853,14 +4859,21 @@ class CallbackMember(CGNativeMember):
|
|||
# Avoid weird 0-sized arrays
|
||||
replacements["argvDecl"] = ""
|
||||
|
||||
return string.Template(
|
||||
# Newlines and semicolons are in the values
|
||||
# Newlines and semicolons are in the values
|
||||
pre = string.Template(
|
||||
"${setupCall}"
|
||||
"${declRval}"
|
||||
"${argvDecl}"
|
||||
"${argvDecl}").substitute(replacements)
|
||||
body = string.Template(
|
||||
"${convertArgs}"
|
||||
"${doCall}"
|
||||
"${returnResult}").substitute(replacements)
|
||||
return CGList([
|
||||
CGGeneric(pre),
|
||||
CGWrapper(CGIndenter(CGGeneric(body)),
|
||||
pre="with_compartment(cx, self.parent.callback, || {\n",
|
||||
post="})")
|
||||
], "\n").define()
|
||||
|
||||
def getResultConversion(self):
|
||||
replacements = {
|
||||
|
@ -4883,7 +4896,7 @@ class CallbackMember(CGNativeMember):
|
|||
assignRetval = string.Template(
|
||||
self.getRetvalInfo(self.retvalType,
|
||||
False)[2]).substitute(replacements)
|
||||
return convertType.define() + "\n" + assignRetval
|
||||
return convertType.define() + "\n" + assignRetval + "\n"
|
||||
|
||||
def getArgConversions(self):
|
||||
# Just reget the arglist from self.originalSig, because our superclasses
|
||||
|
|
|
@ -41,6 +41,7 @@ use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
|
|||
use js::jsval::JSVal;
|
||||
use js::jsval::{PrivateValue, ObjectValue, NullValue, ObjectOrNullValue};
|
||||
use js::jsval::{Int32Value, UInt32Value, DoubleValue, BooleanValue, UndefinedValue};
|
||||
use js::rust::with_compartment;
|
||||
use js::{JSPROP_ENUMERATE, JSCLASS_IS_GLOBAL, JSCLASS_IS_DOMJSCLASS};
|
||||
use js::JSPROP_PERMANENT;
|
||||
use js::{JSFUN_CONSTRUCTOR, JSPROP_READONLY};
|
||||
|
@ -583,7 +584,9 @@ pub fn CreateDOMGlobal(cx: *JSContext, class: *JSClass) -> *JSObject {
|
|||
if obj.is_null() {
|
||||
return ptr::null();
|
||||
}
|
||||
JS_InitStandardClasses(cx, obj);
|
||||
with_compartment(cx, obj, || {
|
||||
JS_InitStandardClasses(cx, obj);
|
||||
});
|
||||
initialize_global(obj);
|
||||
obj
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use dom::window::Window;
|
|||
|
||||
use js::jsapi::JSObject;
|
||||
use js::glue::{WrapperNew, CreateWrapperProxyHandler, ProxyTraps};
|
||||
use js::rust::with_compartment;
|
||||
|
||||
use libc::c_void;
|
||||
use std::ptr;
|
||||
|
@ -56,9 +57,9 @@ impl BrowserContext {
|
|||
|
||||
let parent = win.deref().reflector().get_jsobject();
|
||||
let cx = js_info.get_ref().js_context.deref().deref().ptr;
|
||||
let wrapper = unsafe {
|
||||
let wrapper = with_compartment(cx, parent, || unsafe {
|
||||
WrapperNew(cx, parent, *handler.deref())
|
||||
};
|
||||
});
|
||||
assert!(wrapper.is_not_null());
|
||||
wrapper
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue