diff --git a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions1.js b/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions1.js deleted file mode 100644 index f668719c654..00000000000 --- a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions1.js +++ /dev/null @@ -1,6 +0,0 @@ -// Forward to the target if the trap is not defined -target = {}; -var proxy = new Proxy(target, {}); -Object.preventExtensions(proxy); -assertEq(Object.isExtensible(target), false); -assertEq(Object.isExtensible(proxy), false); diff --git a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions2.js b/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions2.js deleted file mode 100644 index cc6db477b60..00000000000 --- 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); - called = true; - Object.preventExtensions(target); - return true; - } -}; -Object.preventExtensions(new Proxy(target, handler)); -assertEq(called, true); diff --git a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions3.js b/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions3.js deleted file mode 100644 index e04e1073fad..00000000000 --- a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions3.js +++ /dev/null @@ -1,13 +0,0 @@ -load(libdir + "asserts.js"); - -/* - * Throw a TypeError if the trap reports that the proxy has been made - * non-extensible, while the target is still extensible - */ -assertThrowsInstanceOf(function () { - Object.preventExtensions(new Proxy({}, { - preventExtensions: function (target) { - return true; - } - })); -}, TypeError); diff --git a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions4.js b/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions4.js deleted file mode 100644 index 4333464ba29..00000000000 --- a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions4.js +++ /dev/null @@ -1,13 +0,0 @@ -load(libdir + "asserts.js"); - -/* - * Throw a TypeError if the trap reports that the proxy cannot be made - * non-extensible - */ -assertThrowsInstanceOf(function () { - Object.preventExtensions(new Proxy({}, { - preventExtensions: function (target) { - return false; - } - })); -}, TypeError); diff --git a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions5.js b/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions5.js deleted file mode 100644 index d0b618fc123..00000000000 --- a/js/src/jit-test/tests/proxy/testDirectProxyPreventExtensions5.js +++ /dev/null @@ -1,12 +0,0 @@ -// Reflect side-effects from the trap -target = {}; -var proxy = new Proxy(target, { - preventExtensions: function (target) { - Object.preventExtensions(target); - return true; - } -}); -Object.preventExtensions(proxy); -assertEq(Object.isExtensible(target), false); -assertEq(Object.isExtensible(proxy), false); - diff --git a/js/src/js.msg b/js/src/js.msg index 8128405d81e..92d4519c6f9 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -375,5 +375,3 @@ MSG_DEF(JSMSG_MUST_REPORT_UNDEFINED, 321, 0, JSEXN_TYPEERR, "proxy must report MSG_DEF(JSMSG_CANT_SET_NW_NC, 322, 0, JSEXN_TYPEERR, "proxy can't successfully set a non-writable, non-configurable property") MSG_DEF(JSMSG_CANT_SET_WO_SETTER, 323, 0, JSEXN_TYPEERR, "proxy can't succesfully set an accessor property without a setter") MSG_DEF(JSMSG_DEBUG_BAD_REFERENT, 324, 2, JSEXN_TYPEERR, "{0} does not refer to {1}") -MSG_DEF(JSMSG_CANT_REPORT_NON_EXT, 325, 0, JSEXN_TYPEERR, "proxy can't report extensible object as non-extensible") -MSG_DEF(JSMSG_CANT_MAKE_NON_EXT, 326, 0, JSEXN_TYPEERR, "can't prevent extensions on object") diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index f78861756e7..1b4845ed716 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3482,7 +3482,7 @@ JS_DeepFreezeObject(JSContext *cx, JSObject *objArg) assertSameCompartment(cx, obj); /* Assume that non-extensible objects are already deep-frozen, to avoid divergence. */ - if (obj->isExtensible()) + if (!obj->isExtensible()) return true; if (!JSObject::freeze(cx, obj)) diff --git a/js/src/jsobj.h b/js/src/jsobj.h index 752b62f3328..bf14f7f2cad 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -548,9 +548,6 @@ struct JSObject : public js::ObjectImpl static inline unsigned getSealedOrFrozenAttributes(unsigned attrs, ImmutabilityType it); public: - friend class js::BaseProxyHandler; - - bool isExtensible() const; bool preventExtensions(JSContext *cx); /* ES5 15.2.3.8: non-extensible, all props non-configurable */ diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index ae8f98e8691..306c8cc6d5c 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -412,12 +412,6 @@ IndirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy, jsid id_, JS_DefinePropertyById(cx, obj, id, v, desc->getter, desc->setter, desc->attrs); } -bool -IndirectProxyHandler::preventExtensions(JSContext *cx, JSObject *proxy) -{ - return GetProxyTargetObject(proxy)->preventExtensions(cx); -} - bool IndirectProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoIdVector &props) @@ -448,12 +442,6 @@ IndirectProxyHandler::enumerate(JSContext *cx, JSObject *proxy, return GetPropertyNames(cx, target, 0, &props); } -bool -IndirectProxyHandler::isExtensible(JSObject *proxy) -{ - return GetProxyTargetObject(proxy)->isExtensible(); -} - bool IndirectProxyHandler::call(JSContext *cx, JSObject *proxy, unsigned argc, Value *vp) @@ -1043,7 +1031,6 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler { PropertyDescriptor *desc) MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc) MOZ_OVERRIDE; - virtual bool preventExtensions(JSContext *cx, JSObject *proxy) MOZ_OVERRIDE; virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoIdVector &props); virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp) MOZ_OVERRIDE; virtual bool enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &props) MOZ_OVERRIDE; @@ -1667,47 +1654,6 @@ ScriptedDirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy_, jsid return TrapDefineOwnProperty(cx, proxy, id, &v); } -bool -ScriptedDirectProxyHandler::preventExtensions(JSContext *cx, JSObject *proxy_) -{ - RootedObject proxy(cx, 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; - - // steps f-h - if (ToBoolean(trapResult)) { - if (target->isExtensible()) { - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_REPORT_NON_EXT); - return false; - } - return true; - } else { - JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_MAKE_NON_EXT); - return false; - } -} - bool ScriptedDirectProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy_, AutoIdVector &props) @@ -2340,14 +2286,6 @@ Proxy::defineProperty(JSContext *cx, JSObject *proxy_, jsid id_, const Value &v) Proxy::defineProperty(cx, proxy, id, &desc); } -bool -Proxy::preventExtensions(JSContext *cx, JSObject *proxy_) -{ - JS_CHECK_RECURSION(cx, return false); - RootedObject proxy(cx, proxy_); - return GetProxyHandler(proxy)->preventExtensions(cx, proxy); -} - bool Proxy::getOwnPropertyNames(JSContext *cx, JSObject *proxy_, AutoIdVector &props) { @@ -2515,12 +2453,6 @@ Proxy::iterate(JSContext *cx, HandleObject proxy_, unsigned flags, MutableHandle return EnumeratedIdVectorToIterator(cx, proxy, flags, props, vp); } -bool -Proxy::isExtensible(JSObject *proxy) -{ - return GetProxyHandler(proxy)->isExtensible(proxy); -} - bool Proxy::call(JSContext *cx, JSObject *proxy_, unsigned argc, Value *vp) { diff --git a/js/src/jsproxy.h b/js/src/jsproxy.h index cbd45115816..93a40005f88 100644 --- a/js/src/jsproxy.h +++ b/js/src/jsproxy.h @@ -49,7 +49,6 @@ class JS_FRIEND_API(Wrapper); class JS_FRIEND_API(BaseProxyHandler) { void *mFamily; bool mHasPrototype; - protected: // Subclasses may set this in their constructor. void setHasPrototype(bool hasPrototype) { mHasPrototype = hasPrototype; } @@ -92,7 +91,6 @@ class JS_FRIEND_API(BaseProxyHandler) { PropertyDescriptor *desc) = 0; virtual bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc) = 0; - virtual bool preventExtensions(JSContext *cx, JSObject *proxy); virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoIdVector &props) = 0; virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp) = 0; @@ -111,7 +109,6 @@ class JS_FRIEND_API(BaseProxyHandler) { Value *vp); /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy); virtual bool call(JSContext *cx, JSObject *proxy, unsigned argc, Value *vp); virtual bool construct(JSContext *cx, JSObject *proxy, unsigned argc, Value *argv, Value *rval); virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args); @@ -151,7 +148,6 @@ class JS_PUBLIC_API(IndirectProxyHandler) : public BaseProxyHandler { PropertyDescriptor *desc) MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc) MOZ_OVERRIDE; - virtual bool preventExtensions(JSContext *cx, JSObject *proxy) MOZ_OVERRIDE; virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoIdVector &props) MOZ_OVERRIDE; virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id, @@ -160,7 +156,6 @@ class JS_PUBLIC_API(IndirectProxyHandler) : public BaseProxyHandler { AutoIdVector &props) MOZ_OVERRIDE; /* Spidermonkey extensions. */ - virtual bool isExtensible(JSObject *proxy); virtual bool call(JSContext *cx, JSObject *proxy, unsigned argc, Value *vp) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, JSObject *proxy, unsigned argc, @@ -223,7 +218,6 @@ class Proxy { Value *vp); static bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc); static bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, const Value &v); - static bool preventExtensions(JSContext *cx, JSObject *proxy); static bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoIdVector &props); static bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp); static bool enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &props); @@ -240,7 +234,6 @@ class Proxy { static bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp); /* Spidermonkey extensions. */ - static bool isExtensible(JSObject *proxy); static bool call(JSContext *cx, JSObject *proxy, unsigned argc, Value *vp); static bool construct(JSContext *cx, JSObject *proxy, unsigned argc, Value *argv, Value *rval); static bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args); diff --git a/js/src/jsscope.cpp b/js/src/jsscope.cpp index 96864ae1daa..48e22fff833 100644 --- a/js/src/jsscope.cpp +++ b/js/src/jsscope.cpp @@ -1028,21 +1028,12 @@ Shape::setObjectParent(JSContext *cx, JSObject *parent, TaggedProto proto, Shape return replaceLastProperty(cx, base, proto, last); } -bool -JSObject::isExtensible() const -{ - if (isProxy()) - return Proxy::isExtensible(const_cast(this)); - return !lastProperty()->hasObjectFlag(js::BaseShape::NOT_EXTENSIBLE); -} - bool JSObject::preventExtensions(JSContext *cx) { JS_ASSERT(isExtensible()); + RootedObject self(cx, this); - if (self->isProxy()) - return Proxy::preventExtensions(cx, self); /* * Force lazy properties to be resolved by iterating over the objects' own @@ -1058,38 +1049,6 @@ JSObject::preventExtensions(JSContext *cx) return self->setFlag(cx, BaseShape::NOT_EXTENSIBLE, GENERATE_SHAPE); } -/* - * Per spec, preventExtensions should be a fundamental trap. We don't want to - * force consumers of BaseProxyHandler (i.e. DOM bindings) to implement yet - * another fundamental trap, however, so we provide a default implementation - * here. We cannot simply forward the operation to the target object, since - * BaseProxyHandler is not guaranteed to have one. Instead, we use the proxy's - * shape tree (as we would for normal objects) to store a flag indicating that - * the proxy is not extensible. - */ -bool -BaseProxyHandler::isExtensible(JSObject *proxy) -{ - return !proxy->lastProperty()->hasObjectFlag(js::BaseShape::NOT_EXTENSIBLE); -} - -bool -BaseProxyHandler::preventExtensions(JSContext *cx, JSObject *proxy_) -{ - JS_ASSERT(isExtensible()); - RootedObject proxy(cx, proxy_); - - /* - * Force lazy properties to be resolved by iterating over the objects' own - * properties. - */ - AutoIdVector props(cx); - if (!js::GetPropertyNames(cx, proxy, JSITER_HIDDEN | JSITER_OWNONLY, &props)) - return false; - JS_ASSERT(!proxy->isDenseArray()); - return proxy_->setFlag(cx, BaseShape::NOT_EXTENSIBLE, JSObject::GENERATE_SHAPE); -} - bool JSObject::setFlag(JSContext *cx, /*BaseShape::Flag*/ uint32_t flag_, GenerateShape generateShape) { diff --git a/js/src/jsscope.h b/js/src/jsscope.h index a7ec511634c..d869196e55c 100644 --- a/js/src/jsscope.h +++ b/js/src/jsscope.h @@ -15,7 +15,6 @@ #endif #include "jsobj.h" -#include "jsproxy.h" #include "jspropertytree.h" #include "jstypes.h" diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h index 6714a05ef28..bfeb290c7d5 100644 --- a/js/src/vm/CommonPropertyNames.h +++ b/js/src/vm/CommonPropertyNames.h @@ -106,7 +106,6 @@ macro(of, of, "of") \ macro(parseFloat, parseFloat, "parseFloat") \ macro(parseInt, parseInt, "parseInt") \ - macro(preventExtensions, preventExtensions, "preventExtensions") \ macro(propertyIsEnumerable, propertyIsEnumerable, "propertyIsEnumerable") \ macro(proto, proto, "__proto__") \ macro(return, return_, "return") \ diff --git a/js/src/vm/ObjectImpl-inl.h b/js/src/vm/ObjectImpl-inl.h index b30da6f6d76..f2265d2fcd8 100644 --- a/js/src/vm/ObjectImpl-inl.h +++ b/js/src/vm/ObjectImpl-inl.h @@ -100,6 +100,12 @@ js::ObjectImpl::nativeContainsNoAllocation(Shape &shape) return nativeLookupNoAllocation(shape.propid()) == &shape; } +inline bool +js::ObjectImpl::isExtensible() const +{ + return !lastProperty()->hasObjectFlag(BaseShape::NOT_EXTENSIBLE); +} + inline bool js::ObjectImpl::isDenseArray() const { diff --git a/js/src/vm/ObjectImpl.cpp b/js/src/vm/ObjectImpl.cpp index 9eb0251b1d8..5a5e57bbd19 100644 --- a/js/src/vm/ObjectImpl.cpp +++ b/js/src/vm/ObjectImpl.cpp @@ -414,7 +414,7 @@ DenseElementsHeader::defineElement(JSContext *cx, Handle obj, uint3 * If the element doesn't exist, we can only add it if the object is * extensible. */ - if (!obj->asObjectPtr()->isExtensible()) { + if (!obj->isExtensible()) { *succeeded = false; if (!shouldThrow) return true; diff --git a/js/src/vm/ObjectImpl.h b/js/src/vm/ObjectImpl.h index b7bc0081a25..56ab79a1b19 100644 --- a/js/src/vm/ObjectImpl.h +++ b/js/src/vm/ObjectImpl.h @@ -1016,6 +1016,8 @@ class ObjectImpl : public gc::Cell return type_->proto; } + inline bool isExtensible() const; + /* * XXX Once the property/element split of bug 586842 is complete, these * methods should move back to JSObject.