From dbae036f372397255b7bbf12f1de56f5bb3ccc8a Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 29 Mar 2012 13:34:36 -0700 Subject: [PATCH] Bug 740469 - JSNative->JSFunction fixup should happen in DefinePropertyById, not DefineProperty. r=luke --- js/src/jsapi.cpp | 49 ++++++++++++++++++++++++------------------- js/src/jsobj.cpp | 1 + js/src/jsobjinlines.h | 1 + 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index a29354d4f6b..28d7c91e88c 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3635,6 +3635,34 @@ DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, const Value &value, if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) attrs &= ~JSPROP_READONLY; + /* + * When we use DefineProperty, we need full scriptable Function objects rather + * than JSNatives. However, we might be pulling this property descriptor off + * of something with JSNative property descriptors. If we are, wrap them in + * JS Function objects. + */ + if (attrs & JSPROP_NATIVE_ACCESSORS) { + RootId idRoot(cx, &id); + + JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER))); + attrs &= ~JSPROP_NATIVE_ACCESSORS; + if (getter) { + JSObject *getobj = JS_NewFunction(cx, (Native) getter, 0, 0, &obj->global(), NULL); + if (!getobj) + return false; + getter = JS_DATA_TO_FUNC_PTR(PropertyOp, getobj); + attrs |= JSPROP_GETTER; + } + if (setter) { + JSObject *setobj = JS_NewFunction(cx, (Native) setter, 1, 0, &obj->global(), NULL); + if (!setobj) + return false; + setter = JS_DATA_TO_FUNC_PTR(StrictPropertyOp, setobj); + attrs |= JSPROP_SETTER; + } + } + + AssertNoGC(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, obj, id, value, @@ -3694,27 +3722,6 @@ DefineProperty(JSContext *cx, JSObject *obj, const char *name, const Value &valu id = ATOM_TO_JSID(atom); } - if (attrs & JSPROP_NATIVE_ACCESSORS) { - RootId idRoot(cx, &id); - - JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER))); - attrs &= ~JSPROP_NATIVE_ACCESSORS; - if (getter) { - JSObject *getobj = JS_NewFunction(cx, (Native) getter, 0, 0, &obj->global(), NULL); - if (!getobj) - return false; - getter = JS_DATA_TO_FUNC_PTR(PropertyOp, getobj); - attrs |= JSPROP_GETTER; - } - if (setter) { - JSObject *setobj = JS_NewFunction(cx, (Native) setter, 1, 0, &obj->global(), NULL); - if (!setobj) - return false; - setter = JS_DATA_TO_FUNC_PTR(StrictPropertyOp, setobj); - attrs |= JSPROP_SETTER; - } - } - return DefinePropertyById(cx, obj, id, value, getter, setter, attrs, flags, tinyid); } diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index fa14eb89e09..c3d8f243bd8 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -4453,6 +4453,7 @@ DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, const Value &value_, { JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_DONT_PURGE | DNP_SKIP_TYPE)) == 0); + JS_ASSERT(!(attrs & JSPROP_NATIVE_ACCESSORS)); RootObject objRoot(cx, &obj); RootId idRoot(cx, &id); diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 19df3268a56..e38f6e8d2fe 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -1029,6 +1029,7 @@ JSObject::defineGeneric(JSContext *cx, jsid id, const js::Value &value, JSStrictPropertyOp setter /* = JS_StrictPropertyStub */, unsigned attrs /* = JSPROP_ENUMERATE */) { + JS_ASSERT(!(attrs & JSPROP_NATIVE_ACCESSORS)); js::DefineGenericOp op = getOps()->defineGeneric; return (op ? op : js_DefineProperty)(cx, this, id, &value, getter, setter, attrs); }