aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-04-25 02:45:29 -0700
committerbors-servo <lbergstrom+bors@mozilla.com>2016-04-25 02:45:29 -0700
commita92a6360cf2833c405ec668ee144db5de44c15cf (patch)
treecca9606df80b4a8b3bebdc03873c9392c08ada91
parent59205323da10b5867d4386a50a290c3a7500c217 (diff)
parent4c2ca7a8c9244746ac168942651b0df6b6476626 (diff)
downloadservo-a92a6360cf2833c405ec668ee144db5de44c15cf.tar.gz
servo-a92a6360cf2833c405ec668ee144db5de44c15cf.zip
Auto merge of #10819 - nox:call-without-new, r=Ms2ger
Refactor the `call` hook on non-callback interface objects (fixes #10744) <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10819) <!-- Reviewable:end -->
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py27
-rw-r--r--components/script/dom/bindings/interface.rs61
-rw-r--r--components/script/dom/bindings/utils.rs13
-rw-r--r--tests/wpt/metadata/FileAPI/blob/Blob-constructor.html.ini4
-rw-r--r--tests/wpt/metadata/dom/events/Event-constructors.html.ini6
-rw-r--r--tests/wpt/metadata/url/urlsearchparams-constructor.html.ini5
6 files changed, 67 insertions, 49 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 74dff1cce9f..1ef2e0a4eb9 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1897,20 +1897,24 @@ class CGInterfaceObjectJSClass(CGThing):
def define(self):
if self.descriptor.interface.ctor():
- constructor = CONSTRUCT_HOOK_NAME
+ constructorBehavior = "InterfaceConstructorBehavior::call(%s)" % CONSTRUCT_HOOK_NAME
else:
- constructor = "throwing_constructor"
+ constructorBehavior = "InterfaceConstructorBehavior::throw()"
name = self.descriptor.interface.identifier.name
args = {
- "constructor": constructor,
+ "constructorBehavior": constructorBehavior,
"id": name,
"representation": str_to_const_array("function %s() {\\n [native code]\\n}" % name),
"depth": self.descriptor.prototypeDepth
}
return """\
-static InterfaceObjectClass: NonCallbackInterfaceObjectClass =
- NonCallbackInterfaceObjectClass::new(%(constructor)s, %(representation)s,
- PrototypeList::ID::%(id)s, %(depth)s);
+static InterfaceObjectClass: NonCallbackInterfaceObjectClass = unsafe {
+ NonCallbackInterfaceObjectClass::new(
+ %(constructorBehavior)s,
+ %(representation)s,
+ PrototypeList::ID::%(id)s,
+ %(depth)s)
+};
""" % args
@@ -2449,10 +2453,8 @@ if <*mut JSObject>::needs_post_barrier(prototype.ptr) {
if self.descriptor.interface.hasInterfaceObject():
properties["name"] = str_to_const_array(name)
if self.descriptor.interface.ctor():
- properties["constructor"] = CONSTRUCT_HOOK_NAME
properties["length"] = methodLength(self.descriptor.interface.ctor())
else:
- properties["constructor"] = "throwing_constructor"
properties["length"] = 0
if self.descriptor.interface.parent:
parentName = toBindingNamespace(self.descriptor.getParentName())
@@ -5400,9 +5402,9 @@ class CGBindingRoot(CGThing):
'js::rust::{GCMethods, define_methods, define_properties}',
'dom::bindings',
'dom::bindings::global::{GlobalRef, global_root_from_object, global_root_from_reflector}',
- 'dom::bindings::interface::{NonCallbackInterfaceObjectClass, create_callback_interface_object}',
- 'dom::bindings::interface::{create_interface_prototype_object, create_named_constructors}',
- 'dom::bindings::interface::{create_noncallback_interface_object}',
+ 'dom::bindings::interface::{InterfaceConstructorBehavior, NonCallbackInterfaceObjectClass}',
+ 'dom::bindings::interface::{create_callback_interface_object, create_interface_prototype_object}',
+ 'dom::bindings::interface::{create_named_constructors, create_noncallback_interface_object}',
'dom::bindings::interface::{ConstantSpec, NonNullJSNative}',
'dom::bindings::interface::ConstantVal::{IntVal, UintVal}',
'dom::bindings::js::{JS, Root, RootedReference}',
@@ -5416,8 +5418,7 @@ class CGBindingRoot(CGThing):
'dom::bindings::utils::{generic_method, generic_setter, get_array_index_from_id}',
'dom::bindings::utils::{get_dictionary_property, get_property_on_prototype}',
'dom::bindings::utils::{get_proto_or_iface_array, has_property_on_prototype}',
- 'dom::bindings::utils::{is_platform_object, resolve_global, set_dictionary_property}',
- 'dom::bindings::utils::{throwing_constructor, trace_global}',
+ 'dom::bindings::utils::{is_platform_object, resolve_global, set_dictionary_property, trace_global}',
'dom::bindings::trace::{JSTraceable, RootedTraceable}',
'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}',
'dom::bindings::callback::{CallSetup,ExceptionHandling}',
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
+}
diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs
index 2b4e5ee5ae0..9302bb40a09 100644
--- a/components/script/dom/bindings/utils.rs
+++ b/components/script/dom/bindings/utils.rs
@@ -16,7 +16,6 @@ use dom::browsingcontext;
use dom::window;
use heapsize::HeapSizeOf;
use js;
-use js::error::throw_type_error;
use js::glue::{CallJitGetterOp, CallJitMethodOp, CallJitSetterOp, IsWrapper};
use js::glue::{GetCrossCompartmentWrapper, WrapperNew};
use js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO, RUST_JSID_IS_INT, RUST_JSID_IS_STRING};
@@ -35,7 +34,7 @@ use js::jsval::{JSVal};
use js::jsval::{PrivateValue, UndefinedValue};
use js::rust::{GCMethods, ToString};
use js::{JS_CALLEE};
-use libc::{self, c_uint};
+use libc;
use std::default::Default;
use std::ffi::CString;
use std::os::raw::c_void;
@@ -123,16 +122,6 @@ pub fn get_proto_or_iface_array(global: *mut JSObject) -> *mut ProtoOrIfaceArray
}
}
-/// A throwing constructor, for those interfaces that have neither
-/// `NoInterfaceObject` nor `Constructor`.
-pub unsafe extern "C" fn throwing_constructor(cx: *mut JSContext,
- _argc: c_uint,
- _vp: *mut JSVal)
- -> bool {
- throw_type_error(cx, "Illegal constructor.");
- false
-}
-
/// An array of *mut JSObject of size PROTO_OR_IFACE_LENGTH.
pub type ProtoOrIfaceArray = [*mut JSObject; PROTO_OR_IFACE_LENGTH];
diff --git a/tests/wpt/metadata/FileAPI/blob/Blob-constructor.html.ini b/tests/wpt/metadata/FileAPI/blob/Blob-constructor.html.ini
index 233ecbce3d6..d0887557728 100644
--- a/tests/wpt/metadata/FileAPI/blob/Blob-constructor.html.ini
+++ b/tests/wpt/metadata/FileAPI/blob/Blob-constructor.html.ini
@@ -42,7 +42,3 @@
[Array with mixed types]
expected: FAIL
- [Blob constructor with no arguments, without 'new']
- bug: https://github.com/servo/servo/issues/10744
- expected: FAIL
-
diff --git a/tests/wpt/metadata/dom/events/Event-constructors.html.ini b/tests/wpt/metadata/dom/events/Event-constructors.html.ini
deleted file mode 100644
index 82df4c7bb6b..00000000000
--- a/tests/wpt/metadata/dom/events/Event-constructors.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[Event-constructors.html]
- type: testharness
- [Event constructors 4]
- expected: FAIL
- bug: https://github.com/servo/servo/issues/10744
-
diff --git a/tests/wpt/metadata/url/urlsearchparams-constructor.html.ini b/tests/wpt/metadata/url/urlsearchparams-constructor.html.ini
deleted file mode 100644
index af33a71e148..00000000000
--- a/tests/wpt/metadata/url/urlsearchparams-constructor.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[urlsearchparams-constructor.html]
- type: testharness
- [URLSearchParams constructor, empty.]
- expected: FAIL
-