mirror of
https://github.com/servo/servo.git
synced 2025-08-09 07:25:35 +01:00
Refactor the call
hook on non-callback interface objects (fixes #10744)
It's now set through the intermediate InterfaceConstructorBehavior structure, which lets us improve the abstraction around NonCallbackInterfaceObjectClass a bit better. When the interface's constructor is supposed to always throw, the error for calling `Foo()` without new is "Illegal constructor.". when the interface actually defines an interface, the error is instead "This constructor needs to be called with `new`.".
This commit is contained in:
parent
a45f117838
commit
4c2ca7a8c9
6 changed files with 64 additions and 47 deletions
|
@ -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 {
|
||||
|
@ -115,7 +112,7 @@ unsafe impl Sync for NonCallbackInterfaceObjectClass {}
|
|||
impl NonCallbackInterfaceObjectClass {
|
||||
/// Create a new `NonCallbackInterfaceObjectClass` structure.
|
||||
pub const unsafe fn new(
|
||||
constructor: ConstructorClassHook,
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue