Backed out bug 789897 due to regressions.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 29 Mar 2013 14:07:32 -0400
changeset 137933 dc0b6744aef665c2445664d3758fa828a28e3d8a
parent 137932 a61aa08ab4ac92a5f909a87f0aa717a05eb36df2
child 137934 af6a5d1a3097deb61215c8573ae3762d52dc3e2d
push id336
push userakeybl@mozilla.com
push dateMon, 17 Jun 2013 22:53:19 +0000
treeherdermozilla-release@574a39cdf657 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs789897
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out bug 789897 due to regressions.
dom/bindings/DOMJSProxyHandler.cpp
dom/bindings/DOMJSProxyHandler.h
js/src/builtin/Object.cpp
js/src/jit-test/tests/proxy/testDirectProxyDefineProperty2.js
js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions1.js
js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions2.js
js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions3.js
js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions4.js
js/src/js.msg
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/vm/CommonPropertyNames.h
js/src/vm/Debugger.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/ObjectImpl-inl.h
js/src/vm/ObjectImpl.h
js/src/vm/ScopeObject.cpp
js/src/vm/Shape.cpp
js/xpconnect/wrappers/XrayWrapper.cpp
js/xpconnect/wrappers/XrayWrapper.h
--- a/dom/bindings/DOMJSProxyHandler.cpp
+++ b/dom/bindings/DOMJSProxyHandler.cpp
@@ -71,30 +71,16 @@ DOMProxyHandler::EnsureExpandoObject(JSC
     cache->SetPreservingWrapper(true);
 
     js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(*expando));
   }
   return expando;
 }
 
 bool
-DOMProxyHandler::isExtensible(JSObject *proxy)
-{
-  return true; // always extensible per WebIDL
-}
-
-bool
-DOMProxyHandler::preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy)
-{
-  // Throw a TypeError, per WebIDL.
-  JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CHANGE_EXTENSIBILITY);
-  return false;
-}
-
-bool
 DOMProxyHandler::getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
                                        JSPropertyDescriptor* desc, unsigned flags)
 {
   if (!getOwnPropertyDescriptor(cx, proxy, id, desc, flags)) {
     return false;
   }
   if (desc->obj) {
     return true;
--- a/dom/bindings/DOMJSProxyHandler.h
+++ b/dom/bindings/DOMJSProxyHandler.h
@@ -31,26 +31,24 @@ class DOMProxyHandler : public js::BaseP
 {
 public:
   DOMProxyHandler(const DOMClass& aClass)
     : js::BaseProxyHandler(ProxyFamily()),
       mClass(aClass)
   {
   }
 
-  bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy) MOZ_OVERRIDE;
   bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
                             JSPropertyDescriptor* desc, unsigned flags) MOZ_OVERRIDE;
   bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
                       JSPropertyDescriptor* desc) MOZ_OVERRIDE;
   bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
                JS::Handle<jsid> id, bool* bp) MOZ_OVERRIDE;
   bool enumerate(JSContext* cx, JS::Handle<JSObject*> proxy, JS::AutoIdVector& props) MOZ_OVERRIDE;
   bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) MOZ_OVERRIDE;
-  bool isExtensible(JSObject *proxy) MOZ_OVERRIDE;
   using js::BaseProxyHandler::obj_toString;
 
   static JSObject* GetExpandoObject(JSObject* obj)
   {
     MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
     JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
     return v.isUndefined() ? NULL : v.toObjectOrNull();
   }
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -909,17 +909,17 @@ obj_preventExtensions(JSContext *cx, uns
     RootedObject obj(cx);
     if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.preventExtensions", &obj))
         return false;
 
     vp->setObject(*obj);
     if (!obj->isExtensible())
         return true;
 
-    return JSObject::preventExtensions(cx, obj);
+    return obj->preventExtensions(cx);
 }
 
 static JSBool
 obj_freeze(JSContext *cx, unsigned argc, Value *vp)
 {
     RootedObject obj(cx);
     if (!GetFirstArgumentAsObject(cx, argc, vp, "Object.freeze", &obj))
         return false;
--- a/js/src/jit-test/tests/proxy/testDirectProxyDefineProperty2.js
+++ b/js/src/jit-test/tests/proxy/testDirectProxyDefineProperty2.js
@@ -19,17 +19,10 @@ var handler = {
     }
 }
 var desc = {
     value: 'bar',
     writable: true,
     enumerable: false,
     configurable: true
 };
-
-var p = new Proxy(target, handler);
-Object.defineProperty(p, 'foo', desc);
+Object.defineProperty(new Proxy(target, handler), 'foo', desc);
 assertEq(called, true);
-assertEq(Object.isExtensible(target), true);
-assertEq(Object.isExtensible(p), true);
-Object.preventExtensions(target);
-assertEq(Object.isExtensible(target), false);
-assertEq(Object.isExtensible(p), false);
deleted file mode 100644
--- a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions1.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Forward to the target if the trap is not defined
-var target = {};
-Object.preventExtensions(new Proxy(target, {}));
-assertEq(Object.isExtensible(target), false);
deleted file mode 100644
--- a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions2.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Call the trap with the handler as the this value and the target as the first
- * argument.
- */
-var target = {};
-var called = false;
-var handler = {
-    preventExtensions: function (target1) {
-        assertEq(this, handler);
-        assertEq(target1, target);
-        Object.preventExtensions(target1);
-        called = true;
-        return true;
-    }
-};
-Object.preventExtensions(new Proxy(target, handler));
-assertEq(called, true);
deleted file mode 100644
--- a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions3.js
+++ /dev/null
@@ -1,10 +0,0 @@
-load(libdir + "asserts.js");
-
-// Throw a TypeError if the trap reports an extensible object as non-extensible
-assertThrowsInstanceOf(function () {
-    Object.preventExtensions(new Proxy({}, {
-        preventExtensions: function () {
-            return true;
-        }
-    }));
-}, TypeError);
deleted file mode 100644
--- a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions4.js
+++ /dev/null
@@ -1,10 +0,0 @@
-load(libdir + "asserts.js");
-
-// Throw a TypeError if the object refuses to be made non-extensible
-assertThrowsInstanceOf(function () {
-    Object.preventExtensions(new Proxy({}, {
-        preventExtensions: function () {
-            return false;
-        }
-    }));
-}, TypeError);
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -230,17 +230,17 @@ MSG_DEF(JSMSG_UNUSED176,              17
 MSG_DEF(JSMSG_UNUSED177,              177, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_UNUSED178,              178, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_UNUSED179,              179, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_UNUSED180,              180, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_UNUSED181,              181, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_BAD_GENERATOR_SEND,     182, 1, JSEXN_TYPEERR, "attempt to send {0} to newborn generator")
 MSG_DEF(JSMSG_UNUSED183,              183, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_UNUSED184,              184, 0, JSEXN_NONE, "")
-MSG_DEF(JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE, 185, 0, JSEXN_TYPEERR, "proxy can't report an extensible object as non-extensible")
+MSG_DEF(JSMSG_UNUSED185,              185, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_UNUSED186,              186, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_UNUSED187,              187, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_INCOMPATIBLE_METHOD,    188, 3, JSEXN_TYPEERR, "{0} {1} called on incompatible {2}")
 MSG_DEF(JSMSG_UNUSED189,              189, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_UNUSED190,              190, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_UNUSED191,              191, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_UNUSED192,              192, 0, JSEXN_NONE, "")
 MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP,      193, 0, JSEXN_SYNTAXERR, "invalid for each loop")
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1067,17 +1067,17 @@ JSObject::getSealedOrFrozenAttributes(un
 }
 
 /* static */ bool
 JSObject::sealOrFreeze(JSContext *cx, HandleObject obj, ImmutabilityType it)
 {
     assertSameCompartment(cx, obj);
     JS_ASSERT(it == SEAL || it == FREEZE);
 
-    if (obj->isExtensible() && !JSObject::preventExtensions(cx, obj))
+    if (obj->isExtensible() && !obj->preventExtensions(cx))
         return false;
 
     AutoIdVector props(cx);
     if (!GetPropertyNames(cx, obj, JSITER_HIDDEN | JSITER_OWNONLY, &props))
         return false;
 
     /* preventExtensions must sparsify dense objects, so we can assign to holes without checks. */
     JS_ASSERT_IF(obj->isNative(), obj->getDenseCapacity() == 0);
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -543,16 +543,18 @@ class JSObject : public js::ObjectImpl
      */
     static bool sealOrFreeze(JSContext *cx, js::HandleObject obj, ImmutabilityType it);
 
     static bool isSealedOrFrozen(JSContext *cx, js::HandleObject obj, ImmutabilityType it, bool *resultp);
 
     static inline unsigned getSealedOrFrozenAttributes(unsigned attrs, ImmutabilityType it);
 
   public:
+    bool preventExtensions(JSContext *cx);
+
     /* ES5 15.2.3.8: non-extensible, all props non-configurable */
     static inline bool seal(JSContext *cx, js::HandleObject obj) { return sealOrFreeze(cx, obj, SEAL); }
     /* ES5 15.2.3.9: non-extensible, all properties non-configurable, all data props read-only */
     static inline bool freeze(JSContext *cx, js::HandleObject obj) { return sealOrFreeze(cx, obj, FREEZE); }
 
     static inline bool isSealed(JSContext *cx, js::HandleObject obj, bool *resultp) {
         return isSealedOrFrozen(cx, obj, SEAL, resultp);
     }
@@ -953,17 +955,17 @@ class JSObject : public js::ObjectImpl
     inline bool isFunction() const;
     inline bool isGenerator() const;
     inline bool isGlobal() const;
     inline bool isMapIterator() const;
     inline bool isModule() const;
     inline bool isObject() const;
     inline bool isPrimitive() const;
     inline bool isPropertyIterator() const;
-    using js::ObjectImpl::isProxy;
+    inline bool isProxy() const;
     inline bool isRegExp() const;
     inline bool isRegExpStatics() const;
     inline bool isScope() const;
     inline bool isScript() const;
     inline bool isSetIterator() const;
     inline bool isStopIteration() const;
     inline bool isTypedArray() const;
     inline bool isWeakMap() const;
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -1253,19 +1253,19 @@ JSObject::getElementAttributes(JSContext
 JSObject::getSpecialAttributes(JSContext *cx, js::HandleObject obj,
                                js::SpecialId sid, unsigned *attrsp)
 {
     JS::RootedId id(cx, SPECIALID_TO_JSID(sid));
     return getGenericAttributes(cx, obj, id, attrsp);
 }
 
 inline bool
-js::ObjectImpl::isProxy() const
+JSObject::isProxy() const
 {
-    return js::IsProxy(const_cast<JSObject*>(this->asObjectPtr()));
+    return js::IsProxy(const_cast<JSObject*>(this));
 }
 
 inline bool
 JSObject::isCrossCompartmentWrapper() const
 {
     return js::IsCrossCompartmentWrapper(const_cast<JSObject*>(this));
 }
 
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -634,29 +634,16 @@ DirectProxyHandler::iterate(JSContext *c
                             MutableHandleValue vp)
 {
     assertEnteredPolicy(cx, proxy, JSID_VOID);
     JS_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
     RootedObject target(cx, GetProxyTargetObject(proxy));
     return GetIterator(cx, target, flags, vp);
 }
 
-bool
-DirectProxyHandler::isExtensible(JSObject *proxy)
-{
-    return GetProxyTargetObject(proxy)->isExtensible();
-}
-
-bool
-DirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy)
-{
-    RootedObject target(cx, GetProxyTargetObject(proxy));
-    return JSObject::preventExtensions(cx, target);
-}
-
 static bool
 GetFundamentalTrap(JSContext *cx, HandleObject handler, HandlePropertyName name,
                    MutableHandleValue fvalp)
 {
     JS_CHECK_RECURSION(cx, return false);
 
     return JSObject::getProperty(cx, handler, handler, name, fvalp);
 }
@@ -771,17 +758,16 @@ ArrayToIdVector(JSContext *cx, const Val
 
 /* Derived class for all scripted indirect proxy handlers. */
 class ScriptedIndirectProxyHandler : public BaseProxyHandler {
   public:
     ScriptedIndirectProxyHandler();
     virtual ~ScriptedIndirectProxyHandler();
 
     /* ES5 Harmony fundamental proxy traps. */
-    virtual bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                           PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props);
     virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) MOZ_OVERRIDE;
@@ -794,17 +780,16 @@ class ScriptedIndirectProxyHandler : pub
                      MutableHandleValue vp) MOZ_OVERRIDE;
     virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
                      bool strict, MutableHandleValue vp) MOZ_OVERRIDE;
     virtual bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags,
                          MutableHandleValue vp) MOZ_OVERRIDE;
 
     /* Spidermonkey extensions. */
-    virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE;
     virtual bool call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp) MOZ_OVERRIDE;
     virtual bool construct(JSContext *cx, HandleObject proxy, unsigned argc,
                            Value *argv, MutableHandleValue rval) MOZ_OVERRIDE;
     virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
                             CallArgs args) MOZ_OVERRIDE;
     virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) MOZ_OVERRIDE;
     virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint,
                               MutableHandleValue vp) MOZ_OVERRIDE;
@@ -818,24 +803,16 @@ ScriptedIndirectProxyHandler::ScriptedIn
         : BaseProxyHandler(&sScriptedIndirectProxyHandlerFamily)
 {
 }
 
 ScriptedIndirectProxyHandler::~ScriptedIndirectProxyHandler()
 {
 }
 
-bool
-ScriptedIndirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy)
-{
-    // Scripted indirect proxies don't support extensibility changes.
-    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CHANGE_EXTENSIBILITY);
-    return false;
-}
-
 static bool
 ReturnedValueMustNotBePrimitive(JSContext *cx, HandleObject proxy, JSAtom *atom, const Value &v)
 {
     if (v.isPrimitive()) {
         JSAutoByteString bytes;
         if (js_AtomToPrintableString(cx, atom, &bytes)) {
             RootedValue val(cx, ObjectOrNullValue(proxy));
             js_ReportValueError2(cx, JSMSG_BAD_TRAP_RETURN_VALUE,
@@ -1007,23 +984,16 @@ ScriptedIndirectProxyHandler::iterate(JS
         return false;
     if (!js_IsCallable(value))
         return BaseProxyHandler::iterate(cx, proxy, flags, vp);
     return Trap(cx, handler, value, 0, NULL, vp) &&
            ReturnedValueMustNotBePrimitive(cx, proxy, cx->names().iterate, vp);
 }
 
 bool
-ScriptedIndirectProxyHandler::isExtensible(JSObject *proxy)
-{
-    // Scripted indirect proxies don't support extensibility changes.
-    return true;
-}
-
-bool
 ScriptedIndirectProxyHandler::call(JSContext *cx, HandleObject proxy, unsigned argc,
                                    Value *vp)
 {
     assertEnteredPolicy(cx, proxy, JSID_VOID);
     AutoValueRooter rval(cx);
     RootedValue call(cx, GetCall(proxy));
     JSBool ok = Invoke(cx, vp[1], call, argc, JS_ARGV(cx, vp), rval.addr());
     if (ok)
@@ -1087,17 +1057,16 @@ GetDirectProxyHandlerObject(JSObject *pr
 
 /* Derived class for all scripted direct proxy handlers. */
 class ScriptedDirectProxyHandler : public DirectProxyHandler {
   public:
     ScriptedDirectProxyHandler();
     virtual ~ScriptedDirectProxyHandler();
 
     /* ES5 Harmony fundamental proxy traps. */
-    virtual bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                           PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props);
     virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) MOZ_OVERRIDE;
@@ -1656,58 +1625,16 @@ ScriptedDirectProxyHandler::ScriptedDire
         : DirectProxyHandler(&sScriptedDirectProxyHandlerFamily)
 {
 }
 
 ScriptedDirectProxyHandler::~ScriptedDirectProxyHandler()
 {
 }
 
-bool
-ScriptedDirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy)
-{
-    // step a
-    RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
-
-    // step b
-    RootedObject target(cx, GetProxyTargetObject(proxy));
-
-    // step c
-    RootedValue trap(cx);
-    if (!JSObject::getProperty(cx, handler, handler, cx->names().preventExtensions, &trap))
-        return false;
-
-    // step d
-    if (trap.isUndefined())
-        return DirectProxyHandler::preventExtensions(cx, proxy);
-
-    // step e
-    Value argv[] = {
-        ObjectValue(*target)
-    };
-    RootedValue trapResult(cx);
-    if (!Invoke(cx, ObjectValue(*handler), trap, 1, argv, trapResult.address()))
-        return false;
-
-    // step f
-    bool success = ToBoolean(trapResult);
-    if (success) {
-        // step g
-        if (target->isExtensible()) {
-            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE);
-            return false;
-        }
-        return true;
-    }
-
-    // step h
-    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CHANGE_EXTENSIBILITY);
-    return false;
-}
-
 // FIXME: Move to Proxy::getPropertyDescriptor once ScriptedIndirectProxy is removed
 bool
 ScriptedDirectProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                                   PropertyDescriptor *desc, unsigned flags)
 {
     JS_CHECK_RECURSION(cx, return false);
 
     if (!GetOwnPropertyDescriptor(cx, proxy, id, desc))
@@ -2591,30 +2518,16 @@ Proxy::iterate(JSContext *cx, HandleObje
         ? !Proxy::keys(cx, proxy, props)
         : !Proxy::enumerate(cx, proxy, props)) {
         return false;
     }
     return EnumeratedIdVectorToIterator(cx, proxy, flags, props, vp);
 }
 
 bool
-Proxy::preventExtensions(JSContext *cx, HandleObject proxy)
-{
-    JS_CHECK_RECURSION(cx, return false);
-    BaseProxyHandler *handler = GetProxyHandler(proxy);
-    return handler->preventExtensions(cx, proxy);
-}
-
-bool
-Proxy::isExtensible(JSObject *proxy)
-{
-    return GetProxyHandler(proxy)->isExtensible(proxy);
-}
-
-bool
 Proxy::call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = GetProxyHandler(proxy);
 
     // Because vp[0] is JS_CALLEE on the way in and JS_RVAL on the way out, we
     // can only set our default value once we're sure that we're not calling the
     // trap.
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -99,17 +99,16 @@ class JS_FRIEND_API(BaseProxyHandler) {
         GET,
         SET,
         CALL
     };
     virtual bool enter(JSContext *cx, HandleObject wrapper, HandleId id, Action act,
                        bool *bp);
 
     /* ES5 Harmony fundamental proxy traps. */
-    virtual bool preventExtensions(JSContext *cx, HandleObject proxy) = 0;
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) = 0;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy,
                                           HandleId id, PropertyDescriptor *desc,
                                           unsigned flags) = 0;
     virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                 PropertyDescriptor *desc) = 0;
     virtual bool getOwnPropertyNames(JSContext *cx, HandleObject proxy,
@@ -124,17 +123,16 @@ class JS_FRIEND_API(BaseProxyHandler) {
                      HandleId id, MutableHandleValue vp);
     virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver,
                      HandleId id, bool strict, MutableHandleValue vp);
     virtual bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props);
     virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags,
                          MutableHandleValue vp);
 
     /* Spidermonkey extensions. */
-    virtual bool isExtensible(JSObject *proxy) = 0;
     virtual bool call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp);
     virtual bool construct(JSContext *cx, HandleObject proxy, unsigned argc,
                            Value *argv, MutableHandleValue rval);
     virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
     virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx);
     virtual JSString *obj_toString(JSContext *cx, HandleObject proxy);
     virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent);
@@ -155,17 +153,16 @@ class JS_FRIEND_API(BaseProxyHandler) {
  * allows consumers of this class to forward to another object as transparently
  * and efficiently as possible.
  */
 class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler {
 public:
     explicit DirectProxyHandler(void *family);
 
     /* ES5 Harmony fundamental proxy traps. */
-    virtual bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy,
                                           HandleId id, PropertyDescriptor *desc,
                                           unsigned flags) MOZ_OVERRIDE;
     virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, HandleObject proxy,
@@ -185,17 +182,16 @@ public:
     virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver,
                      HandleId id, bool strict, MutableHandleValue vp) MOZ_OVERRIDE;
     virtual bool keys(JSContext *cx, HandleObject proxy,
                       AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags,
                          MutableHandleValue vp) MOZ_OVERRIDE;
 
     /* Spidermonkey extensions. */
-    virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE;
     virtual bool call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp) MOZ_OVERRIDE;
     virtual bool construct(JSContext *cx, HandleObject proxy, unsigned argc,
                            Value *argv, MutableHandleValue rval) MOZ_OVERRIDE;
     virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
                             CallArgs args) MOZ_OVERRIDE;
     virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
                              bool *bp) MOZ_OVERRIDE;
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
@@ -209,17 +205,16 @@ public:
                               MutableHandleValue vp) MOZ_OVERRIDE;
     virtual JSObject *weakmapKeyDelegate(JSObject *proxy);
 };
 
 /* Dispatch point for handlers that executes the appropriate C++ or scripted traps. */
 class Proxy {
   public:
     /* ES5 Harmony fundamental proxy traps. */
-    static bool preventExtensions(JSContext *cx, HandleObject proxy);
     static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                       PropertyDescriptor *desc, unsigned flags);
     static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, unsigned flags, HandleId id,
                                       MutableHandleValue vp);
     static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                          PropertyDescriptor *desc, unsigned flags);
     static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, unsigned flags, HandleId id,
                                          MutableHandleValue vp);
@@ -237,17 +232,16 @@ class Proxy {
     static bool getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject receiver,
                                     uint32_t index, MutableHandleValue vp, bool *present);
     static bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
                     bool strict, MutableHandleValue vp);
     static bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props);
     static bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp);
 
     /* Spidermonkey extensions. */
-    static bool isExtensible(JSObject *proxy);
     static bool call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp);
     static bool construct(JSContext *cx, HandleObject proxy, unsigned argc, Value *argv,
                           MutableHandleValue rval);
     static bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
     static bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
     static bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx);
     static JSString *obj_toString(JSContext *cx, HandleObject proxy);
     static JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent);
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -623,45 +623,26 @@ SecurityWrapper<Base>::SecurityWrapper(u
   : Base(flags)
 {
     Base::setSafeToUnwrap(false);
     BaseProxyHandler::setHasPolicy(true);
 }
 
 template <class Base>
 bool
-SecurityWrapper<Base>::isExtensible(JSObject *wrapper)
-{
-    // Just like BaseProxyHandler, SecurityWrappers claim by default to always
-    // be extensible, so as not to leak information about the state of the
-    // underlying wrapped thing.
-    return true;
-}
-
-template <class Base>
-bool
-SecurityWrapper<Base>::preventExtensions(JSContext *cx, HandleObject wrapper)
-{
-    // See above.
-    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNWRAP_DENIED);
-    return false;
-}
-
-template <class Base>
-bool
 SecurityWrapper<Base>::enter(JSContext *cx, HandleObject wrapper, HandleId id,
                              Wrapper::Action act, bool *bp)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNWRAP_DENIED);
     *bp = false;
     return false;
 }
 
-template <class Base>
-bool
+ template <class Base>
+ bool
 SecurityWrapper<Base>::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
                                   CallArgs args)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNWRAP_DENIED);
     return false;
 }
 
 template <class Base>
@@ -683,23 +664,16 @@ template class js::SecurityWrapper<Wrapp
 template class js::SecurityWrapper<CrossCompartmentWrapper>;
 
 DeadObjectProxy::DeadObjectProxy()
   : BaseProxyHandler(&sDeadObjectFamily)
 {
 }
 
 bool
-DeadObjectProxy::preventExtensions(JSContext *cx, HandleObject proxy)
-{
-    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEAD_OBJECT);
-    return false;
-}
-
-bool
 DeadObjectProxy::getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEAD_OBJECT);
     return false;
 }
 
 bool
@@ -736,24 +710,16 @@ DeadObjectProxy::delete_(JSContext *cx, 
 bool
 DeadObjectProxy::enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEAD_OBJECT);
     return false;
 }
 
 bool
-DeadObjectProxy::isExtensible(JSObject *proxy)
-{
-    // This is kind of meaningless, but dead-object semantics aside,
-    // [[Extensible]] always being true is consistent with other proxy types.
-    return true;
-}
-
-bool
 DeadObjectProxy::call(JSContext *cx, HandleObject wrapper, unsigned argc, Value *vp)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEAD_OBJECT);
     return false;
 }
 
 bool
 DeadObjectProxy::construct(JSContext *cx, HandleObject wrapper, unsigned argc,
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -138,18 +138,16 @@ class JS_FRIEND_API(CrossCompartmentWrap
  * access, relying on derived SecurityWrapper to block access when necessary.
  */
 template <class Base>
 class JS_FRIEND_API(SecurityWrapper) : public Base
 {
   public:
     SecurityWrapper(unsigned flags);
 
-    virtual bool isExtensible(JSObject *wrapper) MOZ_OVERRIDE;
-    virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) MOZ_OVERRIDE;
     virtual bool enter(JSContext *cx, HandleObject wrapper, HandleId id, Wrapper::Action act,
                        bool *bp) MOZ_OVERRIDE;
     virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
                             CallArgs args) MOZ_OVERRIDE;
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
                                JSContext *cx) MOZ_OVERRIDE;
     virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) MOZ_OVERRIDE;
 
@@ -167,30 +165,28 @@ typedef SecurityWrapper<CrossCompartment
 class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler
 {
   public:
     static int sDeadObjectFamily;
 
     explicit DeadObjectProxy();
 
     /* ES5 Harmony fundamental wrapper traps. */
-    virtual bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
                                           PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, HandleObject wrapper,
                                      AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) MOZ_OVERRIDE;
     virtual bool enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) MOZ_OVERRIDE;
 
     /* Spidermonkey extensions. */
-    virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE;
     virtual bool call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp);
     virtual bool construct(JSContext *cx, HandleObject proxy, unsigned argc,
                            Value *argv, MutableHandleValue rval);
     virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
                             CallArgs args) MOZ_OVERRIDE;
     virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx);
     virtual JSString *obj_toString(JSContext *cx, HandleObject proxy);
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -109,17 +109,16 @@
     macro(numeric, numeric, "numeric") \
     macro(objectNull, objectNull, "[object Null]") \
     macro(objectUndefined, objectUndefined, "[object Undefined]") \
     macro(of, of, "of") \
     macro(offset, offset, "offset") \
     macro(parseFloat, parseFloat, "parseFloat") \
     macro(parseInt, parseInt, "parseInt") \
     macro(pattern, pattern, "pattern") \
-    macro(preventExtensions, preventExtensions, "preventExtensions") \
     macro(propertyIsEnumerable, propertyIsEnumerable, "propertyIsEnumerable") \
     macro(proto, proto, "__proto__") \
     macro(return, return_, "return") \
     macro(sensitivity, sensitivity, "sensitivity") \
     macro(set, set, "set") \
     macro(shape, shape, "shape") \
     macro(source, source, "source") \
     macro(stack, stack, "stack") \
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -4494,17 +4494,17 @@ DebuggerObject_sealHelper(JSContext *cx,
     } else if (op == Freeze) {
         ok = JSObject::freeze(cx, obj);
     } else {
         JS_ASSERT(op == PreventExtensions);
         if (!obj->isExtensible()) {
             args.rval().setUndefined();
             return true;
         }
-        ok = JSObject::preventExtensions(cx, obj);
+        ok = obj->preventExtensions(cx);
     }
     if (!ok)
         return false;
     args.rval().setUndefined();
     return true;
 }
 
 static JSBool
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -371,17 +371,17 @@ GlobalObject::initFunctionAndObjectClass
         return NULL;
     self->setOriginalEval(evalobj);
 
     /* ES5 13.2.3: Construct the unique [[ThrowTypeError]] function object. */
     RootedFunction throwTypeError(cx, NewFunction(cx, NullPtr(), ThrowTypeError, 0,
                                                   JSFunction::NATIVE_FUN, self, NullPtr()));
     if (!throwTypeError)
         return NULL;
-    if (!JSObject::preventExtensions(cx, throwTypeError))
+    if (!throwTypeError->preventExtensions(cx))
         return NULL;
     self->setThrowTypeError(throwTypeError);
 
     RootedObject intrinsicsHolder(cx);
     if (cx->runtime->isSelfHostingGlobal(self)) {
         intrinsicsHolder = self;
     } else {
         intrinsicsHolder = NewObjectWithClassProto(cx, &ObjectClass, NULL, self);
--- a/js/src/vm/ObjectImpl-inl.h
+++ b/js/src/vm/ObjectImpl-inl.h
@@ -8,17 +8,16 @@
 #ifndef ObjectImpl_inl_h___
 #define ObjectImpl_inl_h___
 
 #include "mozilla/Assertions.h"
 
 #include "jscompartment.h"
 #include "jsgc.h"
 #include "jsinterp.h"
-#include "jsproxy.h"
 
 #include "gc/Heap.h"
 #include "gc/Marking.h"
 #include "js/TemplateLib.h"
 
 #include "ObjectImpl.h"
 
 namespace js {
@@ -81,20 +80,16 @@ inline bool
 js::ObjectImpl::nativeContains(JSContext *cx, Shape *shape)
 {
     return nativeLookup(cx, shape->propid()) == shape;
 }
 
 inline bool
 js::ObjectImpl::isExtensible() const
 {
-    if (this->isProxy())
-        return Proxy::isExtensible(const_cast<JSObject*>(this->asObjectPtr()));
-
-    // [[Extensible]] for ordinary non-proxy objects is an object flag.
     return !lastProperty()->hasObjectFlag(BaseShape::NOT_EXTENSIBLE);
 }
 
 inline uint32_t
 js::ObjectImpl::getDenseInitializedLength()
 {
     MOZ_ASSERT(isNative());
     return getElementsHeader()->initializedLength;
--- a/js/src/vm/ObjectImpl.h
+++ b/js/src/vm/ObjectImpl.h
@@ -1107,35 +1107,28 @@ class ObjectImpl : public gc::Cell
     }
 
     Class *getClass() const {
         return type_->clasp;
     }
 
     inline bool isExtensible() const;
 
-    // Attempt to change the [[Extensible]] bit on |obj| to false.  Callers
-    // must ensure that |obj| is currently extensible before calling this!
-    static bool
-    preventExtensions(JSContext *cx, Handle<ObjectImpl*> obj);
-
     inline HeapSlotArray getDenseElements();
     inline const Value & getDenseElement(uint32_t idx);
     inline bool containsDenseElement(uint32_t idx);
     inline uint32_t getDenseInitializedLength();
 
     bool makeElementsSparse(JSContext *cx) {
         NEW_OBJECT_REPRESENTATION_ONLY();
 
         MOZ_NOT_REACHED("NYI");
         return false;
     }
 
-    inline bool isProxy() const;
-
   protected:
 #ifdef DEBUG
     void checkShapeConsistency();
 #else
     void checkShapeConsistency() { }
 #endif
 
     Shape *
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -1302,22 +1302,16 @@ class DebugScopeProxy : public BaseProxy
     }
 
   public:
     static int family;
     static DebugScopeProxy singleton;
 
     DebugScopeProxy() : BaseProxyHandler(&family) {}
 
-    bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE
-    {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CHANGE_EXTENSIBILITY);
-        return false;
-    }
-
     bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc,
                                unsigned flags) MOZ_OVERRIDE
     {
         return getOwnPropertyDescriptor(cx, proxy, id, desc, flags);
     }
 
     bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                   PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE
@@ -1467,23 +1461,16 @@ class DebugScopeProxy : public BaseProxy
     }
 
     bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) MOZ_OVERRIDE
     {
         RootedValue idval(cx, IdToValue(id));
         return js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_CANT_DELETE,
                                         JSDVG_IGNORE_STACK, idval, NullPtr(), NULL, NULL);
     }
-
-    bool isExtensible(JSObject *proxy) MOZ_OVERRIDE
-    {
-        // always [[Extensible]], can't be made non-[[Extensible]], like most
-        // proxies
-        return true;
-    }
 };
 
 int DebugScopeProxy::family = 0;
 DebugScopeProxy DebugScopeProxy::singleton;
 
 /* static */ DebugScopeObject *
 DebugScopeObject::create(JSContext *cx, ScopeObject &scope, HandleObject enclosing)
 {
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -1023,29 +1023,22 @@ Shape::setObjectParent(JSContext *cx, JS
 
     StackBaseShape base(last);
     base.parent = parent;
 
     RootedShape lastRoot(cx, last);
     return replaceLastProperty(cx, base, proto, lastRoot);
 }
 
-/* static */ bool
-js::ObjectImpl::preventExtensions(JSContext *cx, Handle<ObjectImpl*> obj)
+bool
+JSObject::preventExtensions(JSContext *cx)
 {
-    MOZ_ASSERT(obj->isExtensible(),
-               "Callers must ensure |obj| is extensible before calling "
-               "preventExtensions");
+    JS_ASSERT(isExtensible());
 
-    if (obj->isProxy()) {
-        RootedObject object(cx, obj->asObjectPtr());
-        return js::Proxy::preventExtensions(cx, object);
-    }
-
-    RootedObject self(cx, obj->asObjectPtr());
+    RootedObject self(cx, this);
 
     /*
      * Force lazy properties to be resolved by iterating over the objects' own
      * properties.
      */
     AutoIdVector props(cx);
     if (!js::GetPropertyNames(cx, self, JSITER_HIDDEN | JSITER_OWNONLY, &props))
         return false;
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -1332,17 +1332,17 @@ IsXrayResolving(JSContext *cx, JSObject 
     {
         return false;
     }
     JSObject *holder =
       XPCWrappedNativeXrayTraits::singleton.ensureHolder(cx, wrapper);
     return XPCWrappedNativeXrayTraits::isResolving(cx, holder, id);
 }
 
-} // namespace XrayUtils
+}
 
 static JSBool
 XrayToString(JSContext *cx, unsigned argc, jsval *vp)
 {
     JSObject *wrapper = JS_THIS_OBJECT(cx, vp);
     if (!wrapper)
         return false;
     if (IsWrapper(wrapper) &&
@@ -1413,37 +1413,16 @@ DEBUG_CheckXBLLookup(JSContext *cx, JSPr
     }
 }
 #else
 #define DEBUG_CheckXBLLookup(a, b) {}
 #endif
 
 template <typename Base, typename Traits>
 bool
-XrayWrapper<Base, Traits>::isExtensible(JSObject *wrapper)
-{
-    // Xray wrappers are supposed to provide a clean view of the target
-    // reflector, hiding any modifications by script in the target scope.  So
-    // even if that script freezes the reflector, we don't want to make that
-    // visible to the caller. DOM reflectors are always extensible by default,
-    // so we can just return true here.
-    return true;
-}
-
-template <typename Base, typename Traits>
-bool
-XrayWrapper<Base, Traits>::preventExtensions(JSContext *cx, JS::Handle<JSObject*> wrapper)
-{
-    // See above.
-    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CHANGE_EXTENSIBILITY);
-    return false;
-}
-
-template <typename Base, typename Traits>
-bool
 XrayWrapper<Base, Traits>::getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper,
                                                  JS::Handle<jsid> id,
                                                  js::PropertyDescriptor *desc, unsigned flags)
 {
     assertEnteredPolicy(cx, wrapper, id);
     JSObject *holder = Traits::singleton.ensureHolder(cx, wrapper);
     if (Traits::isResolving(cx, holder, id)) {
         desc->obj = NULL;
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -61,18 +61,16 @@ XrayTraits* GetXrayTraits(JSObject *obj)
 // NB: Base *must* derive from JSProxyHandler
 template <typename Base, typename Traits = XPCWrappedNativeXrayTraits >
 class XrayWrapper : public Base {
   public:
     XrayWrapper(unsigned flags);
     virtual ~XrayWrapper();
 
     /* Fundamental proxy traps. */
-    virtual bool isExtensible(JSObject *wrapper) MOZ_OVERRIDE;
-    virtual bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> wrapper) MOZ_OVERRIDE;
     virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
                                        js::PropertyDescriptor *desc, unsigned flags);
     virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
                                           js::PropertyDescriptor *desc,
                                           unsigned flags);
     virtual bool defineProperty(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
                                 js::PropertyDescriptor *desc);
     virtual bool getOwnPropertyNames(JSContext *cx, JS::Handle<JSObject*> wrapper,