Bug 697343 - Remove getElementIfPresent. r=Waldo
☠☠ backed out by fbc0b4c30fd0 ☠ ☠
authorTom Schuster <evilpies@gmail.com>
Thu, 05 Dec 2013 20:07:24 +0100
changeset 158933 bfe768b8746466df23f9f141b8ed32ba991bc5ff
parent 158932 c63eaabaefb176376dc71a598eb7a1d47a08772b
child 158934 4ef4764c1b559115664fbd4534629e48d45e3cf0
push id37154
push userevilpies@gmail.com
push dateThu, 05 Dec 2013 19:17:07 +0000
treeherdermozilla-inbound@22770b30545b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs697343
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 697343 - Remove getElementIfPresent. r=Waldo
dom/bindings/Codegen.py
js/public/Class.h
js/src/builtin/TypedObject.cpp
js/src/builtin/TypedObject.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/vm/ScopeObject.cpp
js/src/vm/TypedArrayObject.cpp
js/src/vm/TypedArrayObject.h
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/xpcprivate.h
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -8279,76 +8279,16 @@ class CGDOMJSProxyHandler_finalize(Class
     def __init__(self, descriptor):
         args = [Argument('JSFreeOp*', 'fop'), Argument('JSObject*', 'proxy')]
         ClassMethod.__init__(self, "finalize", "void", args)
         self.descriptor = descriptor
     def getBody(self):
         return ("%s self = UnwrapProxy(proxy);\n\n" % (self.descriptor.nativeType + "*") +
                 finalizeHook(self.descriptor, FINALIZE_HOOK_NAME, self.args[0].name).define())
 
-class CGDOMJSProxyHandler_getElementIfPresent(ClassMethod):
-    def __init__(self, descriptor):
-        args = [Argument('JSContext*', 'cx'),
-                Argument('JS::Handle<JSObject*>', 'proxy'),
-                Argument('JS::Handle<JSObject*>', 'receiver'),
-                Argument('uint32_t', 'index'),
-                Argument('JS::MutableHandle<JS::Value>', 'vp'),
-                Argument('bool*', 'present')]
-        ClassMethod.__init__(self, "getElementIfPresent", "bool", args)
-        self.descriptor = descriptor
-    def getBody(self):
-        successCode = ("*present = found;\n"
-                       "return true;")
-        templateValues = {'jsvalRef': 'vp', 'jsvalHandle': 'vp',
-                          'obj': 'proxy', 'successCode': successCode}
-        if self.descriptor.supportsIndexedProperties():
-            get = (CGProxyIndexedGetter(self.descriptor, templateValues).define() + "\n"
-                   "// We skip the expando object and any named getters if\n"
-                   "// there is an indexed getter.\n" +
-                   "\n") % (self.descriptor.nativeType)
-        else:
-            if self.descriptor.supportsNamedProperties():
-                get = CGProxyNamedGetter(self.descriptor, templateValues,
-                                         "UINT_TO_JSVAL(index)").define()
-            get += """
-
-JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
-if (expando) {
-  bool isPresent;
-  if (!JS_GetElementIfPresent(cx, expando, index, expando, vp, &isPresent)) {
-    return false;
-  }
-  if (isPresent) {
-    *present = true;
-    return true;
-  }
-}
-"""
-
-        return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
-             "Should not have a XrayWrapper here");
-
-""" + get + """
-JS::Rooted<JSObject*> proto(cx);
-if (!js::GetObjectProto(cx, proxy, &proto)) {
-  return false;
-}
-if (proto) {
-  bool isPresent;
-  if (!JS_GetElementIfPresent(cx, proto, index, proxy, vp, &isPresent)) {
-    return false;
-  }
-  *present = isPresent;
-  return true;
-}
-
-*present = false;
-// Can't Debug_SetValueRangeToCrashOnTouch because it's not public
-return true;"""
-
 class CGDOMJSProxyHandler_getInstance(ClassMethod):
     def __init__(self):
         ClassMethod.__init__(self, "getInstance", "DOMProxyHandler*", [], static=True)
     def getBody(self):
         return """static DOMProxyHandler instance;
 return &instance;"""
 
 class CGDOMJSProxyHandler(CGClass):
@@ -8361,17 +8301,16 @@ class CGDOMJSProxyHandler(CGClass):
                    ClassUsingDeclaration("mozilla::dom::DOMProxyHandler",
                                          "defineProperty"),
                    CGDOMJSProxyHandler_getOwnPropertyNames(descriptor),
                    CGDOMJSProxyHandler_hasOwn(descriptor),
                    CGDOMJSProxyHandler_get(descriptor),
                    CGDOMJSProxyHandler_className(descriptor),
                    CGDOMJSProxyHandler_finalizeInBackground(descriptor),
                    CGDOMJSProxyHandler_finalize(descriptor),
-                   CGDOMJSProxyHandler_getElementIfPresent(descriptor),
                    CGDOMJSProxyHandler_getInstance(),
                    CGDOMJSProxyHandler_delete(descriptor)]
         CGClass.__init__(self, 'DOMProxyHandler',
                          bases=[ClassBase('mozilla::dom::DOMProxyHandler')],
                          constructors=constructors,
                          methods=methods)
 
 class CGDOMJSProxyHandlerDeclarer(CGThing):
--- a/js/public/Class.h
+++ b/js/public/Class.h
@@ -342,19 +342,16 @@ typedef bool
                 JS::MutableHandleValue vp);
 typedef bool
 (* PropertyIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver,
                  JS::Handle<PropertyName*> name, JS::MutableHandleValue vp);
 typedef bool
 (* ElementIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, uint32_t index,
                 JS::MutableHandleValue vp);
 typedef bool
-(* ElementIfPresentOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver,
-                       uint32_t index, JS::MutableHandleValue vp, bool* present);
-typedef bool
 (* SpecialIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver,
                 HandleSpecialId sid, JS::MutableHandleValue vp);
 typedef bool
 (* StrictGenericIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
                       JS::MutableHandleValue vp, bool strict);
 typedef bool
 (* StrictPropertyIdOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
                        JS::MutableHandleValue vp, bool strict);
@@ -454,17 +451,16 @@ struct ObjectOps
     LookupSpecialOp     lookupSpecial;
     DefineGenericOp     defineGeneric;
     DefinePropOp        defineProperty;
     DefineElementOp     defineElement;
     DefineSpecialOp     defineSpecial;
     GenericIdOp         getGeneric;
     PropertyIdOp        getProperty;
     ElementIdOp         getElement;
-    ElementIfPresentOp  getElementIfPresent; /* can be null */
     SpecialIdOp         getSpecial;
     StrictGenericIdOp   setGeneric;
     StrictPropertyIdOp  setProperty;
     StrictElementIdOp   setElement;
     StrictSpecialIdOp   setSpecial;
     GenericAttributesOp getGenericAttributes;
     GenericAttributesOp setGenericAttributes;
     DeletePropertyOp    deleteProperty;
@@ -475,17 +471,17 @@ struct ObjectOps
 
     JSNewEnumerateOp    enumerate;
     ObjectOp            thisObject;
 };
 
 #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}
 
 } // namespace js
 
 // Classes, objects, and properties.
 
 typedef void (*JSClassInternal)();
 
 struct JSClass {
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -2050,58 +2050,47 @@ TypedDatum::obj_getProperty(JSContext *c
     RootedId id(cx, NameToId(name));
     return obj_getGeneric(cx, obj, receiver, id, vp);
 }
 
 bool
 TypedDatum::obj_getElement(JSContext *cx, HandleObject obj, HandleObject receiver,
                              uint32_t index, MutableHandleValue vp)
 {
-    bool present;
-    return obj_getElementIfPresent(cx, obj, receiver, index, vp, &present);
-}
-
-bool
-TypedDatum::obj_getElementIfPresent(JSContext *cx, HandleObject obj,
-                                    HandleObject receiver, uint32_t index,
-                                    MutableHandleValue vp, bool *present)
-{
     RootedObject type(cx, GetType(*obj));
     TypeRepresentation *typeRepr = typeRepresentation(*type);
 
     switch (typeRepr->kind()) {
       case TypeRepresentation::Scalar:
       case TypeRepresentation::Reference:
       case TypeRepresentation::X4:
       case TypeRepresentation::Struct:
         break;
 
       case TypeRepresentation::Array: {
-        *present = true;
         ArrayTypeRepresentation *arrayTypeRepr = typeRepr->asArray();
 
         if (index >= arrayTypeRepr->length()) {
             vp.setUndefined();
             return true;
         }
 
         RootedObject elementType(cx, ArrayElementType(type));
         size_t offset = arrayTypeRepr->element()->size() * index;
         return Reify(cx, arrayTypeRepr->element(), elementType, obj, offset, vp);
       }
     }
 
     RootedObject proto(cx, obj->getProto());
     if (!proto) {
-        *present = false;
         vp.setUndefined();
         return true;
     }
 
-    return JSObject::getElementIfPresent(cx, proto, receiver, index, vp, present);
+    return JSObject::getElement(cx, proto, receiver, index, vp);
 }
 
 bool
 TypedDatum::obj_getSpecial(JSContext *cx, HandleObject obj,
                             HandleObject receiver, HandleSpecialId sid,
                             MutableHandleValue vp)
 {
     RootedId id(cx, SPECIALID_TO_JSID(sid));
@@ -2456,17 +2445,16 @@ const Class TypedObject::class_ = {
         TypedDatum::obj_lookupSpecial,
         TypedDatum::obj_defineGeneric,
         TypedDatum::obj_defineProperty,
         TypedDatum::obj_defineElement,
         TypedDatum::obj_defineSpecial,
         TypedDatum::obj_getGeneric,
         TypedDatum::obj_getProperty,
         TypedDatum::obj_getElement,
-        TypedDatum::obj_getElementIfPresent,
         TypedDatum::obj_getSpecial,
         TypedDatum::obj_setGeneric,
         TypedDatum::obj_setProperty,
         TypedDatum::obj_setElement,
         TypedDatum::obj_setSpecial,
         TypedDatum::obj_getGenericAttributes,
         TypedDatum::obj_setGenericAttributes,
         TypedDatum::obj_deleteProperty,
@@ -2548,17 +2536,16 @@ const Class TypedHandle::class_ = {
         TypedDatum::obj_lookupSpecial,
         TypedDatum::obj_defineGeneric,
         TypedDatum::obj_defineProperty,
         TypedDatum::obj_defineElement,
         TypedDatum::obj_defineSpecial,
         TypedDatum::obj_getGeneric,
         TypedDatum::obj_getProperty,
         TypedDatum::obj_getElement,
-        TypedDatum::obj_getElementIfPresent,
         TypedDatum::obj_getSpecial,
         TypedDatum::obj_setGeneric,
         TypedDatum::obj_setProperty,
         TypedDatum::obj_setElement,
         TypedDatum::obj_setSpecial,
         TypedDatum::obj_getGenericAttributes,
         TypedDatum::obj_setGenericAttributes,
         TypedDatum::obj_deleteProperty,
--- a/js/src/builtin/TypedObject.h
+++ b/js/src/builtin/TypedObject.h
@@ -263,19 +263,16 @@ class TypedDatum : public JSObject
                                 HandlePropertyName name, MutableHandleValue vp);
 
     static bool obj_getElement(JSContext *cx, HandleObject obj, HandleObject receiver,
                                uint32_t index, MutableHandleValue vp);
 
     static bool obj_getSpecial(JSContext *cx, HandleObject obj, HandleObject receiver,
                                HandleSpecialId sid, MutableHandleValue vp);
 
-    static bool obj_getElementIfPresent(JSContext *cx, HandleObject obj,
-                                        HandleObject receiver, uint32_t index,
-                                        MutableHandleValue vp, bool *present);
     static bool obj_setGeneric(JSContext *cx, HandleObject obj, HandleId id,
                                MutableHandleValue vp, bool strict);
     static bool obj_setProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
                                 MutableHandleValue vp, bool strict);
     static bool obj_setElement(JSContext *cx, HandleObject obj, uint32_t index,
                                MutableHandleValue vp, bool strict);
     static bool obj_setSpecial(JSContext *cx, HandleObject obj,
                                HandleSpecialId sid, MutableHandleValue vp, bool strict);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -3389,35 +3389,16 @@ JS_ForwardGetElementTo(JSContext *cx, JS
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     JSAutoResolveFlags rf(cx, 0);
 
     return JSObject::getElement(cx, obj, onBehalfOf, index, vp);
 }
 
 JS_PUBLIC_API(bool)
-JS_GetElementIfPresent(JSContext *cx, JSObject *objArg, uint32_t index, JSObject *onBehalfOfArg,
-                       MutableHandleValue vp, bool* present)
-{
-    RootedObject obj(cx, objArg);
-    RootedObject onBehalfOf(cx, onBehalfOfArg);
-    AssertHeapIsIdle(cx);
-    CHECK_REQUEST(cx);
-    assertSameCompartment(cx, obj);
-    JSAutoResolveFlags rf(cx, 0);
-
-    bool isPresent;
-    if (!JSObject::getElementIfPresent(cx, obj, onBehalfOf, index, vp, &isPresent))
-        return false;
-
-    *present = isPresent;
-    return true;
-}
-
-JS_PUBLIC_API(bool)
 JS_GetProperty(JSContext *cx, JSObject *objArg, const char *name, MutableHandleValue vp)
 {
     RootedObject obj(cx, objArg);
     JSAtom *atom = Atomize(cx, name, strlen(name));
     return atom && JS_GetPropertyById(cx, obj, AtomToId(atom), vp);
 }
 
 JS_PUBLIC_API(bool)
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3035,25 +3035,16 @@ JS_LookupElement(JSContext *cx, JSObject
 
 extern JS_PUBLIC_API(bool)
 JS_GetElement(JSContext *cx, JSObject *obj, uint32_t index, JS::MutableHandle<JS::Value> vp);
 
 extern JS_PUBLIC_API(bool)
 JS_ForwardGetElementTo(JSContext *cx, JSObject *obj, uint32_t index, JSObject *onBehalfOf,
                        JS::MutableHandle<JS::Value> vp);
 
-/*
- * Get the property with name given by |index|, if it has one.  If
- * not, |*present| will be set to false and the value of |vp| must not
- * be relied on.
- */
-extern JS_PUBLIC_API(bool)
-JS_GetElementIfPresent(JSContext *cx, JSObject *obj, uint32_t index, JSObject *onBehalfOf,
-                       JS::MutableHandle<JS::Value> vp, bool* present);
-
 extern JS_PUBLIC_API(bool)
 JS_SetElement(JSContext *cx, JSObject *obj, uint32_t index, JS::MutableHandle<JS::Value> vp);
 
 extern JS_PUBLIC_API(bool)
 JS_DeleteElement(JSContext *cx, JSObject *obj, uint32_t index);
 
 extern JS_PUBLIC_API(bool)
 JS_DeleteElement2(JSContext *cx, JSObject *obj, uint32_t index, bool *succeeded);
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -129,37 +129,44 @@ js::StringIsArrayIndex(JSLinearString *s
         *indexp = index;
         return true;
     }
 
     return false;
 }
 
 static bool
-DoubleIndexToId(JSContext *cx, double index, MutableHandleId id)
+ToId(JSContext *cx, double index, MutableHandleId id)
 {
     if (index == uint32_t(index))
         return IndexToId(cx, uint32_t(index), id.address());
 
     Value tmp = DoubleValue(index);
     return ValueToId<CanGC>(cx, HandleValue::fromMarkedLocation(&tmp), id);
 }
 
+static bool
+ToId(JSContext *cx, uint32_t index, MutableHandleId id)
+{
+    return IndexToId(cx, index, id.address());
+}
+
 /*
  * If the property at the given index exists, get its value into location
  * pointed by vp and set *hole to false. Otherwise set *hole to true and *vp
  * to JSVAL_VOID. This function assumes that the location pointed by vp is
  * properly rooted and can be used as GC-protected storage for temporaries.
  */
+template<typename IndexType>
 static inline bool
-DoGetElement(JSContext *cx, HandleObject obj, double index, bool *hole, MutableHandleValue vp)
+DoGetElement(JSContext *cx, HandleObject obj, IndexType index, bool *hole, MutableHandleValue vp)
 {
     RootedId id(cx);
 
-    if (!DoubleIndexToId(cx, index, &id))
+    if (!ToId(cx, index, &id))
         return false;
 
     RootedObject obj2(cx);
     RootedShape prop(cx);
     if (!JSObject::lookupGeneric(cx, obj, id, &obj2, &prop))
         return false;
 
     if (!prop) {
@@ -168,30 +175,16 @@ DoGetElement(JSContext *cx, HandleObject
     } else {
         if (!JSObject::getGeneric(cx, obj, obj, id, vp))
             return false;
         *hole = false;
     }
     return true;
 }
 
-static inline bool
-DoGetElement(JSContext *cx, HandleObject obj, uint32_t index, bool *hole, MutableHandleValue vp)
-{
-    bool present;
-    if (!JSObject::getElementIfPresent(cx, obj, obj, index, vp, &present))
-        return false;
-
-    *hole = !present;
-    if (*hole)
-        vp.setUndefined();
-
-    return true;
-}
-
 template<typename IndexType>
 static void
 AssertGreaterThanZero(IndexType index)
 {
     JS_ASSERT(index >= 0);
     JS_ASSERT(index == floor(index));
 }
 
@@ -291,17 +284,17 @@ SetArrayElement(JSContext *cx, HandleObj
         } while (false);
 
         if (result == JSObject::ED_FAILED)
             return false;
         JS_ASSERT(result == JSObject::ED_SPARSE);
     }
 
     RootedId id(cx);
-    if (!DoubleIndexToId(cx, index, &id))
+    if (!ToId(cx, index, &id))
         return false;
 
     RootedValue tmp(cx, v);
     return JSObject::setGeneric(cx, obj, obj, id, &tmp, true);
 }
 
 /*
  * Attempt to delete the element |index| from |obj| as if by
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -1025,22 +1025,16 @@ class JSObject : public js::ObjectImpl
         return getGenericNoGC(cx, obj, receiver, js::NameToId(name), vp);
     }
 
     static inline bool getElement(JSContext *cx, js::HandleObject obj, js::HandleObject receiver,
                                   uint32_t index, js::MutableHandleValue vp);
     static inline bool getElementNoGC(JSContext *cx, JSObject *obj, JSObject *receiver,
                                       uint32_t index, js::Value *vp);
 
-    /* If element is not present (e.g. array hole) *present is set to
-       false and the contents of *vp are unusable garbage. */
-    static inline bool getElementIfPresent(JSContext *cx, js::HandleObject obj,
-                                           js::HandleObject receiver, uint32_t index,
-                                           js::MutableHandleValue vp, bool *present);
-
     static bool getSpecial(JSContext *cx, js::HandleObject obj,
                            js::HandleObject receiver, js::SpecialId sid,
                            js::MutableHandleValue vp)
     {
         JS::RootedId id(cx, SPECIALID_TO_JSID(sid));
         return getGeneric(cx, obj, receiver, id, vp);
     }
 
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -578,48 +578,16 @@ JSObject::getElementNoGC(JSContext *cx, 
         return false;
 
     jsid id;
     if (!js::IndexToId(cx, index, &id))
         return false;
     return getGenericNoGC(cx, obj, receiver, id, vp);
 }
 
-/* static */ inline bool
-JSObject::getElementIfPresent(JSContext *cx, js::HandleObject obj, js::HandleObject receiver,
-                              uint32_t index, js::MutableHandleValue vp,
-                              bool *present)
-{
-    js::ElementIfPresentOp op = obj->getOps()->getElementIfPresent;
-    if (op)
-        return op(cx, obj, receiver, index, vp, present);
-
-    /*
-     * For now, do the index-to-id conversion just once, then use
-     * lookupGeneric/getGeneric.  Once lookupElement and getElement stop both
-     * doing index-to-id conversions, we can use those here.
-     */
-    JS::RootedId id(cx);
-    if (!js::IndexToId(cx, index, id.address()))
-        return false;
-
-    JS::RootedObject obj2(cx);
-    js::RootedShape prop(cx);
-    if (!lookupGeneric(cx, obj, id, &obj2, &prop))
-        return false;
-
-    if (!prop) {
-        *present = false;
-        return true;
-    }
-
-    *present = true;
-    return getGeneric(cx, obj, receiver, id, vp);
-}
-
 inline js::GlobalObject &
 JSObject::global() const
 {
 #ifdef DEBUG
     JSObject *obj = const_cast<JSObject *>(this);
     while (JSObject *parent = obj->getParent())
         obj = parent;
 #endif
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -147,37 +147,16 @@ BaseProxyHandler::get(JSContext *cx, Han
     if (desc.hasShortId()) {
         RootedId id(cx, INT_TO_JSID(desc.shortid()));
         return CallJSPropertyOp(cx, desc.getter(), receiver, id, vp);
     }
     return CallJSPropertyOp(cx, desc.getter(), receiver, id, vp);
 }
 
 bool
-BaseProxyHandler::getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject receiver,
-                                      uint32_t index, MutableHandleValue vp, bool *present)
-{
-    RootedId id(cx);
-    if (!IndexToId(cx, index, id.address()))
-        return false;
-
-    assertEnteredPolicy(cx, proxy, id);
-
-    if (!has(cx, proxy, id, present))
-        return false;
-
-    if (!*present) {
-        Debug_SetValueRangeToCrashOnTouch(vp.address(), 1);
-        return true;
-    }
-
-    return get(cx, proxy, receiver, id, vp);
-}
-
-bool
 BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
                       HandleId id, bool strict, MutableHandleValue vp)
 {
     assertEnteredPolicy(cx, proxy, id);
 
     Rooted<PropertyDescriptor> desc(cx);
     if (!getOwnPropertyDescriptor(cx, proxy, id, &desc, JSRESOLVE_ASSIGNING))
         return false;
@@ -2514,51 +2493,16 @@ Proxy::callProp(JSContext *cx, HandleObj
         if (!OnUnknownMethod(cx, proxy, IdToValue(id), vp))
             return false;
     }
 #endif
 
     return true;
 }
 
-
-bool
-Proxy::getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject receiver, uint32_t index,
-                           MutableHandleValue vp, bool *present)
-{
-    JS_CHECK_RECURSION(cx, return false);
-
-    RootedId id(cx);
-    if (!IndexToId(cx, index, id.address()))
-        return false;
-
-    BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
-    AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
-    if (!policy.allowed())
-        return policy.returnValue();
-
-    if (!handler->hasPrototype()) {
-        return handler->getElementIfPresent(cx, proxy, receiver, index,
-                                            vp, present);
-    }
-
-    bool hasOwn;
-    if (!handler->hasOwn(cx, proxy, id, &hasOwn))
-        return false;
-
-    if (hasOwn) {
-        *present = true;
-        return proxy->as<ProxyObject>().handler()->get(cx, proxy, receiver, id, vp);
-    }
-
-    *present = false;
-    INVOKE_ON_PROTOTYPE(cx, handler, proxy,
-                        JSObject::getElementIfPresent(cx, proto, receiver, index, vp, present));
-}
-
 bool
 Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, bool strict,
            MutableHandleValue vp)
 {
     JS_CHECK_RECURSION(cx, return false);
     BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
     AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
     if (!policy.allowed())
@@ -2887,23 +2831,16 @@ proxy_GetElement(JSContext *cx, HandleOb
 {
     RootedId id(cx);
     if (!IndexToId(cx, index, id.address()))
         return false;
     return proxy_GetGeneric(cx, obj, receiver, id, vp);
 }
 
 static bool
-proxy_GetElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index,
-                          MutableHandleValue vp, bool *present)
-{
-    return Proxy::getElementIfPresent(cx, obj, receiver, index, vp, present);
-}
-
-static bool
 proxy_GetSpecial(JSContext *cx, HandleObject obj, HandleObject receiver, HandleSpecialId sid,
                  MutableHandleValue vp)
 {
     Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
     return proxy_GetGeneric(cx, obj, receiver, id, vp);
 }
 
 static bool
@@ -3123,17 +3060,16 @@ proxy_Unwatch(JSContext *cx, JS::HandleO
         proxy_LookupSpecial,                        \
         proxy_DefineGeneric,                        \
         proxy_DefineProperty,                       \
         proxy_DefineElement,                        \
         proxy_DefineSpecial,                        \
         proxy_GetGeneric,                           \
         proxy_GetProperty,                          \
         proxy_GetElement,                           \
-        proxy_GetElementIfPresent,                  \
         proxy_GetSpecial,                           \
         proxy_SetGeneric,                           \
         proxy_SetProperty,                          \
         proxy_SetElement,                           \
         proxy_SetSpecial,                           \
         proxy_GetGenericAttributes,                 \
         proxy_SetGenericAttributes,                 \
         proxy_DeleteProperty,                       \
@@ -3181,17 +3117,16 @@ const Class js::OuterWindowProxyObject::
         proxy_LookupSpecial,
         proxy_DefineGeneric,
         proxy_DefineProperty,
         proxy_DefineElement,
         proxy_DefineSpecial,
         proxy_GetGeneric,
         proxy_GetProperty,
         proxy_GetElement,
-        proxy_GetElementIfPresent,
         proxy_GetSpecial,
         proxy_SetGeneric,
         proxy_SetProperty,
         proxy_SetElement,
         proxy_SetSpecial,
         proxy_GetGenericAttributes,
         proxy_SetGenericAttributes,
         proxy_DeleteProperty,
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -157,18 +157,16 @@ class JS_FRIEND_API(BaseProxyHandler)
     virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
     virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx);
     virtual const char *className(JSContext *cx, HandleObject proxy);
     virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent);
     virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g);
     virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp);
     virtual void finalize(JSFreeOp *fop, JSObject *proxy);
-    virtual bool getElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver,
-                                     uint32_t index, MutableHandleValue vp, bool *present);
     virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop);
 
     // These two hooks must be overridden, or not overridden, in tandem -- no
     // overriding just one!
     virtual bool watch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
                        JS::HandleObject callable);
     virtual bool unwatch(JSContext *cx, JS::HandleObject proxy, JS::HandleId id);
 
@@ -257,18 +255,16 @@ class Proxy
     static bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp);
     static bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props);
 
     /* ES5 Harmony derived proxy traps. */
     static bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp);
     static bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp);
     static bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
                     MutableHandleValue vp);
-    static bool getElementIfPresent(JSContext *cx, HandleObject proxy, HandleObject receiver,
-                                    uint32_t index, MutableHandleValue vp, bool *present);
     static bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
                     bool strict, MutableHandleValue vp);
     static bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props);
     static bool iterate(JSContext *cx, HandleObject proxy, unsigned flags, MutableHandleValue vp);
 
     /* Spidermonkey extensions. */
     static bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible);
     static bool call(JSContext *cx, HandleObject proxy, const CallArgs &args);
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -816,24 +816,16 @@ DeadObjectProxy::regexp_toShared(JSConte
 bool
 DeadObjectProxy::defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
     return false;
 }
 
 bool
-DeadObjectProxy::getElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver,
-                                     uint32_t index, MutableHandleValue vp, bool *present)
-{
-    JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
-    return false;
-}
-
-bool
 DeadObjectProxy::getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop)
 {
     protop.set(nullptr);
     return true;
 }
 
 DeadObjectProxy DeadObjectProxy::singleton;
 const char DeadObjectProxy::sDeadObjectFamily = 0;
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -199,19 +199,16 @@ class JS_FRIEND_API(DeadObjectProxy) : p
                              bool *bp) MOZ_OVERRIDE;
     virtual bool objectClassIs(HandleObject obj, ESClassValue classValue,
                                JSContext *cx) MOZ_OVERRIDE;
     virtual const char *className(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
     virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) MOZ_OVERRIDE;
     virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) MOZ_OVERRIDE;
     virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint,
                               MutableHandleValue vp) MOZ_OVERRIDE;
-    virtual bool getElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver,
-                                     uint32_t index, MutableHandleValue vp,
-                                     bool *present) MOZ_OVERRIDE;
     virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
                                 MutableHandleObject protop) MOZ_OVERRIDE;
 
     static DeadObjectProxy singleton;
 };
 
 extern JSObject *
 TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj,
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -552,17 +552,16 @@ const Class WithObject::class_ = {
         with_LookupSpecial,
         nullptr,             /* defineGeneric */
         nullptr,             /* defineProperty */
         nullptr,             /* defineElement */
         nullptr,             /* defineSpecial */
         with_GetGeneric,
         with_GetProperty,
         with_GetElement,
-        nullptr,             /* getElementIfPresent */
         with_GetSpecial,
         with_SetGeneric,
         with_SetProperty,
         with_SetElement,
         with_SetSpecial,
         with_GetGenericAttributes,
         with_SetGenericAttributes,
         with_DeleteProperty,
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -1033,26 +1033,16 @@ ArrayBufferObject::obj_getElement(JSCont
 {
     RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
     if (!delegate)
         return false;
     return baseops::GetElement(cx, delegate, receiver, index, vp);
 }
 
 bool
-ArrayBufferObject::obj_getElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver,
-                                           uint32_t index, MutableHandleValue vp, bool *present)
-{
-    RootedObject delegate(cx, ArrayBufferDelegate(cx, obj));
-    if (!delegate)
-        return false;
-    return JSObject::getElementIfPresent(cx, delegate, receiver, index, vp, present);
-}
-
-bool
 ArrayBufferObject::obj_getSpecial(JSContext *cx, HandleObject obj,
                                   HandleObject receiver, HandleSpecialId sid,
                                   MutableHandleValue vp)
 {
     Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
     return obj_getGeneric(cx, obj, receiver, id, vp);
 }
 
@@ -1490,37 +1480,16 @@ class TypedArrayObjectTemplate : public 
         if (atom->isIndex(&index))
             return obj_getElement(cx, obj, receiver, index, vp);
 
         Rooted<PropertyName*> name(cx, atom->asPropertyName());
         return obj_getProperty(cx, obj, receiver, name, vp);
     }
 
     static bool
-    obj_getElementIfPresent(JSContext *cx, HandleObject tarray, HandleObject receiver, uint32_t index,
-                            MutableHandleValue vp, bool *present)
-    {
-        // Fast-path the common case of index < length
-        if (index < tarray->as<TypedArrayObject>().length()) {
-            // this inline function is specialized for each type
-            copyIndexToValue(tarray, index, vp);
-            *present = true;
-            return true;
-        }
-
-        RootedObject proto(cx, tarray->getProto());
-        if (!proto) {
-            vp.setUndefined();
-            return true;
-        }
-
-        return JSObject::getElementIfPresent(cx, proto, receiver, index, vp, present);
-    }
-
-    static bool
     setElementTail(JSContext *cx, HandleObject tarray, uint32_t index,
                    MutableHandleValue vp, bool strict)
     {
         JS_ASSERT(tarray);
         JS_ASSERT(index < tarray->as<TypedArrayObject>().length());
 
         if (vp.isInt32()) {
             setIndex(tarray, index, NativeType(vp.toInt32()));
@@ -3475,17 +3444,16 @@ const Class ArrayBufferObject::class_ = 
         ArrayBufferObject::obj_lookupSpecial,
         ArrayBufferObject::obj_defineGeneric,
         ArrayBufferObject::obj_defineProperty,
         ArrayBufferObject::obj_defineElement,
         ArrayBufferObject::obj_defineSpecial,
         ArrayBufferObject::obj_getGeneric,
         ArrayBufferObject::obj_getProperty,
         ArrayBufferObject::obj_getElement,
-        ArrayBufferObject::obj_getElementIfPresent,
         ArrayBufferObject::obj_getSpecial,
         ArrayBufferObject::obj_setGeneric,
         ArrayBufferObject::obj_setProperty,
         ArrayBufferObject::obj_setElement,
         ArrayBufferObject::obj_setSpecial,
         ArrayBufferObject::obj_getGenericAttributes,
         ArrayBufferObject::obj_setGenericAttributes,
         ArrayBufferObject::obj_deleteProperty,
@@ -3638,17 +3606,16 @@ IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Flo
         _typedArray##Object::obj_lookupSpecial,                                \
         _typedArray##Object::obj_defineGeneric,                                \
         _typedArray##Object::obj_defineProperty,                               \
         _typedArray##Object::obj_defineElement,                                \
         _typedArray##Object::obj_defineSpecial,                                \
         _typedArray##Object::obj_getGeneric,                                   \
         _typedArray##Object::obj_getProperty,                                  \
         _typedArray##Object::obj_getElement,                                   \
-        _typedArray##Object::obj_getElementIfPresent,                          \
         _typedArray##Object::obj_getSpecial,                                   \
         _typedArray##Object::obj_setGeneric,                                   \
         _typedArray##Object::obj_setProperty,                                  \
         _typedArray##Object::obj_setElement,                                   \
         _typedArray##Object::obj_setSpecial,                                   \
         _typedArray##Object::obj_getGenericAttributes,                         \
         _typedArray##Object::obj_setGenericAttributes,                         \
         _typedArray##Object::obj_deleteProperty,                               \
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -102,18 +102,16 @@ class ArrayBufferObject : public JSObjec
     static bool obj_getGeneric(JSContext *cx, HandleObject obj, HandleObject receiver,
                                HandleId id, MutableHandleValue vp);
 
     static bool obj_getProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
                                 HandlePropertyName name, MutableHandleValue vp);
 
     static bool obj_getElement(JSContext *cx, HandleObject obj, HandleObject receiver,
                                uint32_t index, MutableHandleValue vp);
-    static bool obj_getElementIfPresent(JSContext *cx, HandleObject obj, HandleObject receiver,
-                                        uint32_t index, MutableHandleValue vp, bool *present);
 
     static bool obj_getSpecial(JSContext *cx, HandleObject obj, HandleObject receiver,
                                HandleSpecialId sid, MutableHandleValue vp);
 
     static bool obj_setGeneric(JSContext *cx, HandleObject obj, HandleId id,
                                MutableHandleValue vp, bool strict);
     static bool obj_setProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
                                 MutableHandleValue vp, bool strict);
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -715,17 +715,16 @@ const XPCWrappedNativeJSClass XPC_WN_NoH
         nullptr, // lookupSpecial
         nullptr, // defineGeneric
         nullptr, // defineProperty
         nullptr, // defineElement
         nullptr, // defineSpecial
         nullptr, // getGeneric
         nullptr, // getProperty
         nullptr, // getElement
-        nullptr, // getElementIfPresent
         nullptr, // getSpecial
         nullptr, // setGeneric
         nullptr, // setProperty
         nullptr, // setElement
         nullptr, // setSpecial
         nullptr, // getGenericAttributes
         nullptr, // setGenericAttributes
         nullptr, // deleteProperty
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -977,17 +977,16 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS
         nullptr, /* lookupSpecial */                                          \
         nullptr, /* defineGeneric */                                          \
         nullptr, /* defineProperty */                                         \
         nullptr, /* defineElement */                                          \
         nullptr, /* defineSpecial */                                          \
         nullptr, /* getGeneric    */                                          \
         nullptr, /* getProperty    */                                         \
         nullptr, /* getElement    */                                          \
-        nullptr, /* getElementIfPresent */                                    \
         nullptr, /* getSpecial    */                                          \
         nullptr, /* setGeneric    */                                          \
         nullptr, /* setProperty    */                                         \
         nullptr, /* setElement    */                                          \
         nullptr, /* setSpecial    */                                          \
         nullptr, /* getGenericAttributes  */                                  \
         nullptr, /* setGenericAttributes  */                                  \
         nullptr, /* deleteProperty */                                         \
@@ -1006,17 +1005,16 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS
         nullptr, /* lookupSpecial */                                          \
         nullptr, /* defineGeneric */                                          \
         nullptr, /* defineProperty */                                         \
         nullptr, /* defineElement */                                          \
         nullptr, /* defineSpecial */                                          \
         nullptr, /* getGeneric    */                                          \
         nullptr, /* getProperty    */                                         \
         nullptr, /* getElement    */                                          \
-        nullptr, /* getElementIfPresent */                                    \
         nullptr, /* getSpecial    */                                          \
         nullptr, /* setGeneric    */                                          \
         nullptr, /* setProperty    */                                         \
         nullptr, /* setElement    */                                          \
         nullptr, /* setSpecial    */                                          \
         nullptr, /* getGenericAttributes  */                                  \
         nullptr, /* setGenericAttributes  */                                  \
         nullptr, /* deleteProperty */                                         \