Bug 1017067 - Merge deleteProperty/deleteElement ops back into a single deleteGeneric op. r=bhackett.

This commit is contained in:
Jason Orendorff
2014-06-05 13:19:23 -04:00
parent 01dce61b91
commit 201acb0e94
18 changed files with 86 additions and 179 deletions

View File

@@ -377,8 +377,7 @@ JS_NULL_OBJECT_OPS
nullptr, /* setElement */ nullptr, /* setElement */
nullptr, /* getGenericAttributes */ nullptr, /* getGenericAttributes */
nullptr, /* setGenericAttributes */ nullptr, /* setGenericAttributes */
nullptr, /* deleteProperty */ nullptr, /* deleteGeneric */
nullptr, /* deleteElement */
nullptr, /* watch */ nullptr, /* watch */
nullptr, /* unwatch */ nullptr, /* unwatch */
nullptr, /* slice */ nullptr, /* slice */

View File

@@ -232,10 +232,7 @@ typedef bool
(* PropertyAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name, (* PropertyAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
unsigned *attrsp); unsigned *attrsp);
typedef bool typedef bool
(* DeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name, (* DeleteGenericOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
bool *succeeded);
typedef bool
(* DeleteElementOp)(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded);
typedef bool typedef bool
(* WatchOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable); (* WatchOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable);
@@ -342,20 +339,18 @@ struct ObjectOps
StrictElementIdOp setElement; StrictElementIdOp setElement;
GenericAttributesOp getGenericAttributes; GenericAttributesOp getGenericAttributes;
GenericAttributesOp setGenericAttributes; GenericAttributesOp setGenericAttributes;
DeletePropertyOp deleteProperty; DeleteGenericOp deleteGeneric;
DeleteElementOp deleteElement;
WatchOp watch; WatchOp watch;
UnwatchOp unwatch; UnwatchOp unwatch;
SliceOp slice; // Optimized slice, can be null. SliceOp slice; // Optimized slice, can be null.
JSNewEnumerateOp enumerate; JSNewEnumerateOp enumerate;
ObjectOp thisObject; ObjectOp thisObject;
}; };
#define JS_NULL_OBJECT_OPS \ #define JS_NULL_OBJECT_OPS \
{nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, \
nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, \
nullptr,nullptr} nullptr, nullptr, nullptr}
} // namespace js } // namespace js
@@ -366,7 +361,7 @@ typedef void (*JSClassInternal)();
struct JSClass { struct JSClass {
JS_CLASS_MEMBERS(JSFinalizeOp); JS_CLASS_MEMBERS(JSFinalizeOp);
void *reserved[32]; void *reserved[31];
}; };
#define JSCLASS_HAS_PRIVATE (1<<0) // objects have private slot #define JSCLASS_HAS_PRIVATE (1<<0) // objects have private slot

View File

@@ -2093,10 +2093,8 @@ TypedObject::obj_setGenericAttributes(JSContext *cx, HandleObject obj,
} }
bool bool
TypedObject::obj_deleteProperty(JSContext *cx, HandleObject obj, TypedObject::obj_deleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
HandlePropertyName name, bool *succeeded)
{ {
Rooted<jsid> id(cx, NameToId(name));
if (IsOwnId(cx, obj, id)) if (IsOwnId(cx, obj, id))
return ReportPropertyError(cx, JSMSG_CANT_DELETE, id); return ReportPropertyError(cx, JSMSG_CANT_DELETE, id);
@@ -2106,27 +2104,7 @@ TypedObject::obj_deleteProperty(JSContext *cx, HandleObject obj,
return true; return true;
} }
return JSObject::deleteProperty(cx, proto, name, succeeded); return JSObject::deleteGeneric(cx, proto, id, succeeded);
}
bool
TypedObject::obj_deleteElement(JSContext *cx, HandleObject obj, uint32_t index,
bool *succeeded)
{
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
if (IsOwnId(cx, obj, id))
return ReportPropertyError(cx, JSMSG_CANT_DELETE, id);
RootedObject proto(cx, obj->getProto());
if (!proto) {
*succeeded = false;
return true;
}
return JSObject::deleteElement(cx, proto, index, succeeded);
} }
bool bool
@@ -2287,8 +2265,7 @@ const Class TransparentTypedObject::class_ = {
TypedObject::obj_setElement, TypedObject::obj_setElement,
TypedObject::obj_getGenericAttributes, TypedObject::obj_getGenericAttributes,
TypedObject::obj_setGenericAttributes, TypedObject::obj_setGenericAttributes,
TypedObject::obj_deleteProperty, TypedObject::obj_deleteGeneric,
TypedObject::obj_deleteElement,
nullptr, nullptr, // watch/unwatch nullptr, nullptr, // watch/unwatch
nullptr, /* slice */ nullptr, /* slice */
TypedObject::obj_enumerate, TypedObject::obj_enumerate,
@@ -2633,8 +2610,7 @@ const Class OpaqueTypedObject::class_ = {
TypedObject::obj_setElement, TypedObject::obj_setElement,
TypedObject::obj_getGenericAttributes, TypedObject::obj_getGenericAttributes,
TypedObject::obj_setGenericAttributes, TypedObject::obj_setGenericAttributes,
TypedObject::obj_deleteProperty, TypedObject::obj_deleteGeneric,
TypedObject::obj_deleteElement,
nullptr, nullptr, // watch/unwatch nullptr, nullptr, // watch/unwatch
nullptr, // slice nullptr, // slice
TypedObject::obj_enumerate, TypedObject::obj_enumerate,

View File

@@ -576,10 +576,7 @@ class TypedObject : public ArrayBufferViewObject
static bool obj_setGenericAttributes(JSContext *cx, HandleObject obj, static bool obj_setGenericAttributes(JSContext *cx, HandleObject obj,
HandleId id, unsigned *attrsp); HandleId id, unsigned *attrsp);
static bool obj_deleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, static bool obj_deleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded);
bool *succeeded);
static bool obj_deleteElement(JSContext *cx, HandleObject obj, uint32_t index,
bool *succeeded);
static bool obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op, static bool obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
MutableHandleValue statep, MutableHandleId idp); MutableHandleValue statep, MutableHandleId idp);

View File

@@ -3631,7 +3631,7 @@ JS_DeletePropertyById2(JSContext *cx, HandleObject obj, HandleId id, bool *resul
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, id); assertSameCompartment(cx, obj, id);
return JSObject::deleteByValue(cx, obj, IdToValue(id), result); return JSObject::deleteGeneric(cx, obj, id, result);
} }
JS_PUBLIC_API(bool) JS_PUBLIC_API(bool)
@@ -3653,7 +3653,8 @@ JS_DeleteProperty2(JSContext *cx, HandleObject obj, const char *name, bool *resu
JSAtom *atom = Atomize(cx, name, strlen(name)); JSAtom *atom = Atomize(cx, name, strlen(name));
if (!atom) if (!atom)
return false; return false;
return JSObject::deleteByValue(cx, obj, StringValue(atom), result); RootedId id(cx, AtomToId(atom));
return JSObject::deleteGeneric(cx, obj, id, result);
} }
JS_PUBLIC_API(bool) JS_PUBLIC_API(bool)
@@ -3666,7 +3667,8 @@ JS_DeleteUCProperty2(JSContext *cx, HandleObject obj, const jschar *name, size_t
JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen)); JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
if (!atom) if (!atom)
return false; return false;
return JSObject::deleteByValue(cx, obj, StringValue(atom), result); RootedId id(cx, AtomToId(atom));
return JSObject::deleteGeneric(cx, obj, id, result);
} }
JS_PUBLIC_API(bool) JS_PUBLIC_API(bool)

View File

@@ -337,10 +337,10 @@ DeleteArrayElement(JSContext *cx, HandleObject obj, double index, bool *succeede
return true; return true;
} }
if (index <= UINT32_MAX) RootedId id(cx);
return JSObject::deleteElement(cx, obj, uint32_t(index), succeeded); if (!ToId(cx, index, &id))
return false;
return JSObject::deleteByValue(cx, obj, DoubleValue(index), succeeded); return JSObject::deleteGeneric(cx, obj, id, succeeded);
} }
/* ES6 20130308 draft 9.3.5 */ /* ES6 20130308 draft 9.3.5 */

View File

@@ -283,8 +283,7 @@ namespace js {
js::proxy_SetElement, \ js::proxy_SetElement, \
js::proxy_GetGenericAttributes, \ js::proxy_GetGenericAttributes, \
js::proxy_SetGenericAttributes, \ js::proxy_SetGenericAttributes, \
js::proxy_DeleteProperty, \ js::proxy_DeleteGeneric, \
js::proxy_DeleteElement, \
js::proxy_Watch, js::proxy_Unwatch, \ js::proxy_Watch, js::proxy_Unwatch, \
js::proxy_Slice, \ js::proxy_Slice, \
nullptr, /* enumerate */ \ nullptr, /* enumerate */ \
@@ -349,10 +348,7 @@ proxy_GetGenericAttributes(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
extern JS_FRIEND_API(bool) extern JS_FRIEND_API(bool)
proxy_SetGenericAttributes(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp); proxy_SetGenericAttributes(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp);
extern JS_FRIEND_API(bool) extern JS_FRIEND_API(bool)
proxy_DeleteProperty(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name, proxy_DeleteGeneric(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
bool *succeeded);
extern JS_FRIEND_API(bool)
proxy_DeleteElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded);
extern JS_FRIEND_API(void) extern JS_FRIEND_API(void)
proxy_Trace(JSTracer *trc, JSObject *obj); proxy_Trace(JSTracer *trc, JSObject *obj);

View File

@@ -1819,26 +1819,6 @@ JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj,
return obj->getOps()->setElement(cx, obj, index, vp, strict); return obj->getOps()->setElement(cx, obj, index, vp, strict);
} }
/* static */ bool
JSObject::deleteByValue(JSContext *cx, HandleObject obj, const Value &property, bool *succeeded)
{
uint32_t index;
if (IsDefinitelyIndex(property, &index))
return deleteElement(cx, obj, index, succeeded);
RootedValue propval(cx, property);
JSAtom *name = ToAtom<CanGC>(cx, propval);
if (!name)
return false;
if (name->isIndex(&index))
return deleteElement(cx, obj, index, succeeded);
Rooted<PropertyName*> propname(cx, name->asPropertyName());
return deleteProperty(cx, obj, propname, succeeded);
}
JS_FRIEND_API(bool) JS_FRIEND_API(bool)
JS_CopyPropertyFrom(JSContext *cx, HandleId id, HandleObject target, JS_CopyPropertyFrom(JSContext *cx, HandleId id, HandleObject target,
HandleObject obj) HandleObject obj)
@@ -2716,7 +2696,8 @@ DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, H
bad: bad:
if (named) { if (named) {
bool succeeded; bool succeeded;
JSObject::deleteByValue(cx, obj, StringValue(atom), &succeeded); RootedId id(cx, AtomToId(atom));
JSObject::deleteGeneric(cx, obj, id, &succeeded);
} }
if (cached) if (cached)
ClearClassObject(obj, key); ClearClassObject(obj, key);
@@ -5312,23 +5293,6 @@ baseops::DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succe
return obj->removeProperty(cx, id) && js_SuppressDeletedProperty(cx, obj, id); return obj->removeProperty(cx, id) && js_SuppressDeletedProperty(cx, obj, id);
} }
bool
baseops::DeleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
bool *succeeded)
{
Rooted<jsid> id(cx, NameToId(name));
return baseops::DeleteGeneric(cx, obj, id, succeeded);
}
bool
baseops::DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, bool *succeeded)
{
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
return baseops::DeleteGeneric(cx, obj, id, succeeded);
}
bool bool
js::WatchGuts(JSContext *cx, JS::HandleObject origObj, JS::HandleId id, JS::HandleObject callable) js::WatchGuts(JSContext *cx, JS::HandleObject origObj, JS::HandleId id, JS::HandleObject callable)
{ {

View File

@@ -148,12 +148,6 @@ GetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp);
extern bool extern bool
SetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp); SetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp);
extern bool
DeleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, bool *succeeded);
extern bool
DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, bool *succeeded);
extern bool extern bool
DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded); DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded);
@@ -1054,13 +1048,10 @@ class JSObject : public js::ObjectImpl
static inline bool setGenericAttributes(JSContext *cx, js::HandleObject obj, static inline bool setGenericAttributes(JSContext *cx, js::HandleObject obj,
js::HandleId id, unsigned *attrsp); js::HandleId id, unsigned *attrsp);
static inline bool deleteProperty(JSContext *cx, js::HandleObject obj, static inline bool deleteGeneric(JSContext *cx, js::HandleObject obj, js::HandleId id,
js::HandlePropertyName name, bool *succeeded);
bool *succeeded); static inline bool deleteElement(JSContext *cx, js::HandleObject obj, uint32_t index,
static inline bool deleteElement(JSContext *cx, js::HandleObject obj, bool *succeeded);
uint32_t index, bool *succeeded);
static bool deleteByValue(JSContext *cx, js::HandleObject obj,
const js::Value &property, bool *succeeded);
static inline bool watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id, static inline bool watch(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::HandleObject callable); JS::HandleObject callable);

View File

@@ -41,13 +41,12 @@ JSObject::changePropertyAttributes(JSContext *cx, js::HandleObject obj,
} }
/* static */ inline bool /* static */ inline bool
JSObject::deleteProperty(JSContext *cx, js::HandleObject obj, js::HandlePropertyName name, JSObject::deleteGeneric(JSContext *cx, js::HandleObject obj, js::HandleId id,
bool *succeeded) bool *succeeded)
{ {
JS::RootedId id(cx, js::NameToId(name));
js::types::MarkTypePropertyNonData(cx, obj, id); js::types::MarkTypePropertyNonData(cx, obj, id);
js::DeletePropertyOp op = obj->getOps()->deleteProperty; js::DeleteGenericOp op = obj->getOps()->deleteGeneric;
return (op ? op : js::baseops::DeleteProperty)(cx, obj, name, succeeded); return (op ? op : js::baseops::DeleteGeneric)(cx, obj, id, succeeded);
} }
/* static */ inline bool /* static */ inline bool
@@ -56,9 +55,7 @@ JSObject::deleteElement(JSContext *cx, js::HandleObject obj, uint32_t index, boo
JS::RootedId id(cx); JS::RootedId id(cx);
if (!js::IndexToId(cx, index, &id)) if (!js::IndexToId(cx, index, &id))
return false; return false;
js::types::MarkTypePropertyNonData(cx, obj, id); return deleteGeneric(cx, obj, id, succeeded);
js::DeleteElementOp op = obj->getOps()->deleteElement;
return (op ? op : js::baseops::DeleteElement)(cx, obj, index, succeeded);
} }
/* static */ inline bool /* static */ inline bool

View File

@@ -698,7 +698,7 @@ Walk(JSContext *cx, HandleObject holder, HandleId name, HandleValue reviver, Mut
if (newElement.isUndefined()) { if (newElement.isUndefined()) {
/* Step 2a(iii)(2). */ /* Step 2a(iii)(2). */
bool succeeded; bool succeeded;
if (!JSObject::deleteByValue(cx, obj, IdToValue(id), &succeeded)) if (!JSObject::deleteGeneric(cx, obj, id, &succeeded))
return false; return false;
} else { } else {
/* Step 2a(iii)(3). */ /* Step 2a(iii)(3). */
@@ -726,7 +726,7 @@ Walk(JSContext *cx, HandleObject holder, HandleId name, HandleValue reviver, Mut
if (newElement.isUndefined()) { if (newElement.isUndefined()) {
/* Step 2b(ii)(2). */ /* Step 2b(ii)(2). */
bool succeeded; bool succeeded;
if (!JSObject::deleteByValue(cx, obj, IdToValue(id), &succeeded)) if (!JSObject::deleteGeneric(cx, obj, id, &succeeded))
return false; return false;
} else { } else {
/* Step 2b(ii)(3). */ /* Step 2b(ii)(3). */

View File

@@ -427,7 +427,7 @@ DirectProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool
{ {
assertEnteredPolicy(cx, proxy, id, SET); assertEnteredPolicy(cx, proxy, id, SET);
RootedObject target(cx, proxy->as<ProxyObject>().target()); RootedObject target(cx, proxy->as<ProxyObject>().target());
return JS_DeletePropertyById2(cx, target, id, bp); return JSObject::deleteGeneric(cx, target, id, bp);
} }
bool bool
@@ -2920,8 +2920,8 @@ js::proxy_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, uns
return Proxy::defineProperty(cx, obj, id, &desc); return Proxy::defineProperty(cx, obj, id, &desc);
} }
static bool bool
proxy_DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded) js::proxy_DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
{ {
bool deleted; bool deleted;
if (!Proxy::delete_(cx, obj, id, &deleted)) if (!Proxy::delete_(cx, obj, id, &deleted))
@@ -2930,22 +2930,6 @@ proxy_DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeede
return js_SuppressDeletedProperty(cx, obj, id); return js_SuppressDeletedProperty(cx, obj, id);
} }
bool
js::proxy_DeleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, bool *succeeded)
{
RootedId id(cx, NameToId(name));
return proxy_DeleteGeneric(cx, obj, id, succeeded);
}
bool
js::proxy_DeleteElement(JSContext *cx, HandleObject obj, uint32_t index, bool *succeeded)
{
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
return proxy_DeleteGeneric(cx, obj, id, succeeded);
}
void void
js::proxy_Trace(JSTracer *trc, JSObject *obj) js::proxy_Trace(JSTracer *trc, JSObject *obj)
{ {

View File

@@ -0,0 +1,21 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
// delete o[p] only performs ToString(p) once, even if there's a strict error.
var hits = 0;
var p = {
toString: function () {
hits++;
return "noconfig";
}
};
assertEq(testLenientAndStrict('var o = Object.freeze({noconfig: "ow"}); delete o[p]',
returns(false), raisesException(TypeError)),
true);
assertEq(hits, 2);
reportCompare(true, true);

View File

@@ -5417,16 +5417,18 @@ static bool
DebuggerObject_deleteProperty(JSContext *cx, unsigned argc, Value *vp) DebuggerObject_deleteProperty(JSContext *cx, unsigned argc, Value *vp)
{ {
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "deleteProperty", args, dbg, obj); THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "deleteProperty", args, dbg, obj);
RootedValue nameArg(cx, args.get(0)); RootedId id(cx);
if (!ValueToId<CanGC>(cx, args.get(0), &id))
return false;
Maybe<AutoCompartment> ac; Maybe<AutoCompartment> ac;
ac.construct(cx, obj); ac.construct(cx, obj);
if (!cx->compartment()->wrap(cx, &nameArg)) if (!cx->compartment()->wrapId(cx, id.address()))
return false; return false;
bool succeeded; bool succeeded;
ErrorCopier ec(ac, dbg->toJSObject()); ErrorCopier ec(ac, dbg->toJSObject());
if (!JSObject::deleteByValue(cx, obj, nameArg, &succeeded)) if (!JSObject::deleteGeneric(cx, obj, id, &succeeded))
return false; return false;
args.rval().setBoolean(succeeded); args.rval().setBoolean(succeeded);
return true; return true;

View File

@@ -2312,17 +2312,17 @@ END_CASE(JSOP_DELNAME)
CASE(JSOP_DELPROP) CASE(JSOP_DELPROP)
{ {
RootedPropertyName &name = rootName0; RootedId &id = rootId0;
name = script->getName(REGS.pc); id = NameToId(script->getName(REGS.pc));
RootedObject &obj = rootObject0; RootedObject &obj = rootObject0;
FETCH_OBJECT(cx, -1, obj); FETCH_OBJECT(cx, -1, obj);
bool succeeded; bool succeeded;
if (!JSObject::deleteProperty(cx, obj, name, &succeeded)) if (!JSObject::deleteGeneric(cx, obj, id, &succeeded))
goto error; goto error;
if (!succeeded && script->strict()) { if (!succeeded && script->strict()) {
obj->reportNotConfigurable(cx, NameToId(name)); obj->reportNotConfigurable(cx, id);
goto error; goto error;
} }
MutableHandleValue res = REGS.stackHandleAt(-1); MutableHandleValue res = REGS.stackHandleAt(-1);
@@ -2340,15 +2340,12 @@ CASE(JSOP_DELELEM)
propval = REGS.sp[-1]; propval = REGS.sp[-1];
bool succeeded; bool succeeded;
if (!JSObject::deleteByValue(cx, obj, propval, &succeeded)) RootedId &id = rootId0;
if (!ValueToId<CanGC>(cx, propval, &id))
goto error;
if (!JSObject::deleteGeneric(cx, obj, id, &succeeded))
goto error; goto error;
if (!succeeded && script->strict()) { if (!succeeded && script->strict()) {
// XXX This observably calls ToString(propval). We should convert to
// PropertyKey and use that to delete, and to report an error if
// necessary!
RootedId id(cx);
if (!ValueToId<CanGC>(cx, propval, &id))
goto error;
obj->reportNotConfigurable(cx, id); obj->reportNotConfigurable(cx, id);
goto error; goto error;
} }
@@ -3684,7 +3681,8 @@ js::DeleteProperty(JSContext *cx, HandleValue v, HandlePropertyName name, bool *
if (!obj) if (!obj)
return false; return false;
if (!JSObject::deleteProperty(cx, obj, name, bp)) RootedId id(cx, NameToId(name));
if (!JSObject::deleteGeneric(cx, obj, id, bp))
return false; return false;
if (strict && !*bp) { if (strict && !*bp) {
@@ -3705,16 +3703,13 @@ js::DeleteElement(JSContext *cx, HandleValue val, HandleValue index, bool *bp)
if (!obj) if (!obj)
return false; return false;
if (!JSObject::deleteByValue(cx, obj, index, bp)) RootedId id(cx);
if (!ValueToId<CanGC>(cx, index, &id))
return false;
if (!JSObject::deleteGeneric(cx, obj, id, bp))
return false; return false;
if (strict && !*bp) { if (strict && !*bp) {
// XXX This observably calls ToString(propval). We should convert to
// PropertyKey and use that to delete, and to report an error if
// necessary!
RootedId id(cx);
if (!ValueToId<CanGC>(cx, index, &id))
return false;
obj->reportNotConfigurable(cx, id); obj->reportNotConfigurable(cx, id);
return false; return false;
} }
@@ -3815,7 +3810,8 @@ js::DeleteNameOperation(JSContext *cx, HandlePropertyName name, HandleObject sco
} }
bool succeeded; bool succeeded;
if (!JSObject::deleteProperty(cx, scope, name, &succeeded)) RootedId id(cx, NameToId(name));
if (!JSObject::deleteGeneric(cx, scope, id, &succeeded))
return false; return false;
res.setBoolean(succeeded); res.setBoolean(succeeded);
return true; return true;

View File

@@ -534,19 +534,10 @@ with_SetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned
} }
static bool static bool
with_DeleteProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, with_DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded)
bool *succeeded)
{ {
RootedObject actual(cx, &obj->as<DynamicWithObject>().object()); RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
return JSObject::deleteProperty(cx, actual, name, succeeded); return JSObject::deleteGeneric(cx, actual, id, succeeded);
}
static bool
with_DeleteElement(JSContext *cx, HandleObject obj, uint32_t index,
bool *succeeded)
{
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
return JSObject::deleteElement(cx, actual, index, succeeded);
} }
static JSObject * static JSObject *
@@ -602,8 +593,7 @@ const Class DynamicWithObject::class_ = {
with_SetElement, with_SetElement,
with_GetGenericAttributes, with_GetGenericAttributes,
with_SetGenericAttributes, with_SetGenericAttributes,
with_DeleteProperty, with_DeleteGeneric,
with_DeleteElement,
nullptr, nullptr, /* watch/unwatch */ nullptr, nullptr, /* watch/unwatch */
nullptr, /* slice */ nullptr, /* slice */
nullptr, /* enumerate (native enumeration of target doesn't work) */ nullptr, /* enumerate (native enumeration of target doesn't work) */

View File

@@ -697,8 +697,7 @@ const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
nullptr, // setElement nullptr, // setElement
nullptr, // getGenericAttributes nullptr, // getGenericAttributes
nullptr, // setGenericAttributes nullptr, // setGenericAttributes
nullptr, // deleteProperty nullptr, // deleteGeneric
nullptr, // deleteElement
nullptr, nullptr, // watch/unwatch nullptr, nullptr, // watch/unwatch
nullptr, // slice nullptr, // slice
XPC_WN_JSOp_Enumerate, XPC_WN_JSOp_Enumerate,

View File

@@ -912,8 +912,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
nullptr, /* setElement */ \ nullptr, /* setElement */ \
nullptr, /* getGenericAttributes */ \ nullptr, /* getGenericAttributes */ \
nullptr, /* setGenericAttributes */ \ nullptr, /* setGenericAttributes */ \
nullptr, /* deleteProperty */ \ nullptr, /* deleteGeneric */ \
nullptr, /* deleteElement */ \
nullptr, nullptr, /* watch/unwatch */ \ nullptr, nullptr, /* watch/unwatch */ \
nullptr, /* slice */ \ nullptr, /* slice */ \
XPC_WN_JSOp_Enumerate, \ XPC_WN_JSOp_Enumerate, \
@@ -936,8 +935,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
nullptr, /* setElement */ \ nullptr, /* setElement */ \
nullptr, /* getGenericAttributes */ \ nullptr, /* getGenericAttributes */ \
nullptr, /* setGenericAttributes */ \ nullptr, /* setGenericAttributes */ \
nullptr, /* deleteProperty */ \ nullptr, /* deleteGeneric */ \
nullptr, /* deleteElement */ \
nullptr, nullptr, /* watch/unwatch */ \ nullptr, nullptr, /* watch/unwatch */ \
nullptr, /* slice */ \ nullptr, /* slice */ \
XPC_WN_JSOp_Enumerate, \ XPC_WN_JSOp_Enumerate, \