mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Auto merge of #23872 - marmeladema:issue-20377, r=jdm
Make DOM bindings methods not take raw JSContext pointers. Part 2. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [ ] `./mach build -d` does not report any errors - [ ] `./mach test-tidy` does not report any errors - [ ] These changes fix #20377 <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- 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/23872) <!-- Reviewable:end -->
This commit is contained in:
commit
da559d47b9
28 changed files with 543 additions and 558 deletions
|
@ -50,7 +50,7 @@ fn main() {
|
|||
let mut phf = File::create(&phf).unwrap();
|
||||
write!(
|
||||
&mut phf,
|
||||
"pub static MAP: phf::Map<&'static [u8], unsafe fn(JSContext, HandleObject)> = "
|
||||
"pub static MAP: phf::Map<&'static [u8], fn(JSContext, HandleObject)> = "
|
||||
)
|
||||
.unwrap();
|
||||
map.build(&mut phf).unwrap();
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
use crate::dom::bindings::reflector::DomObject;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use js::jsapi::{GetCurrentRealmOrNull, JSAutoRealm, JSContext};
|
||||
use crate::script_runtime::JSContext;
|
||||
use js::jsapi::{GetCurrentRealmOrNull, JSAutoRealm};
|
||||
|
||||
pub struct AlreadyInCompartment(());
|
||||
|
||||
|
@ -17,9 +18,9 @@ impl AlreadyInCompartment {
|
|||
AlreadyInCompartment(())
|
||||
}
|
||||
|
||||
pub fn assert_for_cx(cx: *mut JSContext) -> AlreadyInCompartment {
|
||||
pub fn assert_for_cx(cx: JSContext) -> AlreadyInCompartment {
|
||||
unsafe {
|
||||
assert!(!GetCurrentRealmOrNull(cx).is_null());
|
||||
assert!(!GetCurrentRealmOrNull(*cx).is_null());
|
||||
}
|
||||
AlreadyInCompartment(())
|
||||
}
|
||||
|
|
|
@ -13,10 +13,10 @@ use crate::dom::bindings::num::Finite;
|
|||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::window::Window;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use dom_struct::dom_struct;
|
||||
use js::jsapi::JS_GetArrayBufferViewBuffer;
|
||||
use js::jsapi::{Heap, JSContext, JSObject};
|
||||
use js::jsapi::{Heap, JSObject};
|
||||
use js::rust::wrappers::DetachArrayBuffer;
|
||||
use js::rust::CustomAutoRooterGuard;
|
||||
use js::typedarray::{CreateWith, Float32Array};
|
||||
|
@ -127,7 +127,7 @@ impl AudioBuffer {
|
|||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn restore_js_channel_data(&self, cx: *mut JSContext) -> bool {
|
||||
fn restore_js_channel_data(&self, cx: JSContext) -> bool {
|
||||
let _ac = enter_realm(&*self);
|
||||
for (i, channel) in self.js_channels.borrow_mut().iter().enumerate() {
|
||||
if !channel.get().is_null() {
|
||||
|
@ -135,20 +135,22 @@ impl AudioBuffer {
|
|||
continue;
|
||||
}
|
||||
|
||||
rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>());
|
||||
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
|
||||
if let Some(ref shared_channels) = *self.shared_channels.borrow() {
|
||||
// Step 4. of
|
||||
// https://webaudio.github.io/web-audio-api/#acquire-the-content
|
||||
// "Attach ArrayBuffers containing copies of the data to the AudioBuffer,
|
||||
// to be returned by the next call to getChannelData()".
|
||||
if Float32Array::create(
|
||||
cx,
|
||||
CreateWith::Slice(&shared_channels.buffers[i]),
|
||||
array.handle_mut(),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return false;
|
||||
unsafe {
|
||||
if Float32Array::create(
|
||||
*cx,
|
||||
CreateWith::Slice(&shared_channels.buffers[i]),
|
||||
array.handle_mut(),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
channel.set(array.get());
|
||||
|
@ -231,16 +233,15 @@ impl AudioBufferMethods for AudioBuffer {
|
|||
|
||||
// https://webaudio.github.io/web-audio-api/#dom-audiobuffer-getchanneldata
|
||||
#[allow(unsafe_code)]
|
||||
fn GetChannelData(&self, cx: SafeJSContext, channel: u32) -> Fallible<NonNull<JSObject>> {
|
||||
fn GetChannelData(&self, cx: JSContext, channel: u32) -> Fallible<NonNull<JSObject>> {
|
||||
if channel >= self.number_of_channels {
|
||||
return Err(Error::IndexSize);
|
||||
}
|
||||
|
||||
if !self.restore_js_channel_data(cx) {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
unsafe {
|
||||
if !self.restore_js_channel_data(*cx) {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
|
||||
Ok(NonNull::new_unchecked(
|
||||
self.js_channels.borrow()[channel as usize].get(),
|
||||
))
|
||||
|
@ -307,7 +308,7 @@ impl AudioBufferMethods for AudioBuffer {
|
|||
}
|
||||
|
||||
let cx = self.global().get_cx();
|
||||
if unsafe { !self.restore_js_channel_data(*cx) } {
|
||||
if !self.restore_js_channel_data(cx) {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@ use crate::dom::bindings::settings_stack::{AutoEntryScript, AutoIncumbentScript}
|
|||
use crate::dom::bindings::utils::AsCCharPtrPtr;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::window::Window;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use js::jsapi::Heap;
|
||||
use js::jsapi::JSAutoRealm;
|
||||
use js::jsapi::{AddRawValueRoot, IsCallable, JSContext, JSObject};
|
||||
use js::jsapi::{AddRawValueRoot, IsCallable, JSObject};
|
||||
use js::jsapi::{EnterRealm, LeaveRealm, Realm, RemoveRawValueRoot};
|
||||
use js::jsval::{JSVal, ObjectValue, UndefinedValue};
|
||||
use js::rust::wrappers::{JS_GetProperty, JS_WrapObject};
|
||||
|
@ -82,11 +82,11 @@ impl CallbackObject {
|
|||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn init(&mut self, cx: *mut JSContext, callback: *mut JSObject) {
|
||||
unsafe fn init(&mut self, cx: JSContext, callback: *mut JSObject) {
|
||||
self.callback.set(callback);
|
||||
self.permanent_js_root.set(ObjectValue(callback));
|
||||
assert!(AddRawValueRoot(
|
||||
cx,
|
||||
*cx,
|
||||
self.permanent_js_root.get_unsafe(),
|
||||
b"CallbackObject::root\n".as_c_char_ptr()
|
||||
));
|
||||
|
@ -113,7 +113,7 @@ impl PartialEq for CallbackObject {
|
|||
/// callback interface types.
|
||||
pub trait CallbackContainer {
|
||||
/// Create a new CallbackContainer object for the given `JSObject`.
|
||||
unsafe fn new(cx: SafeJSContext, callback: *mut JSObject) -> Rc<Self>;
|
||||
unsafe fn new(cx: JSContext, callback: *mut JSObject) -> Rc<Self>;
|
||||
/// Returns the underlying `CallbackObject`.
|
||||
fn callback_holder(&self) -> &CallbackObject;
|
||||
/// Returns the underlying `JSObject`.
|
||||
|
@ -152,8 +152,8 @@ impl CallbackFunction {
|
|||
|
||||
/// Initialize the callback function with a value.
|
||||
/// Should be called once this object is done moving.
|
||||
pub unsafe fn init(&mut self, cx: SafeJSContext, callback: *mut JSObject) {
|
||||
self.object.init(*cx, callback);
|
||||
pub unsafe fn init(&mut self, cx: JSContext, callback: *mut JSObject) {
|
||||
self.object.init(cx, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,18 +179,18 @@ impl CallbackInterface {
|
|||
|
||||
/// Initialize the callback function with a value.
|
||||
/// Should be called once this object is done moving.
|
||||
pub unsafe fn init(&mut self, cx: SafeJSContext, callback: *mut JSObject) {
|
||||
self.object.init(*cx, callback);
|
||||
pub unsafe fn init(&mut self, cx: JSContext, callback: *mut JSObject) {
|
||||
self.object.init(cx, callback);
|
||||
}
|
||||
|
||||
/// Returns the property with the given `name`, if it is a callable object,
|
||||
/// or an error otherwise.
|
||||
pub fn get_callable_property(&self, cx: *mut JSContext, name: &str) -> Fallible<JSVal> {
|
||||
rooted!(in(cx) let mut callable = UndefinedValue());
|
||||
rooted!(in(cx) let obj = self.callback_holder().get());
|
||||
pub fn get_callable_property(&self, cx: JSContext, name: &str) -> Fallible<JSVal> {
|
||||
rooted!(in(*cx) let mut callable = UndefinedValue());
|
||||
rooted!(in(*cx) let obj = self.callback_holder().get());
|
||||
unsafe {
|
||||
let c_name = CString::new(name).unwrap();
|
||||
if !JS_GetProperty(cx, obj.handle(), c_name.as_ptr(), callable.handle_mut()) {
|
||||
if !JS_GetProperty(*cx, obj.handle(), c_name.as_ptr(), callable.handle_mut()) {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
|
||||
|
@ -206,16 +206,12 @@ impl CallbackInterface {
|
|||
}
|
||||
|
||||
/// Wraps the reflector for `p` into the compartment of `cx`.
|
||||
pub fn wrap_call_this_object<T: DomObject>(
|
||||
cx: *mut JSContext,
|
||||
p: &T,
|
||||
mut rval: MutableHandleObject,
|
||||
) {
|
||||
pub fn wrap_call_this_object<T: DomObject>(cx: JSContext, p: &T, mut rval: MutableHandleObject) {
|
||||
rval.set(p.reflector().get_jsobject().get());
|
||||
assert!(!rval.get().is_null());
|
||||
|
||||
unsafe {
|
||||
if !JS_WrapObject(cx, rval) {
|
||||
if !JS_WrapObject(*cx, rval) {
|
||||
rval.set(ptr::null_mut());
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +224,7 @@ pub struct CallSetup {
|
|||
/// (possibly wrapped) callback object.
|
||||
exception_global: DomRoot<GlobalScope>,
|
||||
/// The `JSContext` used for the call.
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
/// The compartment we were in before the call.
|
||||
old_realm: *mut Realm,
|
||||
/// The exception handling used for the call.
|
||||
|
@ -255,7 +251,7 @@ impl CallSetup {
|
|||
let ais = callback.incumbent().map(AutoIncumbentScript::new);
|
||||
CallSetup {
|
||||
exception_global: global,
|
||||
cx: *cx,
|
||||
cx: cx,
|
||||
old_realm: unsafe { EnterRealm(*cx, callback.callback()) },
|
||||
handling: handling,
|
||||
entry_script: Some(aes),
|
||||
|
@ -264,7 +260,7 @@ impl CallSetup {
|
|||
}
|
||||
|
||||
/// Returns the `JSContext` used for the call.
|
||||
pub fn get_context(&self) -> *mut JSContext {
|
||||
pub fn get_context(&self) -> JSContext {
|
||||
self.cx
|
||||
}
|
||||
}
|
||||
|
@ -272,13 +268,13 @@ impl CallSetup {
|
|||
impl Drop for CallSetup {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
LeaveRealm(self.cx, self.old_realm);
|
||||
LeaveRealm(*self.cx, self.old_realm);
|
||||
if self.handling == ExceptionHandling::Report {
|
||||
let _ac = JSAutoRealm::new(
|
||||
self.cx,
|
||||
*self.cx,
|
||||
self.exception_global.reflector().get_jsobject().get(),
|
||||
);
|
||||
report_pending_exception(self.cx, true);
|
||||
report_pending_exception(*self.cx, true);
|
||||
}
|
||||
drop(self.incumbent_script.take());
|
||||
drop(self.entry_script.take().unwrap());
|
||||
|
|
|
@ -810,10 +810,10 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||
if !JS_WrapValue(*cx, valueToResolve.handle_mut()) {
|
||||
$*{exceptionCode}
|
||||
}
|
||||
match Promise::new_resolved(&promiseGlobal, *cx, valueToResolve.handle()) {
|
||||
match Promise::new_resolved(&promiseGlobal, cx, valueToResolve.handle()) {
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
throw_dom_exception(*cx, &promiseGlobal, error);
|
||||
throw_dom_exception(cx, &promiseGlobal, error);
|
||||
$*{exceptionCode}
|
||||
}
|
||||
}
|
||||
|
@ -2588,8 +2588,7 @@ class CGConstructorEnabled(CGAbstractMethod):
|
|||
CGAbstractMethod.__init__(self, descriptor,
|
||||
'ConstructorEnabled', 'bool',
|
||||
[Argument("SafeJSContext", "aCx"),
|
||||
Argument("HandleObject", "aObj")],
|
||||
unsafe=True)
|
||||
Argument("HandleObject", "aObj")])
|
||||
|
||||
def definition_body(self):
|
||||
conditions = []
|
||||
|
@ -2651,8 +2650,8 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties):
|
|||
"""
|
||||
unforgeables = []
|
||||
|
||||
defineUnforgeableAttrs = "define_guarded_properties(*cx, unforgeable_holder.handle(), %s, global);"
|
||||
defineUnforgeableMethods = "define_guarded_methods(*cx, unforgeable_holder.handle(), %s, global);"
|
||||
defineUnforgeableAttrs = "define_guarded_properties(cx, unforgeable_holder.handle(), %s, global);"
|
||||
defineUnforgeableMethods = "define_guarded_methods(cx, unforgeable_holder.handle(), %s, global);"
|
||||
|
||||
unforgeableMembers = [
|
||||
(defineUnforgeableAttrs, properties.unforgeable_attrs),
|
||||
|
@ -2762,7 +2761,7 @@ class CGWrapGlobalMethod(CGAbstractMethod):
|
|||
("define_guarded_methods", self.properties.methods),
|
||||
("define_guarded_constants", self.properties.consts)
|
||||
]
|
||||
members = ["%s(*cx, obj.handle(), %s, obj.handle());" % (function, array.variableName())
|
||||
members = ["%s(cx, obj.handle(), %s, obj.handle());" % (function, array.variableName())
|
||||
for (function, array) in pairs if array.length() > 0]
|
||||
values["members"] = "\n".join(members)
|
||||
|
||||
|
@ -2772,7 +2771,7 @@ let _rt = RootedTraceable::new(&*raw);
|
|||
|
||||
rooted!(in(*cx) let mut obj = ptr::null_mut::<JSObject>());
|
||||
create_global_object(
|
||||
*cx,
|
||||
cx,
|
||||
&Class.base,
|
||||
raw as *const libc::c_void,
|
||||
_trace,
|
||||
|
@ -2911,7 +2910,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
rooted!(in(*cx) let proto = %(proto)s);
|
||||
assert!(!proto.is_null());
|
||||
rooted!(in(*cx) let mut namespace = ptr::null_mut::<JSObject>());
|
||||
create_namespace_object(*cx, global, proto.handle(), &NAMESPACE_OBJECT_CLASS,
|
||||
create_namespace_object(cx, global, proto.handle(), &NAMESPACE_OBJECT_CLASS,
|
||||
%(methods)s, %(name)s, namespace.handle_mut());
|
||||
assert!(!namespace.is_null());
|
||||
assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null());
|
||||
|
@ -2924,7 +2923,7 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null());
|
|||
assert not self.descriptor.interface.ctor() and self.descriptor.interface.hasConstants()
|
||||
return CGGeneric("""\
|
||||
rooted!(in(*cx) let mut interface = ptr::null_mut::<JSObject>());
|
||||
create_callback_interface_object(*cx, global, sConstants, %(name)s, interface.handle_mut());
|
||||
create_callback_interface_object(cx, global, sConstants, %(name)s, interface.handle_mut());
|
||||
assert!(!interface.is_null());
|
||||
assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null());
|
||||
(*cache)[PrototypeList::Constructor::%(id)s as usize] = interface.get();
|
||||
|
@ -2976,7 +2975,7 @@ assert!(!prototype_proto.is_null());""" % getPrototypeProto)]
|
|||
|
||||
code.append(CGGeneric("""
|
||||
rooted!(in(*cx) let mut prototype = ptr::null_mut::<JSObject>());
|
||||
create_interface_prototype_object(*cx,
|
||||
create_interface_prototype_object(cx,
|
||||
global.into(),
|
||||
prototype_proto.handle().into(),
|
||||
&PrototypeClass,
|
||||
|
@ -3011,7 +3010,7 @@ assert!((*cache)[PrototypeList::ID::%(id)s as usize].is_null());
|
|||
assert!(!interface_proto.is_null());
|
||||
|
||||
rooted!(in(*cx) let mut interface = ptr::null_mut::<JSObject>());
|
||||
create_noncallback_interface_object(*cx,
|
||||
create_noncallback_interface_object(cx,
|
||||
global.into(),
|
||||
interface_proto.handle(),
|
||||
&INTERFACE_OBJECT_CLASS,
|
||||
|
@ -3093,7 +3092,7 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null());
|
|||
specs.append(CGGeneric("(%s as ConstructorClassHook, %s, %d)" % (hook, name, length)))
|
||||
values = CGIndenter(CGList(specs, "\n"), 4)
|
||||
code.append(CGWrapper(values, pre="%s = [\n" % decl, post="\n];"))
|
||||
code.append(CGGeneric("create_named_constructors(*cx, global, &named_constructors, prototype.handle());"))
|
||||
code.append(CGGeneric("create_named_constructors(cx, global, &named_constructors, prototype.handle());"))
|
||||
|
||||
if self.descriptor.hasUnforgeableMembers:
|
||||
# We want to use the same JSClass and prototype as the object we'll
|
||||
|
@ -3137,23 +3136,25 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
|
|||
Argument('HandleObject', 'global'),
|
||||
Argument('MutableHandleObject', 'mut rval')]
|
||||
CGAbstractMethod.__init__(self, descriptor, name,
|
||||
'void', args, pub=pub, unsafe=True)
|
||||
'void', args, pub=pub)
|
||||
self.id = idPrefix + "::" + MakeNativeName(self.descriptor.name)
|
||||
|
||||
def definition_body(self):
|
||||
return CGGeneric("""
|
||||
assert!(((*get_object_class(global.get())).flags & JSCLASS_DOM_GLOBAL) != 0);
|
||||
unsafe {
|
||||
assert!(((*get_object_class(global.get())).flags & JSCLASS_DOM_GLOBAL) != 0);
|
||||
|
||||
/* Check to see whether the interface objects are already installed */
|
||||
let proto_or_iface_array = get_proto_or_iface_array(global.get());
|
||||
rval.set((*proto_or_iface_array)[%(id)s as usize]);
|
||||
if !rval.get().is_null() {
|
||||
return;
|
||||
/* Check to see whether the interface objects are already installed */
|
||||
let proto_or_iface_array = get_proto_or_iface_array(global.get());
|
||||
rval.set((*proto_or_iface_array)[%(id)s as usize]);
|
||||
if !rval.get().is_null() {
|
||||
return;
|
||||
}
|
||||
|
||||
CreateInterfaceObjects(cx, global, proto_or_iface_array);
|
||||
rval.set((*proto_or_iface_array)[%(id)s as usize]);
|
||||
assert!(!rval.get().is_null());
|
||||
}
|
||||
|
||||
CreateInterfaceObjects(cx, global, proto_or_iface_array);
|
||||
rval.set((*proto_or_iface_array)[%(id)s as usize]);
|
||||
assert!(!rval.get().is_null());
|
||||
""" % {"id": self.id})
|
||||
|
||||
|
||||
|
@ -3274,7 +3275,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
|||
Argument('HandleObject', 'global'),
|
||||
]
|
||||
CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface',
|
||||
'void', args, pub=True, unsafe=True)
|
||||
'void', args, pub=True)
|
||||
|
||||
def define(self):
|
||||
return CGAbstractMethod.define(self)
|
||||
|
@ -3335,7 +3336,7 @@ class CGCallGenerator(CGThing):
|
|||
if "cx" not in argsPre and needsCx:
|
||||
args.prepend(CGGeneric("cx"))
|
||||
if nativeMethodName in descriptor.inCompartmentMethods:
|
||||
args.append(CGGeneric("InCompartment::in_compartment(&AlreadyInCompartment::assert_for_cx(*cx))"))
|
||||
args.append(CGGeneric("InCompartment::in_compartment(&AlreadyInCompartment::assert_for_cx(cx))"))
|
||||
|
||||
# Build up our actual call
|
||||
self.cgRoot = CGList([], "\n")
|
||||
|
@ -3371,7 +3372,7 @@ class CGCallGenerator(CGThing):
|
|||
"let result = match result {\n"
|
||||
" Ok(result) => result,\n"
|
||||
" Err(e) => {\n"
|
||||
" throw_dom_exception(*cx, %s, e);\n"
|
||||
" throw_dom_exception(cx, %s, e);\n"
|
||||
" return%s;\n"
|
||||
" },\n"
|
||||
"};" % (glob, errorResult)))
|
||||
|
@ -5555,12 +5556,12 @@ let global = DomRoot::downcast::<dom::types::%s>(global).unwrap();
|
|||
// so we can do the spec's object-identity checks.
|
||||
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()));
|
||||
throw_dom_exception(cx, global.upcast::<GlobalScope>(), Error::Type("new.target is null".to_owned()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if args.callee() == new_target.get() {
|
||||
throw_dom_exception(*cx, global.upcast::<GlobalScope>(),
|
||||
throw_dom_exception(cx, global.upcast::<GlobalScope>(),
|
||||
Error::Type("new.target must not be the active function object".to_owned()));
|
||||
return false;
|
||||
}
|
||||
|
@ -5601,7 +5602,7 @@ let result: Result<DomRoot<%s>, Error> = html_constructor(&global, &args);
|
|||
let result = match result {
|
||||
Ok(result) => result,
|
||||
Err(e) => {
|
||||
throw_dom_exception(*cx, global.upcast::<GlobalScope>(), e);
|
||||
throw_dom_exception(cx, global.upcast::<GlobalScope>(), e);
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
@ -6355,21 +6356,23 @@ class CGDictionary(CGThing):
|
|||
return string.Template(
|
||||
"impl ${selfName} {\n"
|
||||
"${empty}\n"
|
||||
" pub unsafe fn new(cx: SafeJSContext, val: HandleValue) \n"
|
||||
" pub fn new(cx: SafeJSContext, val: HandleValue) \n"
|
||||
" -> Result<ConversionResult<${actualType}>, ()> {\n"
|
||||
" let object = if val.get().is_null_or_undefined() {\n"
|
||||
" ptr::null_mut()\n"
|
||||
" } else if val.get().is_object() {\n"
|
||||
" val.get().to_object()\n"
|
||||
" } else {\n"
|
||||
" return Ok(ConversionResult::Failure(\"Value is not an object.\".into()));\n"
|
||||
" };\n"
|
||||
" rooted!(in(*cx) let object = object);\n"
|
||||
" unsafe {\n"
|
||||
" let object = if val.get().is_null_or_undefined() {\n"
|
||||
" ptr::null_mut()\n"
|
||||
" } else if val.get().is_object() {\n"
|
||||
" val.get().to_object()\n"
|
||||
" } else {\n"
|
||||
" return Ok(ConversionResult::Failure(\"Value is not an object.\".into()));\n"
|
||||
" };\n"
|
||||
" rooted!(in(*cx) let object = object);\n"
|
||||
"${preInitial}"
|
||||
"${initParent}"
|
||||
"${initMembers}"
|
||||
"${postInitial}"
|
||||
" Ok(ConversionResult::Success(dictionary))\n"
|
||||
" Ok(ConversionResult::Success(dictionary))\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
|
@ -6391,11 +6394,11 @@ class CGDictionary(CGThing):
|
|||
"selfName": selfName,
|
||||
"actualType": actualType,
|
||||
"empty": CGIndenter(CGGeneric(self.makeEmpty()), indentLevel=4).define(),
|
||||
"initParent": CGIndenter(CGGeneric(initParent), indentLevel=12).define(),
|
||||
"initMembers": CGIndenter(memberInits, indentLevel=12).define(),
|
||||
"initParent": CGIndenter(CGGeneric(initParent), indentLevel=16).define(),
|
||||
"initMembers": CGIndenter(memberInits, indentLevel=16).define(),
|
||||
"insertMembers": CGIndenter(memberInserts, indentLevel=8).define(),
|
||||
"preInitial": CGIndenter(CGGeneric(preInitial), indentLevel=12).define(),
|
||||
"postInitial": CGIndenter(CGGeneric(postInitial), indentLevel=12).define(),
|
||||
"preInitial": CGIndenter(CGGeneric(preInitial), indentLevel=16).define(),
|
||||
"postInitial": CGIndenter(CGGeneric(postInitial), indentLevel=16).define(),
|
||||
})
|
||||
|
||||
def membersNeedTracing(self):
|
||||
|
@ -6825,8 +6828,8 @@ class CGCallback(CGClass):
|
|||
# Record the names of all the arguments, so we can use them when we call
|
||||
# the private method.
|
||||
argnames = [arg.name for arg in args]
|
||||
argnamesWithThis = ["SafeJSContext::from_ptr(s.get_context())", "thisObjJS.handle()"] + argnames
|
||||
argnamesWithoutThis = ["SafeJSContext::from_ptr(s.get_context())", "thisObjJS.handle()"] + argnames
|
||||
argnamesWithThis = ["s.get_context()", "thisObjJS.handle()"] + argnames
|
||||
argnamesWithoutThis = ["s.get_context()", "thisObjJS.handle()"] + argnames
|
||||
# Now that we've recorded the argnames for our call to our private
|
||||
# method, insert our optional argument for deciding whether the
|
||||
# CallSetup should re-throw exceptions on aRv.
|
||||
|
@ -6846,7 +6849,7 @@ class CGCallback(CGClass):
|
|||
|
||||
bodyWithThis = string.Template(
|
||||
setupCall +
|
||||
"rooted!(in(s.get_context()) let mut thisObjJS = ptr::null_mut::<JSObject>());\n"
|
||||
"rooted!(in(*s.get_context()) let mut thisObjJS = ptr::null_mut::<JSObject>());\n"
|
||||
"wrap_call_this_object(s.get_context(), thisObj, thisObjJS.handle_mut());\n"
|
||||
"if thisObjJS.is_null() {\n"
|
||||
" return Err(JSFailed);\n"
|
||||
|
@ -6857,7 +6860,7 @@ class CGCallback(CGClass):
|
|||
})
|
||||
bodyWithoutThis = string.Template(
|
||||
setupCall +
|
||||
"rooted!(in(s.get_context()) let thisObjJS = ptr::null_mut::<JSObject>());\n"
|
||||
"rooted!(in(*s.get_context()) let thisObjJS = ptr::null_mut::<JSObject>());\n"
|
||||
"unsafe { ${methodName}(${callArgs}) }").substitute({
|
||||
"callArgs": ", ".join(argnamesWithoutThis),
|
||||
"methodName": 'self.' + method.name,
|
||||
|
@ -7115,7 +7118,7 @@ class CallbackMember(CGNativeMember):
|
|||
return ""
|
||||
return (
|
||||
"CallSetup s(CallbackPreserveColor(), aRv, aExceptionHandling);\n"
|
||||
"JSContext* cx = s.get_context();\n"
|
||||
"JSContext* cx = *s.get_context();\n"
|
||||
"if (!cx) {\n"
|
||||
" return Err(JSFailed);\n"
|
||||
"}\n")
|
||||
|
@ -7216,7 +7219,7 @@ class CallbackOperationBase(CallbackMethod):
|
|||
"methodName": self.methodName
|
||||
}
|
||||
getCallableFromProp = string.Template(
|
||||
'r#try!(self.parent.get_callable_property(*cx, "${methodName}"))'
|
||||
'r#try!(self.parent.get_callable_property(cx, "${methodName}"))'
|
||||
).substitute(replacements)
|
||||
if not self.singleOperation:
|
||||
return 'rooted!(in(*cx) let callable =\n' + getCallableFromProp + ');\n'
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
|
||||
//! WebIDL constants.
|
||||
|
||||
use crate::script_runtime::JSContext;
|
||||
use js::jsapi::JSPROP_READONLY;
|
||||
use js::jsapi::{JSContext, JSPROP_ENUMERATE, JSPROP_PERMANENT};
|
||||
use js::jsapi::{JSPROP_ENUMERATE, JSPROP_PERMANENT};
|
||||
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UInt32Value};
|
||||
use js::rust::wrappers::JS_DefineProperty;
|
||||
use js::rust::HandleObject;
|
||||
|
@ -50,15 +51,17 @@ impl ConstantSpec {
|
|||
|
||||
/// Defines constants on `obj`.
|
||||
/// Fails on JSAPI failure.
|
||||
pub unsafe fn define_constants(cx: *mut JSContext, obj: HandleObject, constants: &[ConstantSpec]) {
|
||||
pub fn define_constants(cx: JSContext, obj: HandleObject, constants: &[ConstantSpec]) {
|
||||
for spec in constants {
|
||||
rooted!(in(cx) let value = spec.get_value());
|
||||
assert!(JS_DefineProperty(
|
||||
cx,
|
||||
obj,
|
||||
spec.name.as_ptr() as *const libc::c_char,
|
||||
value.handle(),
|
||||
(JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) as u32
|
||||
));
|
||||
rooted!(in(*cx) let value = spec.get_value());
|
||||
unsafe {
|
||||
assert!(JS_DefineProperty(
|
||||
*cx,
|
||||
obj,
|
||||
spec.name.as_ptr() as *const libc::c_char,
|
||||
value.handle(),
|
||||
(JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) as u32
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ use crate::dom::bindings::conversions::{
|
|||
use crate::dom::bindings::str::USVString;
|
||||
use crate::dom::domexception::{DOMErrorName, DOMException};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
#[cfg(feature = "js_backtrace")]
|
||||
use backtrace::Backtrace;
|
||||
use js::error::{throw_range_error, throw_type_error};
|
||||
|
@ -104,10 +105,10 @@ pub type Fallible<T> = Result<T, Error>;
|
|||
pub type ErrorResult = Fallible<()>;
|
||||
|
||||
/// Set a pending exception for the given `result` on `cx`.
|
||||
pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: &GlobalScope, result: Error) {
|
||||
pub fn throw_dom_exception(cx: SafeJSContext, global: &GlobalScope, result: Error) {
|
||||
#[cfg(feature = "js_backtrace")]
|
||||
{
|
||||
capture_stack!(in(cx) let stack);
|
||||
capture_stack!(in(*cx) let stack);
|
||||
let js_stack = stack.and_then(|s| s.as_string(None));
|
||||
let rust_stack = Backtrace::new();
|
||||
LAST_EXCEPTION_BACKTRACE.with(|backtrace| {
|
||||
|
@ -139,27 +140,29 @@ pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: &GlobalScope, resu
|
|||
Error::InvalidModification => DOMErrorName::InvalidModificationError,
|
||||
Error::NotReadable => DOMErrorName::NotReadableError,
|
||||
Error::Operation => DOMErrorName::OperationError,
|
||||
Error::Type(message) => {
|
||||
assert!(!JS_IsExceptionPending(cx));
|
||||
throw_type_error(cx, &message);
|
||||
Error::Type(message) => unsafe {
|
||||
assert!(!JS_IsExceptionPending(*cx));
|
||||
throw_type_error(*cx, &message);
|
||||
return;
|
||||
},
|
||||
Error::Range(message) => {
|
||||
assert!(!JS_IsExceptionPending(cx));
|
||||
throw_range_error(cx, &message);
|
||||
Error::Range(message) => unsafe {
|
||||
assert!(!JS_IsExceptionPending(*cx));
|
||||
throw_range_error(*cx, &message);
|
||||
return;
|
||||
},
|
||||
Error::JSFailed => {
|
||||
assert!(JS_IsExceptionPending(cx));
|
||||
Error::JSFailed => unsafe {
|
||||
assert!(JS_IsExceptionPending(*cx));
|
||||
return;
|
||||
},
|
||||
};
|
||||
|
||||
assert!(!JS_IsExceptionPending(cx));
|
||||
let exception = DOMException::new(global, code);
|
||||
rooted!(in(cx) let mut thrown = UndefinedValue());
|
||||
exception.to_jsval(cx, thrown.handle_mut());
|
||||
JS_SetPendingException(cx, thrown.handle());
|
||||
unsafe {
|
||||
assert!(!JS_IsExceptionPending(*cx));
|
||||
let exception = DOMException::new(global, code);
|
||||
rooted!(in(*cx) let mut thrown = UndefinedValue());
|
||||
exception.to_jsval(*cx, thrown.handle_mut());
|
||||
JS_SetPendingException(*cx, thrown.handle());
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct encapsulating information about a runtime script error.
|
||||
|
@ -310,7 +313,7 @@ impl Error {
|
|||
Error::JSFailed => (),
|
||||
_ => assert!(!JS_IsExceptionPending(cx)),
|
||||
}
|
||||
throw_dom_exception(cx, global, self);
|
||||
throw_dom_exception(SafeJSContext::from_ptr(cx), global, self);
|
||||
assert!(JS_IsExceptionPending(cx));
|
||||
assert!(JS_GetPendingException(cx, rval));
|
||||
JS_ClearPendingException(cx);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
use crate::dom::bindings::codegen::InterfaceObjectMap;
|
||||
use crate::dom::bindings::interface::is_exposed_in;
|
||||
use js::jsapi::JSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use js::rust::HandleObject;
|
||||
use servo_config::prefs;
|
||||
|
||||
|
@ -28,12 +28,7 @@ impl<T: Clone + Copy> Guard<T> {
|
|||
/// Expose the value if the condition is satisfied.
|
||||
///
|
||||
/// The passed handle is the object on which the value may be exposed.
|
||||
pub unsafe fn expose(
|
||||
&self,
|
||||
cx: *mut JSContext,
|
||||
obj: HandleObject,
|
||||
global: HandleObject,
|
||||
) -> Option<T> {
|
||||
pub fn expose(&self, cx: JSContext, obj: HandleObject, global: HandleObject) -> Option<T> {
|
||||
if self.condition.is_satisfied(cx, obj, global) {
|
||||
Some(self.value)
|
||||
} else {
|
||||
|
@ -45,7 +40,7 @@ impl<T: Clone + Copy> Guard<T> {
|
|||
/// A condition to expose things.
|
||||
pub enum Condition {
|
||||
/// The condition is satisfied if the function returns true.
|
||||
Func(unsafe fn(*mut JSContext, HandleObject) -> bool),
|
||||
Func(fn(JSContext, HandleObject) -> bool),
|
||||
/// The condition is satisfied if the preference is set.
|
||||
Pref(&'static str),
|
||||
// The condition is satisfied if the interface is exposed in the global.
|
||||
|
@ -55,12 +50,7 @@ pub enum Condition {
|
|||
}
|
||||
|
||||
impl Condition {
|
||||
unsafe fn is_satisfied(
|
||||
&self,
|
||||
cx: *mut JSContext,
|
||||
obj: HandleObject,
|
||||
global: HandleObject,
|
||||
) -> bool {
|
||||
fn is_satisfied(&self, cx: JSContext, obj: HandleObject, global: HandleObject) -> bool {
|
||||
match *self {
|
||||
Condition::Pref(name) => prefs::pref_map().get(name).as_bool().unwrap_or(false),
|
||||
Condition::Func(f) => f(cx, obj),
|
||||
|
|
|
@ -76,13 +76,13 @@ use crate::dom::customelementregistry::{ConstructionStackEntry, CustomElementSta
|
|||
use crate::dom::element::{Element, ElementCreator};
|
||||
use crate::dom::htmlelement::HTMLElement;
|
||||
use crate::dom::window::Window;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use crate::script_thread::ScriptThread;
|
||||
use html5ever::interface::QualName;
|
||||
use html5ever::LocalName;
|
||||
use js::glue::UnwrapObjectStatic;
|
||||
use js::jsapi::{CallArgs, CurrentGlobalOrNull};
|
||||
use js::jsapi::{JSAutoRealm, JSContext, JSObject};
|
||||
use js::jsapi::{JSAutoRealm, JSObject};
|
||||
use js::rust::HandleObject;
|
||||
use js::rust::MutableHandleObject;
|
||||
use std::ptr;
|
||||
|
@ -134,7 +134,7 @@ where
|
|||
// Step 5
|
||||
get_constructor_object_from_local_name(
|
||||
definition.local_name.clone(),
|
||||
*window.get_cx(),
|
||||
window.get_cx(),
|
||||
global_object.handle(),
|
||||
constructor.handle_mut(),
|
||||
);
|
||||
|
@ -196,13 +196,13 @@ where
|
|||
/// This list should only include elements marked with the [HTMLConstructor] extended attribute.
|
||||
pub fn get_constructor_object_from_local_name(
|
||||
name: LocalName,
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
global: HandleObject,
|
||||
rval: MutableHandleObject,
|
||||
) -> bool {
|
||||
macro_rules! get_constructor(
|
||||
($binding:ident) => ({
|
||||
unsafe { $binding::GetConstructorObject(SafeJSContext::from_ptr(cx), global, rval); }
|
||||
$binding::GetConstructorObject(cx, global, rval);
|
||||
true
|
||||
})
|
||||
);
|
||||
|
|
|
@ -12,6 +12,7 @@ use crate::dom::bindings::guard::Guard;
|
|||
use crate::dom::bindings::utils::{
|
||||
get_proto_or_iface_array, ProtoOrIfaceArray, DOM_PROTOTYPE_SLOT,
|
||||
};
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use js::error::throw_type_error;
|
||||
use js::glue::UncheckedUnwrapObject;
|
||||
use js::jsapi::HandleObject as RawHandleObject;
|
||||
|
@ -129,7 +130,7 @@ pub type TraceHook = unsafe extern "C" fn(trc: *mut JSTracer, obj: *mut JSObject
|
|||
|
||||
/// Create a global object with the given class.
|
||||
pub unsafe fn create_global_object(
|
||||
cx: *mut JSContext,
|
||||
cx: SafeJSContext,
|
||||
class: &'static JSClass,
|
||||
private: *const libc::c_void,
|
||||
trace: TraceHook,
|
||||
|
@ -142,7 +143,7 @@ pub unsafe fn create_global_object(
|
|||
options.creationOptions_.sharedMemoryAndAtomics_ = true;
|
||||
|
||||
rval.set(JS_NewGlobalObject(
|
||||
cx,
|
||||
*cx,
|
||||
class,
|
||||
ptr::null_mut(),
|
||||
OnNewGlobalHookOption::DontFireOnNewGlobalHook,
|
||||
|
@ -159,20 +160,22 @@ pub unsafe fn create_global_object(
|
|||
let val = PrivateValue(Box::into_raw(proto_array) as *const libc::c_void);
|
||||
JS_SetReservedSlot(rval.get(), DOM_PROTOTYPE_SLOT, &val);
|
||||
|
||||
let _ac = JSAutoRealm::new(cx, rval.get());
|
||||
JS_FireOnNewGlobalObject(cx, rval.handle());
|
||||
let _ac = JSAutoRealm::new(*cx, rval.get());
|
||||
JS_FireOnNewGlobalObject(*cx, rval.handle());
|
||||
}
|
||||
|
||||
/// Create and define the interface object of a callback interface.
|
||||
pub unsafe fn create_callback_interface_object(
|
||||
cx: *mut JSContext,
|
||||
pub fn create_callback_interface_object(
|
||||
cx: SafeJSContext,
|
||||
global: HandleObject,
|
||||
constants: &[Guard<&[ConstantSpec]>],
|
||||
name: &[u8],
|
||||
mut rval: MutableHandleObject,
|
||||
) {
|
||||
assert!(!constants.is_empty());
|
||||
rval.set(JS_NewObject(cx, ptr::null()));
|
||||
unsafe {
|
||||
rval.set(JS_NewObject(*cx, ptr::null()));
|
||||
}
|
||||
assert!(!rval.is_null());
|
||||
define_guarded_constants(cx, rval.handle(), constants, global);
|
||||
define_name(cx, rval.handle(), name);
|
||||
|
@ -180,8 +183,8 @@ pub unsafe fn create_callback_interface_object(
|
|||
}
|
||||
|
||||
/// Create the interface prototype object of a non-callback interface.
|
||||
pub unsafe fn create_interface_prototype_object(
|
||||
cx: *mut JSContext,
|
||||
pub fn create_interface_prototype_object(
|
||||
cx: SafeJSContext,
|
||||
global: HandleObject,
|
||||
proto: HandleObject,
|
||||
class: &'static JSClass,
|
||||
|
@ -203,27 +206,29 @@ pub unsafe fn create_interface_prototype_object(
|
|||
);
|
||||
|
||||
if !unscopable_names.is_empty() {
|
||||
rooted!(in(cx) let mut unscopable_obj = ptr::null_mut::<JSObject>());
|
||||
rooted!(in(*cx) let mut unscopable_obj = ptr::null_mut::<JSObject>());
|
||||
create_unscopable_object(cx, unscopable_names, unscopable_obj.handle_mut());
|
||||
unsafe {
|
||||
let unscopable_symbol = GetWellKnownSymbol(*cx, SymbolCode::unscopables);
|
||||
assert!(!unscopable_symbol.is_null());
|
||||
|
||||
let unscopable_symbol = GetWellKnownSymbol(cx, SymbolCode::unscopables);
|
||||
assert!(!unscopable_symbol.is_null());
|
||||
rooted!(in(*cx) let mut unscopable_id: jsid);
|
||||
RUST_SYMBOL_TO_JSID(unscopable_symbol, unscopable_id.handle_mut());
|
||||
|
||||
rooted!(in(cx) let mut unscopable_id: jsid);
|
||||
RUST_SYMBOL_TO_JSID(unscopable_symbol, unscopable_id.handle_mut());
|
||||
assert!(JS_DefinePropertyById5(
|
||||
cx,
|
||||
rval.handle(),
|
||||
unscopable_id.handle(),
|
||||
unscopable_obj.handle(),
|
||||
JSPROP_READONLY as u32
|
||||
))
|
||||
assert!(JS_DefinePropertyById5(
|
||||
*cx,
|
||||
rval.handle(),
|
||||
unscopable_id.handle(),
|
||||
unscopable_obj.handle(),
|
||||
JSPROP_READONLY as u32
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create and define the interface object of a non-callback interface.
|
||||
pub unsafe fn create_noncallback_interface_object(
|
||||
cx: *mut JSContext,
|
||||
pub fn create_noncallback_interface_object(
|
||||
cx: SafeJSContext,
|
||||
global: HandleObject,
|
||||
proto: HandleObject,
|
||||
class: &'static NonCallbackInterfaceObjectClass,
|
||||
|
@ -245,54 +250,58 @@ pub unsafe fn create_noncallback_interface_object(
|
|||
constants,
|
||||
rval,
|
||||
);
|
||||
assert!(JS_LinkConstructorAndPrototype(
|
||||
cx,
|
||||
rval.handle(),
|
||||
interface_prototype_object
|
||||
));
|
||||
unsafe {
|
||||
assert!(JS_LinkConstructorAndPrototype(
|
||||
*cx,
|
||||
rval.handle(),
|
||||
interface_prototype_object
|
||||
));
|
||||
}
|
||||
define_name(cx, rval.handle(), name);
|
||||
define_length(cx, rval.handle(), i32::try_from(length).expect("overflow"));
|
||||
define_on_global_object(cx, global, name, rval.handle());
|
||||
}
|
||||
|
||||
/// Create and define the named constructors of a non-callback interface.
|
||||
pub unsafe fn create_named_constructors(
|
||||
cx: *mut JSContext,
|
||||
pub fn create_named_constructors(
|
||||
cx: SafeJSContext,
|
||||
global: HandleObject,
|
||||
named_constructors: &[(ConstructorClassHook, &[u8], u32)],
|
||||
interface_prototype_object: HandleObject,
|
||||
) {
|
||||
rooted!(in(cx) let mut constructor = ptr::null_mut::<JSObject>());
|
||||
rooted!(in(*cx) let mut constructor = ptr::null_mut::<JSObject>());
|
||||
|
||||
for &(native, name, arity) in named_constructors {
|
||||
assert_eq!(*name.last().unwrap(), b'\0');
|
||||
|
||||
let fun = JS_NewFunction(
|
||||
cx,
|
||||
Some(native),
|
||||
arity,
|
||||
JSFUN_CONSTRUCTOR,
|
||||
name.as_ptr() as *const libc::c_char,
|
||||
);
|
||||
assert!(!fun.is_null());
|
||||
constructor.set(JS_GetFunctionObject(fun));
|
||||
assert!(!constructor.is_null());
|
||||
unsafe {
|
||||
let fun = JS_NewFunction(
|
||||
*cx,
|
||||
Some(native),
|
||||
arity,
|
||||
JSFUN_CONSTRUCTOR,
|
||||
name.as_ptr() as *const libc::c_char,
|
||||
);
|
||||
assert!(!fun.is_null());
|
||||
constructor.set(JS_GetFunctionObject(fun));
|
||||
assert!(!constructor.is_null());
|
||||
|
||||
assert!(JS_DefineProperty3(
|
||||
cx,
|
||||
constructor.handle(),
|
||||
b"prototype\0".as_ptr() as *const libc::c_char,
|
||||
interface_prototype_object,
|
||||
(JSPROP_PERMANENT | JSPROP_READONLY) as u32
|
||||
));
|
||||
assert!(JS_DefineProperty3(
|
||||
*cx,
|
||||
constructor.handle(),
|
||||
b"prototype\0".as_ptr() as *const libc::c_char,
|
||||
interface_prototype_object,
|
||||
(JSPROP_PERMANENT | JSPROP_READONLY) as u32
|
||||
));
|
||||
}
|
||||
|
||||
define_on_global_object(cx, global, name, constructor.handle());
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new object with a unique type.
|
||||
pub unsafe fn create_object(
|
||||
cx: *mut JSContext,
|
||||
pub fn create_object(
|
||||
cx: SafeJSContext,
|
||||
global: HandleObject,
|
||||
proto: HandleObject,
|
||||
class: &'static JSClass,
|
||||
|
@ -301,7 +310,9 @@ pub unsafe fn create_object(
|
|||
constants: &[Guard<&[ConstantSpec]>],
|
||||
mut rval: MutableHandleObject,
|
||||
) {
|
||||
rval.set(JS_NewObjectWithUniqueType(cx, class, proto));
|
||||
unsafe {
|
||||
rval.set(JS_NewObjectWithUniqueType(*cx, class, proto));
|
||||
}
|
||||
assert!(!rval.is_null());
|
||||
define_guarded_methods(cx, rval.handle(), methods, global);
|
||||
define_guarded_properties(cx, rval.handle(), properties, global);
|
||||
|
@ -309,8 +320,8 @@ pub unsafe fn create_object(
|
|||
}
|
||||
|
||||
/// Conditionally define constants on an object.
|
||||
pub unsafe fn define_guarded_constants(
|
||||
cx: *mut JSContext,
|
||||
pub fn define_guarded_constants(
|
||||
cx: SafeJSContext,
|
||||
obj: HandleObject,
|
||||
constants: &[Guard<&[ConstantSpec]>],
|
||||
global: HandleObject,
|
||||
|
@ -323,57 +334,65 @@ pub unsafe fn define_guarded_constants(
|
|||
}
|
||||
|
||||
/// Conditionally define methods on an object.
|
||||
pub unsafe fn define_guarded_methods(
|
||||
cx: *mut JSContext,
|
||||
pub fn define_guarded_methods(
|
||||
cx: SafeJSContext,
|
||||
obj: HandleObject,
|
||||
methods: &[Guard<&'static [JSFunctionSpec]>],
|
||||
global: HandleObject,
|
||||
) {
|
||||
for guard in methods {
|
||||
if let Some(specs) = guard.expose(cx, obj, global) {
|
||||
define_methods(cx, obj, specs).unwrap();
|
||||
unsafe {
|
||||
define_methods(*cx, obj, specs).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Conditionally define properties on an object.
|
||||
pub unsafe fn define_guarded_properties(
|
||||
cx: *mut JSContext,
|
||||
pub fn define_guarded_properties(
|
||||
cx: SafeJSContext,
|
||||
obj: HandleObject,
|
||||
properties: &[Guard<&'static [JSPropertySpec]>],
|
||||
global: HandleObject,
|
||||
) {
|
||||
for guard in properties {
|
||||
if let Some(specs) = guard.expose(cx, obj, global) {
|
||||
define_properties(cx, obj, specs).unwrap();
|
||||
unsafe {
|
||||
define_properties(*cx, obj, specs).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether an interface with exposure set given by `globals` should
|
||||
/// be exposed in the global object `obj`.
|
||||
pub unsafe fn is_exposed_in(object: HandleObject, globals: Globals) -> bool {
|
||||
let unwrapped = UncheckedUnwrapObject(object.get(), /* stopAtWindowProxy = */ 0);
|
||||
let dom_class = get_dom_class(unwrapped).unwrap();
|
||||
globals.contains(dom_class.global)
|
||||
pub fn is_exposed_in(object: HandleObject, globals: Globals) -> bool {
|
||||
unsafe {
|
||||
let unwrapped = UncheckedUnwrapObject(object.get(), /* stopAtWindowProxy = */ 0);
|
||||
let dom_class = get_dom_class(unwrapped).unwrap();
|
||||
globals.contains(dom_class.global)
|
||||
}
|
||||
}
|
||||
|
||||
/// Define a property with a given name on the global object. Should be called
|
||||
/// through the resolve hook.
|
||||
pub unsafe fn define_on_global_object(
|
||||
cx: *mut JSContext,
|
||||
pub fn define_on_global_object(
|
||||
cx: SafeJSContext,
|
||||
global: HandleObject,
|
||||
name: &[u8],
|
||||
obj: HandleObject,
|
||||
) {
|
||||
assert_eq!(*name.last().unwrap(), b'\0');
|
||||
assert!(JS_DefineProperty3(
|
||||
cx,
|
||||
global,
|
||||
name.as_ptr() as *const libc::c_char,
|
||||
obj,
|
||||
JSPROP_RESOLVING
|
||||
));
|
||||
unsafe {
|
||||
assert!(JS_DefineProperty3(
|
||||
*cx,
|
||||
global,
|
||||
name.as_ptr() as *const libc::c_char,
|
||||
obj,
|
||||
JSPROP_RESOLVING
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
const OBJECT_OPS: ObjectOps = ObjectOps {
|
||||
|
@ -409,6 +428,7 @@ unsafe extern "C" fn has_instance_hook(
|
|||
value: RawMutableHandleValue,
|
||||
rval: *mut bool,
|
||||
) -> bool {
|
||||
let cx = SafeJSContext::from_ptr(cx);
|
||||
let obj_raw = HandleObject::from_raw(obj);
|
||||
let val_raw = HandleValue::from_raw(value.handle());
|
||||
match has_instance(cx, obj_raw, val_raw) {
|
||||
|
@ -422,8 +442,8 @@ unsafe extern "C" fn has_instance_hook(
|
|||
|
||||
/// Return whether a value is an instance of a given prototype.
|
||||
/// <http://heycam.github.io/webidl/#es-interface-hasinstance>
|
||||
unsafe fn has_instance(
|
||||
cx: *mut JSContext,
|
||||
fn has_instance(
|
||||
cx: SafeJSContext,
|
||||
interface_object: HandleObject,
|
||||
value: HandleValue,
|
||||
) -> Result<bool, ()> {
|
||||
|
@ -432,86 +452,91 @@ unsafe fn has_instance(
|
|||
return Ok(false);
|
||||
}
|
||||
|
||||
rooted!(in(cx) let mut value_out = value.to_object());
|
||||
rooted!(in(cx) let mut value = value.to_object());
|
||||
rooted!(in(*cx) let mut value_out = value.to_object());
|
||||
rooted!(in(*cx) let mut value = value.to_object());
|
||||
|
||||
let js_class = get_object_class(interface_object.get());
|
||||
let object_class = &*(js_class as *const NonCallbackInterfaceObjectClass);
|
||||
unsafe {
|
||||
let js_class = get_object_class(interface_object.get());
|
||||
let object_class = &*(js_class as *const NonCallbackInterfaceObjectClass);
|
||||
|
||||
if let Ok(dom_class) = get_dom_class(UncheckedUnwrapObject(
|
||||
value.get(),
|
||||
/* stopAtWindowProxy = */ 0,
|
||||
)) {
|
||||
if dom_class.interface_chain[object_class.proto_depth as usize] == object_class.proto_id {
|
||||
// Step 4.
|
||||
return Ok(true);
|
||||
if let Ok(dom_class) = get_dom_class(UncheckedUnwrapObject(
|
||||
value.get(),
|
||||
/* stopAtWindowProxy = */ 0,
|
||||
)) {
|
||||
if dom_class.interface_chain[object_class.proto_depth as usize] == object_class.proto_id
|
||||
{
|
||||
// Step 4.
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Step 2.
|
||||
let global = GetNonCCWObjectGlobal(interface_object.get());
|
||||
assert!(!global.is_null());
|
||||
let proto_or_iface_array = get_proto_or_iface_array(global);
|
||||
rooted!(in(cx) let prototype = (*proto_or_iface_array)[object_class.proto_id as usize]);
|
||||
assert!(!prototype.is_null());
|
||||
// Step 3 only concern legacy callback interface objects (i.e. NodeFilter).
|
||||
// Step 2.
|
||||
let global = GetNonCCWObjectGlobal(interface_object.get());
|
||||
assert!(!global.is_null());
|
||||
let proto_or_iface_array = get_proto_or_iface_array(global);
|
||||
rooted!(in(*cx) let prototype = (*proto_or_iface_array)[object_class.proto_id as usize]);
|
||||
assert!(!prototype.is_null());
|
||||
// Step 3 only concern legacy callback interface objects (i.e. NodeFilter).
|
||||
|
||||
while JS_GetPrototype(cx, value.handle(), value_out.handle_mut()) {
|
||||
*value = *value_out;
|
||||
if value.is_null() {
|
||||
// Step 5.2.
|
||||
return Ok(false);
|
||||
} else if value.get() as *const _ == prototype.get() {
|
||||
// Step 5.3.
|
||||
return Ok(true);
|
||||
while JS_GetPrototype(*cx, value.handle(), value_out.handle_mut()) {
|
||||
*value = *value_out;
|
||||
if value.is_null() {
|
||||
// Step 5.2.
|
||||
return Ok(false);
|
||||
} else if value.get() as *const _ == prototype.get() {
|
||||
// Step 5.3.
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// JS_GetPrototype threw an exception.
|
||||
Err(())
|
||||
}
|
||||
|
||||
unsafe fn create_unscopable_object(
|
||||
cx: *mut JSContext,
|
||||
names: &[&[u8]],
|
||||
mut rval: MutableHandleObject,
|
||||
) {
|
||||
fn create_unscopable_object(cx: SafeJSContext, names: &[&[u8]], mut rval: MutableHandleObject) {
|
||||
assert!(!names.is_empty());
|
||||
assert!(rval.is_null());
|
||||
rval.set(JS_NewPlainObject(cx));
|
||||
assert!(!rval.is_null());
|
||||
for &name in names {
|
||||
assert_eq!(*name.last().unwrap(), b'\0');
|
||||
assert!(JS_DefineProperty(
|
||||
cx,
|
||||
rval.handle(),
|
||||
name.as_ptr() as *const libc::c_char,
|
||||
HandleValue::from_raw(TrueHandleValue),
|
||||
JSPROP_READONLY as u32,
|
||||
unsafe {
|
||||
rval.set(JS_NewPlainObject(*cx));
|
||||
assert!(!rval.is_null());
|
||||
for &name in names {
|
||||
assert_eq!(*name.last().unwrap(), b'\0');
|
||||
assert!(JS_DefineProperty(
|
||||
*cx,
|
||||
rval.handle(),
|
||||
name.as_ptr() as *const libc::c_char,
|
||||
HandleValue::from_raw(TrueHandleValue),
|
||||
JSPROP_READONLY as u32,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn define_name(cx: SafeJSContext, obj: HandleObject, name: &[u8]) {
|
||||
assert_eq!(*name.last().unwrap(), b'\0');
|
||||
unsafe {
|
||||
rooted!(in(*cx) let name = JS_AtomizeAndPinString(*cx, name.as_ptr() as *const libc::c_char));
|
||||
assert!(!name.is_null());
|
||||
assert!(JS_DefineProperty4(
|
||||
*cx,
|
||||
obj,
|
||||
b"name\0".as_ptr() as *const libc::c_char,
|
||||
name.handle().into(),
|
||||
JSPROP_READONLY as u32
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn define_name(cx: *mut JSContext, obj: HandleObject, name: &[u8]) {
|
||||
assert_eq!(*name.last().unwrap(), b'\0');
|
||||
rooted!(in(cx) let name = JS_AtomizeAndPinString(cx, name.as_ptr() as *const libc::c_char));
|
||||
assert!(!name.is_null());
|
||||
assert!(JS_DefineProperty4(
|
||||
cx,
|
||||
obj,
|
||||
b"name\0".as_ptr() as *const libc::c_char,
|
||||
name.handle().into(),
|
||||
JSPROP_READONLY as u32
|
||||
));
|
||||
}
|
||||
|
||||
unsafe fn define_length(cx: *mut JSContext, obj: HandleObject, length: i32) {
|
||||
assert!(JS_DefineProperty5(
|
||||
cx,
|
||||
obj,
|
||||
b"length\0".as_ptr() as *const libc::c_char,
|
||||
length,
|
||||
JSPROP_READONLY as u32
|
||||
));
|
||||
fn define_length(cx: SafeJSContext, obj: HandleObject, length: i32) {
|
||||
unsafe {
|
||||
assert!(JS_DefineProperty5(
|
||||
*cx,
|
||||
obj,
|
||||
b"length\0".as_ptr() as *const libc::c_char,
|
||||
length,
|
||||
JSPROP_READONLY as u32
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn invalid_constructor(
|
||||
|
|
|
@ -13,10 +13,10 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
|||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::bindings::trace::{JSTraceable, RootedTraceableBox};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use dom_struct::dom_struct;
|
||||
use js::conversions::ToJSValConvertible;
|
||||
use js::jsapi::{Heap, JSContext, JSObject};
|
||||
use js::jsapi::{Heap, JSObject};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::{HandleValue, MutableHandleObject};
|
||||
use std::cell::Cell;
|
||||
|
@ -63,7 +63,7 @@ impl<T: DomObject + JSTraceable + Iterable> IterableIterator<T> {
|
|||
pub fn new(
|
||||
iterable: &T,
|
||||
type_: IteratorType,
|
||||
wrap: unsafe fn(SafeJSContext, &GlobalScope, Box<IterableIterator<T>>) -> DomRoot<Self>,
|
||||
wrap: unsafe fn(JSContext, &GlobalScope, Box<IterableIterator<T>>) -> DomRoot<Self>,
|
||||
) -> DomRoot<Self> {
|
||||
let iterator = Box::new(IterableIterator {
|
||||
reflector: Reflector::new(),
|
||||
|
@ -76,12 +76,12 @@ impl<T: DomObject + JSTraceable + Iterable> IterableIterator<T> {
|
|||
|
||||
/// Return the next value from the iterable object.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Next(&self, cx: SafeJSContext) -> Fallible<NonNull<JSObject>> {
|
||||
pub fn Next(&self, cx: JSContext) -> Fallible<NonNull<JSObject>> {
|
||||
let index = self.index.get();
|
||||
rooted!(in(*cx) let mut value = UndefinedValue());
|
||||
rooted!(in(*cx) let mut rval = ptr::null_mut::<JSObject>());
|
||||
let result = if index >= self.iterable.get_iterable_length() {
|
||||
dict_return(*cx, rval.handle_mut(), true, value.handle())
|
||||
dict_return(cx, rval.handle_mut(), true, value.handle())
|
||||
} else {
|
||||
match self.type_ {
|
||||
IteratorType::Keys => {
|
||||
|
@ -90,7 +90,7 @@ impl<T: DomObject + JSTraceable + Iterable> IterableIterator<T> {
|
|||
.get_key_at_index(index)
|
||||
.to_jsval(*cx, value.handle_mut());
|
||||
}
|
||||
dict_return(*cx, rval.handle_mut(), false, value.handle())
|
||||
dict_return(cx, rval.handle_mut(), false, value.handle())
|
||||
},
|
||||
IteratorType::Values => {
|
||||
unsafe {
|
||||
|
@ -98,7 +98,7 @@ impl<T: DomObject + JSTraceable + Iterable> IterableIterator<T> {
|
|||
.get_value_at_index(index)
|
||||
.to_jsval(*cx, value.handle_mut());
|
||||
}
|
||||
dict_return(*cx, rval.handle_mut(), false, value.handle())
|
||||
dict_return(cx, rval.handle_mut(), false, value.handle())
|
||||
},
|
||||
IteratorType::Entries => {
|
||||
rooted!(in(*cx) let mut key = UndefinedValue());
|
||||
|
@ -110,7 +110,7 @@ impl<T: DomObject + JSTraceable + Iterable> IterableIterator<T> {
|
|||
.get_value_at_index(index)
|
||||
.to_jsval(*cx, value.handle_mut());
|
||||
}
|
||||
key_and_value_return(*cx, rval.handle_mut(), key.handle(), value.handle())
|
||||
key_and_value_return(cx, rval.handle_mut(), key.handle(), value.handle())
|
||||
},
|
||||
}
|
||||
};
|
||||
|
@ -120,7 +120,7 @@ impl<T: DomObject + JSTraceable + Iterable> IterableIterator<T> {
|
|||
}
|
||||
|
||||
fn dict_return(
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
mut result: MutableHandleObject,
|
||||
done: bool,
|
||||
value: HandleValue,
|
||||
|
@ -128,16 +128,16 @@ fn dict_return(
|
|||
let mut dict = IterableKeyOrValueResult::empty();
|
||||
dict.done = done;
|
||||
dict.value.set(value.get());
|
||||
rooted!(in(cx) let mut dict_value = UndefinedValue());
|
||||
rooted!(in(*cx) let mut dict_value = UndefinedValue());
|
||||
unsafe {
|
||||
dict.to_jsval(cx, dict_value.handle_mut());
|
||||
dict.to_jsval(*cx, dict_value.handle_mut());
|
||||
}
|
||||
result.set(dict_value.to_object());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn key_and_value_return(
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
mut result: MutableHandleObject,
|
||||
key: HandleValue,
|
||||
value: HandleValue,
|
||||
|
@ -150,9 +150,9 @@ fn key_and_value_return(
|
|||
.map(|handle| RootedTraceableBox::from_box(Heap::boxed(handle.get())))
|
||||
.collect(),
|
||||
);
|
||||
rooted!(in(cx) let mut dict_value = UndefinedValue());
|
||||
rooted!(in(*cx) let mut dict_value = UndefinedValue());
|
||||
unsafe {
|
||||
dict.to_jsval(cx, dict_value.handle_mut());
|
||||
dict.to_jsval(*cx, dict_value.handle_mut());
|
||||
}
|
||||
result.set(dict_value.to_object());
|
||||
Ok(())
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
use crate::dom::bindings::guard::Guard;
|
||||
use crate::dom::bindings::interface::{create_object, define_on_global_object};
|
||||
use js::jsapi::{JSClass, JSContext, JSFunctionSpec};
|
||||
use crate::script_runtime::JSContext;
|
||||
use js::jsapi::{JSClass, JSFunctionSpec};
|
||||
use js::rust::{HandleObject, MutableHandleObject};
|
||||
|
||||
/// The class of a namespace object.
|
||||
|
@ -28,8 +29,8 @@ impl NamespaceObjectClass {
|
|||
}
|
||||
|
||||
/// Create a new namespace object.
|
||||
pub unsafe fn create_namespace_object(
|
||||
cx: *mut JSContext,
|
||||
pub fn create_namespace_object(
|
||||
cx: JSContext,
|
||||
global: HandleObject,
|
||||
proto: HandleObject,
|
||||
class: &'static NamespaceObjectClass,
|
||||
|
|
|
@ -30,13 +30,13 @@ use crate::dom::eventtarget::EventTarget;
|
|||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::permissions::{get_descriptor_permission_state, PermissionAlgorithm};
|
||||
use crate::dom::promise::Promise;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use crate::task::TaskOnce;
|
||||
use dom_struct::dom_struct;
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
use ipc_channel::router::ROUTER;
|
||||
use js::conversions::ConversionResult;
|
||||
use js::jsapi::{JSContext, JSObject};
|
||||
use js::jsapi::JSObject;
|
||||
use js::jsval::{ObjectValue, UndefinedValue};
|
||||
use profile_traits::ipc as ProfiledIpc;
|
||||
use std::cell::Ref;
|
||||
|
@ -616,28 +616,24 @@ impl PermissionAlgorithm for Bluetooth {
|
|||
type Descriptor = BluetoothPermissionDescriptor;
|
||||
type Status = BluetoothPermissionResult;
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
fn create_descriptor(
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
permission_descriptor_obj: *mut JSObject,
|
||||
) -> Result<BluetoothPermissionDescriptor, Error> {
|
||||
rooted!(in(cx) let mut property = UndefinedValue());
|
||||
rooted!(in(*cx) let mut property = UndefinedValue());
|
||||
property
|
||||
.handle_mut()
|
||||
.set(ObjectValue(permission_descriptor_obj));
|
||||
unsafe {
|
||||
match BluetoothPermissionDescriptor::new(SafeJSContext::from_ptr(cx), property.handle())
|
||||
{
|
||||
Ok(ConversionResult::Success(descriptor)) => Ok(descriptor),
|
||||
Ok(ConversionResult::Failure(error)) => Err(Error::Type(error.into_owned())),
|
||||
Err(_) => Err(Error::Type(String::from(BT_DESC_CONVERSION_ERROR))),
|
||||
}
|
||||
match BluetoothPermissionDescriptor::new(cx, property.handle()) {
|
||||
Ok(ConversionResult::Success(descriptor)) => Ok(descriptor),
|
||||
Ok(ConversionResult::Failure(error)) => Err(Error::Type(error.into_owned())),
|
||||
Err(_) => Err(Error::Type(String::from(BT_DESC_CONVERSION_ERROR))),
|
||||
}
|
||||
}
|
||||
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/#query-the-bluetooth-permission
|
||||
fn permission_query(
|
||||
_cx: *mut JSContext,
|
||||
_cx: JSContext,
|
||||
promise: &Rc<Promise>,
|
||||
descriptor: &BluetoothPermissionDescriptor,
|
||||
status: &BluetoothPermissionResult,
|
||||
|
@ -727,7 +723,7 @@ impl PermissionAlgorithm for Bluetooth {
|
|||
|
||||
// https://webbluetoothcg.github.io/web-bluetooth/#request-the-bluetooth-permission
|
||||
fn permission_request(
|
||||
_cx: *mut JSContext,
|
||||
_cx: JSContext,
|
||||
promise: &Rc<Promise>,
|
||||
descriptor: &BluetoothPermissionDescriptor,
|
||||
status: &BluetoothPermissionResult,
|
||||
|
|
|
@ -158,7 +158,7 @@ fn create_html_element(
|
|||
unsafe {
|
||||
let _ac =
|
||||
JSAutoRealm::new(*cx, global.reflector().get_jsobject().get());
|
||||
throw_dom_exception(*cx, &global, error);
|
||||
throw_dom_exception(cx, &global, error);
|
||||
report_pending_exception(*cx, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,14 +31,14 @@ use crate::dom::node::{document_from_node, window_from_node, Node, ShadowIncludi
|
|||
use crate::dom::promise::Promise;
|
||||
use crate::dom::window::Window;
|
||||
use crate::microtask::Microtask;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use crate::script_thread::ScriptThread;
|
||||
use dom_struct::dom_struct;
|
||||
use html5ever::{LocalName, Namespace, Prefix};
|
||||
use js::conversions::ToJSValConvertible;
|
||||
use js::glue::UnwrapObjectStatic;
|
||||
use js::jsapi::{HandleValueArray, Heap, IsCallable, IsConstructor};
|
||||
use js::jsapi::{JSAutoRealm, JSContext, JSObject};
|
||||
use js::jsapi::{JSAutoRealm, JSObject};
|
||||
use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue};
|
||||
use js::rust::wrappers::{Construct1, JS_GetProperty, SameValue};
|
||||
use js::rust::{HandleObject, HandleValue, MutableHandleValue};
|
||||
|
@ -171,14 +171,10 @@ impl CustomElementRegistry {
|
|||
|
||||
// Step 4
|
||||
Ok(LifecycleCallbacks {
|
||||
connected_callback: get_callback(*cx, prototype, b"connectedCallback\0")?,
|
||||
disconnected_callback: get_callback(*cx, prototype, b"disconnectedCallback\0")?,
|
||||
adopted_callback: get_callback(*cx, prototype, b"adoptedCallback\0")?,
|
||||
attribute_changed_callback: get_callback(
|
||||
*cx,
|
||||
prototype,
|
||||
b"attributeChangedCallback\0",
|
||||
)?,
|
||||
connected_callback: get_callback(cx, prototype, b"connectedCallback\0")?,
|
||||
disconnected_callback: get_callback(cx, prototype, b"disconnectedCallback\0")?,
|
||||
adopted_callback: get_callback(cx, prototype, b"adoptedCallback\0")?,
|
||||
attribute_changed_callback: get_callback(cx, prototype, b"attributeChangedCallback\0")?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -221,34 +217,32 @@ impl CustomElementRegistry {
|
|||
/// <https://html.spec.whatwg.org/multipage/#dom-customelementregistry-define>
|
||||
/// Step 10.4
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn get_callback(
|
||||
cx: *mut JSContext,
|
||||
fn get_callback(
|
||||
cx: JSContext,
|
||||
prototype: HandleObject,
|
||||
name: &[u8],
|
||||
) -> Fallible<Option<Rc<Function>>> {
|
||||
rooted!(in(cx) let mut callback = UndefinedValue());
|
||||
|
||||
// Step 10.4.1
|
||||
if !JS_GetProperty(
|
||||
cx,
|
||||
prototype,
|
||||
name.as_ptr() as *const _,
|
||||
callback.handle_mut(),
|
||||
) {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
|
||||
// Step 10.4.2
|
||||
if !callback.is_undefined() {
|
||||
if !callback.is_object() || !IsCallable(callback.to_object()) {
|
||||
return Err(Error::Type("Lifecycle callback is not callable".to_owned()));
|
||||
rooted!(in(*cx) let mut callback = UndefinedValue());
|
||||
unsafe {
|
||||
// Step 10.4.1
|
||||
if !JS_GetProperty(
|
||||
*cx,
|
||||
prototype,
|
||||
name.as_ptr() as *const _,
|
||||
callback.handle_mut(),
|
||||
) {
|
||||
return Err(Error::JSFailed);
|
||||
}
|
||||
|
||||
// Step 10.4.2
|
||||
if !callback.is_undefined() {
|
||||
if !callback.is_object() || !IsCallable(callback.to_object()) {
|
||||
return Err(Error::Type("Lifecycle callback is not callable".to_owned()));
|
||||
}
|
||||
Ok(Some(Function::new(cx, callback.to_object())))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
Ok(Some(Function::new(
|
||||
SafeJSContext::from_ptr(cx),
|
||||
callback.to_object(),
|
||||
)))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -409,7 +403,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
|
|||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-customelementregistry-get>
|
||||
#[allow(unsafe_code)]
|
||||
fn Get(&self, cx: SafeJSContext, name: DOMString) -> JSVal {
|
||||
fn Get(&self, cx: JSContext, name: DOMString) -> JSVal {
|
||||
match self.definitions.borrow().get(&LocalName::from(&*name)) {
|
||||
Some(definition) => unsafe {
|
||||
rooted!(in(*cx) let mut constructor = UndefinedValue());
|
||||
|
@ -631,7 +625,7 @@ pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Elemen
|
|||
let global = GlobalScope::current().expect("No current global");
|
||||
let cx = global.get_cx();
|
||||
unsafe {
|
||||
throw_dom_exception(*cx, &global, error);
|
||||
throw_dom_exception(cx, &global, error);
|
||||
report_pending_exception(*cx, true);
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -22,7 +22,7 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable};
|
|||
use crate::dom::eventtarget::EventTarget;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::progressevent::ProgressEvent;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use crate::task::TaskCanceller;
|
||||
use crate::task_source::file_reading::{FileReadingTask, FileReadingTaskSource};
|
||||
use crate::task_source::{TaskSource, TaskSourceName};
|
||||
|
@ -30,7 +30,6 @@ use base64;
|
|||
use dom_struct::dom_struct;
|
||||
use encoding_rs::{Encoding, UTF_8};
|
||||
use js::jsapi::Heap;
|
||||
use js::jsapi::JSContext;
|
||||
use js::jsapi::JSObject;
|
||||
use js::jsval::{self, JSVal};
|
||||
use js::typedarray::{ArrayBuffer, CreateWith};
|
||||
|
@ -233,7 +232,6 @@ impl FileReader {
|
|||
}
|
||||
|
||||
// https://w3c.github.io/FileAPI/#dfn-readAsText
|
||||
#[allow(unsafe_code)]
|
||||
pub fn process_read_eof(
|
||||
filereader: TrustedFileReader,
|
||||
gen_id: GenerationId,
|
||||
|
@ -266,7 +264,7 @@ impl FileReader {
|
|||
let _ac = enter_realm(&*fr);
|
||||
FileReader::perform_readasarraybuffer(
|
||||
&fr.result,
|
||||
*fr.global().get_cx(),
|
||||
fr.global().get_cx(),
|
||||
data,
|
||||
&blob_contents,
|
||||
)
|
||||
|
@ -313,14 +311,14 @@ impl FileReader {
|
|||
#[allow(unsafe_code)]
|
||||
fn perform_readasarraybuffer(
|
||||
result: &DomRefCell<Option<FileReaderResult>>,
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
_: ReadMetaData,
|
||||
bytes: &[u8],
|
||||
) {
|
||||
unsafe {
|
||||
rooted!(in(cx) let mut array_buffer = ptr::null_mut::<JSObject>());
|
||||
rooted!(in(*cx) let mut array_buffer = ptr::null_mut::<JSObject>());
|
||||
assert!(
|
||||
ArrayBuffer::create(cx, CreateWith::Slice(bytes), array_buffer.handle_mut())
|
||||
ArrayBuffer::create(*cx, CreateWith::Slice(bytes), array_buffer.handle_mut())
|
||||
.is_ok()
|
||||
);
|
||||
|
||||
|
@ -392,7 +390,7 @@ impl FileReaderMethods for FileReader {
|
|||
|
||||
#[allow(unsafe_code)]
|
||||
// https://w3c.github.io/FileAPI/#dfn-result
|
||||
fn GetResult(&self, _: SafeJSContext) -> Option<StringOrObject> {
|
||||
fn GetResult(&self, _: JSContext) -> Option<StringOrObject> {
|
||||
self.result.borrow().as_ref().map(|r| match *r {
|
||||
FileReaderResult::String(ref string) => StringOrObject::String(string.clone()),
|
||||
FileReaderResult::ArrayBuffer(ref arr_buffer) => {
|
||||
|
|
|
@ -677,23 +677,17 @@ impl GlobalScope {
|
|||
}
|
||||
|
||||
/// Perform a microtask checkpoint.
|
||||
#[allow(unsafe_code)]
|
||||
pub fn perform_a_microtask_checkpoint(&self) {
|
||||
unsafe {
|
||||
self.microtask_queue.checkpoint(
|
||||
*self.get_cx(),
|
||||
|_| Some(DomRoot::from_ref(self)),
|
||||
vec![DomRoot::from_ref(self)],
|
||||
);
|
||||
}
|
||||
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) {
|
||||
unsafe {
|
||||
self.microtask_queue.enqueue(job, *self.get_cx());
|
||||
}
|
||||
self.microtask_queue.enqueue(job, self.get_cx());
|
||||
}
|
||||
|
||||
/// Create a new sender/receiver pair that can be used to implement an on-demand
|
||||
|
|
|
@ -18,9 +18,9 @@ use crate::dom::globalscope::GlobalScope;
|
|||
use crate::dom::hashchangeevent::HashChangeEvent;
|
||||
use crate::dom::popstateevent::PopStateEvent;
|
||||
use crate::dom::window::Window;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use dom_struct::dom_struct;
|
||||
use js::jsapi::{Heap, JSContext};
|
||||
use js::jsapi::Heap;
|
||||
use js::jsval::{JSVal, NullValue, UndefinedValue};
|
||||
use js::rust::HandleValue;
|
||||
use msg::constellation_msg::{HistoryStateId, TraversalDirection};
|
||||
|
@ -165,7 +165,7 @@ impl History {
|
|||
// https://html.spec.whatwg.org/multipage/#dom-history-replacestate
|
||||
fn push_or_replace_state(
|
||||
&self,
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
data: HandleValue,
|
||||
_title: DOMString,
|
||||
url: Option<USVString>,
|
||||
|
@ -185,7 +185,7 @@ impl History {
|
|||
// TODO: Step 4
|
||||
|
||||
// Step 5
|
||||
let serialized_data = StructuredCloneData::write(cx, data)?.move_to_arraybuffer();
|
||||
let serialized_data = StructuredCloneData::write(*cx, data)?.move_to_arraybuffer();
|
||||
|
||||
let new_url: ServoUrl = match url {
|
||||
// Step 6
|
||||
|
@ -265,7 +265,7 @@ impl History {
|
|||
|
||||
// Step 11
|
||||
let global_scope = self.window.upcast::<GlobalScope>();
|
||||
rooted!(in(cx) let mut state = UndefinedValue());
|
||||
rooted!(in(*cx) let mut state = UndefinedValue());
|
||||
StructuredCloneData::Vector(serialized_data).read(&global_scope, state.handle_mut());
|
||||
|
||||
// Step 12
|
||||
|
@ -280,7 +280,7 @@ impl History {
|
|||
|
||||
impl HistoryMethods for History {
|
||||
// https://html.spec.whatwg.org/multipage/#dom-history-state
|
||||
fn GetState(&self, _cx: SafeJSContext) -> Fallible<JSVal> {
|
||||
fn GetState(&self, _cx: JSContext) -> Fallible<JSVal> {
|
||||
if !self.window.Document().is_fully_active() {
|
||||
return Err(Error::Security);
|
||||
}
|
||||
|
@ -329,22 +329,22 @@ impl HistoryMethods for History {
|
|||
// https://html.spec.whatwg.org/multipage/#dom-history-pushstate
|
||||
fn PushState(
|
||||
&self,
|
||||
cx: SafeJSContext,
|
||||
cx: JSContext,
|
||||
data: HandleValue,
|
||||
title: DOMString,
|
||||
url: Option<USVString>,
|
||||
) -> ErrorResult {
|
||||
self.push_or_replace_state(*cx, data, title, url, PushOrReplace::Push)
|
||||
self.push_or_replace_state(cx, data, title, url, PushOrReplace::Push)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-history-replacestate
|
||||
fn ReplaceState(
|
||||
&self,
|
||||
cx: SafeJSContext,
|
||||
cx: JSContext,
|
||||
data: HandleValue,
|
||||
title: DOMString,
|
||||
url: Option<USVString>,
|
||||
) -> ErrorResult {
|
||||
self.push_or_replace_state(*cx, data, title, url, PushOrReplace::Replace)
|
||||
self.push_or_replace_state(cx, data, title, url, PushOrReplace::Replace)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ use crate::dom::webgl2renderingcontext::WebGL2RenderingContext;
|
|||
use crate::dom::webglrenderingcontext::{
|
||||
LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext,
|
||||
};
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use base64;
|
||||
use canvas_traits::canvas::{CanvasId, CanvasMsg, FromScriptMsg};
|
||||
use canvas_traits::webgl::{GLContextAttributes, WebGLVersion};
|
||||
|
@ -39,7 +39,6 @@ use image::png::PNGEncoder;
|
|||
use image::ColorType;
|
||||
use ipc_channel::ipc::IpcSharedMemory;
|
||||
use js::error::throw_type_error;
|
||||
use js::jsapi::JSContext;
|
||||
use js::rust::HandleValue;
|
||||
use profile_traits::ipc;
|
||||
use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource};
|
||||
|
@ -207,10 +206,9 @@ impl HTMLCanvasElement {
|
|||
Some(context)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn get_or_init_webgl_context(
|
||||
fn get_or_init_webgl_context(
|
||||
&self,
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
options: HandleValue,
|
||||
) -> Option<DomRoot<WebGLRenderingContext>> {
|
||||
if let Some(ctx) = self.context() {
|
||||
|
@ -227,10 +225,9 @@ impl HTMLCanvasElement {
|
|||
Some(context)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn get_or_init_webgl2_context(
|
||||
fn get_or_init_webgl2_context(
|
||||
&self,
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
options: HandleValue,
|
||||
) -> Option<DomRoot<WebGL2RenderingContext>> {
|
||||
if !pref!(dom.webgl2.enabled) {
|
||||
|
@ -260,20 +257,19 @@ impl HTMLCanvasElement {
|
|||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn get_gl_attributes(
|
||||
cx: *mut JSContext,
|
||||
options: HandleValue,
|
||||
) -> Option<GLContextAttributes> {
|
||||
match WebGLContextAttributes::new(SafeJSContext::from_ptr(cx), options) {
|
||||
Ok(ConversionResult::Success(ref attrs)) => Some(From::from(attrs)),
|
||||
Ok(ConversionResult::Failure(ref error)) => {
|
||||
throw_type_error(cx, &error);
|
||||
None
|
||||
},
|
||||
_ => {
|
||||
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||
None
|
||||
},
|
||||
fn get_gl_attributes(cx: JSContext, options: HandleValue) -> Option<GLContextAttributes> {
|
||||
unsafe {
|
||||
match WebGLContextAttributes::new(cx, options) {
|
||||
Ok(ConversionResult::Success(ref attrs)) => Some(From::from(attrs)),
|
||||
Ok(ConversionResult::Failure(ref error)) => {
|
||||
throw_type_error(*cx, &error);
|
||||
None
|
||||
},
|
||||
_ => {
|
||||
debug!("Unexpected error on conversion of WebGLContextAttributes");
|
||||
None
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,10 +325,9 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
|||
make_uint_setter!(SetHeight, "height", DEFAULT_HEIGHT);
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext
|
||||
#[allow(unsafe_code)]
|
||||
fn GetContext(
|
||||
&self,
|
||||
cx: SafeJSContext,
|
||||
cx: JSContext,
|
||||
id: DOMString,
|
||||
options: HandleValue,
|
||||
) -> Option<RenderingContext> {
|
||||
|
@ -340,14 +335,12 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
|||
"2d" => self
|
||||
.get_or_init_2d_context()
|
||||
.map(RenderingContext::CanvasRenderingContext2D),
|
||||
"webgl" | "experimental-webgl" => unsafe {
|
||||
self.get_or_init_webgl_context(*cx, options)
|
||||
.map(RenderingContext::WebGLRenderingContext)
|
||||
},
|
||||
"webgl2" | "experimental-webgl2" => unsafe {
|
||||
self.get_or_init_webgl2_context(*cx, options)
|
||||
.map(RenderingContext::WebGL2RenderingContext)
|
||||
},
|
||||
"webgl" | "experimental-webgl" => self
|
||||
.get_or_init_webgl_context(cx, options)
|
||||
.map(RenderingContext::WebGLRenderingContext),
|
||||
"webgl2" | "experimental-webgl2" => self
|
||||
.get_or_init_webgl2_context(cx, options)
|
||||
.map(RenderingContext::WebGL2RenderingContext),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -355,7 +348,7 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
|||
// https://html.spec.whatwg.org/multipage/#dom-canvas-todataurl
|
||||
fn ToDataURL(
|
||||
&self,
|
||||
_context: SafeJSContext,
|
||||
_context: JSContext,
|
||||
_mime_type: Option<DOMString>,
|
||||
_quality: HandleValue,
|
||||
) -> Fallible<USVString> {
|
||||
|
|
|
@ -17,10 +17,10 @@ use crate::dom::bluetoothpermissionresult::BluetoothPermissionResult;
|
|||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::permissionstatus::PermissionStatus;
|
||||
use crate::dom::promise::Promise;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use dom_struct::dom_struct;
|
||||
use js::conversions::ConversionResult;
|
||||
use js::jsapi::{JSContext, JSObject};
|
||||
use js::jsapi::JSObject;
|
||||
use js::jsval::{ObjectValue, UndefinedValue};
|
||||
use servo_config::pref;
|
||||
use std::rc::Rc;
|
||||
|
@ -37,17 +37,17 @@ pub trait PermissionAlgorithm {
|
|||
type Descriptor;
|
||||
type Status;
|
||||
fn create_descriptor(
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
permission_descriptor_obj: *mut JSObject,
|
||||
) -> Result<Self::Descriptor, Error>;
|
||||
fn permission_query(
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
promise: &Rc<Promise>,
|
||||
descriptor: &Self::Descriptor,
|
||||
status: &Self::Status,
|
||||
);
|
||||
fn permission_request(
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
promise: &Rc<Promise>,
|
||||
descriptor: &Self::Descriptor,
|
||||
status: &Self::Status,
|
||||
|
@ -88,7 +88,7 @@ impl Permissions {
|
|||
fn manipulate(
|
||||
&self,
|
||||
op: Operation,
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
permissionDesc: *mut JSObject,
|
||||
promise: Option<Rc<Promise>>,
|
||||
) -> Rc<Promise> {
|
||||
|
@ -201,18 +201,18 @@ impl Permissions {
|
|||
|
||||
impl PermissionsMethods for Permissions {
|
||||
// https://w3c.github.io/permissions/#dom-permissions-query
|
||||
fn Query(&self, cx: SafeJSContext, permissionDesc: *mut JSObject) -> Rc<Promise> {
|
||||
self.manipulate(Operation::Query, *cx, permissionDesc, None)
|
||||
fn Query(&self, cx: JSContext, permissionDesc: *mut JSObject) -> Rc<Promise> {
|
||||
self.manipulate(Operation::Query, cx, permissionDesc, None)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/permissions/#dom-permissions-request
|
||||
fn Request(&self, cx: SafeJSContext, permissionDesc: *mut JSObject) -> Rc<Promise> {
|
||||
self.manipulate(Operation::Request, *cx, permissionDesc, None)
|
||||
fn Request(&self, cx: JSContext, permissionDesc: *mut JSObject) -> Rc<Promise> {
|
||||
self.manipulate(Operation::Request, cx, permissionDesc, None)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/permissions/#dom-permissions-revoke
|
||||
fn Revoke(&self, cx: SafeJSContext, permissionDesc: *mut JSObject) -> Rc<Promise> {
|
||||
self.manipulate(Operation::Revoke, *cx, permissionDesc, None)
|
||||
fn Revoke(&self, cx: JSContext, permissionDesc: *mut JSObject) -> Rc<Promise> {
|
||||
self.manipulate(Operation::Revoke, cx, permissionDesc, None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,27 +220,24 @@ impl PermissionAlgorithm for Permissions {
|
|||
type Descriptor = PermissionDescriptor;
|
||||
type Status = PermissionStatus;
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
fn create_descriptor(
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
permission_descriptor_obj: *mut JSObject,
|
||||
) -> Result<PermissionDescriptor, Error> {
|
||||
rooted!(in(cx) let mut property = UndefinedValue());
|
||||
rooted!(in(*cx) let mut property = UndefinedValue());
|
||||
property
|
||||
.handle_mut()
|
||||
.set(ObjectValue(permission_descriptor_obj));
|
||||
unsafe {
|
||||
match PermissionDescriptor::new(SafeJSContext::from_ptr(cx), property.handle()) {
|
||||
Ok(ConversionResult::Success(descriptor)) => Ok(descriptor),
|
||||
Ok(ConversionResult::Failure(error)) => Err(Error::Type(error.into_owned())),
|
||||
Err(_) => Err(Error::JSFailed),
|
||||
}
|
||||
match PermissionDescriptor::new(cx, property.handle()) {
|
||||
Ok(ConversionResult::Success(descriptor)) => Ok(descriptor),
|
||||
Ok(ConversionResult::Failure(error)) => Err(Error::Type(error.into_owned())),
|
||||
Err(_) => Err(Error::JSFailed),
|
||||
}
|
||||
}
|
||||
|
||||
// https://w3c.github.io/permissions/#boolean-permission-query-algorithm
|
||||
fn permission_query(
|
||||
_cx: *mut JSContext,
|
||||
_cx: JSContext,
|
||||
_promise: &Rc<Promise>,
|
||||
_descriptor: &PermissionDescriptor,
|
||||
status: &PermissionStatus,
|
||||
|
@ -251,7 +248,7 @@ impl PermissionAlgorithm for Permissions {
|
|||
|
||||
// https://w3c.github.io/permissions/#boolean-permission-request-algorithm
|
||||
fn permission_request(
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
promise: &Rc<Promise>,
|
||||
descriptor: &PermissionDescriptor,
|
||||
status: &PermissionStatus,
|
||||
|
|
|
@ -18,6 +18,7 @@ use crate::dom::bindings::reflector::{DomObject, MutDomObject, Reflector};
|
|||
use crate::dom::bindings::utils::AsCCharPtrPtr;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::promisenativehandler::PromiseNativeHandler;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use dom_struct::dom_struct;
|
||||
use js::conversions::ToJSValConvertible;
|
||||
use js::jsapi::{AddRawValueRoot, CallArgs, GetFunctionNativeReserved};
|
||||
|
@ -49,20 +50,21 @@ pub struct Promise {
|
|||
|
||||
/// Private helper to enable adding new methods to Rc<Promise>.
|
||||
trait PromiseHelper {
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn initialize(&self, cx: *mut JSContext);
|
||||
fn initialize(&self, cx: SafeJSContext);
|
||||
}
|
||||
|
||||
impl PromiseHelper for Rc<Promise> {
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn initialize(&self, cx: *mut JSContext) {
|
||||
fn initialize(&self, cx: SafeJSContext) {
|
||||
let obj = self.reflector().get_jsobject();
|
||||
self.permanent_js_root.set(ObjectValue(*obj));
|
||||
assert!(AddRawValueRoot(
|
||||
cx,
|
||||
self.permanent_js_root.get_unsafe(),
|
||||
b"Promise::root\0".as_c_char_ptr()
|
||||
));
|
||||
unsafe {
|
||||
assert!(AddRawValueRoot(
|
||||
*cx,
|
||||
self.permanent_js_root.get_unsafe(),
|
||||
b"Promise::root\0".as_c_char_ptr()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,75 +88,72 @@ impl Promise {
|
|||
Promise::new_in_current_compartment(global, comp)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub fn new_in_current_compartment(global: &GlobalScope, _comp: InCompartment) -> Rc<Promise> {
|
||||
let cx = global.get_cx();
|
||||
rooted!(in(*cx) let mut obj = ptr::null_mut::<JSObject>());
|
||||
unsafe {
|
||||
Promise::create_js_promise(*cx, HandleObject::null(), obj.handle_mut());
|
||||
Promise::new_with_js_promise(obj.handle(), *cx)
|
||||
}
|
||||
Promise::create_js_promise(cx, HandleObject::null(), obj.handle_mut());
|
||||
Promise::new_with_js_promise(obj.handle(), cx)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub fn duplicate(&self) -> Rc<Promise> {
|
||||
let cx = self.global().get_cx();
|
||||
unsafe { Promise::new_with_js_promise(self.reflector().get_jsobject(), *cx) }
|
||||
Promise::new_with_js_promise(self.reflector().get_jsobject(), cx)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code, unrooted_must_root)]
|
||||
pub unsafe fn new_with_js_promise(obj: HandleObject, cx: *mut JSContext) -> Rc<Promise> {
|
||||
assert!(IsPromiseObject(obj));
|
||||
let promise = Promise {
|
||||
reflector: Reflector::new(),
|
||||
permanent_js_root: Heap::default(),
|
||||
};
|
||||
let mut promise = Rc::new(promise);
|
||||
Rc::get_mut(&mut promise).unwrap().init_reflector(obj.get());
|
||||
promise.initialize(cx);
|
||||
promise
|
||||
pub fn new_with_js_promise(obj: HandleObject, cx: SafeJSContext) -> Rc<Promise> {
|
||||
unsafe {
|
||||
assert!(IsPromiseObject(obj));
|
||||
let promise = Promise {
|
||||
reflector: Reflector::new(),
|
||||
permanent_js_root: Heap::default(),
|
||||
};
|
||||
let mut promise = Rc::new(promise);
|
||||
Rc::get_mut(&mut promise).unwrap().init_reflector(obj.get());
|
||||
promise.initialize(cx);
|
||||
promise
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn create_js_promise(
|
||||
cx: *mut JSContext,
|
||||
proto: HandleObject,
|
||||
mut obj: MutableHandleObject,
|
||||
) {
|
||||
let do_nothing_func = JS_NewFunction(
|
||||
cx,
|
||||
Some(do_nothing_promise_executor),
|
||||
/* nargs = */ 2,
|
||||
/* flags = */ 0,
|
||||
ptr::null(),
|
||||
);
|
||||
assert!(!do_nothing_func.is_null());
|
||||
rooted!(in(cx) let do_nothing_obj = JS_GetFunctionObject(do_nothing_func));
|
||||
assert!(!do_nothing_obj.is_null());
|
||||
obj.set(NewPromiseObject(cx, do_nothing_obj.handle(), proto));
|
||||
assert!(!obj.is_null());
|
||||
fn create_js_promise(cx: SafeJSContext, proto: HandleObject, mut obj: MutableHandleObject) {
|
||||
unsafe {
|
||||
let do_nothing_func = JS_NewFunction(
|
||||
*cx,
|
||||
Some(do_nothing_promise_executor),
|
||||
/* nargs = */ 2,
|
||||
/* flags = */ 0,
|
||||
ptr::null(),
|
||||
);
|
||||
assert!(!do_nothing_func.is_null());
|
||||
rooted!(in(*cx) let do_nothing_obj = JS_GetFunctionObject(do_nothing_func));
|
||||
assert!(!do_nothing_obj.is_null());
|
||||
obj.set(NewPromiseObject(*cx, do_nothing_obj.handle(), proto));
|
||||
assert!(!obj.is_null());
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root, unsafe_code)]
|
||||
pub unsafe fn new_resolved(
|
||||
pub fn new_resolved(
|
||||
global: &GlobalScope,
|
||||
cx: *mut JSContext,
|
||||
cx: SafeJSContext,
|
||||
value: HandleValue,
|
||||
) -> Fallible<Rc<Promise>> {
|
||||
let _ac = JSAutoRealm::new(cx, global.reflector().get_jsobject().get());
|
||||
rooted!(in(cx) let p = CallOriginalPromiseResolve(cx, value));
|
||||
let _ac = JSAutoRealm::new(*cx, global.reflector().get_jsobject().get());
|
||||
rooted!(in(*cx) let p = unsafe { CallOriginalPromiseResolve(*cx, value) });
|
||||
assert!(!p.handle().is_null());
|
||||
Ok(Promise::new_with_js_promise(p.handle(), cx))
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root, unsafe_code)]
|
||||
pub unsafe fn new_rejected(
|
||||
pub fn new_rejected(
|
||||
global: &GlobalScope,
|
||||
cx: *mut JSContext,
|
||||
cx: SafeJSContext,
|
||||
value: HandleValue,
|
||||
) -> Fallible<Rc<Promise>> {
|
||||
let _ac = JSAutoRealm::new(cx, global.reflector().get_jsobject().get());
|
||||
rooted!(in(cx) let p = CallOriginalPromiseReject(cx, value));
|
||||
let _ac = JSAutoRealm::new(*cx, global.reflector().get_jsobject().get());
|
||||
rooted!(in(*cx) let p = unsafe { CallOriginalPromiseReject(*cx, value) });
|
||||
assert!(!p.handle().is_null());
|
||||
Ok(Promise::new_with_js_promise(p.handle(), cx))
|
||||
}
|
||||
|
@ -169,14 +168,16 @@ impl Promise {
|
|||
rooted!(in(*cx) let mut v = UndefinedValue());
|
||||
unsafe {
|
||||
val.to_jsval(*cx, v.handle_mut());
|
||||
self.resolve(*cx, v.handle());
|
||||
}
|
||||
self.resolve(cx, v.handle());
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root, unsafe_code)]
|
||||
pub unsafe fn resolve(&self, cx: *mut JSContext, value: HandleValue) {
|
||||
if !ResolvePromise(cx, self.promise_obj(), value) {
|
||||
JS_ClearPendingException(cx);
|
||||
pub fn resolve(&self, cx: SafeJSContext, value: HandleValue) {
|
||||
unsafe {
|
||||
if !ResolvePromise(*cx, self.promise_obj(), value) {
|
||||
JS_ClearPendingException(*cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,8 +191,8 @@ impl Promise {
|
|||
rooted!(in(*cx) let mut v = UndefinedValue());
|
||||
unsafe {
|
||||
val.to_jsval(*cx, v.handle_mut());
|
||||
self.reject(*cx, v.handle());
|
||||
}
|
||||
self.reject(cx, v.handle());
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
|
@ -201,14 +202,16 @@ impl Promise {
|
|||
rooted!(in(*cx) let mut v = UndefinedValue());
|
||||
unsafe {
|
||||
error.to_jsval(*cx, &self.global(), v.handle_mut());
|
||||
self.reject(*cx, v.handle());
|
||||
}
|
||||
self.reject(cx, v.handle());
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root, unsafe_code)]
|
||||
pub unsafe fn reject(&self, cx: *mut JSContext, value: HandleValue) {
|
||||
if !RejectPromise(cx, self.promise_obj(), value) {
|
||||
JS_ClearPendingException(cx);
|
||||
pub fn reject(&self, cx: SafeJSContext, value: HandleValue) {
|
||||
unsafe {
|
||||
if !RejectPromise(*cx, self.promise_obj(), value) {
|
||||
JS_ClearPendingException(*cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -941,29 +941,21 @@ impl TestBindingMethods for TestBinding {
|
|||
}
|
||||
|
||||
#[allow(unrooted_must_root)]
|
||||
#[allow(unsafe_code)]
|
||||
fn ReturnResolvedPromise(&self, cx: SafeJSContext, v: HandleValue) -> Fallible<Rc<Promise>> {
|
||||
unsafe { Promise::new_resolved(&self.global(), *cx, v) }
|
||||
Promise::new_resolved(&self.global(), cx, v)
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root)]
|
||||
#[allow(unsafe_code)]
|
||||
fn ReturnRejectedPromise(&self, cx: SafeJSContext, v: HandleValue) -> Fallible<Rc<Promise>> {
|
||||
unsafe { Promise::new_rejected(&self.global(), *cx, v) }
|
||||
Promise::new_rejected(&self.global(), cx, v)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
fn PromiseResolveNative(&self, cx: SafeJSContext, p: &Promise, v: HandleValue) {
|
||||
unsafe {
|
||||
p.resolve(*cx, v);
|
||||
}
|
||||
p.resolve(cx, v);
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
fn PromiseRejectNative(&self, cx: SafeJSContext, p: &Promise, v: HandleValue) {
|
||||
unsafe {
|
||||
p.reject(*cx, v);
|
||||
}
|
||||
p.reject(cx, v);
|
||||
}
|
||||
|
||||
fn PromiseRejectWithTypeError(&self, p: &Promise, s: USVString) {
|
||||
|
@ -1098,12 +1090,11 @@ impl TestBinding {
|
|||
pub fn FuncControlledStaticMethodEnabled(_: &GlobalScope) {}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
impl TestBinding {
|
||||
pub unsafe fn condition_satisfied(_: *mut JSContext, _: HandleObject) -> bool {
|
||||
pub fn condition_satisfied(_: SafeJSContext, _: HandleObject) -> bool {
|
||||
true
|
||||
}
|
||||
pub unsafe fn condition_unsatisfied(_: *mut JSContext, _: HandleObject) -> bool {
|
||||
pub fn condition_unsatisfied(_: SafeJSContext, _: HandleObject) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ use crate::dom::document::Document;
|
|||
use crate::dom::element::Element;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::window::Window;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_thread::ScriptThread;
|
||||
use dom_struct::dom_struct;
|
||||
use embedder_traits::EmbedderMsg;
|
||||
|
@ -959,7 +960,7 @@ pub fn new_window_proxy_handler() -> WindowProxyHandler {
|
|||
unsafe fn throw_security_error(cx: *mut JSContext) -> bool {
|
||||
if !JS_IsExceptionPending(cx) {
|
||||
let global = GlobalScope::from_context(cx);
|
||||
throw_dom_exception(cx, &*global, Error::Security);
|
||||
throw_dom_exception(SafeJSContext::from_ptr(cx), &*global, Error::Security);
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ use crate::dom::xmlhttprequesteventtarget::XMLHttpRequestEventTarget;
|
|||
use crate::dom::xmlhttprequestupload::XMLHttpRequestUpload;
|
||||
use crate::fetch::FetchCanceller;
|
||||
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::JSContext;
|
||||
use crate::task_source::networking::NetworkingTaskSource;
|
||||
use crate::task_source::TaskSourceName;
|
||||
use crate::timers::{OneshotTimerCallback, OneshotTimerHandle};
|
||||
|
@ -54,7 +54,7 @@ use hyper_serde::Serde;
|
|||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use js::jsapi::JS_ClearPendingException;
|
||||
use js::jsapi::{Heap, JSContext, JSObject};
|
||||
use js::jsapi::{Heap, JSObject};
|
||||
use js::jsval::{JSVal, NullValue, UndefinedValue};
|
||||
use js::rust::wrappers::JS_ParseJSON;
|
||||
use js::typedarray::{ArrayBuffer, CreateWith};
|
||||
|
@ -878,7 +878,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
|
||||
#[allow(unsafe_code)]
|
||||
// https://xhr.spec.whatwg.org/#the-response-attribute
|
||||
fn Response(&self, cx: SafeJSContext) -> JSVal {
|
||||
fn Response(&self, cx: JSContext) -> JSVal {
|
||||
rooted!(in(*cx) let mut rval = UndefinedValue());
|
||||
match self.response_type.get() {
|
||||
XMLHttpRequestResponseType::_empty | XMLHttpRequestResponseType::Text => unsafe {
|
||||
|
@ -902,16 +902,14 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
self.document_response().to_jsval(*cx, rval.handle_mut());
|
||||
},
|
||||
XMLHttpRequestResponseType::Json => unsafe {
|
||||
self.json_response(*cx).to_jsval(*cx, rval.handle_mut());
|
||||
self.json_response(cx).to_jsval(*cx, rval.handle_mut());
|
||||
},
|
||||
XMLHttpRequestResponseType::Blob => unsafe {
|
||||
self.blob_response().to_jsval(*cx, rval.handle_mut());
|
||||
},
|
||||
XMLHttpRequestResponseType::Arraybuffer => unsafe {
|
||||
match self.arraybuffer_response(*cx) {
|
||||
Some(js_object) => js_object.to_jsval(*cx, rval.handle_mut()),
|
||||
None => return NullValue(),
|
||||
}
|
||||
XMLHttpRequestResponseType::Arraybuffer => match self.arraybuffer_response(cx) {
|
||||
Some(js_object) => unsafe { js_object.to_jsval(*cx, rval.handle_mut()) },
|
||||
None => return NullValue(),
|
||||
},
|
||||
}
|
||||
rval.get()
|
||||
|
@ -1278,7 +1276,7 @@ impl XMLHttpRequest {
|
|||
|
||||
// https://xhr.spec.whatwg.org/#arraybuffer-response
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn arraybuffer_response(&self, cx: *mut JSContext) -> Option<NonNull<JSObject>> {
|
||||
fn arraybuffer_response(&self, cx: JSContext) -> Option<NonNull<JSObject>> {
|
||||
// Step 1
|
||||
let created = self.response_arraybuffer.get();
|
||||
if let Some(nonnull) = NonNull::new(created) {
|
||||
|
@ -1287,13 +1285,15 @@ impl XMLHttpRequest {
|
|||
|
||||
// Step 2
|
||||
let bytes = self.response.borrow();
|
||||
rooted!(in(cx) let mut array_buffer = ptr::null_mut::<JSObject>());
|
||||
ArrayBuffer::create(cx, CreateWith::Slice(&bytes), array_buffer.handle_mut())
|
||||
.ok()
|
||||
.and_then(|()| {
|
||||
self.response_arraybuffer.set(array_buffer.get());
|
||||
Some(NonNull::new_unchecked(array_buffer.get()))
|
||||
})
|
||||
rooted!(in(*cx) let mut array_buffer = ptr::null_mut::<JSObject>());
|
||||
unsafe {
|
||||
ArrayBuffer::create(*cx, CreateWith::Slice(&bytes), array_buffer.handle_mut())
|
||||
.ok()
|
||||
.and_then(|()| {
|
||||
self.response_arraybuffer.set(array_buffer.get());
|
||||
Some(NonNull::new_unchecked(array_buffer.get()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// https://xhr.spec.whatwg.org/#document-response
|
||||
|
@ -1345,7 +1345,7 @@ impl XMLHttpRequest {
|
|||
|
||||
#[allow(unsafe_code)]
|
||||
// https://xhr.spec.whatwg.org/#json-response
|
||||
fn json_response(&self, cx: *mut JSContext) -> JSVal {
|
||||
fn json_response(&self, cx: JSContext) -> JSVal {
|
||||
// Step 1
|
||||
let response_json = self.response_json.get();
|
||||
if !response_json.is_null_or_undefined() {
|
||||
|
@ -1378,15 +1378,15 @@ impl XMLHttpRequest {
|
|||
// if present, but UTF-16BE/LE BOM must not be honored.
|
||||
let json_text = decode_to_utf16_with_bom_removal(&bytes, UTF_8);
|
||||
// Step 5
|
||||
rooted!(in(cx) let mut rval = UndefinedValue());
|
||||
rooted!(in(*cx) let mut rval = UndefinedValue());
|
||||
unsafe {
|
||||
if !JS_ParseJSON(
|
||||
cx,
|
||||
*cx,
|
||||
json_text.as_ptr(),
|
||||
json_text.len() as u32,
|
||||
rval.handle_mut(),
|
||||
) {
|
||||
JS_ClearPendingException(cx);
|
||||
JS_ClearPendingException(*cx);
|
||||
return NullValue();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ use crate::dom::globalscope::GlobalScope;
|
|||
use crate::dom::htmlimageelement::ImageElementMicrotask;
|
||||
use crate::dom::htmlmediaelement::MediaElementMicrotask;
|
||||
use crate::dom::mutationobserver::MutationObserver;
|
||||
use crate::script_runtime::notify_about_rejected_promises;
|
||||
use crate::script_runtime::{notify_about_rejected_promises, JSContext};
|
||||
use crate::script_thread::ScriptThread;
|
||||
use js::jsapi::{JSContext, JobQueueIsEmpty, JobQueueMayNotBeEmpty};
|
||||
use js::jsapi::{JobQueueIsEmpty, JobQueueMayNotBeEmpty};
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use std::cell::Cell;
|
||||
use std::mem;
|
||||
|
@ -56,17 +56,17 @@ impl MicrotaskQueue {
|
|||
/// Add a new microtask to this queue. It will be invoked as part of the next
|
||||
/// microtask checkpoint.
|
||||
#[allow(unsafe_code)]
|
||||
pub unsafe fn enqueue(&self, job: Microtask, cx: *mut JSContext) {
|
||||
pub fn enqueue(&self, job: Microtask, cx: JSContext) {
|
||||
self.microtask_queue.borrow_mut().push(job);
|
||||
JobQueueMayNotBeEmpty(cx);
|
||||
unsafe { 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.
|
||||
#[allow(unsafe_code)]
|
||||
pub unsafe fn checkpoint<F>(
|
||||
pub fn checkpoint<F>(
|
||||
&self,
|
||||
cx: *mut JSContext,
|
||||
cx: JSContext,
|
||||
target_provider: F,
|
||||
globalscopes: Vec<DomRoot<GlobalScope>>,
|
||||
) where
|
||||
|
@ -86,7 +86,7 @@ impl MicrotaskQueue {
|
|||
|
||||
for (idx, job) in pending_queue.iter().enumerate() {
|
||||
if idx == pending_queue.len() - 1 && self.microtask_queue.borrow().is_empty() {
|
||||
JobQueueIsEmpty(cx);
|
||||
unsafe { JobQueueIsEmpty(*cx) };
|
||||
}
|
||||
|
||||
match *job {
|
||||
|
|
|
@ -172,6 +172,7 @@ unsafe extern "C" fn enqueue_promise_job(
|
|||
_allocation_site: HandleObject,
|
||||
incumbent_global: HandleObject,
|
||||
) -> bool {
|
||||
let cx = JSContext::from_ptr(cx);
|
||||
wrap_panic(
|
||||
AssertUnwindSafe(|| {
|
||||
let microtask_queue = &*(extra as *const MicrotaskQueue);
|
||||
|
@ -179,7 +180,7 @@ unsafe extern "C" fn enqueue_promise_job(
|
|||
let pipeline = global.pipeline_id();
|
||||
microtask_queue.enqueue(
|
||||
Microtask::Promise(EnqueuedPromiseCallback {
|
||||
callback: PromiseJobCallback::new(JSContext::from_ptr(cx), job.get()),
|
||||
callback: PromiseJobCallback::new(cx, job.get()),
|
||||
pipeline,
|
||||
}),
|
||||
cx,
|
||||
|
@ -201,7 +202,8 @@ unsafe extern "C" fn promise_rejection_tracker(
|
|||
// TODO: Step 2 - If script's muted errors is true, terminate these steps.
|
||||
|
||||
// Step 3.
|
||||
let global = GlobalScope::from_context(cx);
|
||||
let cx = JSContext::from_ptr(cx);
|
||||
let global = GlobalScope::from_context(*cx);
|
||||
|
||||
wrap_panic(
|
||||
AssertUnwindSafe(|| {
|
||||
|
@ -281,7 +283,7 @@ pub fn notify_about_rejected_promises(global: &GlobalScope) {
|
|||
.iter()
|
||||
.map(|promise| {
|
||||
let promise =
|
||||
Promise::new_with_js_promise(Handle::from_raw(promise.handle()), *cx);
|
||||
Promise::new_with_js_promise(Handle::from_raw(promise.handle()), cx);
|
||||
|
||||
TrustedPromise::new(promise)
|
||||
})
|
||||
|
|
|
@ -910,16 +910,13 @@ 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() {
|
||||
unsafe {
|
||||
let script_thread = &*script_thread;
|
||||
script_thread
|
||||
.microtask_queue
|
||||
.enqueue(task, *script_thread.get_cx());
|
||||
}
|
||||
let script_thread = unsafe { &*script_thread };
|
||||
script_thread
|
||||
.microtask_queue
|
||||
.enqueue(task, script_thread.get_cx());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -3776,17 +3773,15 @@ impl ScriptThread {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub fn enqueue_microtask(job: Microtask) {
|
||||
SCRIPT_THREAD_ROOT.with(|root| unsafe {
|
||||
let script_thread = &*root.get().unwrap();
|
||||
SCRIPT_THREAD_ROOT.with(|root| {
|
||||
let script_thread = unsafe { &*root.get().unwrap() };
|
||||
script_thread
|
||||
.microtask_queue
|
||||
.enqueue(job, *script_thread.get_cx());
|
||||
.enqueue(job, script_thread.get_cx());
|
||||
});
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
fn perform_a_microtask_checkpoint(&self) {
|
||||
let globals = self
|
||||
.documents
|
||||
|
@ -3795,13 +3790,11 @@ impl ScriptThread {
|
|||
.map(|(_id, document)| document.global())
|
||||
.collect();
|
||||
|
||||
unsafe {
|
||||
self.microtask_queue.checkpoint(
|
||||
*self.get_cx(),
|
||||
|id| self.documents.borrow().find_global(id),
|
||||
globals,
|
||||
)
|
||||
}
|
||||
self.microtask_queue.checkpoint(
|
||||
self.get_cx(),
|
||||
|id| self.documents.borrow().find_global(id),
|
||||
globals,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -739,7 +739,7 @@ pub fn handle_get_property(
|
|||
Err(_) => Ok(WebDriverJSValue::Undefined),
|
||||
},
|
||||
Err(error) => {
|
||||
unsafe { throw_dom_exception(*cx, &node.reflector().global(), error) };
|
||||
throw_dom_exception(cx, &node.reflector().global(), error);
|
||||
Ok(WebDriverJSValue::Undefined)
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue