aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/interface.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings/interface.rs')
-rw-r--r--components/script/dom/bindings/interface.rs61
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
+}