Bug 1113369, part 5 - [[Delete]] ObjectOpResult support. r=Waldo, r=bz in dom, r=dvander in js/ipc, r=bholley in js/xpconnect.

This commit is contained in:
Jason Orendorff 2015-02-04 10:20:04 -06:00
parent e065e5cceb
commit d1204e0adb
60 changed files with 372 additions and 303 deletions

View File

@ -210,10 +210,10 @@ WindowNamedPropertiesHandler::ownPropNames(JSContext* aCx,
bool
WindowNamedPropertiesHandler::delete_(JSContext* aCx,
JS::Handle<JSObject*> aProxy,
JS::Handle<jsid> aId, bool* aBp) const
JS::Handle<jsid> aId,
JS::ObjectOpResult &aResult) const
{
*aBp = false;
return true;
return aResult.failCantDeleteWindowNamedProperty();
}
static bool

View File

@ -35,7 +35,7 @@ public:
JS::AutoIdVector& aProps) const MOZ_OVERRIDE;
virtual bool
delete_(JSContext* aCx, JS::Handle<JSObject*> aProxy, JS::Handle<jsid> aId,
bool* aBp) const MOZ_OVERRIDE;
JS::ObjectOpResult &aResult) const MOZ_OVERRIDE;
virtual bool
preventExtensions(JSContext* aCx, JS::Handle<JSObject*> aProxy,
bool *succeeded) const MOZ_OVERRIDE

View File

@ -629,7 +629,7 @@ public:
JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id,
bool *bp) const MOZ_OVERRIDE;
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::MutableHandle<JSObject*> vp) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx,
@ -825,23 +825,20 @@ nsOuterWindowProxy::ownPropertyKeys(JSContext *cx,
bool
nsOuterWindowProxy::delete_(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool *bp) const
JS::Handle<jsid> id, JS::ObjectOpResult &result) const
{
if (nsCOMPtr<nsIDOMWindow> frame = GetSubframeWindow(cx, proxy, id)) {
// Reject (which means throw if strict, else return false) the delete.
// Except we don't even know whether we're strict. See bug 803157.
*bp = false;
return true;
// Fail (which means throw if strict, else return false).
return result.failCantDeleteWindowElement();
}
int32_t index = GetArrayIndexFromId(cx, id);
if (IsArrayIndex(index)) {
// Indexed, but not supported. Spec says return true.
*bp = true;
return true;
return result.succeed();
}
return js::Wrapper::delete_(cx, proxy, id, bp);
return js::Wrapper::delete_(cx, proxy, id, result);
}
bool

View File

@ -10307,7 +10307,7 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'proxy'),
Argument('JS::Handle<jsid>', 'id'),
Argument('bool*', 'bp')]
Argument('JS::ObjectOpResult&', 'opresult')]
ClassMethod.__init__(self, "delete_", "bool", args,
virtual=True, override=True, const=True)
self.descriptor = descriptor
@ -10316,6 +10316,12 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
def getDeleterBody(type, foundVar=None):
"""
type should be "Named" or "Indexed"
The possible outcomes:
- an error happened (the emitted code returns false)
- own property not found (foundVar=false, deleteSucceeded=true)
- own property found and deleted (foundVar=true, deleteSucceeded=true)
- own property found but can't be deleted (foundVar=true, deleteSucceeded=false)
"""
assert type in ("Named", "Indexed")
deleter = self.descriptor.operations[type + 'Deleter']
@ -10324,29 +10330,34 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
raise TypeError("Can't handle a deleter on an interface "
"that has unforgeables. Figure out how "
"that should work!")
decls = ""
if (not deleter.signatures()[0][0].isPrimitive() or
deleter.signatures()[0][0].nullable() or
deleter.signatures()[0][0].tag() != IDLType.Tags.bool):
setBp = "*bp = true;\n"
else:
decls += "bool result;\n"
# See if the deleter method is fallible.
t = deleter.signatures()[0][0]
if t.isPrimitive() and not t.nullable() and t.tag() == IDLType.Tags.bool:
# The deleter method has a boolean out-parameter. When a
# property is found, the out-param indicates whether it was
# successfully deleted.
decls = "bool result;\n"
if foundVar is None:
foundVar = "found"
decls += "bool found = false;\n"
setBp = fill(
setDS = fill(
"""
if (${foundVar}) {
*bp = result;
} else {
*bp = true;
if (!${foundVar}) {
deleteSucceeded = true;
}
""",
foundVar=foundVar)
else:
# No boolean out-parameter: if a property is found,
# deleting it always succeeds.
decls = ""
setDS = "deleteSucceeded = true;\n"
deleterClass = globals()["CGProxy%sDeleter" % type]
body = (decls +
deleterClass(self.descriptor, resultVar="result", foundVar=foundVar).define() +
setBp)
deleterClass(self.descriptor, resultVar="deleteSucceeded",
foundVar=foundVar).define() +
setDS)
elif getattr(self.descriptor, "supports%sProperties" % type)():
presenceCheckerClass = globals()["CGProxy%sPresenceChecker" % type]
foundDecl = ""
@ -10357,7 +10368,7 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
"""
$*{foundDecl}
$*{presenceChecker}
*bp = !${foundVar};
deleteSucceeded = !${foundVar};
""",
foundDecl=foundDecl,
presenceChecker=presenceCheckerClass(self.descriptor, foundVar=foundVar).define(),
@ -10378,9 +10389,9 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
"""
int32_t index = GetArrayIndexFromId(cx, id);
if (IsArrayIndex(index)) {
bool deleteSucceeded;
$*{indexedBody}
// We always return here, even if the property was not found
return true;
return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
}
""",
indexedBody=indexedBody)
@ -10393,9 +10404,10 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
delete += fill(
"""
bool found = false;
bool deleteSucceeded;
$*{namedBody}
if (found) {
return true;
return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
}
""",
namedBody=namedBody)
@ -10413,7 +10425,7 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
delete += dedent("""
return dom::DOMProxyHandler::delete_(cx, proxy, id, bp);
return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
""")
return delete

View File

@ -260,15 +260,14 @@ DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<JSObject*> r
bool
DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool* bp) const
JS::Handle<jsid> id, JS::ObjectOpResult &result) const
{
JS::Rooted<JSObject*> expando(cx);
if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
return JS_DeletePropertyById2(cx, expando, id, bp);
return JS_DeletePropertyById(cx, expando, id, result);
}
*bp = true;
return true;
return result.succeed();
}
bool

View File

@ -114,8 +114,8 @@ public:
virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::MutableHandle<JSPropertyDescriptor> desc,
JS::ObjectOpResult &result, bool *defined) const;
bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool* bp) const MOZ_OVERRIDE;
bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy,
bool *succeeded) const MOZ_OVERRIDE;
bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)

View File

@ -200,11 +200,11 @@ GetJSValFromKeyPathString(JSContext* aCx,
if (targetObject) {
// If this fails, we lose, and the web page sees a magical property
// appear on the object :-(
bool succeeded;
if (!JS_DeleteUCProperty2(aCx, targetObject,
targetObjectPropName.get(),
targetObjectPropName.Length(),
&succeeded)) {
JS::ObjectOpResult succeeded;
if (!JS_DeleteUCProperty(aCx, targetObject,
targetObjectPropName.get(),
targetObjectPropName.Length(),
succeeded)) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}

View File

@ -161,7 +161,8 @@ static bool
NPObjWrapper_AddProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp);
static bool
NPObjWrapper_DelProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, bool *succeeded);
NPObjWrapper_DelProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
JS::ObjectOpResult &result);
static bool
NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
@ -975,33 +976,33 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier npid)
}
nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
bool ok = false;
AutoJSExceptionReporter reporter(cx);
bool deleted = false;
JS::ObjectOpResult result;
JS::Rooted<JSObject*> obj(cx, npjsobj->mJSObj);
JSAutoCompartment ac(cx, obj);
NS_ASSERTION(NPIdentifierIsInt(npid) || NPIdentifierIsString(npid),
"id must be either string or int!\n");
JS::Rooted<jsid> id(cx, NPIdentifierToJSId(npid));
ok = ::JS_DeletePropertyById2(cx, obj, id, &deleted);
if (ok && deleted) {
if (!::JS_DeletePropertyById(cx, obj, id, result))
return false;
if (result) {
// FIXME: See bug 425823, we shouldn't need to do this, and once
// that bug is fixed we can remove this code.
bool hasProp;
ok = ::JS_HasPropertyById(cx, obj, id, &hasProp);
if (!::JS_HasPropertyById(cx, obj, id, &hasProp))
return false;
if (!hasProp)
return true;
if (ok && hasProp) {
// The property might have been deleted, but it got
// re-resolved, so no, it's not really deleted.
deleted = false;
}
// The property might have been deleted, but it got
// re-resolved, so no, it's not really deleted.
result.failCantDelete();
}
return ok && deleted;
return result.reportError(cx, obj, id);
}
//static
@ -1274,7 +1275,8 @@ NPObjWrapper_AddProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
}
static bool
NPObjWrapper_DelProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, bool *succeeded)
NPObjWrapper_DelProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
JS::ObjectOpResult &result)
{
NPObject *npobj = GetNPObject(cx, obj);
@ -1294,15 +1296,18 @@ NPObjWrapper_DelProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
if (!ReportExceptionIfPending(cx))
return false;
if (!hasProperty) {
*succeeded = true;
return true;
}
if (!hasProperty)
return result.succeed();
}
*succeeded = npobj->_class->removeProperty(npobj, identifier);
return ReportExceptionIfPending(cx);
// This removeProperty hook may throw an exception and return false; or just
// return false without an exception pending, which behaves like `delete
// obj.prop` returning false: in strict mode it becomes a TypeError. Legacy
// code---nothing else that uses the JSAPI works this way anymore.
bool succeeded = npobj->_class->removeProperty(npobj, identifier);
if (!ReportExceptionIfPending(cx))
return false;
return succeeded ? result.succeed() : result.failCantDelete();
}
static bool

View File

@ -342,8 +342,8 @@ nsXBLProtoImpl::UndefineFields(JSContext *cx, JS::Handle<JSObject*> obj) const
bool hasProp;
if (::JS_AlreadyHasOwnUCProperty(cx, obj, s, name.Length(), &hasProp) &&
hasProp) {
bool dummy;
::JS_DeleteUCProperty2(cx, obj, s, name.Length(), &dummy);
JS::ObjectOpResult ignored;
::JS_DeleteUCProperty(cx, obj, s, name.Length(), ignored);
}
}
}

View File

@ -56,8 +56,8 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
return Answer::RecvDefineProperty(ObjectId::deserialize(objId), id, flags, rs);
}
bool RecvDelete(const uint64_t &objId, const JSIDVariant &id,
ReturnStatus *rs, bool *success) {
return Answer::RecvDelete(ObjectId::deserialize(objId), id, rs, success);
ReturnStatus *rs) {
return Answer::RecvDelete(ObjectId::deserialize(objId), id, rs);
}
bool RecvHas(const uint64_t &objId, const JSIDVariant &id,
@ -147,9 +147,8 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
ReturnStatus *rs) {
return Base::SendDefineProperty(objId.serialize(), id, flags, rs);
}
bool SendDelete(const ObjectId &objId, const JSIDVariant &id,
ReturnStatus *rs, bool *success) {
return Base::SendDelete(objId.serialize(), id, rs, success);
bool SendDelete(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs) {
return Base::SendDelete(objId.serialize(), id, rs);
}
bool SendHas(const ObjectId &objId, const JSIDVariant &id,

View File

@ -28,7 +28,7 @@ both:
prio(high) sync GetPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
prio(high) sync GetOwnPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
prio(high) sync DefineProperty(uint64_t objId, JSIDVariant id, PPropertyDescriptor descriptor) returns (ReturnStatus rs);
prio(high) sync Delete(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool successful);
prio(high) sync Delete(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs);
prio(high) sync Has(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
prio(high) sync HasOwn(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);

View File

@ -195,14 +195,12 @@ WrapperAnswer::RecvDefineProperty(const ObjectId &objId, const JSIDVariant &idVa
}
bool
WrapperAnswer::RecvDelete(const ObjectId &objId, const JSIDVariant &idVar, ReturnStatus *rs,
bool *success)
WrapperAnswer::RecvDelete(const ObjectId &objId, const JSIDVariant &idVar, ReturnStatus *rs)
{
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects())))
return false;
JSContext *cx = jsapi.cx();
*success = false;
RootedObject obj(cx, findObjectById(cx, objId));
if (!obj)
@ -214,10 +212,10 @@ WrapperAnswer::RecvDelete(const ObjectId &objId, const JSIDVariant &idVar, Retur
if (!fromJSIDVariant(cx, idVar, &id))
return fail(cx, rs);
if (!JS_DeletePropertyById2(cx, obj, id, success))
ObjectOpResult success;
if (!JS_DeletePropertyById(cx, obj, id, success))
return fail(cx, rs);
return ok(rs);
return ok(rs, success);
}
bool

View File

@ -29,8 +29,7 @@ class WrapperAnswer : public virtual JavaScriptShared
PPropertyDescriptor *out);
bool RecvDefineProperty(const ObjectId &objId, const JSIDVariant &id,
const PPropertyDescriptor &flags, ReturnStatus *rs);
bool RecvDelete(const ObjectId &objId, const JSIDVariant &id,
ReturnStatus *rs, bool *success);
bool RecvDelete(const ObjectId &objId, const JSIDVariant &id, ReturnStatus *rs);
bool RecvHas(const ObjectId &objId, const JSIDVariant &id,
ReturnStatus *rs, bool *bp);

View File

@ -94,7 +94,8 @@ class CPOWProxyHandler : public BaseProxyHandler
ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id,
ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
@ -248,13 +249,14 @@ WrapperOwner::ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &p
}
bool
CPOWProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const
CPOWProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id,
ObjectOpResult &result) const
{
FORWARD(delete_, (cx, proxy, id, bp));
FORWARD(delete_, (cx, proxy, id, result));
}
bool
WrapperOwner::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
WrapperOwner::delete_(JSContext *cx, HandleObject proxy, HandleId id, ObjectOpResult &result)
{
ObjectId objId = idOf(proxy);
@ -263,12 +265,12 @@ WrapperOwner::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
return false;
ReturnStatus status;
if (!SendDelete(objId, idVar, &status, bp))
if (!SendDelete(objId, idVar, &status))
return ipcfail(cx);
LOG_STACK();
return ok(cx, status);
return ok(cx, status, result);
}
bool

View File

@ -35,7 +35,8 @@ class WrapperOwner : public virtual JavaScriptShared
JS::MutableHandle<JSPropertyDescriptor> desc,
JS::ObjectOpResult &result);
bool ownPropertyKeys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::ObjectOpResult &result);
bool preventExtensions(JSContext *cx, JS::HandleObject proxy, bool *succeeded);
bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible);
bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
@ -118,7 +119,7 @@ class WrapperOwner : public virtual JavaScriptShared
const PPropertyDescriptor &flags,
ReturnStatus *rs) = 0;
virtual bool SendDelete(const ObjectId &objId, const JSIDVariant &id,
ReturnStatus *rs, bool *success) = 0;
ReturnStatus *rs) = 0;
virtual bool SendHas(const ObjectId &objId, const JSIDVariant &id,
ReturnStatus *rs, bool *bp) = 0;

View File

@ -122,6 +122,9 @@ class ObjectOpResult
JS_PUBLIC_API(bool) failReadOnly();
JS_PUBLIC_API(bool) failGetterOnly();
JS_PUBLIC_API(bool) failCantSetInterposed();
JS_PUBLIC_API(bool) failCantDelete();
JS_PUBLIC_API(bool) failCantDeleteWindowElement();
JS_PUBLIC_API(bool) failCantDeleteWindowNamedProperty();
uint32_t failureCode() const {
MOZ_ASSERT(!ok());
@ -192,17 +195,17 @@ typedef bool
// If an error occurred, return false as per normal JSAPI error practice.
//
// If no error occurred, but the deletion attempt wasn't allowed (perhaps
// because the property was non-configurable), set *succeeded to false and
// because the property was non-configurable), call result.fail() and
// return true. This will cause |delete obj[id]| to evaluate to false in
// non-strict mode code, and to throw a TypeError in strict mode code.
//
// If no error occurred and the deletion wasn't disallowed (this is *not* the
// same as saying that a deletion actually occurred -- deleting a non-existent
// property, or an inherited property, is allowed -- it's just pointless),
// set *succeeded to true and return true.
// call result.succeed() and return true.
typedef bool
(* JSDeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
bool *succeeded);
JS::ObjectOpResult &result);
// The type of ObjectOps::enumerate. This callback overrides a portion of SpiderMonkey's default
// [[Enumerate]] internal method. When an ordinary object is enumerated, that object and each object
@ -303,7 +306,8 @@ typedef bool
(* GetOwnPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
typedef bool
(* DeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
(* DeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::ObjectOpResult &result);
typedef bool
(* WatchOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable);

View File

@ -256,7 +256,9 @@ class JS_FRIEND_API(BaseProxyHandler)
ObjectOpResult &result) const = 0;
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const = 0;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const = 0;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id,
ObjectOpResult &result) const = 0;
/*
* Because [[Enumerate]] is one of the standard traps it should be overridden.
* However for convenience BaseProxyHandler includes a pure virtual implementation,
@ -374,7 +376,7 @@ class JS_FRIEND_API(DirectProxyHandler) : public BaseProxyHandler
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id,
bool *bp) const MOZ_OVERRIDE;
ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy,
MutableHandleObject objp) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,

View File

@ -2059,18 +2059,16 @@ IsOwnId(JSContext *cx, HandleObject obj, HandleId id)
}
bool
TypedObject::obj_deleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
TypedObject::obj_deleteProperty(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult &result)
{
if (IsOwnId(cx, obj, id))
return ReportPropertyError(cx, JSMSG_CANT_DELETE, id);
RootedObject proto(cx, obj->getProto());
if (!proto) {
*succeeded = false;
return true;
}
if (!proto)
return result.succeed();
return DeleteProperty(cx, proto, id, succeeded);
return DeleteProperty(cx, proto, id, result);
}
bool

View File

@ -546,7 +546,8 @@ class TypedObject : public JSObject
static bool obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc);
static bool obj_deleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded);
static bool obj_deleteProperty(JSContext *cx, HandleObject obj, HandleId id,
ObjectOpResult &result);
static bool obj_enumerate(JSContext *cx, HandleObject obj, AutoIdVector &properties);

View File

@ -2005,8 +2005,10 @@ BaselineCompiler::emit_JSOP_STRICTSETELEM()
}
typedef bool (*DeleteElementFn)(JSContext *, HandleValue, HandleValue, bool *);
static const VMFunction DeleteElementStrictInfo = FunctionInfo<DeleteElementFn>(DeleteElement<true>);
static const VMFunction DeleteElementNonStrictInfo = FunctionInfo<DeleteElementFn>(DeleteElement<false>);
static const VMFunction DeleteElementStrictInfo
= FunctionInfo<DeleteElementFn>(DeleteElementJit<true>);
static const VMFunction DeleteElementNonStrictInfo
= FunctionInfo<DeleteElementFn>(DeleteElementJit<false>);
bool
BaselineCompiler::emit_JSOP_DELELEM()
@ -2170,8 +2172,10 @@ BaselineCompiler::emit_JSOP_GETXPROP()
}
typedef bool (*DeletePropertyFn)(JSContext *, HandleValue, HandlePropertyName, bool *);
static const VMFunction DeletePropertyStrictInfo = FunctionInfo<DeletePropertyFn>(DeleteProperty<true>);
static const VMFunction DeletePropertyNonStrictInfo = FunctionInfo<DeletePropertyFn>(DeleteProperty<false>);
static const VMFunction DeletePropertyStrictInfo =
FunctionInfo<DeletePropertyFn>(DeletePropertyJit<true>);
static const VMFunction DeletePropertyNonStrictInfo =
FunctionInfo<DeletePropertyFn>(DeletePropertyJit<false>);
bool
BaselineCompiler::emit_JSOP_DELPROP()

View File

@ -8147,9 +8147,9 @@ CodeGenerator::visitCallSetProperty(LCallSetProperty *ins)
typedef bool (*DeletePropertyFn)(JSContext *, HandleValue, HandlePropertyName, bool *);
static const VMFunction DeletePropertyStrictInfo =
FunctionInfo<DeletePropertyFn>(DeleteProperty<true>);
FunctionInfo<DeletePropertyFn>(DeletePropertyJit<true>);
static const VMFunction DeletePropertyNonStrictInfo =
FunctionInfo<DeletePropertyFn>(DeleteProperty<false>);
FunctionInfo<DeletePropertyFn>(DeletePropertyJit<false>);
void
CodeGenerator::visitCallDeleteProperty(LCallDeleteProperty *lir)
@ -8165,9 +8165,9 @@ CodeGenerator::visitCallDeleteProperty(LCallDeleteProperty *lir)
typedef bool (*DeleteElementFn)(JSContext *, HandleValue, HandleValue, bool *);
static const VMFunction DeleteElementStrictInfo =
FunctionInfo<DeleteElementFn>(DeleteElement<true>);
FunctionInfo<DeleteElementFn>(DeleteElementJit<true>);
static const VMFunction DeleteElementNonStrictInfo =
FunctionInfo<DeleteElementFn>(DeleteElement<false>);
FunctionInfo<DeleteElementFn>(DeleteElementJit<false>);
void
CodeGenerator::visitCallDeleteElement(LCallDeleteElement *lir)

View File

@ -340,6 +340,7 @@ MSG_DEF(JSMSG_CANT_CHANGE_EXTENSIBILITY, 0, JSEXN_TYPEERR, "can't change object'
MSG_DEF(JSMSG_CANT_DEFINE_INVALID, 0, JSEXN_TYPEERR, "proxy can't define an incompatible property descriptor")
MSG_DEF(JSMSG_CANT_DEFINE_NEW, 0, JSEXN_TYPEERR, "proxy can't define a new property on a non-extensible object")
MSG_DEF(JSMSG_CANT_DEFINE_NE_AS_NC, 0, JSEXN_TYPEERR, "proxy can't define a non-existent property as non-configurable")
MSG_DEF(JSMSG_PROXY_DELETE_RETURNED_FALSE, 1, JSEXN_TYPEERR, "can't delete property '{0}': proxy deleteProperty handler returned false")
MSG_DEF(JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE, 0, JSEXN_TYPEERR, "proxy can't report an extensible object as non-extensible")
MSG_DEF(JSMSG_CANT_REPORT_C_AS_NC, 0, JSEXN_TYPEERR, "proxy can't report existing configurable property as non-configurable")
MSG_DEF(JSMSG_CANT_REPORT_E_AS_NE, 0, JSEXN_TYPEERR, "proxy can't report an existing own property as non-existent on a non-extensible object")
@ -472,3 +473,7 @@ MSG_DEF(JSMSG_ATOMICS_WAIT_NOT_ALLOWED, 0, JSEXN_ERR, "waiting is not allowed o
// XPConnect wrappers
MSG_DEF(JSMSG_CANT_SET_INTERPOSED, 1, JSEXN_TYPEERR, "unable to set interposed data property '{0}'")
// DOM
MSG_DEF(JSMSG_CANT_DELETE_WINDOW_ELEMENT, 0, JSEXN_TYPEERR, "can't delete elements from a Window object")
MSG_DEF(JSMSG_CANT_DELETE_WINDOW_NAMED_PROPERTY, 1, JSEXN_TYPEERR, "can't delete property {0} from window's named properties object")

View File

@ -192,6 +192,24 @@ JS::ObjectOpResult::failCantSetInterposed()
return fail(JSMSG_CANT_SET_INTERPOSED);
}
JS_PUBLIC_API(bool)
JS::ObjectOpResult::failCantDelete()
{
return fail(JSMSG_CANT_DELETE);
}
JS_PUBLIC_API(bool)
JS::ObjectOpResult::failCantDeleteWindowElement()
{
return fail(JSMSG_CANT_DELETE_WINDOW_ELEMENT);
}
JS_PUBLIC_API(bool)
JS::ObjectOpResult::failCantDeleteWindowNamedProperty()
{
return fail(JSMSG_CANT_DELETE_WINDOW_NAMED_PROPERTY);
}
JS_PUBLIC_API(int64_t)
JS_Now()
{
@ -2909,7 +2927,7 @@ JS_SetUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t n
}
JS_PUBLIC_API(bool)
JS_DeletePropertyById2(JSContext *cx, HandleObject obj, HandleId id, bool *result)
JS_DeletePropertyById(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult &result)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
@ -2919,7 +2937,7 @@ JS_DeletePropertyById2(JSContext *cx, HandleObject obj, HandleId id, bool *resul
}
JS_PUBLIC_API(bool)
JS_DeleteElement2(JSContext *cx, HandleObject obj, uint32_t index, bool *result)
JS_DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, ObjectOpResult &result)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
@ -2929,7 +2947,7 @@ JS_DeleteElement2(JSContext *cx, HandleObject obj, uint32_t index, bool *result)
}
JS_PUBLIC_API(bool)
JS_DeleteProperty2(JSContext *cx, HandleObject obj, const char *name, bool *result)
JS_DeleteProperty(JSContext *cx, HandleObject obj, const char *name, ObjectOpResult &result)
{
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
@ -2942,8 +2960,8 @@ JS_DeleteProperty2(JSContext *cx, HandleObject obj, const char *name, bool *resu
}
JS_PUBLIC_API(bool)
JS_DeleteUCProperty2(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
bool *result)
JS_DeleteUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
ObjectOpResult &result)
{
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
@ -2958,22 +2976,22 @@ JS_DeleteUCProperty2(JSContext *cx, HandleObject obj, const char16_t *name, size
JS_PUBLIC_API(bool)
JS_DeletePropertyById(JSContext *cx, HandleObject obj, HandleId id)
{
bool junk;
return JS_DeletePropertyById2(cx, obj, id, &junk);
ObjectOpResult ignored;
return JS_DeletePropertyById(cx, obj, id, ignored);
}
JS_PUBLIC_API(bool)
JS_DeleteElement(JSContext *cx, HandleObject obj, uint32_t index)
{
bool junk;
return JS_DeleteElement2(cx, obj, index, &junk);
ObjectOpResult ignored;
return JS_DeleteElement(cx, obj, index, ignored);
}
JS_PUBLIC_API(bool)
JS_DeleteProperty(JSContext *cx, HandleObject obj, const char *name)
{
bool junk;
return JS_DeleteProperty2(cx, obj, name, &junk);
ObjectOpResult ignored;
return JS_DeleteProperty(cx, obj, name, ignored);
}
JS_PUBLIC_API(void)

View File

@ -2848,13 +2848,15 @@ extern JS_PUBLIC_API(bool)
JS_DeleteProperty(JSContext *cx, JS::HandleObject obj, const char *name);
extern JS_PUBLIC_API(bool)
JS_DeleteProperty2(JSContext *cx, JS::HandleObject obj, const char *name, bool *succeeded);
JS_DeleteProperty(JSContext *cx, JS::HandleObject obj, const char *name,
JS::ObjectOpResult &result);
extern JS_PUBLIC_API(bool)
JS_DeletePropertyById(JSContext *cx, JS::HandleObject obj, jsid id);
extern JS_PUBLIC_API(bool)
JS_DeletePropertyById2(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
JS_DeletePropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::ObjectOpResult &result);
extern JS_PUBLIC_API(bool)
JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
@ -2915,8 +2917,8 @@ JS_SetUCProperty(JSContext *cx, JS::HandleObject obj,
JS::HandleValue v);
extern JS_PUBLIC_API(bool)
JS_DeleteUCProperty2(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
bool *succeeded);
JS_DeleteUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
JS::ObjectOpResult &result);
extern JS_PUBLIC_API(JSObject *)
JS_NewArrayObject(JSContext *cx, const JS::HandleValueArray& contents);
@ -3001,7 +3003,7 @@ extern JS_PUBLIC_API(bool)
JS_DeleteElement(JSContext *cx, JS::HandleObject obj, uint32_t index);
extern JS_PUBLIC_API(bool)
JS_DeleteElement2(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded);
JS_DeleteElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::ObjectOpResult &result);
/*
* Assign 'undefined' to all of the object's non-reserved slots. Note: this is

View File

@ -374,13 +374,13 @@ SetArrayElement(JSContext *cx, HandleObject obj, double index, HandleValue v)
* If an error occurs while attempting to delete the element (that is, the call
* to [[Delete]] threw), return false.
*
* Otherwise set *succeeded to indicate whether the deletion attempt succeeded
* (that is, whether the call to [[Delete]] returned true or false). (Deletes
* generally fail only when the property is non-configurable, but proxies may
* implement different semantics.)
* Otherwise call result.succeed() or result.fail() to indicate whether the
* deletion attempt succeeded (that is, whether the call to [[Delete]] returned
* true or false). (Deletes generally fail only when the property is
* non-configurable, but proxies may implement different semantics.)
*/
static bool
DeleteArrayElement(JSContext *cx, HandleObject obj, double index, bool *succeeded)
DeleteArrayElement(JSContext *cx, HandleObject obj, double index, ObjectOpResult &result)
{
MOZ_ASSERT(index >= 0);
MOZ_ASSERT(floor(index) == index);
@ -403,31 +403,30 @@ DeleteArrayElement(JSContext *cx, HandleObject obj, double index, bool *succeede
}
}
*succeeded = true;
return true;
return result.succeed();
}
RootedId id(cx);
if (!ToId(cx, index, &id))
return false;
return DeleteProperty(cx, obj, id, succeeded);
return DeleteProperty(cx, obj, id, result);
}
/* ES6 20130308 draft 9.3.5 */
/* ES6 draft rev 32 (2 Febr 2015) 7.3.7 */
static bool
DeletePropertyOrThrow(JSContext *cx, HandleObject obj, double index)
{
bool succeeded;
if (!DeleteArrayElement(cx, obj, index, &succeeded))
ObjectOpResult success;
if (!DeleteArrayElement(cx, obj, index, success))
return false;
if (succeeded)
return true;
RootedId id(cx);
RootedValue indexv(cx, NumberValue(index));
if (!ValueToId<CanGC>(cx, indexv, &id))
return false;
return obj->reportNotConfigurable(cx, id, JSREPORT_ERROR);
if (!success) {
RootedId id(cx);
RootedValue indexv(cx, NumberValue(index));
if (!ValueToId<CanGC>(cx, indexv, &id))
return false;
return success.reportError(cx, obj, id);
}
return true;
}
bool
@ -621,8 +620,8 @@ js::ArraySetLength(JSContext *cx, Handle<ArrayObject*> arr, HandleId id,
oldLen--;
/* Steps 15b-d. */
bool deleteSucceeded;
if (!DeleteElement(cx, arr, oldLen, &deleteSucceeded))
ObjectOpResult deleteSucceeded;
if (!DeleteElement(cx, arr, oldLen, deleteSucceeded))
return false;
if (!deleteSucceeded) {
newLen = oldLen + 1;
@ -681,8 +680,8 @@ js::ArraySetLength(JSContext *cx, Handle<ArrayObject*> arr, HandleId id,
index = indexes[i];
/* Steps 15b-d. */
bool deleteSucceeded;
if (!DeleteElement(cx, arr, index, &deleteSucceeded))
ObjectOpResult deleteSucceeded;
if (!DeleteElement(cx, arr, index, deleteSucceeded))
return false;
if (!deleteSucceeded) {
newLen = index + 1;

View File

@ -320,17 +320,16 @@ CallJSSetterOp(JSContext *cx, SetterOp op, HandleObject obj, HandleId id, Mutabl
return op(cx, obj, id, vp, result);
}
static inline bool
inline bool
CallJSDeletePropertyOp(JSContext *cx, JSDeletePropertyOp op, HandleObject receiver, HandleId id,
bool *succeeded)
ObjectOpResult &result)
{
JS_CHECK_RECURSION(cx, return false);
assertSameCompartment(cx, receiver, id);
if (op)
return op(cx, receiver, id, succeeded);
*succeeded = true;
return true;
return op(cx, receiver, id, result);
return result.succeed();
}
inline bool

View File

@ -375,7 +375,8 @@ extern JS_FRIEND_API(bool)
proxy_GetOwnPropertyDescriptor(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
extern JS_FRIEND_API(bool)
proxy_DeleteProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
proxy_DeleteProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::ObjectOpResult &result);
extern JS_FRIEND_API(void)
proxy_Trace(JSTracer *trc, JSObject *obj);

View File

@ -738,8 +738,8 @@ DefinePropertyOnObject(JSContext *cx, HandleNativeObject obj, HandleId id, const
* redefining it or we had invoked its setter to change its value).
*/
if (callDelProperty) {
bool ignored;
if (!CallJSDeletePropertyOp(cx, obj->getClass()->delProperty, obj, id, &ignored))
ObjectOpResult ignored;
if (!CallJSDeletePropertyOp(cx, obj->getClass()->delProperty, obj, id, ignored))
return false;
}
@ -2571,9 +2571,11 @@ DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, H
bad:
if (named) {
bool succeeded;
ObjectOpResult ignored;
RootedId id(cx, AtomToId(atom));
DeleteProperty(cx, obj, id, &succeeded);
// XXX FIXME - absurd to call this here; instead define the property last.
DeleteProperty(cx, obj, id, ignored);
}
if (cached)
ClearClassObject(obj, key);

View File

@ -918,10 +918,10 @@ PutProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, MutableHan
* ES6 [[Delete]]. Equivalent to the JS code `delete obj[id]`.
*/
inline bool
DeleteProperty(JSContext *cx, js::HandleObject obj, js::HandleId id, bool *succeeded);
DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult &result);
inline bool
DeleteElement(JSContext *cx, js::HandleObject obj, uint32_t index, bool *succeeded);
DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, ObjectOpResult &result);
/*** SpiderMonkey nonstandard internal methods ***************************************************/

View File

@ -182,21 +182,21 @@ js::GetElementNoGC(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t in
}
inline bool
js::DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
js::DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult &result)
{
MarkTypePropertyNonData(cx, obj, id);
if (DeletePropertyOp op = obj->getOps()->deleteProperty)
return op(cx, obj, id, succeeded);
return NativeDeleteProperty(cx, obj.as<NativeObject>(), id, succeeded);
return op(cx, obj, id, result);
return NativeDeleteProperty(cx, obj.as<NativeObject>(), id, result);
}
inline bool
js::DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, bool *succeeded)
js::DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, ObjectOpResult &result)
{
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
return DeleteProperty(cx, obj, id, succeeded);
return DeleteProperty(cx, obj, id, result);
}

View File

@ -712,8 +712,8 @@ Walk(JSContext *cx, HandleObject holder, HandleId name, HandleValue reviver, Mut
if (newElement.isUndefined()) {
/* Step 2a(iii)(2). */
bool succeeded;
if (!DeleteProperty(cx, obj, id, &succeeded))
ObjectOpResult ignored;
if (!DeleteProperty(cx, obj, id, ignored))
return false;
} else {
/* Step 2a(iii)(3). */
@ -740,8 +740,8 @@ Walk(JSContext *cx, HandleObject holder, HandleId name, HandleValue reviver, Mut
if (newElement.isUndefined()) {
/* Step 2b(ii)(2). */
bool succeeded;
if (!DeleteProperty(cx, obj, id, &succeeded))
ObjectOpResult ignored;
if (!DeleteProperty(cx, obj, id, ignored))
return false;
} else {
/* Step 2b(ii)(3). */

View File

@ -121,7 +121,8 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool ownPropertyKeys(JSContext *cx, HandleObject wrapper,
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id,
ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject wrapper, MutableHandleObject objp) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
MutableHandleObject protop) const MOZ_OVERRIDE;

View File

@ -70,11 +70,12 @@ CrossCompartmentWrapper::ownPropertyKeys(JSContext *cx, HandleObject wrapper,
}
bool
CrossCompartmentWrapper::delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const
CrossCompartmentWrapper::delete_(JSContext *cx, HandleObject wrapper, HandleId id,
ObjectOpResult &result) const
{
PIERCE(cx, wrapper,
NOTHING,
Wrapper::delete_(cx, wrapper, id, bp),
Wrapper::delete_(cx, wrapper, id, result),
NOTHING);
}

View File

@ -48,7 +48,8 @@ DeadObjectProxy::ownPropertyKeys(JSContext *cx, HandleObject wrapper,
}
bool
DeadObjectProxy::delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const
DeadObjectProxy::delete_(JSContext *cx, HandleObject wrapper, HandleId id,
ObjectOpResult &result) const
{
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
return false;

View File

@ -26,7 +26,8 @@ class DeadObjectProxy : public BaseProxyHandler
ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool ownPropertyKeys(JSContext *cx, HandleObject wrapper,
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id,
ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject wrapper, MutableHandleObject objp) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
MutableHandleObject protop) const MOZ_OVERRIDE;

View File

@ -52,11 +52,12 @@ DirectProxyHandler::ownPropertyKeys(JSContext *cx, HandleObject proxy,
}
bool
DirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const
DirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id,
ObjectOpResult &result) const
{
assertEnteredPolicy(cx, proxy, id, SET);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return DeleteProperty(cx, target, id, bp);
return DeleteProperty(cx, target, id, result);
}
bool

View File

@ -159,15 +159,18 @@ Proxy::ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
}
bool
Proxy::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
Proxy::delete_(JSContext *cx, HandleObject proxy, HandleId id, ObjectOpResult &result)
{
JS_CHECK_RECURSION(cx, return false);
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
*bp = true; // default result if we refuse to perform this action
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
if (!policy.allowed())
return policy.returnValue();
return proxy->as<ProxyObject>().handler()->delete_(cx, proxy, id, bp);
if (!policy.allowed()) {
bool ok = policy.returnValue();
if (ok)
result.succeed();
return ok;
}
return proxy->as<ProxyObject>().handler()->delete_(cx, proxy, id, result);
}
JS_FRIEND_API(bool)
@ -597,13 +600,11 @@ js::proxy_GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
}
bool
js::proxy_DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
js::proxy_DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult &result)
{
bool deleted;
if (!Proxy::delete_(cx, obj, id, &deleted))
if (!Proxy::delete_(cx, obj, id, result))
return false;
*succeeded = deleted;
return SuppressDeletedProperty(cx, obj, id);
return SuppressDeletedProperty(cx, obj, id); // XXX is this necessary?
}
void

View File

@ -31,7 +31,7 @@ class Proxy
static bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
MutableHandle<JSPropertyDescriptor> desc, ObjectOpResult &result);
static bool ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props);
static bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp);
static bool delete_(JSContext *cx, HandleObject proxy, HandleId id, ObjectOpResult &result);
static bool enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp);
static bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible);
static bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded);

View File

@ -689,9 +689,10 @@ ScriptedDirectProxyHandler::ownPropertyKeys(JSContext *cx, HandleObject proxy,
cx->names().ownKeys);
}
// ES6 (5 April 2014) 9.5.10 Proxy.[[Delete]](P)
// ES6 draft rev 32 (2 Feb 2014) 9.5.10 Proxy.[[Delete]](P)
bool
ScriptedDirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const
ScriptedDirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id,
ObjectOpResult &result) const
{
// step 2
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
@ -702,19 +703,19 @@ ScriptedDirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId
return false;
}
// step 4
// steps 4-5
RootedObject target(cx, proxy->as<ProxyObject>().target());
// step 5
// steps 6-7
RootedValue trap(cx);
if (!GetProperty(cx, handler, handler, cx->names().deleteProperty, &trap))
return false;
// step 7
if (trap.isUndefined())
return DirectProxyHandler::delete_(cx, proxy, id, bp);
// step 8
if (trap.isUndefined())
return DirectProxyHandler::delete_(cx, proxy, id, result);
// steps 9-10
RootedValue value(cx);
if (!IdToStringOrSymbol(cx, id, &value))
return false;
@ -726,28 +727,24 @@ ScriptedDirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId
if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
return false;
// step 9
if (ToBoolean(trapResult)) {
// step 12
Rooted<PropertyDescriptor> desc(cx);
if (!GetOwnPropertyDescriptor(cx, target, id, &desc))
return false;
// step 11
if (!ToBoolean(trapResult))
return result.fail(JSMSG_PROXY_DELETE_RETURNED_FALSE);
// step 14-15
if (desc.object() && desc.isPermanent()) {
RootedValue v(cx, IdToValue(id));
ReportValueError(cx, JSMSG_CANT_DELETE, JSDVG_IGNORE_STACK, v, js::NullPtr());
return false;
}
// steps 12-13
Rooted<PropertyDescriptor> desc(cx);
if (!GetOwnPropertyDescriptor(cx, target, id, &desc))
return false;
// step 16
*bp = true;
return true;
// step 14-15
if (desc.object() && desc.isPermanent()) {
RootedValue v(cx, IdToValue(id));
ReportValueError(cx, JSMSG_CANT_DELETE, JSDVG_IGNORE_STACK, v, js::NullPtr());
return false;
}
// step 11
*bp = false;
return true;
// step 16
return result.succeed();
}
// ES6 (14 October, 2014) 9.5.11 Proxy.[[Enumerate]]

View File

@ -26,7 +26,8 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id,
ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp) const MOZ_OVERRIDE;
/* These two are standard internal methods but aren't implemented to spec yet. */

View File

@ -219,13 +219,21 @@ ScriptedIndirectProxyHandler::ownPropertyKeys(JSContext *cx, HandleObject proxy,
}
bool
ScriptedIndirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const
ScriptedIndirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id,
ObjectOpResult &result) const
{
RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy));
RootedValue fval(cx), value(cx);
return GetFundamentalTrap(cx, handler, cx->names().delete_, &fval) &&
Trap1(cx, handler, fval, id, &value) &&
ValueToBool(value, bp);
if (!GetFundamentalTrap(cx, handler, cx->names().delete_, &fval))
return false;
if (!Trap1(cx, handler, fval, id, &value))
return false;
if (ToBoolean(value))
result.succeed();
else
result.fail(JSMSG_PROXY_DELETE_RETURNED_FALSE);
return true;
}
bool

View File

@ -27,7 +27,8 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id,
ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy,
MutableHandleObject objp) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;

View File

@ -86,7 +86,7 @@ reportCompare("f", value[5], summary + ': push String object index 5');
// pop
value = 'abc';
expect = "TypeError: property Array.prototype.pop.call(...) is non-configurable and can't be deleted";
expect = "TypeError: property 2 is non-configurable and can't be deleted";
try
{
actual = Array.prototype.pop.call(value);

View File

@ -274,7 +274,7 @@ ArgumentsObject::createForIon(JSContext *cx, jit::JitFrameLayout *frame, HandleO
}
static bool
args_delProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
args_delProperty(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult &result)
{
ArgumentsObject &argsobj = obj->as<ArgumentsObject>();
if (JSID_IS_INT(id)) {
@ -286,8 +286,7 @@ args_delProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
} else if (JSID_IS_ATOM(id, cx->names().callee)) {
argsobj.as<NormalArgumentsObject>().clearCallee();
}
*succeeded = true;
return true;
return result.succeed();
}
static bool
@ -353,8 +352,8 @@ ArgSetter(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp,
* that we must define the property instead of setting it in case the user
* has changed the prototype to an object that has a setter for this id.
*/
bool succeeded;
return NativeDeleteProperty(cx, argsobj, id, &succeeded) &&
ObjectOpResult ignored;
return NativeDeleteProperty(cx, argsobj, id, ignored) &&
NativeDefineProperty(cx, argsobj, id, vp, nullptr, nullptr, attrs, result);
}
@ -469,8 +468,8 @@ StrictArgSetter(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue
* simple data property. Note that we rely on args_delProperty to clear the
* corresponding reserved slot so the GC can collect its value.
*/
bool succeeded;
return NativeDeleteProperty(cx, argsobj, id, &succeeded) &&
ObjectOpResult ignored;
return NativeDeleteProperty(cx, argsobj, id, ignored) &&
NativeDefineProperty(cx, argsobj, id, vp, nullptr, nullptr, attrs, result);
}

View File

@ -6803,10 +6803,10 @@ DebuggerObject_deleteProperty(JSContext *cx, unsigned argc, Value *vp)
ac.emplace(cx, obj);
ErrorCopier ec(ac);
bool succeeded;
if (!DeleteProperty(cx, obj, id, &succeeded))
ObjectOpResult result;
if (!DeleteProperty(cx, obj, id, result))
return false;
args.rval().setBoolean(succeeded);
args.rval().setBoolean(result.ok());
return true;
}

View File

@ -2333,15 +2333,15 @@ CASE(JSOP_STRICTDELPROP)
RootedObject &obj = rootObject0;
FETCH_OBJECT(cx, -1, obj);
bool succeeded;
if (!DeleteProperty(cx, obj, id, &succeeded))
ObjectOpResult result;
if (!DeleteProperty(cx, obj, id, result))
goto error;
if (!succeeded && JSOp(*REGS.pc) == JSOP_STRICTDELPROP) {
obj->reportNotConfigurable(cx, id);
if (!result && JSOp(*REGS.pc) == JSOP_STRICTDELPROP) {
result.reportError(cx, obj, id);
goto error;
}
MutableHandleValue res = REGS.stackHandleAt(-1);
res.setBoolean(succeeded);
res.setBoolean(result.ok());
}
END_CASE(JSOP_DELPROP)
@ -2357,19 +2357,19 @@ CASE(JSOP_STRICTDELELEM)
RootedValue &propval = rootValue0;
propval = REGS.sp[-1];
bool succeeded;
ObjectOpResult result;
RootedId &id = rootId0;
if (!ValueToId<CanGC>(cx, propval, &id))
goto error;
if (!DeleteProperty(cx, obj, id, &succeeded))
if (!DeleteProperty(cx, obj, id, result))
goto error;
if (!succeeded && JSOp(*REGS.pc) == JSOP_STRICTDELELEM) {
obj->reportNotConfigurable(cx, id);
if (!result && JSOp(*REGS.pc) == JSOP_STRICTDELELEM) {
result.reportError(cx, obj, id);
goto error;
}
MutableHandleValue res = REGS.stackHandleAt(-2);
res.setBoolean(succeeded);
res.setBoolean(result.ok());
REGS.sp--;
}
END_CASE(JSOP_DELELEM)
@ -3833,29 +3833,35 @@ js::GetAndClearException(JSContext *cx, MutableHandleValue res)
template <bool strict>
bool
js::DeleteProperty(JSContext *cx, HandleValue v, HandlePropertyName name, bool *bp)
js::DeletePropertyJit(JSContext *cx, HandleValue v, HandlePropertyName name, bool *bp)
{
RootedObject obj(cx, ToObjectFromStack(cx, v));
if (!obj)
return false;
RootedId id(cx, NameToId(name));
if (!DeleteProperty(cx, obj, id, bp))
ObjectOpResult result;
if (!DeleteProperty(cx, obj, id, result))
return false;
if (strict && !*bp) {
obj->reportNotConfigurable(cx, NameToId(name));
return false;
if (strict) {
if (!result)
return result.reportError(cx, obj, id);
*bp = true;
} else {
*bp = result.ok();
}
return true;
}
template bool js::DeleteProperty<true> (JSContext *cx, HandleValue val, HandlePropertyName name, bool *bp);
template bool js::DeleteProperty<false>(JSContext *cx, HandleValue val, HandlePropertyName name, bool *bp);
template bool js::DeletePropertyJit<true> (JSContext *cx, HandleValue val, HandlePropertyName name,
bool *bp);
template bool js::DeletePropertyJit<false>(JSContext *cx, HandleValue val, HandlePropertyName name,
bool *bp);
template <bool strict>
bool
js::DeleteElement(JSContext *cx, HandleValue val, HandleValue index, bool *bp)
js::DeleteElementJit(JSContext *cx, HandleValue val, HandleValue index, bool *bp)
{
RootedObject obj(cx, ToObjectFromStack(cx, val));
if (!obj)
@ -3864,18 +3870,22 @@ js::DeleteElement(JSContext *cx, HandleValue val, HandleValue index, bool *bp)
RootedId id(cx);
if (!ValueToId<CanGC>(cx, index, &id))
return false;
if (!DeleteProperty(cx, obj, id, bp))
ObjectOpResult result;
if (!DeleteProperty(cx, obj, id, result))
return false;
if (strict && !*bp) {
obj->reportNotConfigurable(cx, id);
return false;
if (strict) {
if (!result)
return result.reportError(cx, obj, id);
*bp = true;
} else {
*bp = result.ok();
}
return true;
}
template bool js::DeleteElement<true> (JSContext *, HandleValue, HandleValue, bool *succeeded);
template bool js::DeleteElement<false>(JSContext *, HandleValue, HandleValue, bool *succeeded);
template bool js::DeleteElementJit<true> (JSContext *, HandleValue, HandleValue, bool *succeeded);
template bool js::DeleteElementJit<false>(JSContext *, HandleValue, HandleValue, bool *succeeded);
bool
js::GetElement(JSContext *cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue vp)
@ -3974,11 +3984,11 @@ js::DeleteNameOperation(JSContext *cx, HandlePropertyName name, HandleObject sco
return false;
}
bool succeeded;
ObjectOpResult result;
RootedId id(cx, NameToId(name));
if (!DeleteProperty(cx, scope, id, &succeeded))
if (!DeleteProperty(cx, scope, id, result))
return false;
res.setBoolean(succeeded);
res.setBoolean(result.ok());
return true;
}

View File

@ -343,11 +343,11 @@ UrshValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Mutabl
template <bool strict>
bool
DeleteProperty(JSContext *ctx, HandleValue val, HandlePropertyName name, bool *bv);
DeletePropertyJit(JSContext *ctx, HandleValue val, HandlePropertyName name, bool *bv);
template <bool strict>
bool
DeleteElement(JSContext *cx, HandleValue val, HandleValue index, bool *bv);
DeleteElementJit(JSContext *cx, HandleValue val, HandleValue index, bool *bv);
bool
DefFunOperation(JSContext *cx, HandleScript script, HandleObject scopeChain, HandleFunction funArg);

View File

@ -2322,7 +2322,8 @@ js::NativeSetElement(JSContext *cx, HandleNativeObject obj, HandleObject receive
// ES6 draft rev31 9.1.10 [[Delete]]
bool
js::NativeDeleteProperty(JSContext *cx, HandleNativeObject obj, HandleId id, bool *succeeded)
js::NativeDeleteProperty(JSContext *cx, HandleNativeObject obj, HandleId id,
ObjectOpResult &result)
{
// Steps 2-3.
RootedShape shape(cx);
@ -2333,20 +2334,18 @@ js::NativeDeleteProperty(JSContext *cx, HandleNativeObject obj, HandleId id, boo
if (!shape) {
// If no property call the class's delProperty hook, passing succeeded
// as the result parameter. This always succeeds when there is no hook.
return CallJSDeletePropertyOp(cx, obj->getClass()->delProperty, obj, id, succeeded);
return CallJSDeletePropertyOp(cx, obj->getClass()->delProperty, obj, id, result);
}
cx->runtime()->gc.poke();
// Step 6. Non-configurable property.
if (GetShapeAttributes(obj, shape) & JSPROP_PERMANENT) {
*succeeded = false;
return true;
}
if (GetShapeAttributes(obj, shape) & JSPROP_PERMANENT)
return result.failCantDelete();
if (!CallJSDeletePropertyOp(cx, obj->getClass()->delProperty, obj, id, succeeded))
if (!CallJSDeletePropertyOp(cx, obj->getClass()->delProperty, obj, id, result))
return false;
if (!*succeeded)
if (!result)
return true;
// Step 5.

View File

@ -1326,7 +1326,7 @@ NativeSetElement(JSContext *cx, HandleNativeObject obj, HandleObject receiver, u
MutableHandleValue vp, ObjectOpResult &result);
extern bool
NativeDeleteProperty(JSContext *cx, HandleNativeObject obj, HandleId id, bool *succeeded);
NativeDeleteProperty(JSContext *cx, HandleNativeObject obj, HandleId id, ObjectOpResult &result);
/*** SpiderMonkey nonstandard internal methods ***************************************************/

View File

@ -513,10 +513,10 @@ with_GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
}
static bool
with_DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
with_DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult &result)
{
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
return DeleteProperty(cx, actual, id, succeeded);
return DeleteProperty(cx, actual, id, result);
}
static JSObject *
@ -956,7 +956,7 @@ uninitialized_GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId
}
static bool
uninitialized_DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
uninitialized_DeleteProperty(JSContext *cx, HandleObject obj, HandleId id, ObjectOpResult &result)
{
ReportUninitializedLexicalId(cx, id);
return false;
@ -1714,11 +1714,10 @@ class DebugScopeProxy : public BaseProxyHandler
return true;
}
bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE
bool delete_(JSContext *cx, HandleObject proxy, HandleId id,
ObjectOpResult &result) const MOZ_OVERRIDE
{
RootedValue idval(cx, IdToValue(id));
return ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_CANT_DELETE,
JSDVG_IGNORE_STACK, idval, NullPtr(), nullptr, nullptr);
return result.fail(JSMSG_CANT_DELETE);
}
};

View File

@ -445,11 +445,11 @@ UnboxedPlainObject::obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj
/* static */ bool
UnboxedPlainObject::obj_deleteProperty(JSContext *cx, HandleObject obj, HandleId id,
bool *succeeded)
ObjectOpResult &result)
{
if (!convertToNative(cx, obj))
return false;
return DeleteProperty(cx, obj, id, succeeded);
return DeleteProperty(cx, obj, id, result);
}
/* static */ bool

View File

@ -179,7 +179,8 @@ class UnboxedPlainObject : public JSObject
static bool obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc);
static bool obj_deleteProperty(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded);
static bool obj_deleteProperty(JSContext *cx, HandleObject obj, HandleId id,
ObjectOpResult &result);
static bool obj_enumerate(JSContext *cx, HandleObject obj, AutoIdVector &properties);
static bool obj_watch(JSContext *cx, HandleObject obj, HandleId id, HandleObject callable);

View File

@ -29,11 +29,11 @@ namespace js {
*
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
*/
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 242;
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 243;
static const uint32_t XDR_BYTECODE_VERSION =
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
static_assert(JSErr_Limit == 376,
static_assert(JSErr_Limit == 379,
"GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
"removed MSG_DEFs from js.msg, you should increment "
"XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "

View File

@ -443,7 +443,7 @@ XPC_WN_CannotModifyPropertyStub(JSContext *cx, HandleObject obj, HandleId id,
static bool
XPC_WN_CantDeletePropertyStub(JSContext *cx, HandleObject obj, HandleId id,
bool *succeeded)
ObjectOpResult &result)
{
return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
}
@ -716,15 +716,15 @@ XPC_WN_MaybeResolvingSetPropertyStub(JSContext *cx, HandleObject obj, HandleId i
}
static bool
XPC_WN_MaybeResolvingDeletePropertyStub(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
XPC_WN_MaybeResolvingDeletePropertyStub(JSContext *cx, HandleObject obj, HandleId id,
ObjectOpResult &result)
{
XPCCallContext ccx(JS_CALLER, cx, obj);
XPCWrappedNative* wrapper = ccx.GetWrapper();
THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
if (ccx.GetResolvingWrapper() == wrapper) {
*succeeded = true;
return true;
return result.succeed();
}
return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
}

View File

@ -163,14 +163,15 @@ AddonWrapper<Base>::defineProperty(JSContext *cx, HandleObject wrapper, HandleId
template<typename Base>
bool
AddonWrapper<Base>::delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const
AddonWrapper<Base>::delete_(JSContext *cx, HandleObject wrapper, HandleId id,
ObjectOpResult &result) const
{
Rooted<JSPropertyDescriptor> desc(cx);
if (!Interpose(cx, wrapper, nullptr, id, &desc))
return false;
if (!desc.object())
return Base::delete_(cx, wrapper, id, bp);
return Base::delete_(cx, wrapper, id, result);
js::ReportErrorWithId(cx, "unable to delete interposed property %s", id);
return false;

View File

@ -30,7 +30,8 @@ class AddonWrapper : public Base {
virtual bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc,
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const MOZ_OVERRIDE;
virtual bool set(JSContext *cx, JS::HandleObject wrapper, JS::HandleObject receiver,

View File

@ -243,7 +243,7 @@ CrossOriginXrayWrapper::defineProperty(JSContext *cx, JS::Handle<JSObject*> wrap
bool
CrossOriginXrayWrapper::delete_(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::Handle<jsid> id, bool *bp) const
JS::Handle<jsid> id, JS::ObjectOpResult &result) const
{
JS_ReportError(cx, "Permission denied to delete property on cross-origin object");
return false;

View File

@ -78,7 +78,7 @@ class CrossOriginXrayWrapper : public SecurityXrayDOM {
virtual bool ownPropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
JS::Handle<jsid> id, JS::ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::Handle<jsid> id,

View File

@ -543,7 +543,7 @@ JSXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper,
}
bool
JSXrayTraits::delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp)
JSXrayTraits::delete_(JSContext *cx, HandleObject wrapper, HandleId id, ObjectOpResult &result)
{
RootedObject holder(cx, ensureHolder(cx, wrapper));
@ -560,10 +560,9 @@ JSXrayTraits::delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp
if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, &desc))
return false;
if (desc.object())
return JS_DeletePropertyById2(cx, target, id, bp);
return JS_DeletePropertyById(cx, target, id, result);
}
*bp = true;
return true;
return result.succeed();
}
bool
@ -2025,7 +2024,7 @@ XrayWrapper<Base, Traits>::ownPropertyKeys(JSContext *cx, HandleObject wrapper,
template <typename Base, typename Traits>
bool
XrayWrapper<Base, Traits>::delete_(JSContext *cx, HandleObject wrapper,
HandleId id, bool *bp) const
HandleId id, ObjectOpResult &result) const
{
assertEnteredPolicy(cx, wrapper, id, BaseProxyHandler::SET);
@ -2037,10 +2036,10 @@ XrayWrapper<Base, Traits>::delete_(JSContext *cx, HandleObject wrapper,
if (expando) {
JSAutoCompartment ac(cx, expando);
return JS_DeletePropertyById2(cx, expando, id, bp);
return JS_DeletePropertyById(cx, expando, id, result);
}
return Traits::singleton.delete_(cx, wrapper, id, bp);
return Traits::singleton.delete_(cx, wrapper, id, result);
}
template <typename Base, typename Traits>

View File

@ -70,9 +70,9 @@ public:
JS::HandleObject wrapper, JS::HandleObject holder,
JS::HandleId id, JS::MutableHandle<JSPropertyDescriptor> desc);
bool delete_(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, bool *bp) {
*bp = true;
return true;
bool delete_(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
JS::ObjectOpResult &result) {
return result.succeed();
}
static const char *className(JSContext *cx, JS::HandleObject wrapper, const js::Wrapper& baseInstance) {
@ -217,7 +217,7 @@ public:
JS::HandleObject holder, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc) MOZ_OVERRIDE;
bool delete_(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, bool *bp);
bool delete_(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, JS::ObjectOpResult &result);
bool defineProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc,
@ -417,7 +417,7 @@ class XrayWrapper : public Base {
virtual bool ownPropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
JS::Handle<jsid> id, JS::ObjectOpResult &result) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::MutableHandle<JSObject*> objp) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, JS::HandleObject wrapper,