diff options
Diffstat (limited to 'components/script/dom/bindings/interface.rs')
-rw-r--r-- | components/script/dom/bindings/interface.rs | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs index 7db3c6e17c4..f41941f08b0 100644 --- a/components/script/dom/bindings/interface.rs +++ b/components/script/dom/bindings/interface.rs @@ -7,10 +7,11 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::conversions::get_dom_class; use dom::bindings::utils::get_proto_or_iface_array; +use js::error::throw_type_error; use js::glue::UncheckedUnwrapObject; use js::jsapi::{Class, ClassExtension, ClassSpec, GetGlobalForObjectCrossCompartment}; use js::jsapi::{HandleObject, HandleValue, JSClass, JSContext, JSFunctionSpec}; -use js::jsapi::{JSPropertySpec, JSString, JS_DefineProperty1, JS_DefineProperty2}; +use js::jsapi::{JSNative, JSPropertySpec, JSString, JS_DefineProperty1, JS_DefineProperty2}; use js::jsapi::{JS_DefineProperty4, JS_GetClass, JS_GetFunctionObject, JS_GetPrototype}; use js::jsapi::{JS_InternString, JS_LinkConstructorAndPrototype, JS_NewFunction, JS_NewObject}; use js::jsapi::{JS_NewObjectWithUniqueType, JS_NewStringCopyZ, JS_DefineProperty}; @@ -93,10 +94,6 @@ unsafe extern "C" fn fun_to_string_hook(cx: *mut JSContext, ret } -/// A constructor class hook. -pub type ConstructorClassHook = - unsafe extern "C" fn(cx: *mut JSContext, argc: u32, vp: *mut Value) -> bool; - /// The class of a non-callback interface object. #[derive(Copy, Clone)] pub struct NonCallbackInterfaceObjectClass { @@ -114,8 +111,8 @@ unsafe impl Sync for NonCallbackInterfaceObjectClass {} impl NonCallbackInterfaceObjectClass { /// Create a new `NonCallbackInterfaceObjectClass` structure. - pub const fn new( - constructor: ConstructorClassHook, + pub const unsafe fn new( + constructor_behavior: InterfaceConstructorBehavior, string_rep: &'static [u8], proto_id: PrototypeList::ID, proto_depth: u16) @@ -132,8 +129,8 @@ impl NonCallbackInterfaceObjectClass { resolve: None, convert: None, finalize: None, - call: Some(constructor), - construct: Some(constructor), + call: constructor_behavior.call, + construct: constructor_behavior.construct, hasInstance: Some(has_instance_hook), trace: None, spec: ClassSpec { @@ -183,6 +180,34 @@ impl NonCallbackInterfaceObjectClass { } } +/// A constructor class hook. +pub type ConstructorClassHook = + unsafe extern "C" fn(cx: *mut JSContext, argc: u32, vp: *mut Value) -> bool; + +/// The constructor behavior of a non-callback interface object. +pub struct InterfaceConstructorBehavior { + call: JSNative, + construct: JSNative, +} + +impl InterfaceConstructorBehavior { + /// An interface constructor that unconditionally throws a type error. + pub const fn throw() -> InterfaceConstructorBehavior { + InterfaceConstructorBehavior { + call: Some(invalid_constructor), + construct: Some(invalid_constructor), + } + } + + /// An interface constructor that calls a native Rust function. + pub const fn call(hook: ConstructorClassHook) -> InterfaceConstructorBehavior { + InterfaceConstructorBehavior { + call: Some(non_new_constructor), + construct: Some(hook), + } + } +} + /// Create and define the interface object of a callback interface. pub unsafe fn create_callback_interface_object( cx: *mut JSContext, @@ -380,3 +405,21 @@ unsafe fn define_on_global_object( 0, None, None)); } + +unsafe extern "C" fn invalid_constructor( + cx: *mut JSContext, + _argc: libc::c_uint, + _vp: *mut JSVal) + -> bool { + throw_type_error(cx, "Illegal constructor."); + false +} + +unsafe extern "C" fn non_new_constructor( + cx: *mut JSContext, + _argc: libc::c_uint, + _vp: *mut JSVal) + -> bool { + throw_type_error(cx, "This constructor needs to be called with `new`."); + false +} |