mirror of
https://github.com/servo/servo.git
synced 2025-07-24 07:40:27 +01:00
Fix the hasInstance hook of interface objects
Step 2 wasn't properly implemented.
This commit is contained in:
parent
e08f817058
commit
ae72d1dfbe
3 changed files with 40 additions and 11 deletions
|
@ -6,14 +6,15 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::PrototypeList;
|
use dom::bindings::codegen::PrototypeList;
|
||||||
use dom::bindings::conversions::get_dom_class;
|
use dom::bindings::conversions::get_dom_class;
|
||||||
|
use dom::bindings::utils::get_proto_or_iface_array;
|
||||||
use js::glue::UncheckedUnwrapObject;
|
use js::glue::UncheckedUnwrapObject;
|
||||||
use js::jsapi::{Class, ClassExtension, ClassSpec, HandleObject, HandleValue, JSClass};
|
use js::jsapi::{Class, ClassExtension, ClassSpec, GetGlobalForObjectCrossCompartment};
|
||||||
use js::jsapi::{JSContext, JSFunctionSpec, JSPropertySpec, JSString, JS_DefineProperty1};
|
use js::jsapi::{HandleObject, HandleValue, JSClass, JSContext, JSFunctionSpec};
|
||||||
use js::jsapi::{JS_DefineProperty2, JS_DefineProperty4, JS_GetFunctionObject};
|
use js::jsapi::{JSPropertySpec, JSString, JS_DefineProperty1, JS_DefineProperty2};
|
||||||
use js::jsapi::{JS_GetPrototype, JS_InternString, JS_LinkConstructorAndPrototype};
|
use js::jsapi::{JS_DefineProperty4, JS_GetFunctionObject, JS_GetPrototype, JS_InternString};
|
||||||
use js::jsapi::{JS_NewFunction, JS_NewObject, JS_NewObjectWithUniqueType, JS_DefineProperty};
|
use js::jsapi::{JS_LinkConstructorAndPrototype, JS_NewFunction, JS_NewObject};
|
||||||
use js::jsapi::{MutableHandleObject, MutableHandleValue, ObjectOps, RootedObject};
|
use js::jsapi::{JS_NewObjectWithUniqueType, JS_DefineProperty, MutableHandleObject};
|
||||||
use js::jsapi::{RootedString, RootedValue, Value};
|
use js::jsapi::{MutableHandleValue, ObjectOps, RootedObject, RootedString, RootedValue, Value};
|
||||||
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UInt32Value};
|
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UInt32Value};
|
||||||
use js::rust::{define_methods, define_properties};
|
use js::rust::{define_methods, define_properties};
|
||||||
use js::{JSPROP_ENUMERATE, JSFUN_CONSTRUCTOR, JSPROP_PERMANENT, JSPROP_READONLY};
|
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
|
/// http://heycam.github.io/webidl/#es-interface-hasinstance
|
||||||
pub unsafe fn has_instance(
|
pub unsafe fn has_instance(
|
||||||
cx: *mut JSContext,
|
cx: *mut JSContext,
|
||||||
prototype: HandleObject,
|
interface_object: HandleObject,
|
||||||
value: HandleValue,
|
value: HandleValue,
|
||||||
id: PrototypeList::ID,
|
id: PrototypeList::ID,
|
||||||
index: usize)
|
index: usize)
|
||||||
|
@ -271,8 +272,6 @@ pub unsafe fn has_instance(
|
||||||
}
|
}
|
||||||
let mut value = RootedObject::new(cx, value.to_object());
|
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 let Ok(dom_class) = get_dom_class(UncheckedUnwrapObject(value.ptr, /* stopAtOuter = */ 0)) {
|
||||||
if dom_class.interface_chain[index] == id {
|
if dom_class.interface_chain[index] == id {
|
||||||
// Step 4.
|
// 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()) {
|
while JS_GetPrototype(cx, value.handle(), value.handle_mut()) {
|
||||||
if value.ptr.is_null() {
|
if value.ptr.is_null() {
|
||||||
// Step 5.2.
|
// Step 5.2.
|
||||||
|
|
|
@ -33806,7 +33806,16 @@
|
||||||
},
|
},
|
||||||
"local_changes": {
|
"local_changes": {
|
||||||
"deleted": [],
|
"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": {}
|
||||||
},
|
},
|
||||||
"reftest_nodes": {
|
"reftest_nodes": {
|
||||||
|
|
|
@ -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>
|
Loading…
Add table
Add a link
Reference in a new issue