aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2019-06-26 18:51:14 -0400
committerGitHub <noreply@github.com>2019-06-26 18:51:14 -0400
commit57205318c5f76fead08e6410512bad86c6d04739 (patch)
treeaec57e35501e04290e25f2b006dcbc1547d33315 /components/script
parentd170f43b53c840b5f6a1f657968092c096a171e9 (diff)
parent63714c90fb5bbad86f28fc188120b2ecfd3337ab (diff)
downloadservo-57205318c5f76fead08e6410512bad86c6d04739.tar.gz
servo-57205318c5f76fead08e6410512bad86c6d04739.zip
Auto merge of #23587 - jdm:smup67, r=asajeffrey
Upgrade to SpiderMonkey 67 <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23587) <!-- Reviewable:end -->
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/audiobuffer.rs4
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py23
-rw-r--r--components/script/dom/bindings/conversions.rs74
-rw-r--r--components/script/dom/bindings/error.rs6
-rw-r--r--components/script/dom/bindings/htmlconstructor.rs4
-rw-r--r--components/script/dom/bindings/proxyhandler.rs34
-rw-r--r--components/script/dom/bindings/structuredclone.rs4
-rw-r--r--components/script/dom/bindings/trace.rs4
-rw-r--r--components/script/dom/bindings/utils.rs17
-rw-r--r--components/script/dom/customelementregistry.rs4
-rw-r--r--components/script/dom/globalscope.rs53
-rw-r--r--components/script/dom/promise.rs2
-rw-r--r--components/script/dom/windowproxy.rs10
-rw-r--r--components/script/dom/workerglobalscope.rs2
-rw-r--r--components/script/microtask.rs24
-rw-r--r--components/script/script_runtime.rs84
-rw-r--r--components/script/script_thread.rs32
17 files changed, 250 insertions, 131 deletions
diff --git a/components/script/dom/audiobuffer.rs b/components/script/dom/audiobuffer.rs
index f36e28ad089..be31e56b3e9 100644
--- a/components/script/dom/audiobuffer.rs
+++ b/components/script/dom/audiobuffer.rs
@@ -15,7 +15,7 @@ use crate::dom::window::Window;
use dom_struct::dom_struct;
use js::jsapi::JS_GetArrayBufferViewBuffer;
use js::jsapi::{Heap, JSAutoRealm, JSContext, JSObject};
-use js::rust::wrappers::JS_DetachArrayBuffer;
+use js::rust::wrappers::DetachArrayBuffer;
use js::rust::CustomAutoRooterGuard;
use js::typedarray::{CreateWith, Float32Array};
use servo_media::audio::buffer_source_node::AudioBuffer as ServoMediaAudioBuffer;
@@ -180,7 +180,7 @@ impl AudioBuffer {
JS_GetArrayBufferViewBuffer(cx, channel.handle(), &mut is_shared));
// This buffer is always created unshared
debug_assert!(!is_shared);
- let _ = JS_DetachArrayBuffer(cx, view_buffer.handle());
+ let _ = DetachArrayBuffer(cx, view_buffer.handle());
data
} else {
return None;
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index d365537e464..dcbdea765d4 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -466,7 +466,7 @@ class CGMethodCall(CGThing):
# Check for vanilla JS objects
# XXXbz Do we need to worry about security wrappers?
- pickFirstSignature("%s.get().is_object() && !is_platform_object(%s.get().to_object())" %
+ pickFirstSignature("%s.get().is_object() && !is_platform_object(%s.get().to_object(), cx)" %
(distinguishingArg, distinguishingArg),
lambda s: (s[1][distinguishingIndex].type.isCallback() or
s[1][distinguishingIndex].type.isCallbackInterface() or
@@ -798,7 +798,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
{ // Scope for our JSAutoRealm.
rooted!(in(cx) let globalObj = CurrentGlobalOrNull(cx));
- let promiseGlobal = GlobalScope::from_object_maybe_wrapped(globalObj.handle().get());
+ let promiseGlobal = GlobalScope::from_object_maybe_wrapped(globalObj.handle().get(), cx);
rooted!(in(cx) let mut valueToResolve = $${val}.get());
if !JS_WrapValue(cx, valueToResolve.handle_mut()) {
@@ -866,7 +866,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
templateBody = fill(
"""
- match ${function}($${val}) {
+ match ${function}($${val}, cx) {
Ok(val) => val,
Err(()) => {
$*{failureCode}
@@ -2158,8 +2158,8 @@ class CGDOMJSClass(CGThing):
static CLASS_OPS: js::jsapi::JSClassOps = js::jsapi::JSClassOps {
addProperty: None,
delProperty: None,
- enumerate: %(enumerateHook)s,
- newEnumerate: None,
+ enumerate: None,
+ newEnumerate: %(enumerateHook)s,
resolve: %(resolveHook)s,
mayResolve: None,
finalize: Some(%(finalizeHook)s),
@@ -3223,7 +3223,6 @@ let traps = ProxyTraps {
set: None,
call: None,
construct: None,
- getPropertyDescriptor: Some(get_property_descriptor),
hasOwn: Some(hasOwn),
getOwnEnumerablePropertyKeys: Some(%(getOwnEnumerablePropertyKeys)s),
nativeCall: None,
@@ -4980,10 +4979,6 @@ class CGProxyUnwrap(CGAbstractMethod):
def definition_body(self):
return CGGeneric("""\
-/*if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
- obj = js::UnwrapObject(obj);
-}*/
-//MOZ_ASSERT(IsProxy(obj));
let mut slot = UndefinedValue();
GetProxyReservedSlot(obj.get(), 0, &mut slot);
let box_ = slot.to_private() as *const %s;
@@ -5430,7 +5425,7 @@ class CGAbstractClassHook(CGAbstractExternMethod):
def definition_body_prologue(self):
return CGGeneric("""
-let this = native_from_object::<%s>(obj).unwrap();
+let this = native_from_object_static::<%s>(obj).unwrap();
""" % self.descriptor.concreteType)
def definition_body(self):
@@ -5530,7 +5525,7 @@ let global = DomRoot::downcast::<dom::types::%s>(global).unwrap();
// The new_target might be a cross-compartment wrapper. Get the underlying object
// so we can do the spec's object-identity checks.
-rooted!(in(cx) let new_target = UnwrapObject(args.new_target().to_object(), 1));
+rooted!(in(cx) let new_target = UnwrapObjectDynamic(args.new_target().to_object(), cx, 1));
if new_target.is_null() {
throw_dom_exception(cx, global.upcast::<GlobalScope>(), Error::Type("new.target is null".to_owned()));
return false;
@@ -5877,7 +5872,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'js::glue::RUST_JSID_IS_STRING',
'js::glue::RUST_SYMBOL_TO_JSID',
'js::glue::int_to_jsid',
- 'js::glue::UnwrapObject',
+ 'js::glue::UnwrapObjectDynamic',
'js::panic::maybe_resume_unwind',
'js::panic::wrap_panic',
'js::rust::GCMethods',
@@ -5959,6 +5954,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'crate::dom::bindings::conversions::is_array_like',
'crate::dom::bindings::conversions::native_from_handlevalue',
'crate::dom::bindings::conversions::native_from_object',
+ 'crate::dom::bindings::conversions::native_from_object_static',
'crate::dom::bindings::conversions::private_from_object',
'crate::dom::bindings::conversions::root_from_handleobject',
'crate::dom::bindings::conversions::root_from_handlevalue',
@@ -5979,7 +5975,6 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'crate::dom::bindings::proxyhandler::ensure_expando_object',
'crate::dom::bindings::proxyhandler::fill_property_descriptor',
'crate::dom::bindings::proxyhandler::get_expando_object',
- 'crate::dom::bindings::proxyhandler::get_property_descriptor',
'crate::dom::bindings::mozmap::MozMap',
'std::ptr::NonNull',
'crate::dom::bindings::num::Finite',
diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs
index 0776d39fdcb..161354479b6 100644
--- a/components/script/dom/bindings/conversions.rs
+++ b/components/script/dom/bindings/conversions.rs
@@ -46,7 +46,7 @@ pub use js::conversions::{ConversionResult, FromJSValConvertible, ToJSValConvert
use js::error::throw_type_error;
use js::glue::GetProxyReservedSlot;
use js::glue::JS_GetReservedSlot;
-use js::glue::{IsWrapper, UnwrapObject};
+use js::glue::{IsWrapper, UnwrapObjectDynamic};
use js::glue::{RUST_JSID_IS_INT, RUST_JSID_TO_INT};
use js::glue::{RUST_JSID_IS_STRING, RUST_JSID_TO_STRING};
use js::jsapi::{Heap, JSContext, JSObject, JSString};
@@ -113,11 +113,11 @@ impl<T: DomObject + IDLInterface> FromJSValConvertible for DomRoot<T> {
type Config = ();
unsafe fn from_jsval(
- _cx: *mut JSContext,
+ cx: *mut JSContext,
value: HandleValue,
_config: Self::Config,
) -> Result<ConversionResult<DomRoot<T>>, ()> {
- Ok(match root_from_handlevalue(value) {
+ Ok(match root_from_handlevalue(value, cx) {
Ok(result) => ConversionResult::Success(result),
Err(()) => ConversionResult::Failure("value is not an object".into()),
})
@@ -411,6 +411,7 @@ pub unsafe fn get_dom_class(obj: *mut JSObject) -> Result<&'static DOMClass, ()>
#[inline]
pub unsafe fn private_from_proto_check<F>(
mut obj: *mut JSObject,
+ cx: *mut JSContext,
proto_check: F,
) -> Result<*const libc::c_void, ()>
where
@@ -419,7 +420,7 @@ where
let dom_class = get_dom_class(obj).or_else(|_| {
if IsWrapper(obj) {
trace!("found wrapper");
- obj = UnwrapObject(obj, /* stopAtWindowProxy = */ 0);
+ obj = UnwrapObjectDynamic(obj, cx, /* stopAtWindowProxy = */ 0);
if obj.is_null() {
trace!("unwrapping security wrapper failed");
Err(())
@@ -443,12 +444,57 @@ where
}
}
+/// Get a `*const libc::c_void` for the given DOM object, unless it is a DOM
+/// wrapper, and checking if the object is of the correct type.
+///
+/// Returns Err(()) if `obj` is a wrapper or if the object is not an object
+/// for a DOM object of the given type (as defined by the proto_id and proto_depth).
+#[inline]
+pub unsafe fn private_from_proto_check_static<F>(
+ obj: *mut JSObject,
+ proto_check: F,
+) -> Result<*const libc::c_void, ()>
+where
+ F: Fn(&'static DOMClass) -> bool,
+{
+ let dom_class = get_dom_class(obj).map_err(|_| ())?;
+ if proto_check(dom_class) {
+ trace!("good prototype");
+ Ok(private_from_object(obj))
+ } else {
+ trace!("bad prototype");
+ Err(())
+ }
+}
+
/// Get a `*const T` for a DOM object accessible from a `JSObject`.
-pub fn native_from_object<T>(obj: *mut JSObject) -> Result<*const T, ()>
+pub fn native_from_object<T>(obj: *mut JSObject, cx: *mut JSContext) -> Result<*const T, ()>
+where
+ T: DomObject + IDLInterface,
+{
+ unsafe { private_from_proto_check(obj, cx, T::derives).map(|ptr| ptr as *const T) }
+}
+
+/// Get a `*const T` for a DOM object accessible from a `JSObject`, where the DOM object
+/// is guaranteed not to be a wrapper.
+pub fn native_from_object_static<T>(obj: *mut JSObject) -> Result<*const T, ()>
+where
+ T: DomObject + IDLInterface,
+{
+ unsafe { private_from_proto_check_static(obj, T::derives).map(|ptr| ptr as *const T) }
+}
+
+/// Get a `DomRoot<T>` for the given DOM object, unwrapping any wrapper
+/// around it first, and checking if the object is of the correct type.
+///
+/// Returns Err(()) if `obj` is an opaque security wrapper or if the object is
+/// not a reflector for a DOM object of the given type (as defined by the
+/// proto_id and proto_depth).
+pub fn root_from_object<T>(obj: *mut JSObject, cx: *mut JSContext) -> Result<DomRoot<T>, ()>
where
T: DomObject + IDLInterface,
{
- unsafe { private_from_proto_check(obj, T::derives).map(|ptr| ptr as *const T) }
+ native_from_object(obj, cx).map(|ptr| unsafe { DomRoot::from_ref(&*ptr) })
}
/// Get a `DomRoot<T>` for the given DOM object, unwrapping any wrapper
@@ -457,43 +503,43 @@ where
/// Returns Err(()) if `obj` is an opaque security wrapper or if the object is
/// not a reflector for a DOM object of the given type (as defined by the
/// proto_id and proto_depth).
-pub fn root_from_object<T>(obj: *mut JSObject) -> Result<DomRoot<T>, ()>
+pub fn root_from_object_static<T>(obj: *mut JSObject) -> Result<DomRoot<T>, ()>
where
T: DomObject + IDLInterface,
{
- native_from_object(obj).map(|ptr| unsafe { DomRoot::from_ref(&*ptr) })
+ native_from_object_static(obj).map(|ptr| unsafe { DomRoot::from_ref(&*ptr) })
}
/// Get a `*const T` for a DOM object accessible from a `HandleValue`.
/// Caller is responsible for throwing a JS exception if needed in case of error.
-pub fn native_from_handlevalue<T>(v: HandleValue) -> Result<*const T, ()>
+pub fn native_from_handlevalue<T>(v: HandleValue, cx: *mut JSContext) -> Result<*const T, ()>
where
T: DomObject + IDLInterface,
{
if !v.get().is_object() {
return Err(());
}
- native_from_object(v.get().to_object())
+ native_from_object(v.get().to_object(), cx)
}
/// Get a `DomRoot<T>` for a DOM object accessible from a `HandleValue`.
/// Caller is responsible for throwing a JS exception if needed in case of error.
-pub fn root_from_handlevalue<T>(v: HandleValue) -> Result<DomRoot<T>, ()>
+pub fn root_from_handlevalue<T>(v: HandleValue, cx: *mut JSContext) -> Result<DomRoot<T>, ()>
where
T: DomObject + IDLInterface,
{
if !v.get().is_object() {
return Err(());
}
- root_from_object(v.get().to_object())
+ root_from_object(v.get().to_object(), cx)
}
/// Get a `DomRoot<T>` for a DOM object accessible from a `HandleObject`.
-pub fn root_from_handleobject<T>(obj: HandleObject) -> Result<DomRoot<T>, ()>
+pub fn root_from_handleobject<T>(obj: HandleObject, cx: *mut JSContext) -> Result<DomRoot<T>, ()>
where
T: DomObject + IDLInterface,
{
- root_from_object(obj.get())
+ root_from_object(obj.get(), cx)
}
impl<T: DomObject> ToJSValConvertible for DomRoot<T> {
diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs
index fdce3f01065..da460ad94b6 100644
--- a/components/script/dom/bindings/error.rs
+++ b/components/script/dom/bindings/error.rs
@@ -207,8 +207,8 @@ impl ErrorInfo {
})
}
- fn from_dom_exception(object: HandleObject) -> Option<ErrorInfo> {
- let exception = match root_from_object::<DOMException>(object.get()) {
+ fn from_dom_exception(object: HandleObject, cx: *mut JSContext) -> Option<ErrorInfo> {
+ let exception = match root_from_object::<DOMException>(object.get(), cx) {
Ok(exception) => exception,
Err(_) => return None,
};
@@ -242,7 +242,7 @@ pub unsafe fn report_pending_exception(cx: *mut JSContext, dispatch_event: bool)
let error_info = if value.is_object() {
rooted!(in(cx) let object = value.to_object());
ErrorInfo::from_native_error(cx, object.handle())
- .or_else(|| ErrorInfo::from_dom_exception(object.handle()))
+ .or_else(|| ErrorInfo::from_dom_exception(object.handle(), cx))
.unwrap_or_else(|| ErrorInfo {
message: format!("uncaught exception: unknown (can't convert to string)"),
filename: String::new(),
diff --git a/components/script/dom/bindings/htmlconstructor.rs b/components/script/dom/bindings/htmlconstructor.rs
index d984c687c16..7e122ef6e29 100644
--- a/components/script/dom/bindings/htmlconstructor.rs
+++ b/components/script/dom/bindings/htmlconstructor.rs
@@ -79,7 +79,7 @@ use crate::dom::window::Window;
use crate::script_thread::ScriptThread;
use html5ever::interface::QualName;
use html5ever::LocalName;
-use js::glue::UnwrapObject;
+use js::glue::UnwrapObjectStatic;
use js::jsapi::{CallArgs, CurrentGlobalOrNull};
use js::jsapi::{JSAutoRealm, JSContext, JSObject};
use js::rust::HandleObject;
@@ -109,7 +109,7 @@ where
},
};
- rooted!(in(window.get_cx()) let callee = UnwrapObject(call_args.callee(), 1));
+ rooted!(in(window.get_cx()) let callee = UnwrapObjectStatic(call_args.callee()));
if callee.is_null() {
return Err(Error::Security);
}
diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs
index 112bec1b60e..a4b5f418cd2 100644
--- a/components/script/dom/bindings/proxyhandler.rs
+++ b/components/script/dom/bindings/proxyhandler.rs
@@ -8,17 +8,13 @@
use crate::dom::bindings::conversions::is_dom_proxy;
use crate::dom::bindings::utils::delete_property_by_id;
-use js::glue::InvokeGetOwnPropertyDescriptor;
-use js::glue::{GetProxyHandler, GetProxyHandlerFamily};
+use js::glue::GetProxyHandlerFamily;
use js::glue::{GetProxyPrivate, SetProxyPrivate};
-use js::jsapi::GetObjectProto;
use js::jsapi::GetStaticPrototype;
use js::jsapi::Handle as RawHandle;
use js::jsapi::HandleId as RawHandleId;
use js::jsapi::HandleObject as RawHandleObject;
use js::jsapi::JS_DefinePropertyById;
-use js::jsapi::JS_GetPropertyDescriptorById;
-use js::jsapi::MutableHandle as RawMutableHandle;
use js::jsapi::MutableHandleObject as RawMutableHandleObject;
use js::jsapi::ObjectOpResult;
use js::jsapi::{DOMProxyShadowsResult, JSContext, JSObject, PropertyDescriptor};
@@ -62,34 +58,6 @@ pub unsafe fn init() {
SetDOMProxyInformation(GetProxyHandlerFamily(), Some(shadow_check_callback));
}
-/// Invoke the [[GetOwnProperty]] trap (`getOwnPropertyDescriptor`) on `proxy`,
-/// with argument `id` and return the result, if it is not `undefined`.
-/// Otherwise, walk along the prototype chain to find a property with that
-/// name.
-pub unsafe extern "C" fn get_property_descriptor(
- cx: *mut JSContext,
- proxy: RawHandleObject,
- id: RawHandleId,
- desc: RawMutableHandle<PropertyDescriptor>,
-) -> bool {
- let handler = GetProxyHandler(proxy.get());
- if !InvokeGetOwnPropertyDescriptor(handler, cx, proxy, id, desc) {
- return false;
- }
- if !desc.obj.is_null() {
- return true;
- }
-
- rooted!(in(cx) let mut proto = ptr::null_mut::<JSObject>());
- if !GetObjectProto(cx, proxy, proto.handle_mut().into()) {
- // FIXME(#11868) Should assign to desc.obj, desc.get() is a copy.
- desc.get().obj = ptr::null_mut();
- return true;
- }
-
- JS_GetPropertyDescriptorById(cx, proto.handle().into(), id, desc)
-}
-
/// Defines an expando on the given `proxy`.
pub unsafe extern "C" fn define_property(
cx: *mut JSContext,
diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs
index c411dece76b..f6f63abbaf7 100644
--- a/components/script/dom/bindings/structuredclone.rs
+++ b/components/script/dom/bindings/structuredclone.rs
@@ -176,12 +176,12 @@ unsafe extern "C" fn read_callback(
}
unsafe extern "C" fn write_callback(
- _cx: *mut JSContext,
+ cx: *mut JSContext,
w: *mut JSStructuredCloneWriter,
obj: RawHandleObject,
_closure: *mut raw::c_void,
) -> bool {
- if let Ok(blob) = root_from_handleobject::<Blob>(Handle::from_raw(obj)) {
+ if let Ok(blob) = root_from_handleobject::<Blob>(Handle::from_raw(obj), cx) {
return write_blob(blob, w).is_ok();
}
return false;
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 023917c172c..b690687d034 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -68,7 +68,7 @@ use hyper::StatusCode;
use indexmap::IndexMap;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use js::glue::{CallObjectTracer, CallValueTracer};
-use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind};
+use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, JobQueue, TraceKind};
use js::jsval::JSVal;
use js::rust::{GCMethods, Handle, Runtime};
use js::typedarray::TypedArray;
@@ -162,6 +162,8 @@ unsafe_no_jsmanaged_fields!(Duration);
unsafe_no_jsmanaged_fields!(TexDataType, TexFormat);
+unsafe_no_jsmanaged_fields!(*mut JobQueue);
+
/// Trace a `JSVal`.
pub fn trace_jsval(tracer: *mut JSTracer, description: &str, val: &Heap<JSVal>) {
unsafe {
diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs
index 621a95c6ef9..54ff2a35eab 100644
--- a/components/script/dom/bindings/utils.rs
+++ b/components/script/dom/bindings/utils.rs
@@ -15,12 +15,12 @@ use crate::dom::bindings::trace::trace_object;
use crate::dom::windowproxy;
use js::glue::{CallJitGetterOp, CallJitMethodOp, CallJitSetterOp, IsWrapper};
use js::glue::{GetCrossCompartmentWrapper, JS_GetReservedSlot, WrapperNew};
-use js::glue::{UnwrapObject, RUST_JSID_TO_INT, RUST_JSID_TO_STRING};
+use js::glue::{UnwrapObjectDynamic, RUST_JSID_TO_INT, RUST_JSID_TO_STRING};
use js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO, RUST_JSID_IS_INT, RUST_JSID_IS_STRING};
use js::jsapi::HandleId as RawHandleId;
use js::jsapi::HandleObject as RawHandleObject;
use js::jsapi::MutableHandleObject as RawMutableHandleObject;
-use js::jsapi::{CallArgs, DOMCallbacks, GetNonCCWObjectGlobal};
+use js::jsapi::{AutoIdVector, CallArgs, DOMCallbacks, GetNonCCWObjectGlobal};
use js::jsapi::{Heap, JSAutoRealm, JSContext};
use js::jsapi::{JSJitInfo, JSObject, JSTracer, JSWrapObjectCallbacks};
use js::jsapi::{JS_EnumerateStandardClasses, JS_GetLatin1StringCharsAndLength};
@@ -210,7 +210,7 @@ pub unsafe fn find_enum_value<'a, T>(
/// Returns wether `obj` is a platform object
/// <https://heycam.github.io/webidl/#dfn-platform-object>
-pub fn is_platform_object(obj: *mut JSObject) -> bool {
+pub fn is_platform_object(obj: *mut JSObject, cx: *mut JSContext) -> bool {
unsafe {
// Fast-path the common case
let mut clasp = get_object_class(obj);
@@ -219,7 +219,7 @@ pub fn is_platform_object(obj: *mut JSObject) -> bool {
}
// Now for simplicity check for security wrappers before anything else
if IsWrapper(obj) {
- let unwrapped_obj = UnwrapObject(obj, /* stopAtWindowProxy = */ 0);
+ let unwrapped_obj = UnwrapObjectDynamic(obj, cx, /* stopAtWindowProxy = */ 0);
if unwrapped_obj.is_null() {
return false;
}
@@ -342,7 +342,12 @@ pub unsafe fn trace_global(tracer: *mut JSTracer, obj: *mut JSObject) {
}
/// Enumerate lazy properties of a global object.
-pub unsafe extern "C" fn enumerate_global(cx: *mut JSContext, obj: RawHandleObject) -> bool {
+pub unsafe extern "C" fn enumerate_global(
+ cx: *mut JSContext,
+ obj: RawHandleObject,
+ _props: *mut AutoIdVector,
+ _enumerable_only: bool,
+) -> bool {
assert!(JS_IsGlobalObject(obj.get()));
if !JS_EnumerateStandardClasses(cx, obj) {
return false;
@@ -463,7 +468,7 @@ unsafe fn generic_call(
let depth = (*info).depth;
let proto_check =
|class: &'static DOMClass| class.interface_chain[depth as usize] as u16 == proto_id;
- let this = match private_from_proto_check(obj.get(), proto_check) {
+ let this = match private_from_proto_check(obj.get(), cx, proto_check) {
Ok(val) => val,
Err(()) => {
if is_lenient {
diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs
index 2613f722d41..913397cf780 100644
--- a/components/script/dom/customelementregistry.rs
+++ b/components/script/dom/customelementregistry.rs
@@ -35,7 +35,7 @@ use crate::script_thread::ScriptThread;
use dom_struct::dom_struct;
use html5ever::{LocalName, Namespace, Prefix};
use js::conversions::ToJSValConvertible;
-use js::glue::UnwrapObject;
+use js::glue::UnwrapObjectStatic;
use js::jsapi::{HandleValueArray, Heap, IsCallable, IsConstructor};
use js::jsapi::{JSAutoRealm, JSContext, JSObject};
use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue};
@@ -259,7 +259,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
// Step 1
// We must unwrap the constructor as all wrappers are constructable if they are callable.
- rooted!(in(cx) let unwrapped_constructor = unsafe { UnwrapObject(constructor.get(), 1) });
+ rooted!(in(cx) let unwrapped_constructor = unsafe { UnwrapObjectStatic(constructor.get()) });
if unwrapped_constructor.is_null() {
// We do not have permission to access the unwrapped constructor.
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index 1330021035a..7bd0e28be6a 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -6,7 +6,7 @@ use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::EventSourceBinding::EventSourceBinding::EventSourceMethods;
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use crate::dom::bindings::codegen::Bindings::WorkerGlobalScopeBinding::WorkerGlobalScopeMethods;
-use crate::dom::bindings::conversions::root_from_object;
+use crate::dom::bindings::conversions::{root_from_object, root_from_object_static};
use crate::dom::bindings::error::{report_pending_exception, ErrorInfo};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::DomObject;
@@ -41,7 +41,7 @@ use crate::timers::{OneshotTimers, TimerCallback};
use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId};
use dom_struct::dom_struct;
use ipc_channel::ipc::IpcSender;
-use js::glue::{IsWrapper, UnwrapObject};
+use js::glue::{IsWrapper, UnwrapObjectDynamic};
use js::jsapi::JSObject;
use js::jsapi::{CurrentGlobalOrNull, GetNonCCWObjectGlobal};
use js::jsapi::{HandleObject, Heap};
@@ -233,22 +233,25 @@ impl GlobalScope {
pub unsafe fn from_object(obj: *mut JSObject) -> DomRoot<Self> {
assert!(!obj.is_null());
let global = GetNonCCWObjectGlobal(obj);
- global_scope_from_global(global)
+ global_scope_from_global_static(global)
}
/// Returns the global scope for the given JSContext
#[allow(unsafe_code)]
pub unsafe fn from_context(cx: *mut JSContext) -> DomRoot<Self> {
let global = CurrentGlobalOrNull(cx);
- global_scope_from_global(global)
+ global_scope_from_global(global, cx)
}
/// Returns the global object of the realm that the given JS object
/// was created in, after unwrapping any wrappers.
#[allow(unsafe_code)]
- pub unsafe fn from_object_maybe_wrapped(mut obj: *mut JSObject) -> DomRoot<Self> {
+ pub unsafe fn from_object_maybe_wrapped(
+ mut obj: *mut JSObject,
+ cx: *mut JSContext,
+ ) -> DomRoot<Self> {
if IsWrapper(obj) {
- obj = UnwrapObject(obj, /* stopAtWindowProxy = */ 0);
+ obj = UnwrapObjectDynamic(obj, cx, /* stopAtWindowProxy = */ 0);
assert!(!obj.is_null());
}
GlobalScope::from_object(obj)
@@ -663,16 +666,23 @@ impl GlobalScope {
}
/// Perform a microtask checkpoint.
+ #[allow(unsafe_code)]
pub fn perform_a_microtask_checkpoint(&self) {
- self.microtask_queue.checkpoint(
- |_| Some(DomRoot::from_ref(self)),
- vec![DomRoot::from_ref(self)],
- );
+ unsafe {
+ self.microtask_queue.checkpoint(
+ self.get_cx(),
+ |_| Some(DomRoot::from_ref(self)),
+ vec![DomRoot::from_ref(self)],
+ );
+ }
}
/// Enqueue a microtask for subsequent execution.
+ #[allow(unsafe_code)]
pub fn enqueue_microtask(&self, job: Microtask) {
- self.microtask_queue.enqueue(job);
+ unsafe {
+ self.microtask_queue.enqueue(job, self.get_cx());
+ }
}
/// Create a new sender/receiver pair that can be used to implement an on-demand
@@ -749,7 +759,7 @@ impl GlobalScope {
if global.is_null() {
None
} else {
- Some(global_scope_from_global(global))
+ Some(global_scope_from_global(global, cx))
}
}
}
@@ -797,12 +807,27 @@ fn timestamp_in_ms(time: Timespec) -> u64 {
/// Returns the Rust global scope from a JS global object.
#[allow(unsafe_code)]
-unsafe fn global_scope_from_global(global: *mut JSObject) -> DomRoot<GlobalScope> {
+unsafe fn global_scope_from_global(
+ global: *mut JSObject,
+ cx: *mut JSContext,
+) -> DomRoot<GlobalScope> {
+ assert!(!global.is_null());
+ let clasp = get_object_class(global);
+ assert_ne!(
+ ((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)),
+ 0
+ );
+ root_from_object(global, cx).unwrap()
+}
+
+/// Returns the Rust global scope from a JS global object.
+#[allow(unsafe_code)]
+unsafe fn global_scope_from_global_static(global: *mut JSObject) -> DomRoot<GlobalScope> {
assert!(!global.is_null());
let clasp = get_object_class(global);
assert_ne!(
((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)),
0
);
- root_from_object(global).unwrap()
+ root_from_object_static(global).unwrap()
}
diff --git a/components/script/dom/promise.rs b/components/script/dom/promise.rs
index 152828b8110..9fcb728ae0f 100644
--- a/components/script/dom/promise.rs
+++ b/components/script/dom/promise.rs
@@ -286,7 +286,7 @@ unsafe extern "C" fn native_handler_callback(
rooted!(in(cx) let v = *GetFunctionNativeReserved(args.callee(), SLOT_NATIVEHANDLER));
assert!(v.get().is_object());
- let handler = root_from_object::<PromiseNativeHandler>(v.to_object())
+ let handler = root_from_object::<PromiseNativeHandler>(v.to_object(), cx)
.expect("unexpected value for native handler in promise native handler callback");
rooted!(in(cx) let v = *GetFunctionNativeReserved(args.callee(), SLOT_NATIVEHANDLER_TASK));
diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs
index 7b53656e918..69a73a1547e 100644
--- a/components/script/dom/windowproxy.rs
+++ b/components/script/dom/windowproxy.rs
@@ -6,7 +6,7 @@ use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::conversions::{root_from_handleobject, ToJSValConvertible};
use crate::dom::bindings::error::{throw_dom_exception, Error};
use crate::dom::bindings::inheritance::Castable;
-use crate::dom::bindings::proxyhandler::{fill_property_descriptor, get_property_descriptor};
+use crate::dom::bindings::proxyhandler::fill_property_descriptor;
use crate::dom::bindings::reflector::{DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
@@ -712,7 +712,7 @@ unsafe fn GetSubframeWindowProxy(
let mut slot = UndefinedValue();
GetProxyPrivate(*proxy, &mut slot);
rooted!(in(cx) let target = slot.to_object());
- if let Ok(win) = root_from_handleobject::<Window>(target.handle()) {
+ if let Ok(win) = root_from_handleobject::<Window>(target.handle(), cx) {
let browsing_context_id = win.window_proxy().browsing_context_id();
let (result_sender, result_receiver) = ipc::channel().unwrap();
@@ -730,7 +730,9 @@ unsafe fn GetSubframeWindowProxy(
.and_then(|maybe_bcid| maybe_bcid)
.and_then(ScriptThread::find_window_proxy)
.map(|proxy| (proxy, (JSPROP_ENUMERATE | JSPROP_READONLY) as u32));
- } else if let Ok(win) = root_from_handleobject::<DissimilarOriginWindow>(target.handle()) {
+ } else if let Ok(win) =
+ root_from_handleobject::<DissimilarOriginWindow>(target.handle(), cx)
+ {
let browsing_context_id = win.window_proxy().browsing_context_id();
let (result_sender, result_receiver) = ipc::channel().unwrap();
@@ -912,7 +914,6 @@ static PROXY_HANDLER: ProxyTraps = ProxyTraps {
set: Some(set),
call: None,
construct: None,
- getPropertyDescriptor: Some(get_property_descriptor),
hasOwn: None,
getOwnEnumerablePropertyKeys: None,
nativeCall: None,
@@ -1049,7 +1050,6 @@ static XORIGIN_PROXY_HANDLER: ProxyTraps = ProxyTraps {
set: Some(set_xorigin),
call: None,
construct: None,
- getPropertyDescriptor: Some(getOwnPropertyDescriptor_xorigin),
hasOwn: Some(has_xorigin),
getOwnEnumerablePropertyKeys: None,
nativeCall: None,
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index 572bebff905..87722f2358e 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -131,7 +131,7 @@ impl WorkerGlobalScope {
init.resource_threads,
timer_event_chan,
MutableOrigin::new(init.origin),
- Default::default(),
+ runtime.microtask_queue.clone(),
),
worker_id: init.worker_id,
worker_name,
diff --git a/components/script/microtask.rs b/components/script/microtask.rs
index a523c1c83dc..db420e20eaa 100644
--- a/components/script/microtask.rs
+++ b/components/script/microtask.rs
@@ -16,6 +16,7 @@ use crate::dom::htmlmediaelement::MediaElementMicrotask;
use crate::dom::mutationobserver::MutationObserver;
use crate::script_runtime::notify_about_rejected_promises;
use crate::script_thread::ScriptThread;
+use js::jsapi::{JSContext, JobQueueIsEmpty, JobQueueMayNotBeEmpty};
use msg::constellation_msg::PipelineId;
use std::cell::Cell;
use std::mem;
@@ -54,14 +55,21 @@ pub struct EnqueuedPromiseCallback {
impl MicrotaskQueue {
/// Add a new microtask to this queue. It will be invoked as part of the next
/// microtask checkpoint.
- pub fn enqueue(&self, job: Microtask) {
+ #[allow(unsafe_code)]
+ pub unsafe fn enqueue(&self, job: Microtask, cx: *mut JSContext) {
self.microtask_queue.borrow_mut().push(job);
+ JobQueueMayNotBeEmpty(cx);
}
/// <https://html.spec.whatwg.org/multipage/#perform-a-microtask-checkpoint>
/// Perform a microtask checkpoint, executing all queued microtasks until the queue is empty.
- pub fn checkpoint<F>(&self, target_provider: F, globalscopes: Vec<DomRoot<GlobalScope>>)
- where
+ #[allow(unsafe_code)]
+ pub unsafe fn checkpoint<F>(
+ &self,
+ cx: *mut JSContext,
+ target_provider: F,
+ globalscopes: Vec<DomRoot<GlobalScope>>,
+ ) where
F: Fn(PipelineId) -> Option<DomRoot<GlobalScope>>,
{
if self.performing_a_microtask_checkpoint.get() {
@@ -76,7 +84,11 @@ impl MicrotaskQueue {
rooted_vec!(let mut pending_queue);
mem::swap(&mut *pending_queue, &mut *self.microtask_queue.borrow_mut());
- for job in pending_queue.iter() {
+ for (idx, job) in pending_queue.iter().enumerate() {
+ if idx == pending_queue.len() - 1 && self.microtask_queue.borrow().is_empty() {
+ JobQueueIsEmpty(cx);
+ }
+
match *job {
Microtask::Promise(ref job) => {
if let Some(target) = target_provider(job.pipeline) {
@@ -109,4 +121,8 @@ impl MicrotaskQueue {
// Step 5
self.performing_a_microtask_checkpoint.set(false);
}
+
+ pub fn empty(&self) -> bool {
+ self.microtask_queue.borrow().is_empty()
+ }
}
diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs
index ce64f363594..b5119949193 100644
--- a/components/script/script_runtime.rs
+++ b/components/script/script_runtime.rs
@@ -21,15 +21,14 @@ use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::promise::Promise;
use crate::dom::promiserejectionevent::PromiseRejectionEvent;
-use crate::microtask::{EnqueuedPromiseCallback, Microtask};
+use crate::microtask::{EnqueuedPromiseCallback, Microtask, MicrotaskQueue};
use crate::script_thread::trace_thread;
use crate::task::TaskBox;
use crate::task_source::{TaskSource, TaskSourceName};
-use js::glue::CollectServoSizes;
-use js::glue::SetBuildId;
+use js::glue::{CollectServoSizes, CreateJobQueue, DeleteJobQueue, JobQueueTraps, SetBuildId};
use js::jsapi::ContextOptionsRef;
use js::jsapi::{BuildIdCharVector, DisableIncrementalGC, GCDescription, GCProgress};
-use js::jsapi::{HandleObject, Heap};
+use js::jsapi::{HandleObject, Heap, JobQueue};
use js::jsapi::{JSContext, JSTracer, SetDOMCallbacks, SetGCSliceCallback};
use js::jsapi::{JSGCInvocationKind, JSGCStatus, JS_AddExtraGCRootsTracer, JS_SetGCCallback};
use js::jsapi::{JSGCMode, JSGCParamKey, JS_SetGCParameter, JS_SetGlobalJitCompilerOption};
@@ -37,9 +36,7 @@ use js::jsapi::{
JSJitCompilerOption, JS_SetOffthreadIonCompilationEnabled, JS_SetParallelParsingEnabled,
};
use js::jsapi::{JSObject, PromiseRejectionHandlingState, SetPreserveWrapperCallback};
-use js::jsapi::{
- SetEnqueuePromiseJobCallback, SetProcessBuildIdOp, SetPromiseRejectionTrackerCallback,
-};
+use js::jsapi::{SetJobQueue, SetProcessBuildIdOp, SetPromiseRejectionTrackerCallback};
use js::panic::wrap_panic;
use js::rust::wrappers::{GetPromiseIsHandled, GetPromiseResult};
use js::rust::Handle;
@@ -60,10 +57,17 @@ use std::os;
use std::os::raw::c_void;
use std::panic::AssertUnwindSafe;
use std::ptr;
+use std::rc::Rc;
use std::sync::Arc;
use style::thread_state::{self, ThreadState};
use time::{now, Tm};
+static JOB_QUEUE_TRAPS: JobQueueTraps = JobQueueTraps {
+ getIncumbentGlobal: Some(get_incumbent_global),
+ enqueuePromiseJob: Some(enqueue_promise_job),
+ empty: Some(empty),
+};
+
/// Common messages used to control the event loops in both the script and the worker
pub enum CommonScriptMsg {
/// Requests that the script thread measure its memory usage. The results are sent back via the
@@ -134,25 +138,52 @@ pub trait ScriptPort {
fn recv(&self) -> Result<CommonScriptMsg, ()>;
}
+#[allow(unsafe_code)]
+unsafe extern "C" fn get_incumbent_global(_: *const c_void, _: *mut JSContext) -> *mut JSObject {
+ wrap_panic(
+ AssertUnwindSafe(|| {
+ GlobalScope::incumbent()
+ .map(|g| g.reflector().get_jsobject().get())
+ .unwrap_or(ptr::null_mut())
+ }),
+ ptr::null_mut(),
+ )
+}
+
+#[allow(unsafe_code)]
+unsafe extern "C" fn empty(extra: *const c_void) -> bool {
+ wrap_panic(
+ AssertUnwindSafe(|| {
+ let microtask_queue = &*(extra as *const MicrotaskQueue);
+ microtask_queue.empty()
+ }),
+ false,
+ )
+}
+
/// SM callback for promise job resolution. Adds a promise callback to the current
/// global's microtask queue.
#[allow(unsafe_code)]
-unsafe extern "C" fn enqueue_job(
+unsafe extern "C" fn enqueue_promise_job(
+ extra: *const c_void,
cx: *mut JSContext,
_promise: HandleObject,
job: HandleObject,
_allocation_site: HandleObject,
incumbent_global: HandleObject,
- _data: *mut c_void,
) -> bool {
wrap_panic(
AssertUnwindSafe(|| {
+ let microtask_queue = &*(extra as *const MicrotaskQueue);
let global = GlobalScope::from_object(incumbent_global.get());
let pipeline = global.pipeline_id();
- global.enqueue_microtask(Microtask::Promise(EnqueuedPromiseCallback {
- callback: PromiseJobCallback::new(cx, job.get()),
- pipeline: pipeline,
- }));
+ microtask_queue.enqueue(
+ Microtask::Promise(EnqueuedPromiseCallback {
+ callback: PromiseJobCallback::new(cx, job.get()),
+ pipeline,
+ }),
+ cx,
+ );
true
}),
false,
@@ -309,10 +340,18 @@ pub fn notify_about_rejected_promises(global: &GlobalScope) {
}
#[derive(JSTraceable)]
-pub struct Runtime(RustRuntime);
+pub struct Runtime {
+ rt: RustRuntime,
+ pub microtask_queue: Rc<MicrotaskQueue>,
+ job_queue: *mut JobQueue,
+}
impl Drop for Runtime {
+ #[allow(unsafe_code)]
fn drop(&mut self) {
+ unsafe {
+ DeleteJobQueue(self.job_queue);
+ }
THREAD_ACTIVE.with(|t| {
LiveDOMReferences::destruct();
t.set(false);
@@ -323,7 +362,7 @@ impl Drop for Runtime {
impl Deref for Runtime {
type Target = RustRuntime;
fn deref(&self) -> &RustRuntime {
- &self.0
+ &self.rt
}
}
@@ -370,7 +409,12 @@ unsafe fn new_rt_and_cx_with_parent(parent: Option<ParentRuntime>) -> Runtime {
// Pre barriers aren't working correctly at the moment
DisableIncrementalGC(cx);
- SetEnqueuePromiseJobCallback(cx, Some(enqueue_job), ptr::null_mut());
+ let microtask_queue = Rc::new(MicrotaskQueue::default());
+ let job_queue = CreateJobQueue(
+ &JOB_QUEUE_TRAPS,
+ &*microtask_queue as *const _ as *const c_void,
+ );
+ SetJobQueue(cx, job_queue);
SetPromiseRejectionTrackerCallback(cx, Some(promise_rejection_tracker), ptr::null_mut());
set_gc_zeal_options(cx);
@@ -407,7 +451,7 @@ unsafe fn new_rt_and_cx_with_parent(parent: Option<ParentRuntime>) -> Runtime {
);
JS_SetGlobalJitCompilerOption(
cx,
- JSJitCompilerOption::JSJITCOMPILER_ION_WARMUP_TRIGGER,
+ JSJitCompilerOption::JSJITCOMPILER_ION_NORMAL_WARMUP_TRIGGER,
if pref!(js.ion.unsafe_eager_compilation.enabled) {
0
} else {
@@ -511,7 +555,11 @@ unsafe fn new_rt_and_cx_with_parent(parent: Option<ParentRuntime>) -> Runtime {
JS_SetGCParameter(cx, JSGCParamKey::JSGC_MAX_EMPTY_CHUNK_COUNT, val as u32);
}
- Runtime(runtime)
+ Runtime {
+ rt: runtime,
+ microtask_queue,
+ job_queue,
+ }
}
fn in_range<T: PartialOrd + Copy>(val: T, min: T, max: T) -> Option<T> {
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index b81ff6d5fc7..a0c8ad3ab43 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -845,11 +845,16 @@ impl ScriptThread {
}
// https://html.spec.whatwg.org/multipage/#await-a-stable-state
+ #[allow(unsafe_code)]
pub fn await_stable_state(task: Microtask) {
SCRIPT_THREAD_ROOT.with(|root| {
if let Some(script_thread) = root.get() {
- let script_thread = unsafe { &*script_thread };
- script_thread.microtask_queue.enqueue(task);
+ unsafe {
+ let script_thread = &*script_thread;
+ script_thread
+ .microtask_queue
+ .enqueue(task, script_thread.get_cx());
+ }
}
});
}
@@ -1123,6 +1128,8 @@ impl ScriptThread {
devtools_port: devtools_port,
devtools_sender: ipc_devtools_sender,
+ microtask_queue: runtime.microtask_queue.clone(),
+
js_runtime: Rc::new(runtime),
topmost_mouse_over_target: MutNullableDom::new(Default::default()),
closed_pipelines: DomRefCell::new(HashSet::new()),
@@ -1133,8 +1140,6 @@ impl ScriptThread {
content_process_shutdown_chan: state.content_process_shutdown_chan,
- microtask_queue: Default::default(),
-
mutation_observer_microtask_queued: Default::default(),
mutation_observers: Default::default(),
@@ -3544,13 +3549,17 @@ impl ScriptThread {
}
}
+ #[allow(unsafe_code)]
pub fn enqueue_microtask(job: Microtask) {
- SCRIPT_THREAD_ROOT.with(|root| {
- let script_thread = unsafe { &*root.get().unwrap() };
- script_thread.microtask_queue.enqueue(job);
+ SCRIPT_THREAD_ROOT.with(|root| unsafe {
+ let script_thread = &*root.get().unwrap();
+ script_thread
+ .microtask_queue
+ .enqueue(job, script_thread.get_cx());
});
}
+ #[allow(unsafe_code)]
fn perform_a_microtask_checkpoint(&self) {
let globals = self
.documents
@@ -3559,8 +3568,13 @@ impl ScriptThread {
.map(|(_id, document)| document.global())
.collect();
- self.microtask_queue
- .checkpoint(|id| self.documents.borrow().find_global(id), globals)
+ unsafe {
+ self.microtask_queue.checkpoint(
+ self.get_cx(),
+ |id| self.documents.borrow().find_global(id),
+ globals,
+ )
+ }
}
}