mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
e065e5cceb
commit
d1204e0adb
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 ***************************************************/
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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). */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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]]
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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 ***************************************************/
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 "
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user