Auto merge of #29374 - jdm:get-cx-cleanup, r=mrobinson

Assert if DomObject::global is called outside of a JS realm

To avoid crashing in https://github.com/servo/servo/issues/27037, we need to progressively add `InRealm` or `AlreadyInRealm` arguments higher up in the call stack. These changes assert that DomObject::global is only called inside of a realm, which is preferable to segfaulting in the JS engine. Making this a compile-time error requires changing lots of `.global()` callsites, but this PR removes a bunch that are now unnecessary.

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix (partially) #27037
- [x] There are tests for these changes
This commit is contained in:
bors-servo 2023-05-21 04:05:58 +02:00 committed by GitHub
commit 1bb713521b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 260 additions and 208 deletions

View file

@ -718,10 +718,8 @@ impl Callback for ConsumeBodyPromiseHandler {
// https://fetch.spec.whatwg.org/#concept-body-consume-body
#[allow(unrooted_must_root)]
pub fn consume_body<T: BodyMixin + DomObject>(object: &T, body_type: BodyType) -> Rc<Promise> {
let global = object.global();
let in_realm_proof = AlreadyInRealm::assert(&global);
let promise =
Promise::new_in_current_realm(&object.global(), InRealm::Already(&in_realm_proof));
let in_realm_proof = AlreadyInRealm::assert();
let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof));
// Step 1
if object.is_disturbed() || object.is_locked() {

View file

@ -33,7 +33,7 @@ use uuid::Uuid;
pub fn handle_evaluate_js(global: &GlobalScope, eval: String, reply: IpcSender<EvaluateJSReply>) {
// global.get_cx() returns a valid `JSContext` pointer, so this is safe.
let result = unsafe {
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let _ac = enter_realm(global);
rooted!(in(*cx) let mut rval = UndefinedValue());
let source_code = SourceCode::Text(Rc::new(DOMString::from_string(eval)));

View file

@ -9,6 +9,7 @@ use crate::dom::dedicatedworkerglobalscope::{AutoWorkerReset, DedicatedWorkerScr
use crate::dom::globalscope::GlobalScope;
use crate::dom::worker::TrustedWorkerAddress;
use crate::dom::workerglobalscope::WorkerGlobalScope;
use crate::realms::enter_realm;
use crate::script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
use crate::task_queue::{QueuedTaskConversion, TaskQueue};
use crossbeam_channel::{Receiver, Sender};
@ -140,6 +141,7 @@ pub fn run_worker_event_loop<T, WorkerMsg, Event>(
}
// Step 3
for event in sequential {
let _realm = enter_realm(&*worker_scope);
if !worker_scope.handle_event(event) {
// Shutdown
return;

View file

@ -9,8 +9,9 @@ use crate::dom::bindings::codegen::Bindings::AudioBufferBinding::{
};
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use crate::dom::window::Window;
use crate::realms::enter_realm;
use crate::script_runtime::JSContext;
@ -172,7 +173,7 @@ impl AudioBuffer {
self.length as usize,
self.sample_rate,
);
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
for (i, channel) in self.js_channels.borrow_mut().iter().enumerate() {
// Step 1.
if channel.get().is_null() {
@ -271,7 +272,7 @@ impl AudioBufferMethods for AudioBuffer {
}
let bytes_to_copy = min(self.length - start_in_channel, destination.len() as u32) as usize;
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
let channel_number = channel_number as usize;
let offset = start_in_channel as usize;
let mut dest = Vec::with_capacity(destination.len());
@ -313,7 +314,7 @@ impl AudioBufferMethods for AudioBuffer {
return Err(Error::IndexSize);
}
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
if !self.restore_js_channel_data(cx) {
return Err(Error::JSFailed);
}

View file

@ -132,7 +132,7 @@ impl AudioContextMethods for AudioContext {
// https://webaudio.github.io/web-audio-api/#dom-audiocontext-suspend
fn Suspend(&self, comp: InRealm) -> Rc<Promise> {
// Step 1.
let promise = Promise::new_in_current_realm(&self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
// Step 2.
if self.context.control_thread_state() == ProcessingState::Closed {
@ -193,7 +193,7 @@ impl AudioContextMethods for AudioContext {
// https://webaudio.github.io/web-audio-api/#dom-audiocontext-close
fn Close(&self, comp: InRealm) -> Rc<Promise> {
// Step 1.
let promise = Promise::new_in_current_realm(&self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
// Step 2.
if self.context.control_thread_state() == ProcessingState::Closed {

View file

@ -284,7 +284,7 @@ impl BaseAudioContextMethods for BaseAudioContext {
/// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-resume
fn Resume(&self, comp: InRealm) -> Rc<Promise> {
// Step 1.
let promise = Promise::new_in_current_realm(&self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
// Step 2.
if self.audio_context_impl.lock().unwrap().state() == ProcessingState::Closed {
@ -440,7 +440,7 @@ impl BaseAudioContextMethods for BaseAudioContext {
comp: InRealm,
) -> Rc<Promise> {
// Step 1.
let promise = Promise::new_in_current_realm(&self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
let global = self.global();
let window = global.as_window();

View file

@ -245,7 +245,7 @@ impl CallSetup {
if let Some(window) = global.downcast::<Window>() {
window.Document().ensure_safe_to_run_script_or_layout();
}
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let aes = AutoEntryScript::new(&global);
let ais = callback.incumbent().map(AutoIncumbentScript::new);

View file

@ -9,6 +9,7 @@ use crate::dom::bindings::iterable::{Iterable, IterableIterator};
use crate::dom::bindings::root::{Dom, DomRoot, Root};
use crate::dom::bindings::trace::JSTraceable;
use crate::dom::globalscope::GlobalScope;
use crate::realms::AlreadyInRealm;
use crate::script_runtime::JSContext;
use js::jsapi::{Heap, JSObject};
use js::rust::HandleObject;
@ -22,7 +23,7 @@ where
U: DerivedFrom<GlobalScope>,
{
let global_scope = global.upcast();
unsafe { T::WRAP(global_scope.get_cx(), global_scope, obj) }
unsafe { T::WRAP(GlobalScope::get_cx(), global_scope, obj) }
}
/// A struct to store a reference to the reflector of a DOM object.
@ -82,7 +83,8 @@ pub trait DomObject: JSTraceable + 'static {
where
Self: Sized,
{
GlobalScope::from_reflector(self)
let realm = AlreadyInRealm::assert_for_cx(GlobalScope::get_cx());
GlobalScope::from_reflector(self, &realm)
}
}

View file

@ -352,7 +352,7 @@ pub fn read(
mut data: StructuredSerializedData,
rval: MutableHandleValue,
) -> Result<Vec<DomRoot<MessagePort>>, ()> {
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let _ac = enter_realm(&*global);
let mut sc_holder = StructuredDataHolder::Read {
blobs: None,

View file

@ -238,8 +238,8 @@ impl BlobMethods for Blob {
// https://w3c.github.io/FileAPI/#text-method-algo
fn Text(&self) -> Rc<Promise> {
let global = self.global();
let in_realm_proof = AlreadyInRealm::assert(&global);
let p = Promise::new_in_current_realm(&global, InRealm::Already(&in_realm_proof));
let in_realm_proof = AlreadyInRealm::assert();
let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof));
let id = self.get_blob_url_id();
global.read_file_async(
id,
@ -261,8 +261,8 @@ impl BlobMethods for Blob {
// https://w3c.github.io/FileAPI/#arraybuffer-method-algo
fn ArrayBuffer(&self) -> Rc<Promise> {
let global = self.global();
let in_realm_proof = AlreadyInRealm::assert(&global);
let p = Promise::new_in_current_realm(&global, InRealm::Already(&in_realm_proof));
let in_realm_proof = AlreadyInRealm::assert();
let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof));
let id = self.get_blob_url_id();
@ -272,7 +272,7 @@ impl BlobMethods for Blob {
Box::new(|promise, bytes| {
match bytes {
Ok(b) => {
let cx = promise.global().get_cx();
let cx = GlobalScope::get_cx();
let result = run_array_buffer_data_algorithm(cx, b);
match result {

View file

@ -287,8 +287,8 @@ where
T: AsyncBluetoothListener + DomObject + 'static,
F: FnOnce(StringOrUnsignedLong) -> Fallible<UUID>,
{
let in_realm_proof = AlreadyInRealm::assert(&attribute.global());
let p = Promise::new_in_current_realm(&attribute.global(), InRealm::Already(&in_realm_proof));
let in_realm_proof = AlreadyInRealm::assert();
let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof));
let result_uuid = if let Some(u) = uuid {
// Step 1.
@ -528,7 +528,7 @@ impl From<BluetoothError> for Error {
impl BluetoothMethods for Bluetooth {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
fn RequestDevice(&self, option: &RequestDeviceOptions, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
// Step 1.
if (option.filters.is_some() && option.acceptAllDevices) ||
(option.filters.is_none() && !option.acceptAllDevices)
@ -546,7 +546,7 @@ impl BluetoothMethods for Bluetooth {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-getavailability
fn GetAvailability(&self, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
// Step 1. We did not override the method
// Step 2 - 3. in handle_response
let sender = response_async(&p, self);

View file

@ -277,7 +277,7 @@ impl BluetoothDeviceMethods for BluetoothDevice {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements
fn WatchAdvertisements(&self, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
let sender = response_async(&p, self);
// TODO: Step 1.
// Note: Steps 2 - 3 are implemented in components/bluetooth/lib.rs in watch_advertisements function

View file

@ -137,7 +137,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue
fn ReadValue(&self, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) {
@ -170,7 +170,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue
fn WriteValue(&self, value: ArrayBufferViewOrArrayBuffer, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Writes) {
@ -221,7 +221,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications
fn StartNotifications(&self, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) {
@ -258,7 +258,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-stopnotifications
fn StopNotifications(&self, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
let sender = response_async(&p, self);
// TODO: Step 3 - 4: Implement `active notification context set` for BluetoothRemoteGATTCharacteristic,

View file

@ -93,7 +93,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue
fn ReadValue(&self, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) {
@ -125,7 +125,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue
fn WriteValue(&self, value: ArrayBufferViewOrArrayBuffer, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Writes) {

View file

@ -71,7 +71,7 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
#[allow(unsafe_code)]
fn Connect(&self, comp: InRealm) -> Rc<Promise> {
// Step 1.
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
let sender = response_async(&p, self);
// TODO: Step 3: Check if the UA is currently using the Bluetooth system.

View file

@ -17,7 +17,8 @@ impl Console {
#[allow(unsafe_code)]
fn send_to_devtools(global: &GlobalScope, level: LogLevel, message: DOMString) {
if let Some(chan) = global.devtools_chan() {
let caller = unsafe { describe_scripted_caller(*global.get_cx()) }.unwrap_or_default();
let caller =
unsafe { describe_scripted_caller(*GlobalScope::get_cx()) }.unwrap_or_default();
let console_message = ConsoleMessage {
message: String::from(message),
logLevel: level,

View file

@ -154,7 +154,7 @@ fn create_html_element(
// Step 6. Recovering from exception.
let global =
GlobalScope::current().unwrap_or_else(|| document.global());
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
// Step 6.1.1
unsafe {

View file

@ -140,11 +140,10 @@ impl CustomElementRegistry {
constructor: HandleObject,
prototype: MutableHandleValue,
) -> ErrorResult {
let global_scope = self.window.upcast::<GlobalScope>();
unsafe {
// Step 10.1
if !JS_GetProperty(
*global_scope.get_cx(),
*GlobalScope::get_cx(),
constructor,
b"prototype\0".as_ptr() as *const _,
prototype,
@ -166,7 +165,7 @@ impl CustomElementRegistry {
/// Steps 10.3, 10.4
#[allow(unsafe_code)]
unsafe fn get_callbacks(&self, prototype: HandleObject) -> Fallible<LifecycleCallbacks> {
let cx = self.window.get_cx();
let cx = GlobalScope::get_cx();
// Step 4
Ok(LifecycleCallbacks {
@ -181,7 +180,7 @@ impl CustomElementRegistry {
/// Step 10.6
#[allow(unsafe_code)]
fn get_observed_attributes(&self, constructor: HandleObject) -> Fallible<Vec<DOMString>> {
let cx = self.window.get_cx();
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let mut observed_attributes = UndefinedValue());
if unsafe {
!JS_GetProperty(
@ -254,7 +253,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
constructor_: Rc<CustomElementConstructor>,
options: &ElementDefinitionOptions,
) -> ErrorResult {
let cx = self.window.get_cx();
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let constructor = constructor_.callback());
let name = LocalName::from(&*name);
@ -429,7 +428,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
// Step 1
if !is_valid_custom_element_name(&name) {
let promise = Promise::new_in_current_realm(&global_scope, comp);
let promise = Promise::new_in_current_realm(comp);
promise.reject_native(&DOMException::new(&global_scope, DOMErrorName::SyntaxError));
return promise;
}
@ -437,12 +436,12 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
// Step 2
if let Some(definition) = self.definitions.borrow().get(&LocalName::from(&*name)) {
unsafe {
let cx = global_scope.get_cx();
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let mut constructor = UndefinedValue());
definition
.constructor
.to_jsval(*cx, constructor.handle_mut());
let promise = Promise::new_in_current_realm(&global_scope, comp);
let promise = Promise::new_in_current_realm(comp);
promise.resolve_native(&constructor.get());
return promise;
}
@ -453,7 +452,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
// Steps 4, 5
let promise = map.get(&name).cloned().unwrap_or_else(|| {
let promise = Promise::new_in_current_realm(&global_scope, comp);
let promise = Promise::new_in_current_realm(comp);
map.insert(name, promise.clone());
promise
});
@ -543,7 +542,7 @@ impl CustomElementDefinition {
prefix: Option<Prefix>,
) -> Fallible<DomRoot<Element>> {
let window = document.window();
let cx = window.get_cx();
let cx = GlobalScope::get_cx();
// Step 2
rooted!(in(*cx) let constructor = ObjectValue(self.constructor.callback()));
rooted!(in(*cx) let mut element = ptr::null_mut::<JSObject>());
@ -662,7 +661,7 @@ pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Elemen
// Step 8.exception.3
let global = GlobalScope::current().expect("No current global");
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
unsafe {
let ar = enter_realm(&*global);
throw_dom_exception(cx, &global, error);
@ -686,7 +685,7 @@ fn run_upgrade_constructor(
element: &Element,
) -> ErrorResult {
let window = window_from_node(element);
let cx = window.get_cx();
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let constructor_val = ObjectValue(constructor.callback()));
rooted!(in(*cx) let mut element_val = UndefinedValue());
unsafe {
@ -909,7 +908,7 @@ impl CustomElementReactionStack {
return;
}
let cx = element.global().get_cx();
let cx = GlobalScope::get_cx();
// We might be here during HTML parsing, rather than
// during Javscript execution, and so we typically aren't
// already in a realm here.

View file

@ -46,7 +46,7 @@ pub struct DissimilarOriginWindow {
impl DissimilarOriginWindow {
#[allow(unsafe_code)]
pub fn new(global_to_clone_from: &GlobalScope, window_proxy: &WindowProxy) -> DomRoot<Self> {
let cx = global_to_clone_from.get_cx();
let cx = GlobalScope::get_cx();
let win = Box::new(Self {
globalscope: GlobalScope::new_inherited(
PipelineId::new(),

View file

@ -3573,9 +3573,8 @@ impl Document {
// https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen
pub fn enter_fullscreen(&self, pending: &Element) -> Rc<Promise> {
// Step 1
let in_realm_proof = AlreadyInRealm::assert(&self.global());
let promise =
Promise::new_in_current_realm(&self.global(), InRealm::Already(&in_realm_proof));
let in_realm_proof = AlreadyInRealm::assert();
let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof));
let mut error = false;
// Step 4
@ -3642,8 +3641,8 @@ impl Document {
pub fn exit_fullscreen(&self) -> Rc<Promise> {
let global = self.global();
// Step 1
let in_realm_proof = AlreadyInRealm::assert(&global);
let promise = Promise::new_in_current_realm(&global, InRealm::Already(&in_realm_proof));
let in_realm_proof = AlreadyInRealm::assert();
let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof));
// Step 2
if self.fullscreen_element.get().is_none() {
promise.reject_error(Error::Type(String::from("fullscreen is null")));

View file

@ -222,10 +222,10 @@ impl EventSourceContext {
// Steps 4-5
let event = {
let _ac = enter_realm(&*event_source);
rooted!(in(*event_source.global().get_cx()) let mut data = UndefinedValue());
rooted!(in(*GlobalScope::get_cx()) let mut data = UndefinedValue());
unsafe {
self.data
.to_jsval(*event_source.global().get_cx(), data.handle_mut())
.to_jsval(*GlobalScope::get_cx(), data.handle_mut())
};
MessageEvent::new(
&*event_source.global(),

View file

@ -184,7 +184,7 @@ impl CompiledEventListener {
CommonEventHandler::ErrorEventHandler(ref handler) => {
if let Some(event) = event.downcast::<ErrorEvent>() {
if object.is::<Window>() || object.is::<WorkerGlobalScope>() {
let cx = object.global().get_cx();
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let error = event.Error(cx));
let return_value = handler.Call_(
object,
@ -242,7 +242,7 @@ impl CompiledEventListener {
CommonEventHandler::EventHandler(ref handler) => {
if let Ok(value) = handler.Call_(object, event, exception_handle) {
let cx = object.global().get_cx();
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let value = value);
let value = value.handle();
@ -525,7 +525,7 @@ impl EventTarget {
let is_error = ty == &atom!("error") && self.is::<Window>();
let args = if is_error { ERROR_ARG_NAMES } else { ARG_NAMES };
let cx = window.get_cx();
let cx = GlobalScope::get_cx();
let options = unsafe {
CompileOptionsWrapper::new(*cx, &handler.url.to_string(), handler.line as u32)
};
@ -592,7 +592,7 @@ impl EventTarget {
where
T: CallbackContainer,
{
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
let event_listener = listener.map(|listener| {
InlineEventListener::Compiled(CommonEventHandler::EventHandler(unsafe {
@ -607,7 +607,7 @@ impl EventTarget {
where
T: CallbackContainer,
{
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
let event_listener = listener.map(|listener| {
InlineEventListener::Compiled(CommonEventHandler::ErrorEventHandler(unsafe {
@ -625,7 +625,7 @@ impl EventTarget {
) where
T: CallbackContainer,
{
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
let event_listener = listener.map(|listener| {
InlineEventListener::Compiled(CommonEventHandler::BeforeUnloadEventHandler(unsafe {
@ -637,7 +637,7 @@ impl EventTarget {
#[allow(unsafe_code)]
pub fn get_event_handler_common<T: CallbackContainer>(&self, ty: &str) -> Option<Rc<T>> {
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
let listener = self.get_inline_event_listener(&Atom::from(ty));
unsafe {
listener.map(|listener| {

View file

@ -258,7 +258,7 @@ impl FileReader {
let _ac = enter_realm(&*fr);
FileReader::perform_readasarraybuffer(
&fr.result,
fr.global().get_cx(),
GlobalScope::get_cx(),
data,
&blob_contents,
)

View file

@ -1215,7 +1215,7 @@ impl GlobalScope {
return;
}
rooted!(in(*global.get_cx()) let mut message = UndefinedValue());
rooted!(in(*GlobalScope::get_cx()) let mut message = UndefinedValue());
// Step 10.3 StructuredDeserialize(serialized, targetRealm).
if let Ok(ports) = structuredclone::read(&global, data, message.handle_mut()) {
@ -1269,7 +1269,7 @@ impl GlobalScope {
};
if let Some((dom_port, PortMessageTask { origin, data })) = should_dispatch {
// Substep 3-4
rooted!(in(*self.get_cx()) let mut message_clone = UndefinedValue());
rooted!(in(*GlobalScope::get_cx()) let mut message_clone = UndefinedValue());
if let Ok(ports) = structuredclone::read(self, data, message_clone.handle_mut()) {
// Substep 6
// Dispatch the event, using the dom message-port.
@ -2120,7 +2120,7 @@ impl GlobalScope {
/// Returns the global scope of the realm that the given DOM object's reflector
/// was created in.
#[allow(unsafe_code)]
pub fn from_reflector<T: DomObject>(reflector: &T) -> DomRoot<Self> {
pub fn from_reflector<T: DomObject>(reflector: &T, _realm: &AlreadyInRealm) -> DomRoot<Self> {
unsafe { GlobalScope::from_object(*reflector.reflector().get_jsobject()) }
}
@ -2221,7 +2221,7 @@ impl GlobalScope {
}
#[allow(unsafe_code)]
pub fn get_cx(&self) -> SafeJSContext {
pub fn get_cx() -> SafeJSContext {
unsafe { SafeJSContext::from_ptr(Runtime::get()) }
}
@ -2603,7 +2603,7 @@ impl GlobalScope {
Some(metadata),
self.time_profiler_chan().clone(),
|| {
let cx = self.get_cx();
let cx = GlobalScope::get_cx();
let ar = enter_realm(&*self);
@ -2733,8 +2733,8 @@ impl GlobalScope {
image: ImageBitmapSource,
options: &ImageBitmapOptions,
) -> Rc<Promise> {
let in_realm_proof = AlreadyInRealm::assert(&self);
let p = Promise::new_in_current_realm(&self, InRealm::Already(&in_realm_proof));
let in_realm_proof = AlreadyInRealm::assert();
let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof));
if options.resizeWidth.map_or(false, |w| w == 0) {
p.reject_error(Error::InvalidState);
return p;
@ -2857,7 +2857,7 @@ impl GlobalScope {
// Only perform the checkpoint if we're not shutting down.
if self.can_continue_running() {
self.microtask_queue.checkpoint(
self.get_cx(),
GlobalScope::get_cx(),
|_| Some(DomRoot::from_ref(self)),
vec![DomRoot::from_ref(self)],
);
@ -2866,7 +2866,7 @@ impl GlobalScope {
/// Enqueue a microtask for subsequent execution.
pub fn enqueue_microtask(&self, job: Microtask) {
self.microtask_queue.enqueue(job, self.get_cx());
self.microtask_queue.enqueue(job, GlobalScope::get_cx());
}
/// Create a new sender/receiver pair that can be used to implement an on-demand

View file

@ -100,7 +100,7 @@ impl GPUMethods for GPU {
// https://gpuweb.github.io/gpuweb/#dom-gpu-requestadapter
fn RequestAdapter(&self, options: &GPURequestAdapterOptions, comp: InRealm) -> Rc<Promise> {
let global = &self.global();
let promise = Promise::new_in_current_realm(global, comp);
let promise = Promise::new_in_current_realm(comp);
let sender = response_async(&promise, self);
let power_preference = match options.powerPreference {
Some(GPUPowerPreference::Low_power) => PowerPreference::LowPower,

View file

@ -78,7 +78,7 @@ impl GPUAdapterMethods for GPUAdapter {
/// https://gpuweb.github.io/gpuweb/#dom-gpuadapter-requestdevice
fn RequestDevice(&self, descriptor: &GPUDeviceDescriptor, comp: InRealm) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(&self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
let sender = response_async(&promise, self);
let mut features = wgt::Features::empty();
for &ext in descriptor.extensions.iter() {

View file

@ -6,7 +6,6 @@ use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::{GPUBufferMethods, GPUSize64};
use crate::dom::bindings::codegen::Bindings::GPUMapModeBinding::GPUMapModeConstants;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::USVString;
@ -134,7 +133,7 @@ impl GPUBufferMethods for GPUBuffer {
#[allow(unsafe_code)]
/// https://gpuweb.github.io/gpuweb/#dom-gpubuffer-unmap
fn Unmap(&self) {
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
// Step 1
match self.state.get() {
GPUBufferState::Unmapped | GPUBufferState::Destroyed => {
@ -209,7 +208,7 @@ impl GPUBufferMethods for GPUBuffer {
size: Option<GPUSize64>,
comp: InRealm,
) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(&self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
let range_size = if let Some(s) = size {
s
} else if offset >= self.size {

View file

@ -357,7 +357,7 @@ impl GPUDeviceMethods for GPUDevice {
/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-lost
fn Lost(&self, comp: InRealm) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(&self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
*self.lost_promise.borrow_mut() = Some(promise.clone());
promise
}
@ -1117,7 +1117,7 @@ impl GPUDeviceMethods for GPUDevice {
/// https://gpuweb.github.io/gpuweb/#dom-gpudevice-poperrorscope
fn PopErrorScope(&self, comp: InRealm) -> Rc<Promise> {
let mut context = self.scope_context.borrow_mut();
let promise = Promise::new_in_current_realm(&self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
let scope_id =
if let Some(meta) = context.scope_stack.iter().rev().find(|m| !m.popped.get()) {
meta.popped.set(true);

View file

@ -117,7 +117,7 @@ impl History {
blobs: None,
};
let global_scope = self.window.upcast::<GlobalScope>();
rooted!(in(*global_scope.get_cx()) let mut state = UndefinedValue());
rooted!(in(*GlobalScope::get_cx()) let mut state = UndefinedValue());
if let Err(_) = structuredclone::read(&global_scope, data, state.handle_mut()) {
warn!("Error reading structuredclone data");
}

View file

@ -46,6 +46,7 @@ use crate::fetch::create_a_potential_cors_request;
use crate::image_listener::{generate_cache_listener_for_element, ImageCacheListener};
use crate::microtask::{Microtask, MicrotaskRunnable};
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
use crate::realms::enter_realm;
use crate::script_thread::ScriptThread;
use crate::task_source::TaskSource;
use app_units::{Au, AU_PER_PX};
@ -56,6 +57,7 @@ use html5ever::{LocalName, Prefix, QualName};
use ipc_channel::ipc;
use ipc_channel::ipc::IpcSender;
use ipc_channel::router::ROUTER;
use js::jsapi::JSAutoRealm;
use mime::{self, Mime};
use msg::constellation_msg::PipelineId;
use net_traits::image::base::{Image, ImageMetadata};
@ -1353,6 +1355,13 @@ impl MicrotaskRunnable for ImageElementMicrotask {
},
}
}
fn enter_realm(&self) -> JSAutoRealm {
match self {
&ImageElementMicrotask::StableStateUpdateImageDataTask { ref elem, .. } |
&ImageElementMicrotask::EnvironmentChangesTask { ref elem, .. } => enter_realm(&**elem),
}
}
}
pub trait LayoutHTMLImageElementHelpers {

View file

@ -833,7 +833,7 @@ impl HTMLInputElement {
}
// Rust's regex is not compatible, we need to use mozjs RegExp.
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
let _ac = enter_realm(self);
rooted!(in(*cx) let mut pattern = ptr::null_mut::<JSObject>());

View file

@ -62,7 +62,7 @@ use crate::dom::virtualmethods::VirtualMethods;
use crate::fetch::{create_a_potential_cors_request, FetchCanceller};
use crate::microtask::{Microtask, MicrotaskRunnable};
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
use crate::realms::InRealm;
use crate::realms::{enter_realm, InRealm};
use crate::script_thread::ScriptThread;
use crate::task_source::TaskSource;
use dom_struct::dom_struct;
@ -74,6 +74,7 @@ use html5ever::{LocalName, Prefix};
use http::header::{self, HeaderMap, HeaderValue};
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use js::jsapi::JSAutoRealm;
use media::{glplayer_channel, GLPlayerMsg, GLPlayerMsgForward, WindowGLContext};
use net_traits::image::base::Image;
use net_traits::request::Destination;
@ -2112,7 +2113,7 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
// https://html.spec.whatwg.org/multipage/#dom-media-play
fn Play(&self, comp: InRealm) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(&self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
// Step 1.
// FIXME(nox): Reject promise if not allowed to play.
@ -2506,6 +2507,14 @@ impl MicrotaskRunnable for MediaElementMicrotask {
},
}
}
fn enter_realm(&self) -> JSAutoRealm {
match self {
&MediaElementMicrotask::ResourceSelectionTask { ref elem, .. } |
&MediaElementMicrotask::PauseIfNotInDocumentTask { ref elem } |
&MediaElementMicrotask::SeekedTask { ref elem, .. } => enter_realm(&**elem),
}
}
}
enum Resource {

View file

@ -110,7 +110,7 @@ unsafe extern "C" fn off_thread_compilation_callback(
task!(off_thread_compile_continue: move || {
let elem = script_element.root();
let global = elem.global();
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let _ar = enter_realm(&*global);
let compiled_script = FinishOffThreadStencil(*cx, token.0, ptr::null_mut());
@ -418,7 +418,7 @@ impl FetchResponseListener for ClassicContext {
let elem = self.elem.root();
let global = elem.global();
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let _ar = enter_realm(&*global);
let options = unsafe { CompileOptionsWrapper::new(*cx, final_url.as_str(), 1) };
@ -1053,7 +1053,7 @@ impl HTMLScriptElement {
} else {
self.line_number as u32
};
rooted!(in(*window.get_cx()) let mut rval = UndefinedValue());
rooted!(in(*GlobalScope::get_cx()) let mut rval = UndefinedValue());
let global = window.upcast::<GlobalScope>();
global.evaluate_script_on_global_with_result(
&script.code,
@ -1108,7 +1108,7 @@ impl HTMLScriptElement {
.map(|record| record.handle());
if let Some(record) = record {
rooted!(in(*global.get_cx()) let mut rval = UndefinedValue());
rooted!(in(*GlobalScope::get_cx()) let mut rval = UndefinedValue());
let evaluated =
module_tree.execute_module(global, record, rval.handle_mut().into());

View file

@ -39,7 +39,7 @@ impl ImageData {
) -> Fallible<DomRoot<ImageData>> {
let len = width * height * 4;
unsafe {
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
rooted!(in (*cx) let mut js_object = ptr::null_mut::<JSObject>());
if let Some(ref mut d) = data {
d.resize(len as usize, 0);
@ -60,7 +60,7 @@ impl ImageData {
jsobject: *mut JSObject,
) -> Fallible<DomRoot<ImageData>> {
// checking jsobject type
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
typedarray!(in(*cx) let array_res: Uint8ClampedArray = jsobject);
let array = array_res.map_err(|_| {
Error::Type("Argument to Image data is not an Uint8ClampedArray".to_owned())
@ -111,7 +111,7 @@ impl ImageData {
});
let len = width * height * 4;
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
Uint8ClampedArray::create(*cx, CreateWith::Length(len as usize), array.handle_mut())
.unwrap();

View file

@ -44,7 +44,7 @@ impl MediaDevicesMethods for MediaDevices {
/// https://w3c.github.io/mediacapture-main/#dom-mediadevices-getusermedia
#[allow(unsafe_code)]
fn GetUserMedia(&self, constraints: &MediaStreamConstraints, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
let media = ServoMedia::get().unwrap();
let stream = MediaStream::new(&self.global());
if let Some(constraints) = convert_constraints(&constraints.audio) {
@ -67,9 +67,8 @@ impl MediaDevicesMethods for MediaDevices {
/// https://w3c.github.io/mediacapture-main/#dom-mediadevices-enumeratedevices
fn EnumerateDevices(&self) -> Rc<Promise> {
// Step 1.
let global = self.global();
let in_realm_proof = AlreadyInRealm::assert(&global);
let p = Promise::new_in_current_realm(&global, InRealm::Already(&in_realm_proof));
let in_realm_proof = AlreadyInRealm::assert();
let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof));
// Step 2.
// XXX These steps should be run in parallel.

View file

@ -43,7 +43,7 @@ impl NavigationPreloadManager {
impl NavigationPreloadManagerMethods for NavigationPreloadManager {
// https://w3c.github.io/ServiceWorker/#navigation-preload-manager-enable
fn Enable(&self, comp: InRealm) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(&*self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
// 2.
if self.serviceworker_registration.is_active() {
@ -65,7 +65,7 @@ impl NavigationPreloadManagerMethods for NavigationPreloadManager {
// https://w3c.github.io/ServiceWorker/#navigation-preload-manager-disable
fn Disable(&self, comp: InRealm) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(&*self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
// 2.
if self.serviceworker_registration.is_active() {
@ -87,7 +87,7 @@ impl NavigationPreloadManagerMethods for NavigationPreloadManager {
// https://w3c.github.io/ServiceWorker/#navigation-preload-manager-setheadervalue
fn SetHeaderValue(&self, value: ByteString, comp: InRealm) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(&*self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
// 2.
if self.serviceworker_registration.is_active() {
@ -109,7 +109,7 @@ impl NavigationPreloadManagerMethods for NavigationPreloadManager {
// https://w3c.github.io/ServiceWorker/#navigation-preload-manager-getstate
fn GetState(&self, comp: InRealm) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(&*self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
// 2.
let mut state = NavigationPreloadState::empty();

View file

@ -121,7 +121,7 @@ impl OfflineAudioContextMethods for OfflineAudioContext {
// https://webaudio.github.io/web-audio-api/#dom-offlineaudiocontext-startrendering
fn StartRendering(&self, comp: InRealm) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(&self.global(), comp);
let promise = Promise::new_in_current_realm(comp);
if self.rendering_started.get() {
promise.reject_error(Error::InvalidState);
return promise;

View file

@ -252,7 +252,7 @@ impl PaintWorkletGlobalScope {
name, size_in_px.width, size_in_px.height, device_pixel_ratio
);
let cx = self.worklet_global.get_cx();
let cx = WorkletGlobalScope::get_cx();
let _ac = JSAutoRealm::new(*cx, self.worklet_global.reflector().get_jsobject().get());
// TODO: Steps 1-2.1.
@ -517,7 +517,7 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobalScope {
/// <https://drafts.css-houdini.org/css-paint-api/#dom-paintworkletglobalscope-registerpaint>
fn RegisterPaint(&self, name: DOMString, paint_ctor: Rc<VoidFunction>) -> Fallible<()> {
let name = Atom::from(name);
let cx = self.worklet_global.get_cx();
let cx = WorkletGlobalScope::get_cx();
rooted!(in(*cx) let paint_obj = paint_ctor.callback_holder().get());
rooted!(in(*cx) let paint_val = ObjectValue(paint_obj.get()));

View file

@ -87,8 +87,8 @@ impl Permissions {
let p = match promise {
Some(promise) => promise,
None => {
let in_realm_proof = AlreadyInRealm::assert(&self.global());
Promise::new_in_current_realm(&self.global(), InRealm::Already(&in_realm_proof))
let in_realm_proof = AlreadyInRealm::assert();
Promise::new_in_current_realm(InRealm::Already(&in_realm_proof))
},
};

View file

@ -88,11 +88,11 @@ impl Promise {
pub fn new(global: &GlobalScope) -> Rc<Promise> {
let realm = enter_realm(&*global);
let comp = InRealm::Entered(&realm);
Promise::new_in_current_realm(global, comp)
Promise::new_in_current_realm(comp)
}
pub fn new_in_current_realm(global: &GlobalScope, _comp: InRealm) -> Rc<Promise> {
let cx = global.get_cx();
pub fn new_in_current_realm(_comp: InRealm) -> Rc<Promise> {
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let mut obj = ptr::null_mut::<JSObject>());
Promise::create_js_promise(cx, obj.handle_mut());
Promise::new_with_js_promise(obj.handle(), cx)
@ -100,7 +100,7 @@ impl Promise {
#[allow(unsafe_code)]
pub fn duplicate(&self) -> Rc<Promise> {
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
Promise::new_with_js_promise(self.reflector().get_jsobject(), cx)
}
@ -172,7 +172,7 @@ impl Promise {
where
T: ToJSValConvertible,
{
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
let _ac = enter_realm(&*self);
rooted!(in(*cx) let mut v = UndefinedValue());
unsafe {
@ -195,7 +195,7 @@ impl Promise {
where
T: ToJSValConvertible,
{
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
let _ac = enter_realm(&*self);
rooted!(in(*cx) let mut v = UndefinedValue());
unsafe {
@ -206,7 +206,7 @@ impl Promise {
#[allow(unsafe_code)]
pub fn reject_error(&self, error: Error) {
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
let _ac = enter_realm(&*self);
rooted!(in(*cx) let mut v = UndefinedValue());
unsafe {
@ -245,7 +245,7 @@ impl Promise {
#[allow(unsafe_code)]
pub fn append_native_handler(&self, handler: &PromiseNativeHandler, _comp: InRealm) {
let _ais = AutoEntryScript::new(&*handler.global());
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let resolve_func =
create_native_handler_function(*cx,
handler.reflector().get_jsobject(),

View file

@ -120,7 +120,7 @@ impl ReadableStream {
) -> DomRoot<ReadableStream> {
let _ar = enter_realm(global);
let _ais = AutoIncumbentScript::new(global);
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let source = Rc::new(ExternalUnderlyingSourceController::new(source));
@ -157,7 +157,7 @@ impl ReadableStream {
pub fn enqueue_native(&self, bytes: Vec<u8>) {
let global = self.global();
let _ar = enter_realm(&*global);
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let handle = unsafe { self.js_stream.handle() };
@ -171,7 +171,7 @@ impl ReadableStream {
pub fn error_native(&self, error: Error) {
let global = self.global();
let _ar = enter_realm(&*global);
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
unsafe {
rooted!(in(*cx) let mut js_error = UndefinedValue());
@ -188,7 +188,7 @@ impl ReadableStream {
pub fn close_native(&self) {
let global = self.global();
let _ar = enter_realm(&*global);
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let handle = unsafe { self.js_stream.handle() };
@ -223,7 +223,7 @@ impl ReadableStream {
let global = self.global();
let _ar = enter_realm(&*global);
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
unsafe {
rooted!(in(*cx) let reader = ReadableStreamGetReader(
@ -253,7 +253,7 @@ impl ReadableStream {
let _ar = enter_realm(&*global);
let _aes = AutoEntryScript::new(&*global);
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
unsafe {
rooted!(in(*cx) let promise_obj = ReadableStreamDefaultReaderRead(
@ -276,7 +276,7 @@ impl ReadableStream {
let global = self.global();
let _ar = enter_realm(&*global);
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
unsafe {
ReadableStreamReaderReleaseLock(*cx, self.js_reader.handle());
@ -293,7 +293,7 @@ impl ReadableStream {
}
// Otherwise, still double-check that script didn't lock the stream.
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
let mut locked_or_disturbed = false;
unsafe {
@ -306,7 +306,7 @@ impl ReadableStream {
#[allow(unsafe_code)]
pub fn is_disturbed(&self) -> bool {
// Check that script didn't disturb the stream.
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
let mut locked_or_disturbed = false;
unsafe {

View file

@ -135,7 +135,7 @@ impl RTCDataChannel {
pub fn on_error(&self, error: WebRtcError) {
let global = self.global();
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get());
let init = RTCErrorInit {
errorDetail: RTCErrorDetailType::Data_channel_failure,
@ -157,7 +157,7 @@ impl RTCDataChannel {
pub fn on_message(&self, channel_message: DataChannelMessage) {
unsafe {
let global = self.global();
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get());
rooted!(in(*cx) let mut message = UndefinedValue());

View file

@ -548,7 +548,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection {
/// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addicecandidate
fn AddIceCandidate(&self, candidate: &RTCIceCandidateInit, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
if candidate.sdpMid.is_none() && candidate.sdpMLineIndex.is_none() {
p.reject_error(Error::Type(format!(
"one of sdpMid and sdpMLineIndex must be set"
@ -583,7 +583,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection {
/// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer
fn CreateOffer(&self, _options: &RTCOfferOptions, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
if self.closed.get() {
p.reject_error(Error::InvalidState);
return p;
@ -595,7 +595,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection {
/// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer
fn CreateAnswer(&self, _options: &RTCAnswerOptions, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
if self.closed.get() {
p.reject_error(Error::InvalidState);
return p;
@ -618,7 +618,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection {
/// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-setlocaldescription
fn SetLocalDescription(&self, desc: &RTCSessionDescriptionInit, comp: InRealm) -> Rc<Promise> {
// XXXManishearth validate the current state
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
let this = Trusted::new(self);
let desc: SessionDescription = desc.into();
let trusted_promise = TrustedPromise::new(p.clone());
@ -651,7 +651,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection {
/// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-setremotedescription
fn SetRemoteDescription(&self, desc: &RTCSessionDescriptionInit, comp: InRealm) -> Rc<Promise> {
// XXXManishearth validate the current state
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
let this = Trusted::new(self);
let desc: SessionDescription = desc.into();
let trusted_promise = TrustedPromise::new(p.clone());

View file

@ -70,7 +70,7 @@ impl ServiceWorkerContainerMethods for ServiceWorkerContainer {
let global = self.client.global();
// A: Step 1
let promise = Promise::new_in_current_realm(&*global, comp);
let promise = Promise::new_in_current_realm(comp);
let USVString(ref script_url) = script_url;
// A: Step 3

View file

@ -34,6 +34,7 @@ use crate::dom::processinginstruction::ProcessingInstruction;
use crate::dom::text::Text;
use crate::dom::virtualmethods::vtable_for;
use crate::network_listener::PreInvoke;
use crate::realms::enter_realm;
use crate::script_thread::ScriptThread;
use content_security_policy::{self as csp, CspList};
use dom_struct::dom_struct;
@ -828,6 +829,8 @@ impl FetchResponseListener for ParserContext {
return;
}
let _realm = enter_realm(&*parser.document);
parser.document.set_csp_list(csp_list);
self.parser = Some(Trusted::new(&*parser));
self.submit_resource_timing();
@ -916,6 +919,7 @@ impl FetchResponseListener for ParserContext {
if parser.aborted.get() {
return;
}
let _realm = enter_realm(&*parser);
parser.parse_bytes_chunk(payload);
}
@ -931,6 +935,8 @@ impl FetchResponseListener for ParserContext {
return;
}
let _realm = enter_realm(&*parser);
match status {
// are we throwing this away or can we use it?
Ok(_) => (),

View file

@ -1005,7 +1005,7 @@ impl TestBindingMethods for TestBinding {
resolve.map(SimpleHandler::new),
reject.map(SimpleHandler::new),
);
let p = Promise::new_in_current_realm(&global, comp.clone());
let p = Promise::new_in_current_realm(comp.clone());
p.append_native_handler(&handler, comp);
return p;
@ -1028,7 +1028,7 @@ impl TestBindingMethods for TestBinding {
}
fn PromiseAttribute(&self, comp: InRealm) -> Rc<Promise> {
Promise::new_in_current_realm(&self.global(), comp)
Promise::new_in_current_realm(comp)
}
fn AcceptPromise(&self, _promise: &Promise) {}

View file

@ -554,9 +554,9 @@ impl TaskOnce for MessageReceivedTask {
// Step 2-5.
let global = ws.global();
// global.get_cx() returns a valid `JSContext` pointer, so this is safe.
// GlobalScope::get_cx() returns a valid `JSContext` pointer, so this is safe.
unsafe {
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let _ac = JSAutoRealm::new(*cx, ws.reflector().get_jsobject().get());
rooted!(in(*cx) let mut message = UndefinedValue());
match self.message {

View file

@ -165,7 +165,7 @@ impl WindowProxy {
let WindowProxyHandler(handler) = window.windowproxy_handler();
assert!(!handler.is_null());
let cx = window.get_cx();
let cx = GlobalScope::get_cx();
let window_jsobject = window.reflector().get_jsobject();
assert!(!window_jsobject.get().is_null());
assert_ne!(
@ -225,7 +225,7 @@ impl WindowProxy {
let handler = CreateWrapperProxyHandler(&XORIGIN_PROXY_HANDLER);
assert!(!handler.is_null());
let cx = global_to_clone_from.get_cx();
let cx = GlobalScope::get_cx();
// Create a new browsing context.
let window_proxy = Box::new(WindowProxy::new_inherited(
@ -624,7 +624,7 @@ impl WindowProxy {
let handler = CreateWrapperProxyHandler(traps);
assert!(!handler.is_null());
let cx = window.get_cx();
let cx = GlobalScope::get_cx();
let window_jsobject = window.reflector().get_jsobject();
let old_js_proxy = self.reflector.get_jsobject();
assert!(!window_jsobject.get().is_null());

View file

@ -169,7 +169,7 @@ impl Worker {
let global = worker.global();
let target = worker.upcast();
let _ac = enter_realm(target);
rooted!(in(*global.get_cx()) let mut message = UndefinedValue());
rooted!(in(*GlobalScope::get_cx()) let mut message = UndefinedValue());
if let Ok(ports) = structuredclone::read(&global, data, message.handle_mut()) {
MessageEvent::dispatch_jsval(target, &global, message.handle(), None, None, ports);
} else {
@ -247,7 +247,7 @@ impl WorkerMethods for Worker {
self.terminated.set(true);
// Step 3
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
unsafe { JS_RequestInterruptCallback(*cx) };
}

View file

@ -130,8 +130,7 @@ impl WorkletMethods for Worklet {
comp: InRealm,
) -> Rc<Promise> {
// Step 1.
let global = self.window.upcast();
let promise = Promise::new_in_current_realm(&global, comp);
let promise = Promise::new_in_current_realm(comp);
// Step 3.
let module_url_record = match self.window.Document().base_url().join(&module_url.0) {

View file

@ -85,14 +85,14 @@ impl WorkletGlobalScope {
}
/// Get the JS context.
pub fn get_cx(&self) -> JSContext {
self.globalscope.get_cx()
pub fn get_cx() -> JSContext {
GlobalScope::get_cx()
}
/// Evaluate a JS script in this global.
pub fn evaluate_js(&self, script: &str) -> bool {
debug!("Evaluating Dom in a worklet.");
rooted!(in (*self.globalscope.get_cx()) let mut rval = UndefinedValue());
rooted!(in (*GlobalScope::get_cx()) let mut rval = UndefinedValue());
self.globalscope.evaluate_js_on_global_with_result(
&*script,
rval.handle_mut(),

View file

@ -57,7 +57,7 @@ impl XRInputSource {
);
let _ac = enter_realm(&*global);
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
unsafe {
rooted!(in(*cx) let mut profiles = UndefinedValue());
source.info.profiles.to_jsval(*cx, profiles.handle_mut());

View file

@ -63,7 +63,7 @@ impl XRInputSourcesChangeEvent {
event.init_event(type_, bubbles, cancelable);
}
let _ac = enter_realm(&*global);
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
unsafe {
rooted!(in(*cx) let mut added_val = UndefinedValue());
added.to_jsval(*cx, added_val.handle_mut());

View file

@ -116,7 +116,7 @@ impl XRRayMethods for XRRay {
// https://immersive-web.github.io/hit-test/#xrray-obtain-the-matrix
// Step 1
if self.matrix.get().is_null() {
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
// Step 2
let z = Vector3D::new(0., 0., -1.);
// Step 3

View file

@ -117,7 +117,7 @@ impl XRRigidTransformMethods for XRRigidTransform {
// https://immersive-web.github.io/webxr/#dom-xrrigidtransform-matrix
fn Matrix(&self, _cx: JSContext) -> NonNull<JSObject> {
if self.matrix.get().is_null() {
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
// According to the spec all matrices are column-major,
// however euclid uses row vectors so we use .to_array()
let arr = self.transform.to_transform().to_array();

View file

@ -757,7 +757,7 @@ impl XRSessionMethods for XRSession {
/// https://immersive-web.github.io/webxr/#dom-xrsession-requestreferencespace
fn RequestReferenceSpace(&self, ty: XRReferenceSpaceType, comp: InRealm) -> Rc<Promise> {
let p = Promise::new_in_current_realm(&self.global(), comp);
let p = Promise::new_in_current_realm(comp);
// https://immersive-web.github.io/webxr/#create-a-reference-space

View file

@ -14,6 +14,7 @@ use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
use crate::dom::bindings::trace::RootedTraceableBox;
use crate::dom::eventtarget::EventTarget;
use crate::dom::gamepad::Gamepad;
use crate::dom::globalscope::GlobalScope;
use crate::dom::promise::Promise;
use crate::dom::window::Window;
use crate::dom::xrsession::XRSession;
@ -158,7 +159,7 @@ impl XRSystemMethods for XRSystem {
) -> Rc<Promise> {
let global = self.global();
let window = global.as_window();
let promise = Promise::new_in_current_realm(&global, comp);
let promise = Promise::new_in_current_realm(comp);
if mode != XRSessionMode::Inline {
if !ScriptThread::is_user_interacting() {
@ -180,7 +181,7 @@ impl XRSystemMethods for XRSystem {
let mut required_features = vec![];
let mut optional_features = vec![];
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
// We are supposed to include "viewer" and on immersive devices "local"
// by default here, but this is handled directly in requestReferenceSpace()

View file

@ -3,7 +3,6 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethods};
use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::utils::create_typed_array;
@ -90,7 +89,7 @@ impl XRViewMethods for XRView {
/// https://immersive-web.github.io/webxr/#dom-xrview-projectionmatrix
fn ProjectionMatrix(&self, _cx: JSContext) -> NonNull<JSObject> {
if self.proj.get().is_null() {
let cx = self.global().get_cx();
let cx = GlobalScope::get_cx();
// row_major since euclid uses row vectors
let proj = self.view.projection.to_array();
create_typed_array(cx, &proj, &self.proj);

View file

@ -154,7 +154,7 @@ impl XRViewerPose {
let transform = XRRigidTransform::new(global, cast_transform(transform));
let pose = reflect_dom_object(Box::new(XRViewerPose::new_inherited(&transform)), global);
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
unsafe {
rooted!(in(*cx) let mut jsval = UndefinedValue());
views.to_jsval(*cx, jsval.handle_mut());

View file

@ -142,7 +142,7 @@ pub fn Fetch(
let core_resource_thread = global.core_resource_thread();
// Step 1
let promise = Promise::new_in_current_realm(global, comp);
let promise = Promise::new_in_current_realm(comp);
let response = Response::new(global);
// Step 2

View file

@ -15,9 +15,10 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlimageelement::ImageElementMicrotask;
use crate::dom::htmlmediaelement::MediaElementMicrotask;
use crate::dom::mutationobserver::MutationObserver;
use crate::realms::enter_realm;
use crate::script_runtime::{notify_about_rejected_promises, JSContext};
use crate::script_thread::ScriptThread;
use js::jsapi::{JobQueueIsEmpty, JobQueueMayNotBeEmpty};
use js::jsapi::{JSAutoRealm, JobQueueIsEmpty, JobQueueMayNotBeEmpty};
use msg::constellation_msg::PipelineId;
use std::cell::Cell;
use std::mem;
@ -44,6 +45,7 @@ pub enum Microtask {
pub trait MicrotaskRunnable {
fn handler(&self) {}
fn enter_realm(&self) -> JSAutoRealm;
}
/// A promise callback scheduled to run during the next microtask checkpoint (#4283).
@ -108,19 +110,23 @@ impl MicrotaskQueue {
if let Some(target) = target_provider(job.pipeline) {
let was_interacting = ScriptThread::is_user_interacting();
ScriptThread::set_user_interacting(job.is_user_interacting);
let _realm = enter_realm(&*target);
let _ = job.callback.Call_(&*target, ExceptionHandling::Report);
ScriptThread::set_user_interacting(was_interacting);
}
},
Microtask::User(ref job) => {
if let Some(target) = target_provider(job.pipeline) {
let _realm = enter_realm(&*target);
let _ = job.callback.Call_(&*target, ExceptionHandling::Report);
}
},
Microtask::MediaElement(ref task) => {
let _realm = task.enter_realm();
task.handler();
},
Microtask::ImageElement(ref task) => {
let _realm = task.enter_realm();
task.handler();
},
Microtask::CustomElementReaction => {

View file

@ -11,9 +11,9 @@ pub struct AlreadyInRealm(());
impl AlreadyInRealm {
#![allow(unsafe_code)]
pub fn assert(global: &GlobalScope) -> AlreadyInRealm {
pub fn assert() -> AlreadyInRealm {
unsafe {
assert!(!GetCurrentRealmOrNull(*global.get_cx()).is_null());
assert!(!GetCurrentRealmOrNull(*GlobalScope::get_cx()).is_null());
}
AlreadyInRealm(())
}
@ -44,7 +44,7 @@ impl<'a> InRealm<'a> {
pub fn enter_realm(object: &impl DomObject) -> JSAutoRealm {
JSAutoRealm::new(
*object.global().get_cx(),
*GlobalScope::get_cx(),
object.reflector().get_jsobject().get(),
)
}

View file

@ -81,8 +81,8 @@ use uuid::Uuid;
#[allow(unsafe_code)]
unsafe fn gen_type_error(global: &GlobalScope, string: String) -> RethrowError {
rooted!(in(*global.get_cx()) let mut thrown = UndefinedValue());
Error::Type(string).to_jsval(*global.get_cx(), &global, thrown.handle_mut());
rooted!(in(*GlobalScope::get_cx()) let mut thrown = UndefinedValue());
Error::Type(string).to_jsval(*GlobalScope::get_cx(), &global, thrown.handle_mut());
return RethrowError(RootedTraceableBox::from_box(Heap::boxed(thrown.get())));
}
@ -357,7 +357,7 @@ impl ModuleTree {
match promise.as_ref() {
Some(promise) => promise.append_native_handler(&handler, comp),
None => {
let new_promise = Promise::new_in_current_realm(&owner.global(), comp);
let new_promise = Promise::new_in_current_realm(comp);
new_promise.append_native_handler(&handler, comp);
*promise = Some(new_promise);
},
@ -393,7 +393,7 @@ impl ModuleTree {
match promise.as_ref() {
Some(promise) => promise.append_native_handler(&handler, comp),
None => {
let new_promise = Promise::new_in_current_realm(&owner.global(), comp);
let new_promise = Promise::new_in_current_realm(comp);
new_promise.append_native_handler(&handler, comp);
*promise = Some(new_promise);
},
@ -421,14 +421,14 @@ impl ModuleTree {
url: ServoUrl,
options: ScriptFetchOptions,
) -> Result<ModuleObject, RethrowError> {
let _ac = JSAutoRealm::new(*global.get_cx(), *global.reflector().get_jsobject());
let cx = GlobalScope::get_cx();
let _ac = JSAutoRealm::new(*cx, *global.reflector().get_jsobject());
let compile_options =
unsafe { CompileOptionsWrapper::new(*global.get_cx(), url.as_str(), 1) };
let compile_options = unsafe { CompileOptionsWrapper::new(*cx, url.as_str(), 1) };
unsafe {
rooted!(in(*global.get_cx()) let mut module_script = CompileModule1(
*global.get_cx(),
rooted!(in(*cx) let mut module_script = CompileModule1(
*cx,
compile_options.ptr,
&mut transform_str_to_source_text(&module_script_text),
));
@ -436,12 +436,9 @@ impl ModuleTree {
if module_script.is_null() {
warn!("fail to compile module script of {}", url);
rooted!(in(*global.get_cx()) let mut exception = UndefinedValue());
assert!(JS_GetPendingException(
*global.get_cx(),
&mut exception.handle_mut()
));
JS_ClearPendingException(*global.get_cx());
rooted!(in(*cx) let mut exception = UndefinedValue());
assert!(JS_GetPendingException(*cx, &mut exception.handle_mut()));
JS_ClearPendingException(*cx);
return Err(RethrowError(RootedTraceableBox::from_box(Heap::boxed(
exception.get(),
@ -474,18 +471,16 @@ impl ModuleTree {
global: &GlobalScope,
module_record: HandleObject,
) -> Result<(), RethrowError> {
let _ac = JSAutoRealm::new(*global.get_cx(), *global.reflector().get_jsobject());
let cx = GlobalScope::get_cx();
let _ac = JSAutoRealm::new(*cx, *global.reflector().get_jsobject());
unsafe {
if !ModuleLink(*global.get_cx(), module_record) {
if !ModuleLink(*cx, module_record) {
warn!("fail to link & instantiate module");
rooted!(in(*global.get_cx()) let mut exception = UndefinedValue());
assert!(JS_GetPendingException(
*global.get_cx(),
&mut exception.handle_mut()
));
JS_ClearPendingException(*global.get_cx());
rooted!(in(*cx) let mut exception = UndefinedValue());
assert!(JS_GetPendingException(*cx, &mut exception.handle_mut()));
JS_ClearPendingException(*cx);
Err(RethrowError(RootedTraceableBox::from_box(Heap::boxed(
exception.get(),
@ -505,7 +500,7 @@ impl ModuleTree {
module_record: HandleObject,
eval_result: MutableHandleValue,
) -> Result<(), RethrowError> {
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let _ac = JSAutoRealm::new(*cx, *global.reflector().get_jsobject());
unsafe {
@ -547,11 +542,11 @@ impl ModuleTree {
unsafe {
let ar = enter_realm(&*global);
JS_SetPendingException(
*global.get_cx(),
*GlobalScope::get_cx(),
exception.handle(),
ExceptionStackBehavior::Capture,
);
report_pending_exception(*global.get_cx(), true, InRealm::Entered(&ar));
report_pending_exception(*GlobalScope::get_cx(), true, InRealm::Entered(&ar));
}
}
}
@ -563,16 +558,17 @@ impl ModuleTree {
module_object: HandleObject,
base_url: ServoUrl,
) -> Result<IndexSet<ServoUrl>, RethrowError> {
let _ac = JSAutoRealm::new(*global.get_cx(), *global.reflector().get_jsobject());
let cx = GlobalScope::get_cx();
let _ac = JSAutoRealm::new(*cx, *global.reflector().get_jsobject());
let mut specifier_urls = IndexSet::new();
unsafe {
rooted!(in(*global.get_cx()) let requested_modules = GetRequestedModules(*global.get_cx(), module_object));
rooted!(in(*cx) let requested_modules = GetRequestedModules(*cx, module_object));
let mut length = 0;
if !GetArrayLength(*global.get_cx(), requested_modules.handle(), &mut length) {
if !GetArrayLength(*cx, requested_modules.handle(), &mut length) {
let module_length_error =
gen_type_error(&global, "Wrong length of requested modules".to_owned());
@ -580,10 +576,10 @@ impl ModuleTree {
}
for index in 0..length {
rooted!(in(*global.get_cx()) let mut element = UndefinedValue());
rooted!(in(*cx) let mut element = UndefinedValue());
if !JS_GetElement(
*global.get_cx(),
*cx,
requested_modules.handle(),
index,
&mut element.handle_mut(),
@ -594,12 +590,12 @@ impl ModuleTree {
return Err(get_element_error);
}
rooted!(in(*global.get_cx()) let specifier = GetRequestedModuleSpecifier(
*global.get_cx(), element.handle()
rooted!(in(*cx) let specifier = GetRequestedModuleSpecifier(
*cx, element.handle()
));
let url = ModuleTree::resolve_module_specifier(
*global.get_cx(),
*cx,
&base_url,
specifier.handle().into_handle(),
);
@ -976,7 +972,7 @@ impl ModuleOwner {
let module = global.dynamic_module_list().remove(dynamic_module_id);
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
let module_tree = module_identity.get_module_tree(&global);
// In the timing of executing this `finish_dynamic_module` function,
@ -986,7 +982,7 @@ impl ModuleOwner {
let network_error = module_tree.get_network_error().borrow().as_ref().cloned();
let existing_rethrow_error = module_tree.get_rethrow_error().borrow().as_ref().cloned();
rooted!(in(*global.get_cx()) let mut rval = UndefinedValue());
rooted!(in(*cx) let mut rval = UndefinedValue());
if network_error.is_none() && existing_rethrow_error.is_none() {
let record = module_tree
.get_record()
@ -1355,7 +1351,7 @@ fn fetch_an_import_module_script_graph(
promise: Rc<Promise>,
) -> Result<(), RethrowError> {
// Step 1.
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let specifier = unsafe { GetModuleRequestSpecifier(*cx, module_request) });
let url = ModuleTree::resolve_module_specifier(*cx, &base_url, specifier.handle().into());
@ -1428,9 +1424,9 @@ unsafe extern "C" fn HostResolveImportedModule(
}
// Step 5.
rooted!(in(*global_scope.get_cx()) let specifier = GetModuleRequestSpecifier(cx, specifier));
rooted!(in(*GlobalScope::get_cx()) let specifier = GetModuleRequestSpecifier(cx, specifier));
let url = ModuleTree::resolve_module_specifier(
*global_scope.get_cx(),
*GlobalScope::get_cx(),
&base_url,
specifier.handle().into(),
);

View file

@ -297,7 +297,7 @@ unsafe extern "C" fn promise_rejection_tracker(
global.dom_manipulation_task_source().queue(
task!(rejection_handled_event: move || {
let target = target.root();
let cx = target.global().get_cx();
let cx = GlobalScope::get_cx();
let root_promise = trusted_promise.root();
rooted!(in(*cx) let mut reason = UndefinedValue());
@ -324,7 +324,7 @@ unsafe extern "C" fn promise_rejection_tracker(
#[allow(unsafe_code, unrooted_must_root)]
/// https://html.spec.whatwg.org/multipage/#notify-about-rejected-promises
pub fn notify_about_rejected_promises(global: &GlobalScope) {
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
unsafe {
// Step 2.
if global.get_uncaught_rejections().borrow().len() > 0 {
@ -350,7 +350,7 @@ pub fn notify_about_rejected_promises(global: &GlobalScope) {
global.dom_manipulation_task_source().queue(
task!(unhandled_rejection_event: move || {
let target = target.root();
let cx = target.global().get_cx();
let cx = GlobalScope::get_cx();
for promise in uncaught_rejections {
let promise = promise.root();

View file

@ -1473,6 +1473,12 @@ impl ScriptThread {
let mut mouse_move_event_index = None;
let mut animation_ticks = HashSet::new();
loop {
let pipeline_id = self.message_to_pipeline(&event);
let _realm = pipeline_id.map(|id| {
let global = self.documents.borrow().find_global(id);
global.map(|global| enter_realm(&*global))
});
// https://html.spec.whatwg.org/multipage/#event-loop-processing-model step 7
match event {
// This has to be handled before the ResizeMsg below,
@ -1592,6 +1598,11 @@ impl ScriptThread {
let category = self.categorize_msg(&msg);
let pipeline_id = self.message_to_pipeline(&msg);
let _realm = pipeline_id.and_then(|id| {
let global = self.documents.borrow().find_global(id);
global.map(|global| enter_realm(&*global))
});
if self.closing.load(Ordering::SeqCst) {
// If we've received the closed signal from the BHM, only handle exit messages.
match msg {
@ -1638,6 +1649,7 @@ impl ScriptThread {
// https://html.spec.whatwg.org/multipage/#the-end step 6
let mut docs = self.docs_with_no_blocking_loads.borrow_mut();
for document in docs.iter() {
let _realm = enter_realm(&**document);
document.maybe_queue_document_completion();
}
docs.clear();
@ -1656,6 +1668,8 @@ impl ScriptThread {
}
let window = document.window();
let _realm = enter_realm(&*document);
window
.upcast::<GlobalScope>()
.perform_a_dom_garbage_collection_checkpoint();
@ -1684,6 +1698,7 @@ impl ScriptThread {
}
for (_, document) in self.documents.borrow().iter() {
let _realm = enter_realm(&*document);
document.animations().send_pending_events(document.window());
}
}
@ -1756,7 +1771,9 @@ impl ScriptThread {
MixedMessage::FromConstellation(ref inner_msg) => match *inner_msg {
StopDelayingLoadEventsMode(id) => Some(id),
NavigationResponse(id, _) => Some(id),
AttachLayout(ref new_layout_info) => Some(new_layout_info.new_pipeline_id),
AttachLayout(ref new_layout_info) => new_layout_info
.parent_info
.or(Some(new_layout_info.new_pipeline_id)),
Resize(id, ..) => Some(id),
ResizeInactive(id, ..) => Some(id),
UnloadDocument(id) => Some(id),
@ -1786,7 +1803,7 @@ impl ScriptThread {
DispatchStorageEvent(id, ..) => Some(id),
ReportCSSError(id, ..) => Some(id),
Reload(id, ..) => Some(id),
PaintMetric(..) => None,
PaintMetric(id, ..) => Some(id),
ExitFullScreen(id, ..) => Some(id),
MediaSessionAction(..) => None,
SetWebGPUPort(..) => None,
@ -2070,7 +2087,13 @@ impl ScriptThread {
fn handle_msg_from_script(&self, msg: MainThreadScriptMsg) {
match msg {
MainThreadScriptMsg::Common(CommonScriptMsg::Task(_, task, _, _)) => task.run_box(),
MainThreadScriptMsg::Common(CommonScriptMsg::Task(_, task, pipeline_id, _)) => {
let _realm = pipeline_id.and_then(|id| {
let global = self.documents.borrow().find_global(id);
global.map(|global| enter_realm(&*global))
});
task.run_box()
},
MainThreadScriptMsg::Common(CommonScriptMsg::CollectReports(chan)) => {
self.collect_reports(chan)
},
@ -3277,6 +3300,8 @@ impl ScriptThread {
incomplete.inherited_secure_context,
);
let _realm = enter_realm(&*window);
// Initialize the browsing context for the window.
let window_proxy = self.local_window_proxy(
&window,
@ -3460,6 +3485,8 @@ impl ScriptThread {
);
}
let _realm = enter_realm(&*window);
// Assuming all CompositionEvent are generated by user interactions.
ScriptThread::set_user_interacting(true);
match event {
@ -3697,7 +3724,7 @@ impl ScriptThread {
// Script source is ready to be evaluated (11.)
let _ac = enter_realm(global_scope);
rooted!(in(*global_scope.get_cx()) let mut jsval = UndefinedValue());
rooted!(in(*GlobalScope::get_cx()) let mut jsval = UndefinedValue());
global_scope.evaluate_js_on_global_with_result(
&script_source,
jsval.handle_mut(),
@ -3708,7 +3735,7 @@ impl ScriptThread {
load_data.js_eval_result = if jsval.get().is_string() {
unsafe {
let strval = DOMString::from_jsval(
*global_scope.get_cx(),
*GlobalScope::get_cx(),
jsval.handle(),
StringificationBehavior::Empty,
);
@ -3978,7 +4005,7 @@ impl ScriptThread {
.documents
.borrow()
.iter()
.map(|(_id, document)| document.global())
.map(|(_id, document)| DomRoot::from_ref(document.window().upcast()))
.collect();
self.microtask_queue.checkpoint(

View file

@ -540,7 +540,7 @@ impl JsTimerTask {
match self.callback {
InternalTimerCallback::StringTimerCallback(ref code_str) => {
let global = this.global();
let cx = global.get_cx();
let cx = GlobalScope::get_cx();
rooted!(in(*cx) let mut rval = UndefinedValue());
// FIXME(cybai): Use base url properly by saving private reference for timers (#27260)
global.evaluate_js_on_global_with_result(