mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
fix(script): one compartment for each script thread (agent)
Documents in the same agent[1] can share and exchange JS and DOM objects freely, so putting them in separate compartments would require almost every instance of `Dom` to be able to handle cross-compartment references. [1]: https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-agent-formalism
This commit is contained in:
parent
42d7892d88
commit
5871d09c26
1 changed files with 42 additions and 0 deletions
|
@ -16,6 +16,10 @@ use js::glue::UncheckedUnwrapObject;
|
|||
use js::jsapi::GetWellKnownSymbol;
|
||||
use js::jsapi::HandleObject as RawHandleObject;
|
||||
use js::jsapi::{jsid, JSClass, JSClassOps};
|
||||
use js::jsapi::{
|
||||
Compartment, CompartmentSpecifier, IsSharableCompartment, IsSystemCompartment,
|
||||
JS_IterateCompartments, JS::CompartmentIterResult,
|
||||
};
|
||||
use js::jsapi::{JSAutoRealm, JSContext, JSFunctionSpec, JSObject, JSFUN_CONSTRUCTOR};
|
||||
use js::jsapi::{JSPropertySpec, JSString, JSTracer, JS_AtomizeAndPinString};
|
||||
use js::jsapi::{JS_GetFunctionObject, JS_NewFunction, JS_NewGlobalObject};
|
||||
|
@ -139,6 +143,7 @@ pub unsafe fn create_global_object(
|
|||
options.creationOptions_.traceGlobal_ = Some(trace);
|
||||
options.creationOptions_.sharedMemoryAndAtomics_ = false;
|
||||
options.creationOptions_.streams_ = true;
|
||||
select_compartment(cx, &mut options);
|
||||
|
||||
rval.set(JS_NewGlobalObject(
|
||||
*cx,
|
||||
|
@ -162,6 +167,43 @@ pub unsafe fn create_global_object(
|
|||
JS_FireOnNewGlobalObject(*cx, rval.handle());
|
||||
}
|
||||
|
||||
/// Choose the compartment to create a new global object in.
|
||||
fn select_compartment(cx: SafeJSContext, options: &mut RealmOptions) {
|
||||
type Data = *mut Compartment;
|
||||
unsafe extern "C" fn callback(
|
||||
_cx: *mut JSContext,
|
||||
data: *mut libc::c_void,
|
||||
compartment: *mut Compartment,
|
||||
) -> CompartmentIterResult {
|
||||
let data = data as *mut Data;
|
||||
|
||||
if !IsSharableCompartment(compartment) || IsSystemCompartment(compartment) {
|
||||
return CompartmentIterResult::KeepGoing;
|
||||
}
|
||||
|
||||
// Choose any sharable, non-system compartment in this context to allow
|
||||
// same-agent documents to share JS and DOM objects.
|
||||
*data = compartment;
|
||||
CompartmentIterResult::Stop
|
||||
}
|
||||
|
||||
let mut compartment: Data = ptr::null_mut();
|
||||
unsafe {
|
||||
JS_IterateCompartments(
|
||||
*cx,
|
||||
(&mut compartment) as *mut Data as *mut libc::c_void,
|
||||
Some(callback),
|
||||
);
|
||||
}
|
||||
|
||||
if compartment.is_null() {
|
||||
options.creationOptions_.compSpec_ = CompartmentSpecifier::NewCompartmentAndZone;
|
||||
} else {
|
||||
options.creationOptions_.compSpec_ = CompartmentSpecifier::ExistingCompartment;
|
||||
options.creationOptions_.__bindgen_anon_1.comp_ = compartment;
|
||||
}
|
||||
}
|
||||
|
||||
/// Create and define the interface object of a callback interface.
|
||||
pub fn create_callback_interface_object(
|
||||
cx: SafeJSContext,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue