diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs
index e400c1678d8..a5be8f1dc96 100644
--- a/components/script/dom/bindings/proxyhandler.rs
+++ b/components/script/dom/bindings/proxyhandler.rs
@@ -17,7 +17,7 @@ use js::jsapi::JS_GetPropertyDescriptorById;
use js::jsapi::MutableHandleObject;
use js::jsapi::{Handle, HandleId, HandleObject, MutableHandle, ObjectOpResult};
use js::jsapi::{JSContext, JSObject, JSPROP_GETTER, PropertyDescriptor, DOMProxyShadowsResult};
-use js::jsapi::{JSErrNum, JS_StrictPropertyStub};
+use js::jsapi::{JSErrNum, JS_StrictPropertyStub, JS_AlreadyHasOwnPropertyById};
use js::jsapi::{JS_DefinePropertyById, JS_NewObjectWithGivenProto, SetDOMProxyInformation};
use js::jsval::ObjectValue;
use libc;
@@ -26,12 +26,26 @@ use std::{mem, ptr};
static JSPROXYSLOT_EXPANDO: u32 = 0;
/// Determine if this id shadows any existing properties for this proxy.
-pub unsafe extern "C" fn shadow_check_callback(_cx: *mut JSContext,
- _object: HandleObject,
- _id: HandleId)
+pub unsafe extern "C" fn shadow_check_callback(cx: *mut JSContext,
+ object: HandleObject,
+ id: HandleId)
-> DOMProxyShadowsResult {
- // XXX implement me
- DOMProxyShadowsResult::ShadowCheckFailed
+ // TODO: support OverrideBuiltins when #12978 is fixed.
+
+ rooted!(in(cx) let expando = get_expando_object(object));
+ if !expando.get().is_null() {
+ let mut has_own = false;
+ if !JS_AlreadyHasOwnPropertyById(cx, expando.handle(), id, &mut has_own) {
+ return DOMProxyShadowsResult::ShadowCheckFailed;
+ }
+
+ if has_own {
+ return DOMProxyShadowsResult::ShadowsViaDirectExpando;
+ }
+ }
+
+ // Our expando, if any, didn't shadow, so we're not shadowing at all.
+ DOMProxyShadowsResult::DoesntShadow
}
/// Initialize the infrastructure for DOM proxy objects.
diff --git a/tests/html/bindings_perf.html b/tests/html/bindings_perf.html
index d50cf940c32..123c53d6c00 100644
--- a/tests/html/bindings_perf.html
+++ b/tests/html/bindings_perf.html
@@ -1,6 +1,7 @@
+