Bug 698495 part 5. Implement getElementIfPresent on nodelist proxies. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 04 Nov 2011 12:25:18 -0400
changeset 79771 37f7444b17da26d1ef1231f884546bef77ad6c07
parent 79770 72b103262305d753cfd57bd3572e4d1d30864bed
child 79772 cd0012b4b44acf5222495cef27f9e91d8060ef45
push id3131
push userbzbarsky@mozilla.com
push dateFri, 04 Nov 2011 16:27:11 +0000
treeherdermozilla-inbound@bdd8a7d0d45a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs698495
milestone10.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 698495 part 5. Implement getElementIfPresent on nodelist proxies. r=peterv
js/xpconnect/src/dombindings.cpp
js/xpconnect/src/dombindings.h
--- a/js/xpconnect/src/dombindings.cpp
+++ b/js/xpconnect/src/dombindings.cpp
@@ -1039,16 +1039,62 @@ ListBase<LC>::get(JSContext *cx, JSObjec
     }
 
     vp->setUndefined();
     return true;
 }
 
 template<class LC>
 bool
+ListBase<LC>::getElementIfPresent(JSContext *cx, JSObject *proxy, JSObject *receiver,
+                                  uint32 index, Value *vp, bool *present)
+{
+    if (hasIndexGetter) {
+        IndexGetterType result;
+        *present = getItemAt(getListObject(proxy), index, result);
+        if (*present)
+            return Wrap(cx, proxy, result, vp);
+
+        vp->setUndefined();
+        return true;
+    }
+
+    jsid id;
+    if (!JS_IndexToId(cx, index, &id))
+        return false;
+
+    JSObject *expando = getExpandoObject(proxy);
+    if (expando) {
+        JSBool isPresent;
+        if (!JS_GetElementIfPresent(cx, expando, index, expando, vp, &isPresent))
+            return false;
+        if (isPresent) {
+            *present = true;
+            return true;
+        }
+    }
+
+    // No need to worry about name getters here, so just check the proto.
+
+    JSObject *proto = js::GetObjectProto(proxy);
+    if (proto) {
+        JSBool 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;
+}
+
+template<class LC>
+bool
 ListBase<LC>::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, bool strict,
                   Value *vp)
 {
     return ProxyHandler::set(cx, proxy, proxy, id, strict, vp);
 }
 
 template<class LC>
 bool
--- a/js/xpconnect/src/dombindings.h
+++ b/js/xpconnect/src/dombindings.h
@@ -220,16 +220,18 @@ public:
     bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, js::AutoIdVector &props);
     bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
     bool enumerate(JSContext *cx, JSObject *proxy, js::AutoIdVector &props);
     bool fix(JSContext *cx, JSObject *proxy, js::Value *vp);
 
     bool has(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
     bool hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
     bool get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, js::Value *vp);
+    bool getElementIfPresent(JSContext *cx, JSObject *proxy, JSObject *receiver,
+                             uint32 index, js::Value *vp, bool *present);
     bool set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, bool strict,
              js::Value *vp);
     bool keys(JSContext *cx, JSObject *proxy, js::AutoIdVector &props);
     bool iterate(JSContext *cx, JSObject *proxy, uintN flags, js::Value *vp);
 
     /* Spidermonkey extensions. */
     bool hasInstance(JSContext *cx, JSObject *proxy, const js::Value *vp, bool *bp);
     JSString *obj_toString(JSContext *cx, JSObject *proxy);