bug 488995 - fixing error reporting for getter-only properties. r=mrbkap sr=jst
authorIgor Bukanov <igor@mir2.org>
Wed, 22 Apr 2009 12:39:08 +0200
changeset 27641 faf08a026ab860300c7e603934925a8ac612ee2f
parent 27640 6684da21fb121e41c40929b67635129489770f96
child 27642 c6dc27a8ce7e4427851caaf7d0f07b7330b97eaf
child 27881 0a1bf400bea11e5e4e83dcc128299c1687189aab
push id6664
push userrsayre@mozilla.com
push dateWed, 22 Apr 2009 17:56:08 +0000
treeherdermozilla-central@ddd5fcb96d72 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap, jst
bugs488995
milestone1.9.2a1pre
bug 488995 - fixing error reporting for getter-only properties. r=mrbkap sr=jst
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsscope.h
js/src/xpconnect/src/XPCIDispatchExtension.cpp
js/src/xpconnect/src/xpcwrappednativejsops.cpp
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -5982,16 +5982,31 @@ js_IsCallable(JSObject *obj, JSContext *
     JS_LOCK_OBJ(cx, obj);
     JSBool callable = (obj->map->ops == &js_ObjectOps)
                       ? HAS_FUNCTION_CLASS(obj) || STOBJ_GET_CLASS(obj)->call
                       : obj->map->ops->call != NULL;
     JS_UNLOCK_OBJ(cx, obj);
     return callable;
 }
 
+void
+js_ReportGetterOnlyAssignment(JSContext *cx)
+{
+    JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
+                         JSMSG_GETTER_ONLY, NULL);
+}
+
+
+JS_FRIEND_API(JSBool)
+js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+    js_ReportGetterOnlyAssignment(cx);
+    return JS_FALSE;
+}
+
 #ifdef DEBUG
 
 /*
  * Routines to print out values during debugging.  These are FRIEND_API to help
  * the debugger find them and to support temporarily hacking js_Dump* calls
  * into other code.
  */
 
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -849,16 +849,22 @@ js_GetWrappedObject(JSContext *cx, JSObj
 extern const char *
 js_ComputeFilename(JSContext *cx, JSStackFrame *caller,
                    JSPrincipals *principals, uintN *linenop);
 
 /* Infallible, therefore cx is last parameter instead of first. */
 extern JSBool
 js_IsCallable(JSObject *obj, JSContext *cx);
 
+void
+js_ReportGetterOnlyAssignment(JSContext *cx);
+
+extern JS_FRIEND_API(JSBool)
+js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
+
 #ifdef DEBUG
 JS_FRIEND_API(void) js_DumpChars(const jschar *s, size_t n);
 JS_FRIEND_API(void) js_DumpString(JSString *str);
 JS_FRIEND_API(void) js_DumpAtom(JSAtom *atom);
 JS_FRIEND_API(void) js_DumpValue(jsval val);
 JS_FRIEND_API(void) js_DumpId(jsid id);
 JS_FRIEND_API(void) js_DumpObject(JSObject *obj);
 #endif
--- a/js/src/jsscope.h
+++ b/js/src/jsscope.h
@@ -370,18 +370,17 @@ js_SetSprop(JSContext* cx, JSScopeProper
 
     if (sprop->attrs & JSPROP_SETTER) {
         jsval fval = js_CastAsObjectJSVal(sprop->setter);
         return js_InternalGetOrSet(cx, obj, (sprop)->id, fval, JSACC_WRITE,
                                    1, vp, vp);
     }
 
     if (sprop->attrs & JSPROP_GETTER) {
-        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
-                             JSMSG_GETTER_ONLY, NULL);
+        js_ReportGetterOnlyAssignment(cx);
         return JS_FALSE;
     }
 
     return sprop->setter(cx, obj, SPROP_USERID(sprop), vp);
 }
 
 /* Macro for common expression to test for shared permanent attributes. */
 #define SPROP_IS_SHARED_PERMANENT(sprop)                                      \
--- a/js/src/xpconnect/src/XPCIDispatchExtension.cpp
+++ b/js/src/xpconnect/src/XPCIDispatchExtension.cpp
@@ -290,28 +290,33 @@ JSBool XPCIDispatchExtension::DefineProp
             *resolved = JS_TRUE;
         return JS_ValueToId(ccx, idval, &id) &&
                JS_DefinePropertyById(ccx, obj, id, OBJECT_TO_JSVAL(funobj),
                                      nsnull, nsnull, propFlags);
     }
     // Define the property on the object
     NS_ASSERTION(member->IsProperty(), "way broken!");
     propFlags |= JSPROP_GETTER | JSPROP_SHARED;
+    JSPropertyOp getter = JS_DATA_TO_FUNC_PTR(JSPropertyOp, funobj);
+    JSPropertyOp setter;
     if(member->IsSetter())
     {
         propFlags |= JSPROP_SETTER;
         propFlags &= ~JSPROP_READONLY;
+        setter = getter;
+    }
+    else
+    {
+        setter = js_GetterOnlyPropertyStub;
     }
     AutoResolveName arn(ccx, idval);
     if(resolved)
         *resolved = JS_TRUE;
     return JS_ValueToId(ccx, idval, &id) &&
-           JS_DefinePropertyById(ccx, obj, id, JSVAL_VOID,
-                                 JS_DATA_TO_FUNC_PTR(JSPropertyOp, funobj),
-                                 JS_DATA_TO_FUNC_PTR(JSPropertyOp, funobj),
+           JS_DefinePropertyById(ccx, obj, id, JSVAL_VOID, getter, setter,
                                  propFlags);
 
 }
 
 JSBool XPCIDispatchExtension::Enumerate(XPCCallContext& ccx, JSObject* obj,
                                         XPCWrappedNative * wrapper)
 {
     XPCNativeInterface* iface = XPCNativeInterface::GetNewOrUsed(
--- a/js/src/xpconnect/src/xpcwrappednativejsops.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativejsops.cpp
@@ -464,31 +464,36 @@ DefinePropertyIfFound(XPCCallContext& cc
                                      propFlags);
     }
 
     // else...
 
     NS_ASSERTION(member->IsAttribute(), "way broken!");
 
     propFlags |= JSPROP_GETTER | JSPROP_SHARED;
+    JSObject* funobj = JSVAL_TO_OBJECT(funval);
+    JSPropertyOp getter = JS_DATA_TO_FUNC_PTR(JSPropertyOp, funobj);
+    JSPropertyOp setter;
     if(member->IsWritableAttribute())
     {
         propFlags |= JSPROP_SETTER;
         propFlags &= ~JSPROP_READONLY;
+        setter = getter;
+    }
+    else
+    {
+        setter = js_GetterOnlyPropertyStub;
     }
 
     AutoResolveName arn(ccx, idval);
     if(resolved)
         *resolved = JS_TRUE;
 
-    JSObject* funobj = JSVAL_TO_OBJECT(funval);
     return JS_ValueToId(ccx, idval, &id) &&
-           JS_DefinePropertyById(ccx, obj, id, JSVAL_VOID,
-                                 JS_DATA_TO_FUNC_PTR(JSPropertyOp, funobj),
-                                 JS_DATA_TO_FUNC_PTR(JSPropertyOp, funobj),
+           JS_DefinePropertyById(ccx, obj, id, JSVAL_VOID, getter, setter,
                                  propFlags);
 }
 
 /***************************************************************************/
 /***************************************************************************/
 
 static JSBool
 XPC_WN_OnlyIWrite_PropertyStub(JSContext *cx, JSObject *obj, jsval idval, jsval *vp)