Bug 713965 - Replace deleteGeneric (taking a jsid) with deleteByValue (taking a Value), and use the property-type-specific methods exclusively. r=bhackett
authorJeff Walden <jwalden@mit.edu>
Wed, 28 Dec 2011 16:33:20 -0600
changeset 85196 0c98dd9fd645d3c76edc881fc8e4050747afa4a3
parent 85195 f03e02f515295167f3a02eb7e63f21cc18b0382c
child 85197 2c5ba63e4884e668d3bd02bbc97fc754dbf4ed24
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs713965
milestone12.0a1
Bug 713965 - Replace deleteGeneric (taking a jsid) with deleteByValue (taking a Value), and use the property-type-specific methods exclusively. r=bhackett
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jsclass.h
js/src/jsfun.cpp
js/src/jsinterp.cpp
js/src/jsiter.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/json.cpp
js/src/jsproxy.cpp
js/src/jstypedarray.cpp
js/src/jstypedarray.h
js/src/jsxml.cpp
js/src/methodjit/StubCalls.cpp
js/src/vm/Debugger.cpp
js/src/vm/ScopeObject.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4156,42 +4156,59 @@ JS_SetUCProperty(JSContext *cx, JSObject
 
 JS_PUBLIC_API(JSBool)
 JS_DeletePropertyById2(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
     JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
-    return obj->deleteGeneric(cx, id, rval, false);
+
+    if (JSID_IS_SPECIAL(id))
+        return obj->deleteSpecial(cx, JSID_TO_SPECIALID(id), rval, false);
+
+    return obj->deleteByValue(cx, IdToValue(id), rval, false);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_DeleteElement2(JSContext *cx, JSObject *obj, uint32_t index, jsval *rval)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
-    jsid id;
-    if (!IndexToId(cx, index, &id))
-        return false;
-    return JS_DeletePropertyById2(cx, obj, id, rval);
+    assertSameCompartment(cx, obj);
+    JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
+    return obj->deleteElement(cx, index, rval, false);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name, jsval *rval)
 {
+    CHECK_REQUEST(cx);
+    assertSameCompartment(cx, obj);
+    JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
+
     JSAtom *atom = js_Atomize(cx, name, strlen(name));
-    return atom && JS_DeletePropertyById2(cx, obj, ATOM_TO_JSID(atom), rval);
+    if (!atom)
+        return false;
+
+    return obj->deleteByValue(cx, StringValue(atom), rval, false);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_DeleteUCProperty2(JSContext *cx, JSObject *obj, const jschar *name, size_t namelen, jsval *rval)
 {
+    CHECK_REQUEST(cx);
+    assertSameCompartment(cx, obj);
+    JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED);
+
     JSAtom *atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
-    return atom && JS_DeletePropertyById2(cx, obj, ATOM_TO_JSID(atom), rval);
+    if (!atom)
+        return false;
+
+    return obj->deleteByValue(cx, StringValue(atom), rval, false);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_DeletePropertyById(JSContext *cx, JSObject *obj, jsid id)
 {
     jsval junk;
     return JS_DeletePropertyById2(cx, obj, id, &junk);
 }
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -517,39 +517,40 @@ SetArrayElement(JSContext *cx, JSObject 
  *   |strict| is true we will throw, not return zero.
  *
  * - Return -1 if an exception occurs (that is, [[Delete]] would throw).
  */
 static int
 DeleteArrayElement(JSContext *cx, JSObject *obj, jsdouble index, bool strict)
 {
     JS_ASSERT(index >= 0);
+    JS_ASSERT(floor(index) == index);
+
     if (obj->isDenseArray()) {
-        if (index <= jsuint(-1)) {
-            jsuint idx = jsuint(index);
+        if (index <= UINT32_MAX) {
+            uint32_t idx = uint32_t(index);
             if (idx < obj->getDenseArrayInitializedLength()) {
                 obj->markDenseArrayNotPacked(cx);
                 obj->setDenseArrayElement(idx, MagicValue(JS_ARRAY_HOLE));
                 if (!js_SuppressDeletedElement(cx, obj, idx))
                     return -1;
             }
         }
         return 1;
     }
 
-    AutoIdRooter idr(cx);
-
-    if (!IndexToId(cx, obj, index, NULL, idr.addr()))
-        return -1;
-    if (JSID_IS_VOID(idr.id()))
-        return 1;
-
     Value v;
-    if (!obj->deleteGeneric(cx, idr.id(), &v, strict))
-        return -1;
+    if (index <= UINT32_MAX) {
+        if (!obj->deleteElement(cx, uint32_t(index), &v, strict))
+            return -1;
+    } else {
+        if (!obj->deleteByValue(cx, DoubleValue(index), &v, strict))
+            return -1;
+    }
+
     return v.isTrue() ? 1 : 0;
 }
 
 /*
  * When hole is true, delete the property at the given index. Otherwise set
  * its value to v assuming v is rooted.
  */
 static JSBool
@@ -1135,46 +1136,30 @@ array_setElementAttributes(JSContext *cx
 static JSBool
 array_setSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, uintN *attrsp)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_SET_ARRAY_ATTRS);
     return false;
 }
 
 static JSBool
-array_deleteGeneric(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
+array_deleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
 {
-    uint32_t i;
-
     if (!obj->isDenseArray())
-        return js_DeleteProperty(cx, obj, id, rval, strict);
-
-    if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
+        return js_DeleteProperty(cx, obj, name, rval, strict);
+
+    if (name == cx->runtime->atomState.lengthAtom) {
         rval->setBoolean(false);
         return true;
     }
 
-    if (js_IdIsIndex(id, &i) && i < obj->getDenseArrayInitializedLength()) {
-        obj->markDenseArrayNotPacked(cx);
-        obj->setDenseArrayElement(i, MagicValue(JS_ARRAY_HOLE));
-    }
-
-    if (!js_SuppressDeletedProperty(cx, obj, id))
-        return false;
-
     rval->setBoolean(true);
     return true;
 }
 
-static JSBool
-array_deleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
-{
-    return array_deleteGeneric(cx, obj, ATOM_TO_JSID(name), rval, strict);
-}
-
 namespace js {
 
 /* non-static for direct deletion of array elements within the engine */
 JSBool
 array_deleteElement(JSContext *cx, JSObject *obj, uint32_t index, Value *rval, JSBool strict)
 {
     if (!obj->isDenseArray())
         return js_DeleteElement(cx, obj, index, rval, strict);
@@ -1191,17 +1176,21 @@ array_deleteElement(JSContext *cx, JSObj
     return true;
 }
 
 } // namespace js
 
 static JSBool
 array_deleteSpecial(JSContext *cx, JSObject *obj, SpecialId sid, Value *rval, JSBool strict)
 {
-    return array_deleteGeneric(cx, obj, SPECIALID_TO_JSID(sid), rval, strict);
+    if (!obj->isDenseArray())
+        return js_DeleteSpecial(cx, obj, sid, rval, strict);
+
+    rval->setBoolean(true);
+    return true;
 }
 
 static void
 array_trace(JSTracer *trc, JSObject *obj)
 {
     JS_ASSERT(obj->isDenseArray());
 
     uint32_t initLength = obj->getDenseArrayInitializedLength();
@@ -1266,17 +1255,16 @@ Class js::ArrayClass = {
         array_getGenericAttributes,
         array_getPropertyAttributes,
         array_getElementAttributes,
         array_getSpecialAttributes,
         array_setGenericAttributes,
         array_setPropertyAttributes,
         array_setElementAttributes,
         array_setSpecialAttributes,
-        array_deleteGeneric,
         array_deleteProperty,
         array_deleteElement,
         array_deleteSpecial,
         NULL,       /* enumerate      */
         array_typeOf,
         array_fix,
         NULL,       /* thisObject     */
         NULL,       /* clear          */
--- a/js/src/jsclass.h
+++ b/js/src/jsclass.h
@@ -223,19 +223,17 @@ typedef JSBool
 (* GenericAttributesOp)(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
 typedef JSBool
 (* PropertyAttributesOp)(JSContext *cx, JSObject *obj, PropertyName *name, uintN *attrsp);
 typedef JSBool
 (* ElementAttributesOp)(JSContext *cx, JSObject *obj, uint32_t index, uintN *attrsp);
 typedef JSBool
 (* SpecialAttributesOp)(JSContext *cx, JSObject *obj, SpecialId sid, uintN *attrsp);
 typedef JSBool
-(* DeleteGenericOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict);
-typedef JSBool
-(* DeleteIdOp)(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict);
+(* DeletePropertyOp)(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict);
 typedef JSBool
 (* DeleteElementOp)(JSContext *cx, JSObject *obj, uint32_t index, Value *vp, JSBool strict);
 typedef JSBool
 (* DeleteSpecialOp)(JSContext *cx, JSObject *obj, SpecialId sid, Value *vp, JSBool strict);
 typedef JSType
 (* TypeOfOp)(JSContext *cx, JSObject *obj);
 
 /*
@@ -324,31 +322,30 @@ struct ObjectOps
     GenericAttributesOp getGenericAttributes;
     PropertyAttributesOp getPropertyAttributes;
     ElementAttributesOp getElementAttributes;
     SpecialAttributesOp getSpecialAttributes;
     GenericAttributesOp setGenericAttributes;
     PropertyAttributesOp setPropertyAttributes;
     ElementAttributesOp setElementAttributes;
     SpecialAttributesOp setSpecialAttributes;
-    DeleteGenericOp     deleteGeneric;
-    DeleteIdOp          deleteProperty;
+    DeletePropertyOp    deleteProperty;
     DeleteElementOp     deleteElement;
     DeleteSpecialOp     deleteSpecial;
 
     JSNewEnumerateOp    enumerate;
     TypeOfOp            typeOf;
     FixOp               fix;
     ObjectOp            thisObject;
     FinalizeOp          clear;
 };
 
 #define JS_NULL_OBJECT_OPS                                                    \
     {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,   \
-     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,   \
+     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,        \
      NULL,NULL,NULL,NULL,NULL,NULL}
 
 struct Class
 {
     JS_CLASS_MEMBERS;
     ClassExtension      ext;
     ObjectOps           ops;
     uint8_t             pad[sizeof(JSClass) - sizeof(ClassSizeMeasurement) -
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -326,17 +326,17 @@ ArgSetter(JSContext *cx, JSObject *obj, 
      * For simplicity we use delete/define to replace the property with one
      * backed by the default Object getter and setter. Note that we rely on
      * args_delProperty to clear the corresponding reserved slot so the GC can
      * collect its value. Note also 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.
      */
     AutoValueRooter tvr(cx);
-    return js_DeleteProperty(cx, &argsobj, id, tvr.addr(), false) &&
+    return js_DeleteGeneric(cx, &argsobj, id, tvr.addr(), false) &&
            js_DefineProperty(cx, &argsobj, id, vp, NULL, NULL, JSPROP_ENUMERATE);
 }
 
 static JSBool
 args_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
              JSObject **objp)
 {
     *objp = NULL;
@@ -441,17 +441,17 @@ StrictArgSetter(JSContext *cx, JSObject 
 
     /*
      * For simplicity we use delete/set to replace the property with one
      * backed by the default Object getter and setter. Note that we rely on
      * args_delProperty to clear the corresponding reserved slot so the GC can
      * collect its value.
      */
     AutoValueRooter tvr(cx);
-    return js_DeleteProperty(cx, &argsobj, id, tvr.addr(), strict) &&
+    return js_DeleteGeneric(cx, &argsobj, id, tvr.addr(), strict) &&
            js_SetPropertyHelper(cx, &argsobj, id, 0, vp, strict);
 }
 
 static JSBool
 strictargs_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject **objp)
 {
     *objp = NULL;
 
@@ -1031,17 +1031,17 @@ StackFrame::getValidCalleeObject(JSConte
             return true;
 
         /*
          * At this point, we couldn't find an already-existing clone (or
          * force to exist a fresh clone) created via thisp's method read
          * barrier, so we must clone fun and store it in fp's callee to
          * avoid re-cloning upon repeated foo.caller access.
          *
-         * This must mean the code in js_DeleteProperty could not find this
+         * This must mean the code in js_DeleteGeneric could not find this
          * stack frame on the stack when the method was deleted. We've lost
          * track of the method, so we associate it with the first barriered
          * object found starting from thisp on the prototype chain.
          */
         JSFunction *newfunobj = CloneFunctionObject(cx, fun);
         if (!newfunobj)
             return false;
         newfunobj->setMethodObj(*first_barriered_thisp);
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -2764,22 +2764,20 @@ BEGIN_CASE(JSOP_DELPROP)
 END_CASE(JSOP_DELPROP)
 
 BEGIN_CASE(JSOP_DELELEM)
 {
     /* Fetch the left part and resolve it to a non-null object. */
     JSObject *obj;
     FETCH_OBJECT(cx, -2, obj);
 
-    /* Fetch index and convert it to id suitable for use with obj. */
-    jsid id;
-    FETCH_ELEMENT_ID(obj, -1, id);
-
-    /* Get or set the element. */
-    if (!obj->deleteGeneric(cx, id, &regs.sp[-2], script->strictModeCode))
+    const Value &propval = regs.sp[-1];
+    Value &rval = regs.sp[-2];
+
+    if (!obj->deleteByValue(cx, propval, &rval, script->strictModeCode))
         goto error;
 
     regs.sp--;
 }
 END_CASE(JSOP_DELELEM)
 
 BEGIN_CASE(JSOP_TOID)
 {
--- a/js/src/jsiter.h
+++ b/js/src/jsiter.h
@@ -129,23 +129,23 @@ EnumeratedIdVectorToIterator(JSContext *
  * iterator will never be exposed to scripts.
  */
 extern JS_FRIEND_API(JSBool)
 js_ValueToIterator(JSContext *cx, uintN flags, js::Value *vp);
 
 extern JS_FRIEND_API(JSBool)
 js_CloseIterator(JSContext *cx, JSObject *iterObj);
 
-bool
+extern bool
 js_SuppressDeletedProperty(JSContext *cx, JSObject *obj, jsid id);
 
-bool
+extern bool
 js_SuppressDeletedElement(JSContext *cx, JSObject *obj, uint32_t index);
 
-bool
+extern bool
 js_SuppressDeletedElements(JSContext *cx, JSObject *obj, uint32_t begin, uint32_t end);
 
 /*
  * IteratorMore() indicates whether another value is available. It might
  * internally call iterobj.next() and then cache the value until its
  * picked up by IteratorNext(). The value is cached in the current context.
  */
 extern JSBool
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3342,16 +3342,38 @@ JSObject::nonNativeSetElement(JSContext 
         JS_ASSERT(id == js_CheckForStringIndex(id));
         WatchpointMap *wpmap = cx->compartment->watchpointMap;
         if (wpmap && !wpmap->triggerWatchpoint(cx, this, id, vp))
             return false;
     }
     return getOps()->setElement(cx, this, index, vp, strict);
 }
 
+bool
+JSObject::deleteByValue(JSContext *cx, const Value &property, Value *rval, bool strict)
+{
+    uint32_t index;
+    if (IsDefinitelyIndex(property, &index))
+        return deleteElement(cx, index, rval, strict);
+
+    Value propval = property;
+    SpecialId sid;
+    if (ValueIsSpecial(this, &propval, &sid, cx))
+        return deleteSpecial(cx, sid, rval, strict);
+
+    JSAtom *name;
+    if (!js_ValueToAtom(cx, propval, &name))
+        return false;
+
+    if (name->isIndex(&index))
+        return deleteElement(cx, index, rval, false);
+
+    return deleteProperty(cx, name->asPropertyName(), rval, false);
+}
+
 JS_FRIEND_API(bool)
 JS_CopyPropertiesFrom(JSContext *cx, JSObject *target, JSObject *obj)
 {
     // If we're not native, then we cannot copy properties.
     JS_ASSERT(target->isNative() == obj->isNative());
     if (!target->isNative())
         return true;
 
@@ -3910,17 +3932,17 @@ DefineConstructorAndPrototype(JSContext 
 
     if (ctorp)
         *ctorp = ctor;
     return proto;
 
 bad:
     if (named) {
         Value rval;
-        obj->deleteGeneric(cx, ATOM_TO_JSID(atom), &rval, false);
+        obj->deleteByValue(cx, StringValue(atom), &rval, false);
     }
     if (cached)
         ClearClassObject(cx, obj, key);
     return NULL;
 }
 
 /*
  * Lazy standard classes need a way to indicate if they have been initialized.
@@ -5898,17 +5920,17 @@ js_SetElementAttributes(JSContext *cx, J
     if (!prop)
         return true;
     return obj->isNative()
            ? js_SetNativeAttributes(cx, obj, (Shape *) prop, *attrsp)
            : obj->setElementAttributes(cx, index, attrsp);
 }
 
 JSBool
-js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
+js_DeleteGeneric(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
 {
     JSObject *proto;
     JSProperty *prop;
     const Shape *shape;
 
     rval->setBoolean(true);
 
     /* Convert string indices to integers if appropriate. */
@@ -5970,22 +5992,34 @@ js_DeleteProperty(JSContext *cx, JSObjec
         return false;
     if (rval->isFalse())
         return true;
 
     return obj->removeProperty(cx, id) && js_SuppressDeletedProperty(cx, obj, id);
 }
 
 JSBool
+js_DeleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
+{
+    return js_DeleteGeneric(cx, obj, ATOM_TO_JSID(name), rval, strict);
+}
+
+JSBool
 js_DeleteElement(JSContext *cx, JSObject *obj, uint32_t index, Value *rval, JSBool strict)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
         return false;
-    return js_DeleteProperty(cx, obj, id, rval, strict);
+    return js_DeleteGeneric(cx, obj, id, rval, strict);
+}
+
+JSBool
+js_DeleteSpecial(JSContext *cx, JSObject *obj, SpecialId sid, Value *rval, JSBool strict)
+{
+    return js_DeleteGeneric(cx, obj, SPECIALID_TO_JSID(sid), rval, strict);
 }
 
 namespace js {
 
 bool
 HasDataProperty(JSContext *cx, JSObject *obj, jsid methodid, Value *vp)
 {
     if (const Shape *shape = obj->nativeLookup(cx, methodid)) {
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -322,21 +322,27 @@ js_GetElementAttributes(JSContext *cx, J
 
 extern JSBool
 js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, uintN *attrsp);
 
 extern JSBool
 js_SetElementAttributes(JSContext *cx, JSObject *obj, uint32_t index, uintN *attrsp);
 
 extern JSBool
-js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, js::Value *rval, JSBool strict);
+js_DeleteProperty(JSContext *cx, JSObject *obj, js::PropertyName *name, js::Value *rval, JSBool strict);
 
 extern JSBool
 js_DeleteElement(JSContext *cx, JSObject *obj, uint32_t index, js::Value *rval, JSBool strict);
 
+extern JSBool
+js_DeleteSpecial(JSContext *cx, JSObject *obj, js::SpecialId sid, js::Value *rval, JSBool strict);
+
+extern JSBool
+js_DeleteGeneric(JSContext *cx, JSObject *obj, jsid id, js::Value *rval, JSBool strict);
+
 extern JSType
 js_TypeOf(JSContext *cx, JSObject *obj);
 
 namespace js {
 
 /* ES5 8.12.8. */
 extern JSBool
 DefaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
@@ -1331,20 +1337,20 @@ struct JSObject : js::gc::Cell
     inline JSBool getElementAttributes(JSContext *cx, uint32_t index, uintN *attrsp);
     inline JSBool getSpecialAttributes(JSContext *cx, js::SpecialId sid, uintN *attrsp);
 
     inline JSBool setGenericAttributes(JSContext *cx, jsid id, uintN *attrsp);
     inline JSBool setPropertyAttributes(JSContext *cx, js::PropertyName *name, uintN *attrsp);
     inline JSBool setElementAttributes(JSContext *cx, uint32_t index, uintN *attrsp);
     inline JSBool setSpecialAttributes(JSContext *cx, js::SpecialId sid, uintN *attrsp);
 
-    inline JSBool deleteGeneric(JSContext *cx, jsid id, js::Value *rval, JSBool strict);
-    inline JSBool deleteProperty(JSContext *cx, js::PropertyName *name, js::Value *rval, JSBool strict);
-    inline JSBool deleteElement(JSContext *cx, uint32_t index, js::Value *rval, JSBool strict);
-    inline JSBool deleteSpecial(JSContext *cx, js::SpecialId sid, js::Value *rval, JSBool strict);
+    inline bool deleteProperty(JSContext *cx, js::PropertyName *name, js::Value *rval, bool strict);
+    inline bool deleteElement(JSContext *cx, uint32_t index, js::Value *rval, bool strict);
+    inline bool deleteSpecial(JSContext *cx, js::SpecialId sid, js::Value *rval, bool strict);
+    bool deleteByValue(JSContext *cx, const js::Value &property, js::Value *rval, bool strict);
 
     inline bool enumerate(JSContext *cx, JSIterateOp iterop, js::Value *statep, jsid *idp);
     inline bool defaultValue(JSContext *cx, JSType hint, js::Value *vp);
     inline JSType typeOf(JSContext *cx);
     inline JSObject *thisObject(JSContext *cx);
 
     static bool thisObject(JSContext *cx, const js::Value &v, js::Value *vp);
 
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -224,45 +224,46 @@ JSObject::getGeneric(JSContext *cx, jsid
 }
 
 inline JSBool
 JSObject::getProperty(JSContext *cx, js::PropertyName *name, js::Value *vp)
 {
     return getGeneric(cx, ATOM_TO_JSID(name), vp);
 }
 
-inline JSBool
-JSObject::deleteGeneric(JSContext *cx, jsid id, js::Value *rval, JSBool strict)
+inline bool
+JSObject::deleteProperty(JSContext *cx, js::PropertyName *name, js::Value *rval, bool strict)
 {
-    js::types::AddTypePropertyId(cx, this, id,
-                                 js::types::Type::UndefinedType());
+    jsid id = js_CheckForStringIndex(ATOM_TO_JSID(name));
+    js::types::AddTypePropertyId(cx, this, id, js::types::Type::UndefinedType());
     js::types::MarkTypePropertyConfigured(cx, this, id);
-    js::DeleteGenericOp op = getOps()->deleteGeneric;
-    return (op ? op : js_DeleteProperty)(cx, this, id, rval, strict);
+    js::DeletePropertyOp op = getOps()->deleteProperty;
+    return (op ? op : js_DeleteProperty)(cx, this, name, rval, strict);
 }
 
-inline JSBool
-JSObject::deleteProperty(JSContext *cx, js::PropertyName *name, js::Value *rval, JSBool strict)
-{
-    return deleteGeneric(cx, ATOM_TO_JSID(name), rval, strict);
-}
-
-inline JSBool
-JSObject::deleteElement(JSContext *cx, uint32_t index, js::Value *rval, JSBool strict)
+inline bool
+JSObject::deleteElement(JSContext *cx, uint32_t index, js::Value *rval, bool strict)
 {
     jsid id;
     if (!js::IndexToId(cx, index, &id))
         return false;
-    return deleteGeneric(cx, id, rval, strict);
+    js::types::AddTypePropertyId(cx, this, id, js::types::Type::UndefinedType());
+    js::types::MarkTypePropertyConfigured(cx, this, id);
+    js::DeleteElementOp op = getOps()->deleteElement;
+    return (op ? op : js_DeleteElement)(cx, this, index, rval, strict);
 }
 
-inline JSBool
-JSObject::deleteSpecial(JSContext *cx, js::SpecialId sid, js::Value *rval, JSBool strict)
+inline bool
+JSObject::deleteSpecial(JSContext *cx, js::SpecialId sid, js::Value *rval, bool strict)
 {
-    return deleteGeneric(cx, SPECIALID_TO_JSID(sid), rval, strict);
+    jsid id = SPECIALID_TO_JSID(sid);
+    js::types::AddTypePropertyId(cx, this, id, js::types::Type::UndefinedType());
+    js::types::MarkTypePropertyConfigured(cx, this, id);
+    js::DeleteSpecialOp op = getOps()->deleteSpecial;
+    return (op ? op : js_DeleteSpecial)(cx, this, sid, rval, strict);
 }
 
 inline void
 JSObject::finalize(JSContext *cx, bool background)
 {
     js::Probes::finalizeObject(this);
 
     if (!background) {
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -834,17 +834,17 @@ Walk(JSContext *cx, JSObject *holder, js
                 /* Step 2b(ii)(1). */
                 Value newElement;
                 jsid id = keys[i];
                 if (!Walk(cx, obj, id, reviver, &newElement))
                     return false;
 
                 if (newElement.isUndefined()) {
                     /* Step 2b(ii)(2). */
-                    if (!js_DeleteProperty(cx, obj, id, &newElement, false))
+                    if (!obj->deleteByValue(cx, IdToValue(id), &newElement, false))
                         return false;
                 } else {
                     /* Step 2b(ii)(3). */
                     JS_ASSERT(obj->isNative());
                     if (!DefineNativeProperty(cx, obj, id, newElement, JS_PropertyStub,
                                               JS_StrictPropertyStub, JSPROP_ENUMERATE, 0, 0))
                     {
                         return false;
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -1161,30 +1161,30 @@ static JSBool
 proxy_SetSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, uintN *attrsp)
 {
     return proxy_SetGenericAttributes(cx, obj, SPECIALID_TO_JSID(sid), attrsp);
 }
 
 static JSBool
 proxy_DeleteGeneric(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
 {
-    id = js_CheckForStringIndex(id);
+    JS_ASSERT(id == js_CheckForStringIndex(id));
 
     // TODO: throwing away strict
     bool deleted;
     if (!Proxy::delete_(cx, obj, id, &deleted) || !js_SuppressDeletedProperty(cx, obj, id))
         return false;
     rval->setBoolean(deleted);
     return true;
 }
 
 static JSBool
 proxy_DeleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
 {
-    return proxy_DeleteGeneric(cx, obj, ATOM_TO_JSID(name), rval, strict);
+    return proxy_DeleteGeneric(cx, obj, js_CheckForStringIndex(ATOM_TO_JSID(name)), rval, strict);
 }
 
 static JSBool
 proxy_DeleteElement(JSContext *cx, JSObject *obj, uint32_t index, Value *rval, JSBool strict)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
         return false;
@@ -1304,17 +1304,16 @@ JS_FRIEND_DATA(Class) js::ObjectProxyCla
         proxy_GetGenericAttributes,
         proxy_GetPropertyAttributes,
         proxy_GetElementAttributes,
         proxy_GetSpecialAttributes,
         proxy_SetGenericAttributes,
         proxy_SetPropertyAttributes,
         proxy_SetElementAttributes,
         proxy_SetSpecialAttributes,
-        proxy_DeleteGeneric,
         proxy_DeleteProperty,
         proxy_DeleteElement,
         proxy_DeleteSpecial,
         NULL,                /* enumerate       */
         proxy_TypeOf,
         proxy_Fix,           /* fix             */
         NULL,                /* thisObject      */
         NULL,                /* clear           */
@@ -1366,17 +1365,16 @@ JS_FRIEND_DATA(Class) js::OuterWindowPro
         proxy_GetGenericAttributes,
         proxy_GetPropertyAttributes,
         proxy_GetElementAttributes,
         proxy_GetSpecialAttributes,
         proxy_SetGenericAttributes,
         proxy_SetPropertyAttributes,
         proxy_SetElementAttributes,
         proxy_SetSpecialAttributes,
-        proxy_DeleteGeneric,
         proxy_DeleteProperty,
         proxy_DeleteElement,
         proxy_DeleteSpecial,
         NULL,                /* enumerate       */
         NULL,                /* typeof          */
         NULL,                /* fix             */
         NULL,                /* thisObject      */
         NULL,                /* clear           */
@@ -1440,17 +1438,16 @@ JS_FRIEND_DATA(Class) js::FunctionProxyC
         proxy_GetGenericAttributes,
         proxy_GetPropertyAttributes,
         proxy_GetElementAttributes,
         proxy_GetSpecialAttributes,
         proxy_SetGenericAttributes,
         proxy_SetPropertyAttributes,
         proxy_SetElementAttributes,
         proxy_SetSpecialAttributes,
-        proxy_DeleteGeneric,
         proxy_DeleteProperty,
         proxy_DeleteElement,
         proxy_DeleteSpecial,
         NULL,                /* enumerate       */
         proxy_TypeOf,
         NULL,                /* fix             */
         NULL,                /* thisObject      */
         NULL,                /* clear           */
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -577,48 +577,45 @@ ArrayBuffer::obj_setElementAttributes(JS
 
 JSBool
 ArrayBuffer::obj_setSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, uintN *attrsp)
 {
     return obj_setGenericAttributes(cx, obj, SPECIALID_TO_JSID(sid), attrsp);
 }
 
 JSBool
-ArrayBuffer::obj_deleteGeneric(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
+ArrayBuffer::obj_deleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
 {
-    if (JSID_IS_ATOM(id, cx->runtime->atomState.byteLengthAtom)) {
+    if (name == cx->runtime->atomState.byteLengthAtom) {
         rval->setBoolean(false);
         return true;
     }
 
     JSObject *delegate = DelegateObject(cx, obj);
     if (!delegate)
         return false;
-    return js_DeleteProperty(cx, delegate, id, rval, strict);
-}
-
-JSBool
-ArrayBuffer::obj_deleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
-{
-    return obj_deleteGeneric(cx, obj, ATOM_TO_JSID(name), rval, strict);
+    return js_DeleteProperty(cx, delegate, name, rval, strict);
 }
 
 JSBool
 ArrayBuffer::obj_deleteElement(JSContext *cx, JSObject *obj, uint32_t index, Value *rval, JSBool strict)
 {
     JSObject *delegate = DelegateObject(cx, obj);
     if (!delegate)
         return false;
     return js_DeleteElement(cx, delegate, index, rval, strict);
 }
 
 JSBool
 ArrayBuffer::obj_deleteSpecial(JSContext *cx, JSObject *obj, SpecialId sid, Value *rval, JSBool strict)
 {
-    return obj_deleteGeneric(cx, obj, SPECIALID_TO_JSID(sid), rval, strict);
+    JSObject *delegate = DelegateObject(cx, obj);
+    if (!delegate)
+        return false;
+    return js_DeleteSpecial(cx, delegate, sid, rval, strict);
 }
 
 JSBool
 ArrayBuffer::obj_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
               Value *statep, jsid *idp)
 {
     statep->setNull();
     return true;
@@ -1256,42 +1253,28 @@ class TypedArrayTemplate
     static JSBool
     obj_defineSpecial(JSContext *cx, JSObject *obj, SpecialId sid, const Value *v,
                       PropertyOp getter, StrictPropertyOp setter, uintN attrs)
     {
         return obj_defineGeneric(cx, obj, SPECIALID_TO_JSID(sid), v, getter, setter, attrs);
     }
 
     static JSBool
-    obj_deleteGeneric(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
+    obj_deleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
     {
-        if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
-            rval->setBoolean(false);
-            return true;
-        }
-
-        JSObject *tarray = TypedArray::getTypedArray(obj);
-        JS_ASSERT(tarray);
-
-        if (isArrayIndex(cx, tarray, id)) {
+        if (name == cx->runtime->atomState.lengthAtom) {
             rval->setBoolean(false);
             return true;
         }
 
         rval->setBoolean(true);
         return true;
     }
 
     static JSBool
-    obj_deleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
-    {
-        return obj_deleteGeneric(cx, obj, ATOM_TO_JSID(name), rval, strict);
-    }
-
-    static JSBool
     obj_deleteElement(JSContext *cx, JSObject *obj, uint32_t index, Value *rval, JSBool strict)
     {
         JSObject *tarray = TypedArray::getTypedArray(obj);
         JS_ASSERT(tarray);
 
         if (index < getLength(tarray)) {
             rval->setBoolean(false);
             return true;
@@ -1299,17 +1282,18 @@ class TypedArrayTemplate
 
         rval->setBoolean(true);
         return true;
     }
 
     static JSBool
     obj_deleteSpecial(JSContext *cx, JSObject *obj, SpecialId sid, Value *rval, JSBool strict)
     {
-        return obj_deleteGeneric(cx, obj, SPECIALID_TO_JSID(sid), rval, strict);
+        rval->setBoolean(true);
+        return true;
     }
 
     static JSBool
     obj_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
                   Value *statep, jsid *idp)
     {
         JSObject *tarray = getTypedArray(obj);
         JS_ASSERT(tarray);
@@ -2167,17 +2151,16 @@ Class js::ArrayBufferClass = {
         ArrayBuffer::obj_getGenericAttributes,
         ArrayBuffer::obj_getPropertyAttributes,
         ArrayBuffer::obj_getElementAttributes,
         ArrayBuffer::obj_getSpecialAttributes,
         ArrayBuffer::obj_setGenericAttributes,
         ArrayBuffer::obj_setPropertyAttributes,
         ArrayBuffer::obj_setElementAttributes,
         ArrayBuffer::obj_setSpecialAttributes,
-        ArrayBuffer::obj_deleteGeneric,
         ArrayBuffer::obj_deleteProperty,
         ArrayBuffer::obj_deleteElement,
         ArrayBuffer::obj_deleteSpecial,
         ArrayBuffer::obj_enumerate,
         ArrayBuffer::obj_typeOf,
         NULL,       /* thisObject      */
         NULL,       /* clear           */
     }
@@ -2280,17 +2263,16 @@ JSFunctionSpec _typedArray::jsfuncs[] = 
         _typedArray::obj_getGenericAttributes,                                 \
         _typedArray::obj_getPropertyAttributes,                                \
         _typedArray::obj_getElementAttributes,                                 \
         _typedArray::obj_getSpecialAttributes,                                 \
         _typedArray::obj_setGenericAttributes,                                 \
         _typedArray::obj_setPropertyAttributes,                                \
         _typedArray::obj_setElementAttributes,                                 \
         _typedArray::obj_setSpecialAttributes,                                 \
-        _typedArray::obj_deleteGeneric,                                        \
         _typedArray::obj_deleteProperty,                                       \
         _typedArray::obj_deleteElement,                                        \
         _typedArray::obj_deleteSpecial,                                        \
         _typedArray::obj_enumerate,                                            \
         _typedArray::obj_typeOf,                                               \
         NULL,                /* thisObject  */                                 \
         NULL,                /* clear       */                                 \
     }                                                                          \
--- a/js/src/jstypedarray.h
+++ b/js/src/jstypedarray.h
@@ -141,18 +141,16 @@ struct JS_FRIEND_API(ArrayBuffer) {
     static JSBool
     obj_setPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, uintN *attrsp);
     static JSBool
     obj_setElementAttributes(JSContext *cx, JSObject *obj, uint32_t index, uintN *attrsp);
     static JSBool
     obj_setSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, uintN *attrsp);
 
     static JSBool
-    obj_deleteGeneric(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict);
-    static JSBool
     obj_deleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict);
     static JSBool
     obj_deleteElement(JSContext *cx, JSObject *obj, uint32_t index, Value *rval, JSBool strict);
     static JSBool
     obj_deleteSpecial(JSContext *cx, JSObject *obj, SpecialId sid, Value *rval, JSBool strict);
 
     static JSBool
     obj_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
--- a/js/src/jsxml.cpp
+++ b/js/src/jsxml.cpp
@@ -4985,52 +4985,50 @@ static JSBool
 xml_setSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, uintN *attrsp)
 {
     return xml_setGenericAttributes(cx, obj, SPECIALID_TO_JSID(sid), attrsp);
 }
 
 static JSBool
 xml_deleteGeneric(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
 {
-    JSXML *xml;
-    jsval idval;
     uint32_t index;
     JSObject *nameqn;
     jsid funid;
 
-    idval = IdToJsval(id);
-    xml = (JSXML *) obj->getPrivate();
+    Value idval = IdToValue(id);
+    JSXML *xml = (JSXML *) obj->getPrivate();
     if (js_IdIsIndex(id, &index)) {
         if (xml->xml_class != JSXML_CLASS_LIST) {
             /* See NOTE in spec: this variation is reserved for future use. */
             ReportBadXMLName(cx, IdToValue(id));
             return false;
         }
 
         /* ECMA-357 9.2.1.3. */
         DeleteListElement(cx, xml, index);
     } else {
         nameqn = ToXMLName(cx, idval, &funid);
         if (!nameqn)
             return false;
         if (!JSID_IS_VOID(funid))
-            return js_DeleteProperty(cx, obj, funid, rval, false);
+            return js_DeleteGeneric(cx, obj, funid, rval, false);
 
         DeleteNamedProperty(cx, xml, nameqn,
                             nameqn->getClass() == &AttributeNameClass);
     }
 
     /*
      * If this object has its own (mutable) scope,  then we may have added a
      * property to the scope in xml_lookupGeneric for it to return to mean
      * "found" and to provide a handle for access operations to call the
      * property's getter or setter. But now it's time to remove any such
      * property, to purge the property cache and remove the scope entry.
      */
-    if (!obj->nativeEmpty() && !js_DeleteProperty(cx, obj, id, rval, false))
+    if (!obj->nativeEmpty() && !js_DeleteGeneric(cx, obj, id, rval, false))
         return false;
 
     rval->setBoolean(true);
     return true;
 }
 
 static JSBool
 xml_deleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
@@ -5393,17 +5391,16 @@ JS_FRIEND_DATA(Class) js::XMLClass = {
         xml_getGenericAttributes,
         xml_getPropertyAttributes,
         xml_getElementAttributes,
         xml_getSpecialAttributes,
         xml_setGenericAttributes,
         xml_setPropertyAttributes,
         xml_setElementAttributes,
         xml_setSpecialAttributes,
-        xml_deleteGeneric,
         xml_deleteProperty,
         xml_deleteElement,
         xml_deleteSpecial,
         xml_enumerate,
         xml_typeOf,
         xml_fix,
         NULL,       /* thisObject     */
         xml_clear
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -2047,21 +2047,20 @@ void JS_FASTCALL
 stubs::DelElem(VMFrame &f)
 {
     JSContext *cx = f.cx;
 
     JSObject *obj = ValueToObject(cx, &f.regs.sp[-2]);
     if (!obj)
         THROW();
 
-    jsid id;
-    if (!FetchElementId(f, obj, f.regs.sp[-1], id, &f.regs.sp[-1]))
-        THROW();
+    const Value &propval = f.regs.sp[-1];
+    Value &rval = f.regs.sp[-2];
 
-    if (!obj->deleteGeneric(cx, id, &f.regs.sp[-2], strict))
+    if (!obj->deleteByValue(cx, propval, &rval, strict))
         THROW();
 }
 
 void JS_FASTCALL
 stubs::DefVarOrConst(VMFrame &f, PropertyName *name)
 {
     JSContext *cx = f.cx;
     StackFrame *fp = f.fp();
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -3359,27 +3359,24 @@ DebuggerObject_defineProperties(JSContex
 /*
  * This does a non-strict delete, as a matter of API design. The case where the
  * property is non-configurable isn't necessarily exceptional here.
  */
 static JSBool
 DebuggerObject_deleteProperty(JSContext *cx, uintN argc, Value *vp)
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "deleteProperty", args, dbg, obj);
-    Value arg = argc > 0 ? args[0] : UndefinedValue();
-    jsid id;
-    if (!ValueToId(cx, arg, &id))
-        return false;
+    Value nameArg = argc > 0 ? args[0] : UndefinedValue();
 
     AutoCompartment ac(cx, obj);
-    if (!ac.enter() || !cx->compartment->wrapId(cx, &id))
+    if (!ac.enter() || !cx->compartment->wrap(cx, &nameArg))
         return false;
 
     ErrorCopier ec(ac, dbg->toJSObject());
-    return obj->deleteGeneric(cx, id, &args.rval(), false);
+    return obj->deleteByValue(cx, nameArg, &args.rval(), false);
 }
 
 enum SealHelperOp { Seal, Freeze, PreventExtensions };
 
 static JSBool
 DebuggerObject_sealHelper(JSContext *cx, uintN argc, Value *vp, SealHelperOp op, const char *name)
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, name, args, dbg, obj);
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -327,22 +327,16 @@ with_SetElementAttributes(JSContext *cx,
 
 static JSBool
 with_SetSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, uintN *attrsp)
 {
     return obj->asWith().object().setSpecialAttributes(cx, sid, attrsp);
 }
 
 static JSBool
-with_DeleteGeneric(JSContext *cx, JSObject *obj, jsid id, Value *rval, JSBool strict)
-{
-    return obj->asWith().object().deleteGeneric(cx, id, rval, strict);
-}
-
-static JSBool
 with_DeleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict)
 {
     return obj->asWith().object().deleteProperty(cx, name, rval, strict);
 }
 
 static JSBool
 with_DeleteElement(JSContext *cx, JSObject *obj, uint32_t index, Value *rval, JSBool strict)
 {
@@ -416,17 +410,16 @@ Class js::WithClass = {
         with_GetGenericAttributes,
         with_GetPropertyAttributes,
         with_GetElementAttributes,
         with_GetSpecialAttributes,
         with_SetGenericAttributes,
         with_SetPropertyAttributes,
         with_SetElementAttributes,
         with_SetSpecialAttributes,
-        with_DeleteGeneric,
         with_DeleteProperty,
         with_DeleteElement,
         with_DeleteSpecial,
         with_Enumerate,
         with_TypeOf,
         NULL,             /* fix   */
         with_ThisObject,
         NULL,             /* clear */
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -871,17 +871,16 @@ js::Class XPC_WN_NoHelper_JSClass = {
         nsnull, // getGenericAttributes
         nsnull, // getAttributes
         nsnull, // getElementAttributes
         nsnull, // getSpecialAttributes
         nsnull, // setGenericAttributes
         nsnull, // setAttributes
         nsnull, // setElementAttributes
         nsnull, // setSpecialAttributes
-        nsnull, // deleteGeneric
         nsnull, // deleteProperty
         nsnull, // deleteElement
         nsnull, // deleteSpecial
         XPC_WN_JSOp_Enumerate,
         XPC_WN_JSOp_TypeOf_Object,
         nsnull, // fix
         XPC_WN_JSOp_ThisObject,
         XPC_WN_JSOp_Clear
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -1410,17 +1410,16 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS
         nsnull, /* getGenericAttributes  */                                   \
         nsnull, /* getAttributes  */                                          \
         nsnull, /* getElementAttributes  */                                   \
         nsnull, /* getSpecialAttributes  */                                   \
         nsnull, /* setGenericAttributes  */                                   \
         nsnull, /* setAttributes  */                                          \
         nsnull, /* setElementAttributes  */                                   \
         nsnull, /* setSpecialAttributes  */                                   \
-        nsnull, /* deleteGeneric */                                           \
         nsnull, /* deleteProperty */                                          \
         nsnull, /* deleteElement */                                           \
         nsnull, /* deleteSpecial */                                           \
         XPC_WN_JSOp_Enumerate,                                                \
         XPC_WN_JSOp_TypeOf_Function,                                          \
         nsnull, /* fix            */                                          \
         XPC_WN_JSOp_ThisObject,                                               \
         XPC_WN_JSOp_Clear                                                     \
@@ -1448,17 +1447,16 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS
         nsnull, /* getGenericAttributes  */                                   \
         nsnull, /* getAttributes  */                                          \
         nsnull, /* getElementAttributes  */                                   \
         nsnull, /* getSpecialAttributes  */                                   \
         nsnull, /* setGenericAttributes  */                                   \
         nsnull, /* setAttributes  */                                          \
         nsnull, /* setElementAttributes  */                                   \
         nsnull, /* setSpecialAttributes  */                                   \
-        nsnull, /* deleteGeneric */                                           \
         nsnull, /* deleteProperty */                                          \
         nsnull, /* deleteElement */                                           \
         nsnull, /* deleteSpecial */                                           \
         XPC_WN_JSOp_Enumerate,                                                \
         XPC_WN_JSOp_TypeOf_Object,                                            \
         nsnull, /* fix            */                                          \
         XPC_WN_JSOp_ThisObject,                                               \
         XPC_WN_JSOp_Clear                                                     \