mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Make callbacks' new methods unsafe
They take raw pointers to contexts and objects.
This commit is contained in:
parent
9c13073075
commit
f903da0a7b
3 changed files with 58 additions and 30 deletions
|
@ -4549,7 +4549,7 @@ class ClassConstructor(ClassItem):
|
||||||
"});\n"
|
"});\n"
|
||||||
"// Note: callback cannot be moved after calling init.\n"
|
"// Note: callback cannot be moved after calling init.\n"
|
||||||
"match Rc::get_mut(&mut ret) {\n"
|
"match Rc::get_mut(&mut ret) {\n"
|
||||||
" Some(ref mut callback) => unsafe { callback.parent.init(%s, %s) },\n"
|
" Some(ref mut callback) => callback.parent.init(%s, %s),\n"
|
||||||
" None => unreachable!(),\n"
|
" None => unreachable!(),\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"ret") % (cgClass.name, '\n'.join(initializers),
|
"ret") % (cgClass.name, '\n'.join(initializers),
|
||||||
|
@ -4564,7 +4564,7 @@ class ClassConstructor(ClassItem):
|
||||||
body = ' {\n' + body + '}'
|
body = ' {\n' + body + '}'
|
||||||
|
|
||||||
return string.Template("""\
|
return string.Template("""\
|
||||||
pub fn ${decorators}new(${args}) -> Rc<${className}>${body}
|
pub unsafe fn ${decorators}new(${args}) -> Rc<${className}>${body}
|
||||||
""").substitute({'decorators': self.getDecorators(True),
|
""").substitute({'decorators': self.getDecorators(True),
|
||||||
'className': cgClass.getNameString(),
|
'className': cgClass.getNameString(),
|
||||||
'args': args,
|
'args': args,
|
||||||
|
|
|
@ -121,7 +121,8 @@ impl CustomElementRegistry {
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#dom-customelementregistry-define>
|
/// <https://html.spec.whatwg.org/multipage/#dom-customelementregistry-define>
|
||||||
/// Steps 10.3, 10.4
|
/// Steps 10.3, 10.4
|
||||||
fn get_callbacks(&self, prototype: HandleObject) -> Fallible<LifecycleCallbacks> {
|
#[allow(unsafe_code)]
|
||||||
|
unsafe fn get_callbacks(&self, prototype: HandleObject) -> Fallible<LifecycleCallbacks> {
|
||||||
let cx = self.window.get_cx();
|
let cx = self.window.get_cx();
|
||||||
|
|
||||||
// Step 4
|
// Step 4
|
||||||
|
@ -164,20 +165,21 @@ impl CustomElementRegistry {
|
||||||
/// <https://html.spec.whatwg.org/multipage/#dom-customelementregistry-define>
|
/// <https://html.spec.whatwg.org/multipage/#dom-customelementregistry-define>
|
||||||
/// Step 10.4
|
/// Step 10.4
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn get_callback(cx: *mut JSContext, prototype: HandleObject, name: &[u8]) -> Fallible<Option<Rc<Function>>> {
|
unsafe fn get_callback(
|
||||||
|
cx: *mut JSContext,
|
||||||
|
prototype: HandleObject,
|
||||||
|
name: &[u8],
|
||||||
|
) -> Fallible<Option<Rc<Function>>> {
|
||||||
rooted!(in(cx) let mut callback = UndefinedValue());
|
rooted!(in(cx) let mut callback = UndefinedValue());
|
||||||
|
|
||||||
// Step 10.4.1
|
// Step 10.4.1
|
||||||
if unsafe { !JS_GetProperty(cx,
|
if !JS_GetProperty(cx, prototype, name.as_ptr() as *const _, callback.handle_mut()) {
|
||||||
prototype,
|
|
||||||
name.as_ptr() as *const _,
|
|
||||||
callback.handle_mut()) } {
|
|
||||||
return Err(Error::JSFailed);
|
return Err(Error::JSFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 10.4.2
|
// Step 10.4.2
|
||||||
if !callback.is_undefined() {
|
if !callback.is_undefined() {
|
||||||
if !callback.is_object() || unsafe { !IsCallable(callback.to_object()) } {
|
if !callback.is_object() || !IsCallable(callback.to_object()) {
|
||||||
return Err(Error::Type("Lifecycle callback is not callable".to_owned()));
|
return Err(Error::Type("Lifecycle callback is not callable".to_owned()));
|
||||||
}
|
}
|
||||||
Ok(Some(Function::new(cx, callback.to_object())))
|
Ok(Some(Function::new(cx, callback.to_object())))
|
||||||
|
@ -265,7 +267,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry {
|
||||||
rooted!(in(cx) let proto_object = prototype.to_object());
|
rooted!(in(cx) let proto_object = prototype.to_object());
|
||||||
let callbacks = {
|
let callbacks = {
|
||||||
let _ac = JSAutoCompartment::new(cx, proto_object.get());
|
let _ac = JSAutoCompartment::new(cx, proto_object.get());
|
||||||
match self.get_callbacks(proto_object.handle()) {
|
match unsafe { self.get_callbacks(proto_object.handle()) } {
|
||||||
Ok(callbacks) => callbacks,
|
Ok(callbacks) => callbacks,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
self.element_definition_is_running.set(false);
|
self.element_definition_is_running.set(false);
|
||||||
|
|
|
@ -471,50 +471,76 @@ impl EventTarget {
|
||||||
assert!(!funobj.is_null());
|
assert!(!funobj.is_null());
|
||||||
// Step 1.14
|
// Step 1.14
|
||||||
if is_error {
|
if is_error {
|
||||||
Some(CommonEventHandler::ErrorEventHandler(OnErrorEventHandlerNonNull::new(cx, funobj)))
|
Some(CommonEventHandler::ErrorEventHandler(
|
||||||
|
unsafe { OnErrorEventHandlerNonNull::new(cx, funobj) },
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
if ty == &atom!("beforeunload") {
|
if ty == &atom!("beforeunload") {
|
||||||
Some(CommonEventHandler::BeforeUnloadEventHandler(
|
Some(CommonEventHandler::BeforeUnloadEventHandler(
|
||||||
OnBeforeUnloadEventHandlerNonNull::new(cx, funobj)))
|
unsafe { OnBeforeUnloadEventHandlerNonNull::new(cx, funobj) },
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Some(CommonEventHandler::EventHandler(EventHandlerNonNull::new(cx, funobj)))
|
Some(CommonEventHandler::EventHandler(
|
||||||
|
unsafe { EventHandlerNonNull::new(cx, funobj) },
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
pub fn set_event_handler_common<T: CallbackContainer>(
|
pub fn set_event_handler_common<T: CallbackContainer>(
|
||||||
&self, ty: &str, listener: Option<Rc<T>>)
|
&self,
|
||||||
|
ty: &str,
|
||||||
|
listener: Option<Rc<T>>,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
T: CallbackContainer,
|
||||||
{
|
{
|
||||||
let cx = self.global().get_cx();
|
let cx = self.global().get_cx();
|
||||||
|
|
||||||
let event_listener = listener.map(|listener|
|
let event_listener = listener.map(|listener| {
|
||||||
InlineEventListener::Compiled(
|
InlineEventListener::Compiled(CommonEventHandler::EventHandler(
|
||||||
CommonEventHandler::EventHandler(
|
unsafe { EventHandlerNonNull::new(cx, listener.callback()) },
|
||||||
EventHandlerNonNull::new(cx, listener.callback()))));
|
))
|
||||||
|
});
|
||||||
self.set_inline_event_listener(Atom::from(ty), event_listener);
|
self.set_inline_event_listener(Atom::from(ty), event_listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
pub fn set_error_event_handler<T: CallbackContainer>(
|
pub fn set_error_event_handler<T: CallbackContainer>(
|
||||||
&self, ty: &str, listener: Option<Rc<T>>)
|
&self,
|
||||||
|
ty: &str,
|
||||||
|
listener: Option<Rc<T>>,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
T: CallbackContainer,
|
||||||
{
|
{
|
||||||
let cx = self.global().get_cx();
|
let cx = self.global().get_cx();
|
||||||
|
|
||||||
let event_listener = listener.map(|listener|
|
let event_listener = listener.map(|listener| {
|
||||||
InlineEventListener::Compiled(
|
InlineEventListener::Compiled(CommonEventHandler::ErrorEventHandler(
|
||||||
CommonEventHandler::ErrorEventHandler(
|
unsafe { OnErrorEventHandlerNonNull::new(cx, listener.callback()) }
|
||||||
OnErrorEventHandlerNonNull::new(cx, listener.callback()))));
|
))
|
||||||
|
});
|
||||||
self.set_inline_event_listener(Atom::from(ty), event_listener);
|
self.set_inline_event_listener(Atom::from(ty), event_listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_beforeunload_event_handler<T: CallbackContainer>(&self, ty: &str,
|
#[allow(unsafe_code)]
|
||||||
listener: Option<Rc<T>>) {
|
pub fn set_beforeunload_event_handler<T: CallbackContainer>(
|
||||||
|
&self,
|
||||||
|
ty: &str,
|
||||||
|
listener: Option<Rc<T>>,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
T: CallbackContainer,
|
||||||
|
{
|
||||||
let cx = self.global().get_cx();
|
let cx = self.global().get_cx();
|
||||||
|
|
||||||
let event_listener = listener.map(|listener|
|
let event_listener = listener.map(|listener| {
|
||||||
InlineEventListener::Compiled(
|
InlineEventListener::Compiled(CommonEventHandler::BeforeUnloadEventHandler(
|
||||||
CommonEventHandler::BeforeUnloadEventHandler(
|
unsafe { OnBeforeUnloadEventHandlerNonNull::new(cx, listener.callback()) }
|
||||||
OnBeforeUnloadEventHandlerNonNull::new(cx, listener.callback())))
|
))
|
||||||
);
|
});
|
||||||
self.set_inline_event_listener(Atom::from(ty), event_listener);
|
self.set_inline_event_listener(Atom::from(ty), event_listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue