Bug 608959 - Don't call non-scripted getters with a proxy as its |this|, because that would require most non-scripted getters to unwrap and maybe do some prototype-chain walking. r=mrbkap
authorJeff Walden <jwalden@mit.edu>
Thu, 04 Nov 2010 15:53:50 -0700
changeset 57739 c400bbbd97f3494b43d209ed5753cb46d0d8b9f0
parent 57738 4b4dce1f1756d223d4028a5897cf5335d9851e85
child 57740 edc26e88b2c483649a4605e28e5be2cddf2ec155
push idunknown
push userunknown
push dateunknown
reviewersmrbkap
bugs608959
milestone2.0b8pre
Bug 608959 - Don't call non-scripted getters with a proxy as its |this|, because that would require most non-scripted getters to unwrap and maybe do some prototype-chain walking. r=mrbkap
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsscope.h
js/src/jsscopeinlines.h
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -4831,18 +4831,18 @@ js_FindIdentifierBase(JSContext *cx, JSO
         if (!parent)
             break;
         obj = parent;
     } while (obj->getParent());
     return obj;
 }
 
 static JS_ALWAYS_INLINE JSBool
-js_NativeGetInline(JSContext *cx, JSObject *obj, JSObject *pobj, const Shape *shape, uintN getHow,
-                   Value *vp)
+js_NativeGetInline(JSContext *cx, JSObject *receiver, JSObject *obj, JSObject *pobj,
+                   const Shape *shape, uintN getHow, Value *vp)
 {
     LeaveTraceIfGlobalObject(cx, pobj);
 
     uint32 slot;
     int32 sample;
 
     JS_ASSERT(pobj->isNative());
 
@@ -4860,17 +4860,17 @@ js_NativeGetInline(JSContext *cx, JSObje
         JS_ASSERT(&shape->methodObject() == &vp->toObject());
         return true;
     }
 
     sample = cx->runtime->propertyRemovals;
     {
         AutoShapeRooter tvr(cx, shape);
         AutoObjectRooter tvr2(cx, pobj);
-        if (!shape->get(cx, obj, pobj, vp))
+        if (!shape->get(cx, receiver, obj, pobj, vp))
             return false;
     }
 
     if (pobj->containsSlot(slot) &&
         (JS_LIKELY(cx->runtime->propertyRemovals == sample) ||
          pobj->nativeContains(*shape))) {
         if (!pobj->methodWriteBarrier(cx, *shape, *vp))
             return false;
@@ -4879,17 +4879,17 @@ js_NativeGetInline(JSContext *cx, JSObje
 
     return true;
 }
 
 JSBool
 js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, const Shape *shape, uintN getHow,
              Value *vp)
 {
-    return js_NativeGetInline(cx, obj, pobj, shape, getHow, vp);
+    return js_NativeGetInline(cx, obj, obj, pobj, shape, getHow, vp);
 }
 
 JSBool
 js_NativeSet(JSContext *cx, JSObject *obj, const Shape *shape, bool added, Value *vp)
 {
     LeaveTraceIfGlobalObject(cx, obj);
 
     uint32 slot;
@@ -5034,17 +5034,17 @@ js_GetPropertyHelperWithShapeInline(JSCo
     *shapeOut = shape;
 
     if (getHow & JSGET_CACHE_RESULT) {
         JS_ASSERT_NOT_ON_TRACE(cx);
         JS_PROPERTY_CACHE(cx).fill(cx, aobj, 0, protoIndex, obj2, shape);
     }
 
     /* This call site is hot -- use the always-inlined variant of js_NativeGet(). */
-    if (!js_NativeGetInline(cx, receiver, obj2, shape, getHow, vp))
+    if (!js_NativeGetInline(cx, receiver, obj, obj2, shape, getHow, vp))
         return JS_FALSE;
 
     return JS_TRUE;
 }
 
 bool
 js_GetPropertyHelperWithShape(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id,
                               uint32 getHow, Value *vp,
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -171,21 +171,21 @@ struct PropDesc {
 
 namespace js {
 
 typedef Vector<PropDesc, 1> PropDescArray;
 
 } /* namespace js */
 
 struct JSObjectMap {
-    static JS_FRIEND_DATA(const JSObjectMap) sharedNonNative;
-
     uint32 shape;       /* shape identifier */
     uint32 slotSpan;    /* one more than maximum live slot number */
 
+    static JS_FRIEND_DATA(const JSObjectMap) sharedNonNative;
+
     explicit JSObjectMap(uint32 shape) : shape(shape), slotSpan(0) {}
     JSObjectMap(uint32 shape, uint32 slotSpan) : shape(shape), slotSpan(slotSpan) {}
 
     enum { INVALID_SHAPE = 0x8fffffff, SHAPELESS = 0xffffffff };
 
     bool isNative() const { return this != &sharedNonNative; }
 
   private:
--- a/js/src/jsscope.h
+++ b/js/src/jsscope.h
@@ -546,17 +546,17 @@ struct Shape : public JSObjectMap
     }
 
     inline JSDHashNumber hash() const;
     inline bool matches(const js::Shape *p) const;
     inline bool matchesParamsAfterId(js::PropertyOp agetter, js::PropertyOp asetter,
                                      uint32 aslot, uintN aattrs, uintN aflags,
                                      intN ashortid) const;
 
-    bool get(JSContext* cx, JSObject *obj, JSObject *pobj, js::Value* vp) const;
+    bool get(JSContext* cx, JSObject *receiver, JSObject *obj, JSObject *pobj, js::Value* vp) const;
     bool set(JSContext* cx, JSObject *obj, js::Value* vp) const;
 
     inline bool isSharedPermanent() const;
 
     void trace(JSTracer *trc) const;
 
     bool hasSlot() const { return (attrs & JSPROP_SHARED) == 0; }
 
--- a/js/src/jsscopeinlines.h
+++ b/js/src/jsscopeinlines.h
@@ -226,25 +226,25 @@ Shape::matchesParamsAfterId(js::Property
            rawSetter == asetter &&
            slot == aslot &&
            attrs == aattrs &&
            ((flags ^ aflags) & PUBLIC_FLAGS) == 0 &&
            shortid == ashortid;
 }
 
 inline bool
-Shape::get(JSContext* cx, JSObject* obj, JSObject *pobj, js::Value* vp) const
+Shape::get(JSContext* cx, JSObject *receiver, JSObject* obj, JSObject *pobj, js::Value* vp) const
 {
     JS_ASSERT(!JSID_IS_VOID(this->id));
     JS_ASSERT(!hasDefaultGetter());
 
     if (hasGetterValue()) {
         JS_ASSERT(!isMethod());
         js::Value fval = getterValue();
-        return js::ExternalGetOrSet(cx, obj, id, fval, JSACC_READ, 0, 0, vp);
+        return js::ExternalGetOrSet(cx, receiver, id, fval, JSACC_READ, 0, 0, vp);
     }
 
     if (isMethod()) {
         vp->setObject(methodObject());
         return pobj->methodReadBarrier(cx, *this, vp);
     }
 
     /*