Backout 12465a1211e0 (bug 789897) for landing without addressing all review comments.

This commit is contained in:
Ryan VanderMeulen 2012-09-30 12:12:47 -04:00
parent df84ae2f04
commit abbf906749
16 changed files with 11 additions and 187 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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")

View File

@ -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))

View File

@ -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 */

View File

@ -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)
{

View File

@ -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);

View File

@ -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<JSObject *>(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)
{

View File

@ -15,7 +15,6 @@
#endif
#include "jsobj.h"
#include "jsproxy.h"
#include "jspropertytree.h"
#include "jstypes.h"

View File

@ -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") \

View File

@ -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
{

View File

@ -414,7 +414,7 @@ DenseElementsHeader::defineElement(JSContext *cx, Handle<ObjectImpl*> 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;

View File

@ -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.