diff options
author | Anthony Ramine <n.oxyde@gmail.com> | 2016-02-15 13:00:46 +0100 |
---|---|---|
committer | Anthony Ramine <n.oxyde@gmail.com> | 2016-02-15 14:12:53 +0100 |
commit | ae72d1dfbe37acaaa26dfa5f050bd6cad19f32a4 (patch) | |
tree | 83263a15b4fd9f43e9851788393e4fc1672aa4e2 | |
parent | e08f817058b22cf73ffbbf6e62b7319669c0519d (diff) | |
download | servo-ae72d1dfbe37acaaa26dfa5f050bd6cad19f32a4.tar.gz servo-ae72d1dfbe37acaaa26dfa5f050bd6cad19f32a4.zip |
Fix the hasInstance hook of interface objects
Step 2 wasn't properly implemented.
-rw-r--r-- | components/script/dom/bindings/interface.rs | 27 | ||||
-rw-r--r-- | tests/wpt/metadata/MANIFEST.json | 11 | ||||
-rw-r--r-- | tests/wpt/web-platform-tests/WebIDL/ecmascript-binding/has-instance.html | 13 |
3 files changed, 40 insertions, 11 deletions
diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs index 86a1f2b38f3..20f5f1c9178 100644 --- a/components/script/dom/bindings/interface.rs +++ b/components/script/dom/bindings/interface.rs @@ -6,14 +6,15 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::conversions::get_dom_class; +use dom::bindings::utils::get_proto_or_iface_array; use js::glue::UncheckedUnwrapObject; -use js::jsapi::{Class, ClassExtension, ClassSpec, HandleObject, HandleValue, JSClass}; -use js::jsapi::{JSContext, JSFunctionSpec, JSPropertySpec, JSString, JS_DefineProperty1}; -use js::jsapi::{JS_DefineProperty2, JS_DefineProperty4, JS_GetFunctionObject}; -use js::jsapi::{JS_GetPrototype, JS_InternString, JS_LinkConstructorAndPrototype}; -use js::jsapi::{JS_NewFunction, JS_NewObject, JS_NewObjectWithUniqueType, JS_DefineProperty}; -use js::jsapi::{MutableHandleObject, MutableHandleValue, ObjectOps, RootedObject}; -use js::jsapi::{RootedString, RootedValue, Value}; +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::{JS_DefineProperty4, JS_GetFunctionObject, JS_GetPrototype, JS_InternString}; +use js::jsapi::{JS_LinkConstructorAndPrototype, JS_NewFunction, JS_NewObject}; +use js::jsapi::{JS_NewObjectWithUniqueType, JS_DefineProperty, MutableHandleObject}; +use js::jsapi::{MutableHandleValue, ObjectOps, RootedObject, RootedString, RootedValue, Value}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UInt32Value}; use js::rust::{define_methods, define_properties}; use js::{JSPROP_ENUMERATE, JSFUN_CONSTRUCTOR, JSPROP_PERMANENT, JSPROP_READONLY}; @@ -260,7 +261,7 @@ pub unsafe fn create_named_constructors( /// http://heycam.github.io/webidl/#es-interface-hasinstance pub unsafe fn has_instance( cx: *mut JSContext, - prototype: HandleObject, + interface_object: HandleObject, value: HandleValue, id: PrototypeList::ID, index: usize) @@ -271,8 +272,6 @@ pub unsafe fn has_instance( } let mut value = RootedObject::new(cx, value.to_object()); - // Steps 2-3 only concern callback interface objects. - if let Ok(dom_class) = get_dom_class(UncheckedUnwrapObject(value.ptr, /* stopAtOuter = */ 0)) { if dom_class.interface_chain[index] == id { // Step 4. @@ -280,6 +279,14 @@ pub unsafe fn has_instance( } } + // Step 2. + let global = GetGlobalForObjectCrossCompartment(interface_object.get()); + assert!(!global.is_null()); + let proto_or_iface_array = get_proto_or_iface_array(global); + let prototype = RootedObject::new(cx, (*proto_or_iface_array)[id as usize]); + assert!(!prototype.ptr.is_null()); + // Step 3 only concern legacy callback interface objects (i.e. NodeFilter). + while JS_GetPrototype(cx, value.handle(), value.handle_mut()) { if value.ptr.is_null() { // Step 5.2. diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 38784ef366e..b1c8a4f322a 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -33806,7 +33806,16 @@ }, "local_changes": { "deleted": [], - "items": {}, + "items": { + "testharness": { + "WebIDL/ecmascript-binding/has-instance.html": [ + { + "path": "WebIDL/ecmascript-binding/has-instance.html", + "url": "/WebIDL/ecmascript-binding/has-instance.html" + } + ] + } + }, "reftest_nodes": {} }, "reftest_nodes": { diff --git a/tests/wpt/web-platform-tests/WebIDL/ecmascript-binding/has-instance.html b/tests/wpt/web-platform-tests/WebIDL/ecmascript-binding/has-instance.html new file mode 100644 index 00000000000..986d27c9b83 --- /dev/null +++ b/tests/wpt/web-platform-tests/WebIDL/ecmascript-binding/has-instance.html @@ -0,0 +1,13 @@ +<!doctype html> +<meta charset="utf-8"> +<title></title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +test(function() { + var obj = Object.create(Element.prototype); + assert_true(obj instanceof Element); + assert_true(obj instanceof Node); + assert_false(obj instanceof Attr); +}, "Manually-constructed prototype chains are correctly handled by instanceof"); +</script> |