Bug 537873: Add 'strict' argument to setters defined throughout Firefox. r=brendan
authorJim Blandy <jimb@mozilla.com>
Wed, 09 Feb 2011 11:31:40 -0800
changeset 62397 48dbd9752e5e725f8ae3d1f1d99bdd9e615d2ab0
parent 62396 cae0570a5c4ce7b265b8edd0b10dad3a7e34033f
child 62398 10ebc5ea11ac28b232ba48f562e23e6a4b3e0ad7
push id18712
push usercleary@mozilla.com
push dateFri, 11 Feb 2011 17:56:41 +0000
treeherdermozilla-central@987efc5f8ba7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbrendan
bugs537873
milestone2.0b12pre
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 537873: Add 'strict' argument to setters defined throughout Firefox. r=brendan This should take care of all setters defined outside SpiderMonkey proper. Very mechanical.
content/canvas/src/CustomQS_Canvas2D.h
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLDocumentInfo.cpp
content/xbl/src/nsXBLProtoImplProperty.cpp
content/xul/document/src/nsXULPrototypeDocument.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
js/ipc/ObjectWrapperChild.cpp
js/ipc/ObjectWrapperParent.cpp
js/ipc/ObjectWrapperParent.h
js/jetpack/Handle.h
js/jetpack/JetpackChild.cpp
js/src/ctypes/CTypes.cpp
js/src/ctypes/Library.cpp
js/src/jsdbgapi.cpp
js/src/xpconnect/shell/xpcshell.cpp
js/src/xpconnect/src/nsXPConnect.cpp
js/src/xpconnect/src/qsgen.py
js/src/xpconnect/src/xpccomponents.cpp
js/src/xpconnect/src/xpcquickstubs.cpp
js/src/xpconnect/src/xpcquickstubs.h
js/src/xpconnect/src/xpcthreadcontext.cpp
js/src/xpconnect/src/xpcwrappedjsclass.cpp
js/src/xpconnect/src/xpcwrappednativejsops.cpp
js/src/xpconnect/src/xpcwrappednativescope.cpp
js/src/xpconnect/tests/TestXPC.cpp
js/src/xpconnect/wrappers/XrayWrapper.cpp
js/src/xpconnect/wrappers/XrayWrapper.h
modules/plugin/base/src/nsJSNPRuntime.cpp
--- a/content/canvas/src/CustomQS_Canvas2D.h
+++ b/content/canvas/src/CustomQS_Canvas2D.h
@@ -125,29 +125,29 @@ Canvas2D_GetStyleHelper(JSContext *cx, J
                                         &interfaces[k_nsIDOMCanvasGradient], vp);
     }
     default:
         return xpc_qsThrowGetterSetterFailed(cx, NS_ERROR_FAILURE, JSVAL_TO_OBJECT(*vp), id);
     }
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+nsIDOMCanvasRenderingContext2D_SetStrokeStyle(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
 {
     return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetStrokeStyle_multi);
 }
 
 static JSBool
 nsIDOMCanvasRenderingContext2D_GetStrokeStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetStrokeStyle_multi);
 }
 
 static JSBool
-nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+nsIDOMCanvasRenderingContext2D_SetFillStyle(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
 {
     return Canvas2D_SetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::SetFillStyle_multi);
 }
 
 static JSBool
 nsIDOMCanvasRenderingContext2D_GetFillStyle(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     return Canvas2D_GetStyleHelper(cx, obj, id, vp, &nsIDOMCanvasRenderingContext2D::GetFillStyle_multi);
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -228,17 +228,18 @@ nsXBLJSClass::nsXBLJSClass(const nsAFlat
   memset(this, 0, sizeof(nsXBLJSClass));
   next = prev = static_cast<JSCList*>(this);
   name = ToNewCString(aClassName);
   flags =
     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
     JSCLASS_NEW_RESOLVE | JSCLASS_NEW_RESOLVE_GETS_START |
     // Our one reserved slot holds the relevant nsXBLPrototypeBinding
     JSCLASS_HAS_RESERVED_SLOTS(1);
-  addProperty = delProperty = setProperty = getProperty = ::JS_PropertyStub;
+  addProperty = delProperty = getProperty = ::JS_PropertyStub;
+  setProperty = ::JS_StrictPropertyStub;
   enumerate = ::JS_EnumerateStub;
   resolve = (JSResolveOp)XBLResolve;
   convert = ::JS_ConvertStub;
   finalize = XBLFinalize;
 }
 
 nsrefcnt
 nsXBLJSClass::Destroy()
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -133,17 +133,17 @@ nsXBLDocGlobalObject_getProperty(JSConte
                                  jsid id, jsval *vp)
 {
   return nsXBLDocGlobalObject::
     doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
 }
 
 static JSBool
 nsXBLDocGlobalObject_setProperty(JSContext *cx, JSObject *obj,
-                                 jsid id, jsval *vp)
+                                 jsid id, JSBool strict, jsval *vp)
 {
   return nsXBLDocGlobalObject::
     doCheckAccess(cx, obj, id, nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
 }
 
 static JSBool
 nsXBLDocGlobalObject_checkAccess(JSContext *cx, JSObject *obj, jsid id,
                                  JSAccessMode mode, jsval *vp)
--- a/content/xbl/src/nsXBLProtoImplProperty.cpp
+++ b/content/xbl/src/nsXBLProtoImplProperty.cpp
@@ -190,17 +190,17 @@ nsXBLProtoImplProperty::InstallMember(ns
       if (!(setter = ::JS_CloneFunctionObject(cx, mJSSetterObject, globalObject)))
         return NS_ERROR_OUT_OF_MEMORY;
 
     nsDependentString name(mName);
     if (!::JS_DefineUCProperty(cx, targetClassObject,
                                reinterpret_cast<const jschar*>(mName),
                                name.Length(), JSVAL_VOID,
                                JS_DATA_TO_FUNC_PTR(JSPropertyOp, getter),
-                               JS_DATA_TO_FUNC_PTR(JSPropertyOp, setter),
+                               JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, setter),
                                mJSAttributes))
       return NS_ERROR_OUT_OF_MEMORY;
   }
   return NS_OK;
 }
 
 nsresult 
 nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCString& aClassStr,
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -139,17 +139,17 @@ nsXULPDGlobalObject_resolve(JSContext *c
 
     return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
 }
 
 
 JSClass nsXULPDGlobalObject::gSharedGlobalClass = {
     "nsXULPrototypeScript compilation scope",
     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_GLOBAL_FLAGS,
-    JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+    JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, nsXULPDGlobalObject_resolve,  JS_ConvertStub,
     nsXULPDGlobalObject_finalize
 };
 
 
 
 //----------------------------------------------------------------------
 //
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1971,17 +1971,17 @@ NS_INTERFACE_MAP_BEGIN(nsDOMClassInfo)
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIClassInfo)
 NS_INTERFACE_MAP_END
 
 
 static JSClass sDOMConstructorProtoClass = {
   "DOM Constructor.prototype", 0,
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nsnull
 };
 
 
 static const char *
 CutPrefix(const char *aName) {
   static const char prefix_nsIDOM[] = "nsIDOM";
   static const char prefix_nsI[]    = "nsI";
@@ -4992,18 +4992,18 @@ nsWindowSH::PreCreate(nsISupports *nativ
   return NS_OK;
 }
 
 // This JS class piggybacks on nsHTMLDocumentSH::ReleaseDocument()...
 
 static JSClass sGlobalScopePolluterClass = {
   "Global Scope Polluter",
   JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_NEW_RESOLVE,
-  nsWindowSH::SecurityCheckOnSetProp,
-  nsWindowSH::SecurityCheckOnSetProp,
+  nsWindowSH::SecurityCheckOnAddDelProp,
+  nsWindowSH::SecurityCheckOnAddDelProp,
   nsWindowSH::GlobalScopePolluterGetProperty,
   nsWindowSH::SecurityCheckOnSetProp,
   JS_EnumerateStub,
   (JSResolveOp)nsWindowSH::GlobalScopePolluterNewResolve,
   JS_ConvertStub,
   nsHTMLDocumentSH::ReleaseDocument
 };
 
@@ -5032,32 +5032,40 @@ nsWindowSH::GlobalScopePolluterGetProper
   // catch and fix these mistakes.
   PrintWarningOnConsole(cx, "GlobalScopeElementReference");
 
   return JS_TRUE;
 }
 
 // static
 JSBool
-nsWindowSH::SecurityCheckOnSetProp(JSContext *cx, JSObject *obj, jsid id,
-                                   jsval *vp)
+nsWindowSH::SecurityCheckOnAddDelProp(JSContext *cx, JSObject *obj, jsid id,
+                                      jsval *vp)
 {
   // Someone is accessing a element by referencing its name/id in the
   // global scope, do a security check to make sure that's ok.
 
   nsresult rv =
     sSecMan->CheckPropertyAccess(cx, ::JS_GetGlobalForObject(cx, obj),
                                  "Window", id,
                                  nsIXPCSecurityManager::ACCESS_SET_PROPERTY);
 
   // If !NS_SUCCEEDED(rv) the security check failed. The security
   // manager set a JS exception for us.
   return NS_SUCCEEDED(rv);
 }
 
+// static
+JSBool
+nsWindowSH::SecurityCheckOnSetProp(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
+                                   jsval *vp)
+{
+  return SecurityCheckOnAddDelProp(cx, obj, id, vp);
+}
+
 static nsHTMLDocument*
 GetDocument(JSContext *cx, JSObject *obj)
 {
   return static_cast<nsHTMLDocument*>(
     static_cast<nsIHTMLDocument*>(::JS_GetPrivate(cx, obj)));
 }
 
 // static
@@ -6900,17 +6908,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       // A readonly "replaceable" property is being set, or a
       // readwrite "replaceable" property is being set w/o being
       // fully qualified. Define the property on obj with the value
       // undefined to override the predefined property. This is done
       // for compatibility with other browsers.
       JSAutoRequest ar(cx);
 
       if (!::JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, JS_PropertyStub,
-                                   JS_PropertyStub, JSPROP_ENUMERATE)) {
+                                   JS_StrictPropertyStub, JSPROP_ENUMERATE)) {
         return NS_ERROR_FAILURE;
       }
       *objp = obj;
 
       return NS_OK;
     }
   } else {
     if (id == sNavigator_id) {
@@ -7062,17 +7070,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       //
       // Since we always create the undeclared property here without given a
       // chance for the interpreter to report applicable strict mode warnings,
       // we must take care to check those warnings here.
       JSString *str = JSID_TO_STRING(id);
       if ((!(flags & JSRESOLVE_QUALIFIED) &&
            !js_CheckUndeclaredVarAssignment(cx, str)) ||
           !::JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, JS_PropertyStub,
-                                   JS_PropertyStub, JSPROP_ENUMERATE)) {
+                                   JS_StrictPropertyStub, JSPROP_ENUMERATE)) {
         *_retval = JS_FALSE;
 
         return NS_OK;
       }
 
       *objp = obj;
     }
   }
@@ -8526,17 +8534,17 @@ nsDocumentSH::PostCreate(nsIXPConnectWra
     NS_ENSURE_SUCCESS(rv, rv);
 
     NS_NAMED_LITERAL_STRING(doc_str, "document");
 
     if (!::JS_DefineUCProperty(cx, JSVAL_TO_OBJECT(winVal),
                                reinterpret_cast<const jschar *>
                                                (doc_str.get()),
                                doc_str.Length(), OBJECT_TO_JSVAL(obj),
-                               JS_PropertyStub, JS_PropertyStub,
+                               JS_PropertyStub, JS_StrictPropertyStub,
                                JSPROP_READONLY | JSPROP_ENUMERATE)) {
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
 // HTMLDocument helper
@@ -8641,37 +8649,37 @@ nsHTMLDocumentSH::DocumentOpen(JSContext
 }
 
 
 static JSClass sHTMLDocumentAllClass = {
   "HTML document.all class",
   JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_NEW_RESOLVE |
   JSCLASS_HAS_RESERVED_SLOTS(1),
   JS_PropertyStub, JS_PropertyStub, nsHTMLDocumentSH::DocumentAllGetProperty,
-  JS_PropertyStub, JS_EnumerateStub,
+  JS_StrictPropertyStub, JS_EnumerateStub,
   (JSResolveOp)nsHTMLDocumentSH::DocumentAllNewResolve, JS_ConvertStub,
   nsHTMLDocumentSH::ReleaseDocument, nsnull, nsnull,
   nsHTMLDocumentSH::CallToGetPropMapper
 };
 
 
 static JSClass sHTMLDocumentAllHelperClass = {
   "HTML document.all helper class", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
   JS_PropertyStub, JS_PropertyStub,
   nsHTMLDocumentSH::DocumentAllHelperGetProperty,
-  JS_PropertyStub, JS_EnumerateStub,
+  JS_StrictPropertyStub, JS_EnumerateStub,
   (JSResolveOp)nsHTMLDocumentSH::DocumentAllHelperNewResolve, JS_ConvertStub,
   nsnull
 };
 
 
 static JSClass sHTMLDocumentAllTagsClass = {
   "HTML document.all.tags class",
   JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_PRIVATE_IS_NSISUPPORTS,
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, (JSResolveOp)nsHTMLDocumentSH::DocumentAllTagsNewResolve,
   JS_ConvertStub, nsHTMLDocumentSH::ReleaseDocument, nsnull, nsnull,
   nsHTMLDocumentSH::CallToGetPropMapper
 };
 
 // static
 JSBool
 nsHTMLDocumentSH::GetDocumentAllNodeList(JSContext *cx, JSObject *obj,
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -571,18 +571,20 @@ public:
   NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
                          JSObject * obj, JSObject * *_retval);
 
   static JSBool GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
                                               jsid id, uintN flags,
                                               JSObject **objp);
   static JSBool GlobalScopePolluterGetProperty(JSContext *cx, JSObject *obj,
                                                jsid id, jsval *vp);
+  static JSBool SecurityCheckOnAddDelProp(JSContext *cx, JSObject *obj, jsid id,
+                                          jsval *vp);
   static JSBool SecurityCheckOnSetProp(JSContext *cx, JSObject *obj, jsid id,
-                                       jsval *vp);
+                                       JSBool strict, jsval *vp);
   static void InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj);
   static nsresult InstallGlobalScopePolluter(JSContext *cx, JSObject *obj,
                                              nsIHTMLDocument *doc);
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData)
   {
     return new nsWindowSH(aData);
   }
 };
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2095,17 +2095,17 @@ nsGlobalWindow::SetNewDocument(nsIDocume
 
       if (!JS_SetPrototype(cx, mJSObject, proto)) {
         NS_ERROR("can't set prototype");
         return NS_ERROR_FAILURE;
       }
     } else {
       if (!JS_DefineProperty(cx, newInnerWindow->mJSObject, "window",
                              OBJECT_TO_JSVAL(mJSObject),
-                             JS_PropertyStub, JS_PropertyStub,
+                             JS_PropertyStub, JS_StrictPropertyStub,
                              JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) {
         NS_ERROR("can't create the 'window' property");
         return NS_ERROR_FAILURE;
       }
     }
   }
 
   JSAutoEnterCompartment ac;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -3198,17 +3198,17 @@ nsJSContext::ClearScope(void *aGlobalObj
     }
 
     if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
       JS_ClearScope(mContext, &obj->getProxyExtra().toObject());
     }
 
     if (window != JSVAL_VOID) {
       if (!JS_DefineProperty(mContext, obj, "window", window,
-                             JS_PropertyStub, JS_PropertyStub,
+                             JS_PropertyStub, JS_StrictPropertyStub,
                              JSPROP_ENUMERATE | JSPROP_READONLY |
                              JSPROP_PERMANENT)) {
         JS_ClearPendingException(mContext);
       }
     }
 
     if (!obj->getParent()) {
       JS_ClearRegExpStatics(mContext, obj);
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -103,17 +103,17 @@ AutoConfigSecMan::CanAccess(PRUint32 aAc
 
 //*****************************************************************************
 
 static  JSContext *autoconfig_cx = nsnull;
 static  JSObject *autoconfig_glob;
 
 static JSClass global_class = {
     "autoconfig_global", JSCLASS_GLOBAL_FLAGS,
-    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   nsnull
 };
 
 static void
 autoConfigErrorReporter(JSContext *cx, const char *message, 
                         JSErrorReport *report)
 {
     NS_ERROR(message);
--- a/js/ipc/ObjectWrapperChild.cpp
+++ b/js/ipc/ObjectWrapperChild.cpp
@@ -424,17 +424,17 @@ CPOW_NewEnumerateState_Finalize(JSContex
 }
 
 // Similar to IteratorClass in XPCWrapper.cpp
 static const JSClass sCPOW_NewEnumerateState_JSClass = {
     "CPOW NewEnumerate State",
     JSCLASS_HAS_PRIVATE |
     JSCLASS_HAS_RESERVED_SLOTS(sNumNewEnumerateStateSlots),
     JS_PropertyStub,  JS_PropertyStub,
-    JS_PropertyStub,  JS_PropertyStub,
+    JS_PropertyStub,  JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub,
     JS_ConvertStub,   CPOW_NewEnumerateState_Finalize,
     JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 bool
 ObjectWrapperChild::AnswerNewEnumerateInit(/* no in-parameters */
                                            OperationStatus* status, JSVariant* statep, int* idp)
--- a/js/ipc/ObjectWrapperParent.cpp
+++ b/js/ipc/ObjectWrapperParent.cpp
@@ -172,17 +172,17 @@ with_error(JSContext* cx,
 
 const js::Class ObjectWrapperParent::sCPOW_JSClass = {
       "CrossProcessObjectWrapper",
       JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE |
       JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(sNumSlots),
       JS_VALUEIFY(js::PropertyOp, ObjectWrapperParent::CPOW_AddProperty),
       JS_VALUEIFY(js::PropertyOp, ObjectWrapperParent::CPOW_DelProperty),
       JS_VALUEIFY(js::PropertyOp, ObjectWrapperParent::CPOW_GetProperty),
-      JS_VALUEIFY(js::PropertyOp, ObjectWrapperParent::CPOW_SetProperty),
+      JS_VALUEIFY(js::StrictPropertyOp, ObjectWrapperParent::CPOW_SetProperty),
       (JSEnumerateOp) ObjectWrapperParent::CPOW_NewEnumerate,
       (JSResolveOp) ObjectWrapperParent::CPOW_NewResolve,
       JS_VALUEIFY(js::ConvertOp, ObjectWrapperParent::CPOW_Convert),
       ObjectWrapperParent::CPOW_Finalize,
       nsnull, // reserved1
       nsnull, // checkAccess
       JS_VALUEIFY(js::CallOp, ObjectWrapperParent::CPOW_Call),
       JS_VALUEIFY(js::CallOp, ObjectWrapperParent::CPOW_Construct),
@@ -445,18 +445,18 @@ ObjectWrapperParent::CPOW_GetProperty(JS
     return (self->Manager()->RequestRunToCompletion() &&
             self->CallGetProperty(in_id,
                                   aco.StatusPtr(), &out_v) &&
             aco.Ok() &&
             self->jsval_from_JSVariant(cx, out_v, vp));
 }
 
 /*static*/ JSBool
-ObjectWrapperParent::CPOW_SetProperty(JSContext *cx, JSObject *obj, jsid id,
-                                      jsval *vp)
+ObjectWrapperParent::CPOW_SetProperty(JSContext *cx, JSObject *obj, jsid id, 
+                                      JSBool strict, jsval *vp)
 {
     CPOW_LOG(("Calling CPOW_SetProperty (%s)...",
               JSVAL_TO_CSTR(cx, id)));
 
     ObjectWrapperParent* self = Unwrap(cx, obj);
     if (!self)
         return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_SetProperty");
 
--- a/js/ipc/ObjectWrapperParent.h
+++ b/js/ipc/ObjectWrapperParent.h
@@ -93,17 +93,17 @@ private:
 
     static JSBool
     CPOW_DelProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
 
     static JSBool
     CPOW_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
     
     static JSBool
-    CPOW_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
+    CPOW_SetProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
 
     JSBool NewEnumerateInit(JSContext* cx, jsval* statep, jsid* idp);
     JSBool NewEnumerateNext(JSContext* cx, jsval* statep, jsid* idp);
     JSBool NewEnumerateDestroy(JSContext* cx, jsval state);
     static JSBool
     CPOW_NewEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
                       jsval *statep, jsid *idp);
 
--- a/js/jetpack/Handle.h
+++ b/js/jetpack/Handle.h
@@ -244,17 +244,17 @@ private:
   GetIsRooted(JSContext* cx, JSObject* obj, jsid, jsval* vp) {
     Handle* self = Unwrap(cx, obj);
     bool rooted = self ? self->mRooted : false;
     JS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(rooted));
     return JS_TRUE;
   }
 
   static JSBool
-  SetIsRooted(JSContext* cx, JSObject* obj, jsid, jsval* vp) {
+  SetIsRooted(JSContext* cx, JSObject* obj, jsid, JSBool strict, jsval* vp) {
     Handle* self = Unwrap(cx, obj);
     JSBool v;
     if (!JS_ValueToBoolean(cx, *vp, &v))
       return JS_FALSE;
 
     if (!self) {
       if (v) {
         JS_ReportError(cx, "Cannot root invalidated handle.");
@@ -325,17 +325,17 @@ private:
   }
 };
 
 template <class BaseType>
 const JSClass
 Handle<BaseType>::sHandle_JSClass = {
   "IPDL Handle", JSCLASS_HAS_PRIVATE,
   JS_PropertyStub, JS_PropertyStub,
-  JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub,
   JS_ConvertStub, Handle::Finalize,
   JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 #define HANDLE_PROP_FLAGS (JSPROP_PERMANENT | JSPROP_SHARED)
 
 template <class BaseType>
--- a/js/jetpack/JetpackChild.cpp
+++ b/js/jetpack/JetpackChild.cpp
@@ -81,17 +81,17 @@ JetpackChild::sImplMethods[] = {
   JS_FS_END
 };
 
 #undef IMPL_METHOD_FLAGS
 
 const JSClass
 JetpackChild::sGlobalClass = {
   "JetpackChild::sGlobalClass", JSCLASS_GLOBAL_FLAGS,
-  JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub,  JS_ConvertStub,  JS_FinalizeStub,
   JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 #ifdef BUILD_CTYPES
 static char*
 UnicodeToNative(JSContext *cx, const jschar *source, size_t slen)
 {
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -102,44 +102,44 @@ namespace CType {
 namespace PointerType {
   static JSBool Create(JSContext* cx, uintN argc, jsval* vp);
   static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, jsval* vp);
 
   static JSBool TargetTypeGetter(JSContext* cx, JSObject* obj, jsid idval,
     jsval* vp);
   static JSBool ContentsGetter(JSContext* cx, JSObject* obj, jsid idval,
     jsval* vp);
-  static JSBool ContentsSetter(JSContext* cx, JSObject* obj, jsid idval,
+  static JSBool ContentsSetter(JSContext* cx, JSObject* obj, jsid idval, JSBool strict,
     jsval* vp);
   static JSBool IsNull(JSContext* cx, uintN argc, jsval* vp);
 }
 
 namespace ArrayType {
   static JSBool Create(JSContext* cx, uintN argc, jsval* vp);
   static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, jsval* vp);
 
   static JSBool ElementTypeGetter(JSContext* cx, JSObject* obj, jsid idval,
     jsval* vp);
   static JSBool LengthGetter(JSContext* cx, JSObject* obj, jsid idval,
     jsval* vp);
   static JSBool Getter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp);
-  static JSBool Setter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp);
+  static JSBool Setter(JSContext* cx, JSObject* obj, jsid idval, JSBool strict, jsval* vp);
   static JSBool AddressOfElement(JSContext* cx, uintN argc, jsval* vp);
 }
 
 namespace StructType {
   static JSBool Create(JSContext* cx, uintN argc, jsval* vp);
   static JSBool ConstructData(JSContext* cx, JSObject* obj, uintN argc, jsval* vp);
 
   static JSBool FieldsArrayGetter(JSContext* cx, JSObject* obj, jsid idval,
     jsval* vp);
   static JSBool FieldGetter(JSContext* cx, JSObject* obj, jsid idval,
     jsval* vp);
-  static JSBool FieldSetter(JSContext* cx, JSObject* obj, jsid idval,
-    jsval* vp);
+  static JSBool FieldSetter(JSContext* cx, JSObject* obj, jsid idval, JSBool strict,
+                            jsval* vp);
   static JSBool AddressOfField(JSContext* cx, uintN argc, jsval* vp);
   static JSBool Define(JSContext* cx, uintN argc, jsval* vp);
 }
 
 namespace FunctionType {
   static JSBool Create(JSContext* cx, uintN argc, jsval* vp);
   static JSBool ConstructData(JSContext* cx, JSObject* typeObj,
     JSObject* dataObj, JSObject* fnObj, JSObject* thisObj);
@@ -163,19 +163,19 @@ namespace CClosure {
   static void ClosureStub(ffi_cif* cif, void* result, void** args,
     void* userData);
 }
 
 namespace CData {
   static void Finalize(JSContext* cx, JSObject* obj);
 
   static JSBool ValueGetter(JSContext* cx, JSObject* obj, jsid idval,
-    jsval* vp);
+                            jsval* vp);
   static JSBool ValueSetter(JSContext* cx, JSObject* obj, jsid idval,
-    jsval* vp);
+                            JSBool strict, jsval* vp);
   static JSBool Address(JSContext* cx, uintN argc, jsval* vp);
   static JSBool ReadString(JSContext* cx, uintN argc, jsval* vp);
   static JSBool ToSource(JSContext* cx, uintN argc, jsval* vp);
 }
 
 // Int64Base provides functions common to Int64 and UInt64.
 namespace Int64Base {
   JSObject* Construct(JSContext* cx, JSObject* proto, JSUint64 data,
@@ -220,71 +220,71 @@ namespace UInt64 {
 ** JSClass definitions and initialization functions
 *******************************************************************************/
 
 // Class representing the 'ctypes' object itself. This exists to contain the
 // JSCTypesCallbacks set of function pointers.
 static JSClass sCTypesGlobalClass = {
   "ctypes",
   JSCLASS_HAS_RESERVED_SLOTS(CTYPESGLOBAL_SLOTS),
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
   JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 static JSClass sCABIClass = {
   "CABI",
   JSCLASS_HAS_RESERVED_SLOTS(CABI_SLOTS),
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
   JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 // Class representing ctypes.{C,Pointer,Array,Struct,Function}Type.prototype.
 // This exists to give said prototypes a class of "CType", and to provide
 // reserved slots for stashing various other prototype objects.
 static JSClass sCTypeProtoClass = {
   "CType",
   JSCLASS_HAS_RESERVED_SLOTS(CTYPEPROTO_SLOTS),
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CType::FinalizeProtoClass,
   NULL, NULL, ConstructAbstract, ConstructAbstract, NULL, NULL, NULL, NULL
 };
 
 // Class representing ctypes.CData.prototype and the 'prototype' properties
 // of CTypes. This exists to give said prototypes a class of "CData".
 static JSClass sCDataProtoClass = {
   "CData",
   0,
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
   JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 static JSClass sCTypeClass = {
   "CType",
   JSCLASS_HAS_RESERVED_SLOTS(CTYPE_SLOTS) | JSCLASS_MARK_IS_TRACE,
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CType::Finalize,
   NULL, NULL, CType::ConstructData, CType::ConstructData, NULL,
   CType::HasInstance, JS_CLASS_TRACE(CType::Trace), NULL
 };
 
 static JSClass sCDataClass = {
   "CData",
   JSCLASS_HAS_RESERVED_SLOTS(CDATA_SLOTS),
   JS_PropertyStub, JS_PropertyStub, ArrayType::Getter, ArrayType::Setter,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CData::Finalize,
   NULL, NULL, FunctionType::Call, FunctionType::Call, NULL, NULL, NULL, NULL
 };
 
 static JSClass sCClosureClass = {
   "CClosure",
   JSCLASS_HAS_RESERVED_SLOTS(CCLOSURE_SLOTS) | JSCLASS_MARK_IS_TRACE,
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CClosure::Finalize,
   NULL, NULL, NULL, NULL, NULL, NULL, JS_CLASS_TRACE(CClosure::Trace), NULL
 };
 
 #define CTYPESFN_FLAGS \
   (JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)
 
 #define CTYPESCTOR_FLAGS \
@@ -391,41 +391,41 @@ static JSPropertySpec sFunctionProps[] =
   { "abi", 0, CTYPESPROP_FLAGS, FunctionType::ABIGetter, NULL },
   { "isVariadic", 0, CTYPESPROP_FLAGS, FunctionType::IsVariadicGetter, NULL },
   { 0, 0, 0, NULL, NULL }
 };
 
 static JSClass sInt64ProtoClass = {
   "Int64",
   0,
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
   JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 static JSClass sUInt64ProtoClass = {
   "UInt64",
   0,
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
   JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 static JSClass sInt64Class = {
   "Int64",
   JSCLASS_HAS_RESERVED_SLOTS(INT64_SLOTS),
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Int64Base::Finalize,
   JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 static JSClass sUInt64Class = {
   "UInt64",
   JSCLASS_HAS_RESERVED_SLOTS(INT64_SLOTS),
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Int64Base::Finalize,
   JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 static JSFunctionSpec sInt64StaticFunctions[] = {
   JS_FN("compare", Int64::Compare, 2, CTYPESFN_FLAGS),
   JS_FN("lo", Int64::Lo, 1, CTYPESFN_FLAGS),
   JS_FN("hi", Int64::Hi, 1, CTYPESFN_FLAGS),
@@ -939,17 +939,17 @@ JS_PUBLIC_API(JSBool)
 JS_InitCTypesClass(JSContext* cx, JSObject* global)
 {
   // attach ctypes property to global object
   JSObject* ctypes = JS_NewObject(cx, &sCTypesGlobalClass, NULL, NULL);
   if (!ctypes)
     return false;
 
   if (!JS_DefineProperty(cx, global, "ctypes", OBJECT_TO_JSVAL(ctypes),
-         JS_PropertyStub, JS_PropertyStub, JSPROP_READONLY | JSPROP_PERMANENT)) {
+         JS_PropertyStub, JS_StrictPropertyStub, JSPROP_READONLY | JSPROP_PERMANENT)) {
     return false;
   }
 
   if (!InitTypeClasses(cx, ctypes))
     return false;
 
   // attach API functions
   if (!JS_DefineFunctions(cx, ctypes, sModuleFunctions))
@@ -3396,16 +3396,17 @@ PointerType::ContentsGetter(JSContext* c
   JS_SET_RVAL(cx, vp, result);
   return JS_TRUE;
 }
 
 JSBool
 PointerType::ContentsSetter(JSContext* cx,
                             JSObject* obj,
                             jsid idval,
+                            JSBool strict,
                             jsval* vp)
 {
   if (!CData::IsCData(cx, obj)) {
     JS_ReportError(cx, "not a CData");
     return JS_FALSE;
   }
 
   // Get pointer type and base type.
@@ -3784,17 +3785,17 @@ ArrayType::Getter(JSContext* cx, JSObjec
 
   JSObject* baseType = GetBaseType(cx, typeObj);
   size_t elementSize = CType::GetSize(cx, baseType);
   char* data = static_cast<char*>(CData::GetData(cx, obj)) + elementSize * index;
   return ConvertToJS(cx, baseType, obj, data, false, false, vp);
 }
 
 JSBool
-ArrayType::Setter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
+ArrayType::Setter(JSContext* cx, JSObject* obj, jsid idval, JSBool strict, jsval* vp)
 {
   // This should never happen, but we'll check to be safe.
   if (!CData::IsCData(cx, obj)) {
     JS_ReportError(cx, "not a CData");
     return JS_FALSE;
   }
 
   // Bail early if we're not an ArrayType. (This setter is present for all
@@ -4426,17 +4427,17 @@ StructType::FieldGetter(JSContext* cx, J
   if (!field)
     return JS_FALSE;
 
   char* data = static_cast<char*>(CData::GetData(cx, obj)) + field->mOffset;
   return ConvertToJS(cx, field->mType, obj, data, false, false, vp);
 }
 
 JSBool
-StructType::FieldSetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
+StructType::FieldSetter(JSContext* cx, JSObject* obj, jsid idval, JSBool strict, jsval* vp)
 {
   if (!CData::IsCData(cx, obj)) {
     JS_ReportError(cx, "not a CData");
     return JS_FALSE;
   }
 
   JSObject* typeObj = CData::GetCType(cx, obj);
   if (CType::GetTypeCode(cx, typeObj) != TYPE_struct) {
@@ -5587,17 +5588,17 @@ CData::ValueGetter(JSContext* cx, JSObje
   // Convert the value to a primitive; do not create a new CData object.
   if (!ConvertToJS(cx, GetCType(cx, obj), NULL, GetData(cx, obj), true, false, vp))
     return JS_FALSE;
 
   return JS_TRUE;
 }
 
 JSBool
-CData::ValueSetter(JSContext* cx, JSObject* obj, jsid idval, jsval* vp)
+CData::ValueSetter(JSContext* cx, JSObject* obj, jsid idval, JSBool strict, jsval* vp)
 {
   if (!IsCData(cx, obj)) {
     JS_ReportError(cx, "not a CData");
     return JS_FALSE;
   }
 
   return ImplicitConvert(cx, *vp, GetCType(cx, obj), GetData(cx, obj), false, NULL);
 }
--- a/js/src/ctypes/Library.cpp
+++ b/js/src/ctypes/Library.cpp
@@ -60,17 +60,17 @@ namespace Library
 
 /*******************************************************************************
 ** JSObject implementation
 *******************************************************************************/
 
 static JSClass sLibraryClass = {
   "Library",
   JSCLASS_HAS_RESERVED_SLOTS(LIBRARY_SLOTS) | JSCLASS_MARK_IS_TRACE,
-  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub,JS_ResolveStub, JS_ConvertStub, Library::Finalize,
   JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 #define CTYPESFN_FLAGS \
   (JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)
 
 static JSFunctionSpec sLibraryFunctions[] = {
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -2171,17 +2171,17 @@ js_ResumeVtune(JSContext *cx, uintN argc
 static JSBool
 ethogram_construct(JSContext *cx, uintN argc, jsval *vp);
 static void
 ethogram_finalize(JSContext *cx, JSObject *obj);
 
 static JSClass ethogram_class = {
     "Ethogram",
     JSCLASS_HAS_PRIVATE,
-    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, ethogram_finalize,
     JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 struct EthogramEvent {
     TraceVisState s;
     TraceVisExitReason r;
     int ts;
--- a/js/src/xpconnect/shell/xpcshell.cpp
+++ b/js/src/xpconnect/shell/xpcshell.cpp
@@ -879,22 +879,22 @@ static JSFunctionSpec glob_functions[] =
     {"stopCallgrind",   js_StopCallgrind,   0,0},
     {"dumpCallgrind",   js_DumpCallgrind,   1,0},
 #endif
     {nsnull,nsnull,0,0}
 };
 
 JSClass global_class = {
     "global", 0,
-    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   nsnull
 };
 
 static JSBool
-env_setProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+env_setProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
 {
 /* XXX porting may be easy, but these don't seem to supply setenv by default */
 #if !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS
     JSString *idstr, *valstr;
     int rv;
 
     jsval idval;
     if (!JS_IdToValue(cx, id, &idval))
--- a/js/src/xpconnect/src/nsXPConnect.cpp
+++ b/js/src/xpconnect/src/nsXPConnect.cpp
@@ -940,17 +940,17 @@ static JSBool
 TempGlobalResolve(JSContext *aJSContext, JSObject *obj, jsid id)
 {
     JSBool resolved;
     return JS_ResolveStandardClass(aJSContext, obj, id, &resolved);
 }
 
 static JSClass xpcTempGlobalClass = {
     "xpcTempGlobalClass", JSCLASS_GLOBAL_FLAGS,
-    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_StrictPropertyStub,
     JS_EnumerateStub, TempGlobalResolve, JS_ConvertStub,   nsnull,
     JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 static bool
 CreateNewCompartment(JSContext *cx, JSClass *clasp, nsIPrincipal *principal,
                      xpc::CompartmentPrivate *priv, JSObject **global,
                      JSCompartment **compartment)
--- a/js/src/xpconnect/src/qsgen.py
+++ b/js/src/xpconnect/src/qsgen.py
@@ -773,17 +773,20 @@ def writeQuickStub(f, customMethodCalls,
     isAttr = (member.kind == 'attribute')
     isMethod = (member.kind == 'method')
     assert isAttr or isMethod
     isGetter = isAttr and not isSetter
 
     signature = "static JSBool\n"
     if isAttr:
         # JSPropertyOp signature.
-        signature += "%s(JSContext *cx, JSObject *obj, jsid id,%s jsval *vp)\n"
+        if isSetter:
+            signature += "%s(JSContext *cx, JSObject *obj, jsid id, JSBool strict,%s jsval *vp)\n"
+        else:
+            signature += "%s(JSContext *cx, JSObject *obj, jsid id,%s jsval *vp)\n"
     else:
         # JSFastNative.
         signature += "%s(JSContext *cx, uintN argc,%s jsval *vp)\n"
 
     customMethodCall = customMethodCalls.get(stubName, None)
 
     if customMethodCall is None:
         customMethodCall = customMethodCalls.get(member.iface.name + '_', None)
@@ -810,18 +813,18 @@ def writeQuickStub(f, customMethodCalls,
             callTemplate = signature % (stubName, '')
             callTemplate += "{\n"
 
             nativeName = (member.binaryname is not None and member.binaryname
                           or header.firstCap(member.name))
             argumentValues = (customMethodCall['additionalArgumentValues']
                               % nativeName)
             if isAttr:
-                callTemplate += ("    return %s(cx, obj, id, %s, vp);\n"
-                                 % (templateName, argumentValues))
+                callTemplate += ("    return %s(cx, obj, id%s, %s, vp);\n"
+                                 % (templateName, ", strict" if isSetter else "", argumentValues))
             else:
                 callTemplate += ("    return %s(cx, argc, %s, vp);\n"
                                  % (templateName, argumentValues))
             callTemplate += "}\n\n"
 
             # Fall through and create the template function stub called from the
             # real stubs, but only generate the stub once. Otherwise, just write
             # out the call to the template function and return.
--- a/js/src/xpconnect/src/xpccomponents.cpp
+++ b/js/src/xpconnect/src/xpccomponents.cpp
@@ -3111,17 +3111,17 @@ sandbox_convert(JSContext *cx, JSObject 
     }
 
     return JS_ConvertStub(cx, obj, type, vp);
 }
 
 static JSClass SandboxClass = {
     "Sandbox",
     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_GLOBAL_FLAGS,
-    JS_PropertyStub,   JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+    JS_PropertyStub,   JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     sandbox_enumerate, sandbox_resolve, sandbox_convert,  sandbox_finalize,
     JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 static JSFunctionSpec SandboxFunctions[] = {
     {"dump",    SandboxDump,    1,0},
     {"debug",   SandboxDebug,   1,0},
     {"importFunction", SandboxImport, 1,0},
--- a/js/src/xpconnect/src/xpcquickstubs.cpp
+++ b/js/src/xpconnect/src/xpcquickstubs.cpp
@@ -113,94 +113,113 @@ LookupInterfaceOrAncestor(PRUint32 table
             if(entry)
                 break;
             info.swap(parent);
         }
     }
     return entry;
 }
 
+// Apply |op| to |obj|, |id|, and |vp|. If |op| is a setter, treat the assignment as lenient.
+template<typename Op>
+static inline JSBool ApplyPropertyOp(JSContext *cx, Op op, JSObject *obj, jsid id, jsval *vp);
+
+template<>
+inline JSBool
+ApplyPropertyOp<JSPropertyOp>(JSContext *cx, JSPropertyOp op, JSObject *obj, jsid id, jsval *vp)
+{
+    return op(cx, obj, id, vp);
+}
+
+template<>
+inline JSBool
+ApplyPropertyOp<JSStrictPropertyOp>(JSContext *cx, JSStrictPropertyOp op, JSObject *obj,
+                                    jsid id, jsval *vp)
+{
+    return op(cx, obj, id, true, vp);
+}
+
+template<typename Op>
 static JSBool
 PropertyOpForwarder(JSContext *cx, uintN argc, jsval *vp)
 {
     // Layout:
     //   this = our this
     //   property op to call = callee reserved slot 0
     //   name of the property = callee reserved slot 1
 
     JSObject *callee = JSVAL_TO_OBJECT(JS_CALLEE(cx, vp));
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     jsval v;
 
     if(!JS_GetReservedSlot(cx, callee, 0, &v))
         return JS_FALSE;
     JSObject *ptrobj = JSVAL_TO_OBJECT(v);
-    JSPropertyOp *popp = static_cast<JSPropertyOp *>(JS_GetPrivate(cx, ptrobj));
+    Op *popp = static_cast<Op *>(JS_GetPrivate(cx, ptrobj));
 
     if(!JS_GetReservedSlot(cx, callee, 1, &v))
         return JS_FALSE;
 
     jsval argval = (argc > 0) ? JS_ARGV(cx, vp)[0] : JSVAL_VOID;
     jsid id;
     if (!JS_ValueToId(cx, argval, &id))
         return JS_FALSE;
     JS_SET_RVAL(cx, vp, argval);
-    return (*popp)(cx, obj, id, vp);
+    return ApplyPropertyOp<Op>(cx, *popp, obj, id, vp);
 }
 
 static void
 PointerFinalize(JSContext *cx, JSObject *obj)
 {
     JSPropertyOp *popp = static_cast<JSPropertyOp *>(JS_GetPrivate(cx, obj));
     delete popp;
 }
 
 static JSClass
 PointerHolderClass = {
     "Pointer", JSCLASS_HAS_PRIVATE,
-    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, PointerFinalize,
     JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
+template<typename Op>
 static JSObject *
-GeneratePropertyOp(JSContext *cx, JSObject *obj, jsid id, uintN argc,
-                   JSPropertyOp pop)
+GeneratePropertyOp(JSContext *cx, JSObject *obj, jsid id, uintN argc, Op pop)
 {
     // The JS engine provides two reserved slots on function objects for
     // XPConnect to use. Use them to stick the necessary info here.
     JSFunction *fun =
-        JS_NewFunctionById(cx, reinterpret_cast<JSNative>(PropertyOpForwarder),
-                           argc, 0, obj, id);
+        JS_NewFunctionById(cx, PropertyOpForwarder<Op>, argc, 0, obj, id);
     if(!fun)
         return JS_FALSE;
 
     JSObject *funobj = JS_GetFunctionObject(fun);
 
     js::AutoObjectRooter tvr(cx, funobj);
 
-    // Unfortunately, we cannot guarantee that JSPropertyOp is aligned. Use a
+    // Unfortunately, we cannot guarantee that Op is aligned. Use a
     // second object to work around this.
     JSObject *ptrobj = JS_NewObject(cx, &PointerHolderClass, nsnull, funobj);
     if(!ptrobj)
         return JS_FALSE;
-    JSPropertyOp *popp = new JSPropertyOp;
+    Op *popp = new Op;
     if(!popp)
         return JS_FALSE;
     *popp = pop;
     JS_SetPrivate(cx, ptrobj, popp);
 
     JS_SetReservedSlot(cx, funobj, 0, OBJECT_TO_JSVAL(ptrobj));
     JS_SetReservedSlot(cx, funobj, 1, js::IdToJsval(id));
     return funobj;
 }
 
 static JSBool
 ReifyPropertyOps(JSContext *cx, JSObject *obj, jsid id,
-                 JSPropertyOp getter, JSPropertyOp setter,
+                 JSPropertyOp getter, JSStrictPropertyOp setter,
                  JSObject **getterobjp, JSObject **setterobjp)
 {
     // Generate both getter and setter and stash them in the prototype.
     jsval roots[2] = { JSVAL_NULL, JSVAL_NULL };
     js::AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(roots), roots);
 
     uintN attrs = JSPROP_SHARED;
     JSObject *getterobj;
@@ -228,17 +247,17 @@ ReifyPropertyOps(JSContext *cx, JSObject
         setterobj = nsnull;
 
     if(getterobjp)
         *getterobjp = getterobj;
     if(setterobjp)
         *setterobjp = setterobj;
     return JS_DefinePropertyById(cx, obj, id, JSVAL_VOID,
                                  JS_DATA_TO_FUNC_PTR(JSPropertyOp, getterobj),
-                                 JS_DATA_TO_FUNC_PTR(JSPropertyOp, setterobj),
+                                 JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, setterobj),
                                  attrs);
 }
 
 static JSBool
 LookupGetterOrSetter(JSContext *cx, JSBool wantGetter, uintN argc, jsval *vp)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
 
@@ -323,17 +342,18 @@ SharedLookupSetter(JSContext *cx, uintN 
     return LookupGetterOrSetter(cx, PR_FALSE, argc, vp);
 }
 
 static JSBool
 DefineGetterOrSetter(JSContext *cx, uintN argc, JSBool wantGetter, jsval *vp)
 {
     uintN attrs;
     JSBool found;
-    JSPropertyOp getter, setter;
+    JSPropertyOp getter;
+    JSStrictPropertyOp setter;
     JSObject *obj2;
     jsval v;
     jsid id;
 
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
@@ -676,17 +696,17 @@ xpc_qsThrowBadSetterValue(JSContext *cx,
                           JSObject *obj, jsid propId)
 {
     const char *ifaceName;
     GetMemberInfo(obj, propId, &ifaceName);
     ThrowBadArg(cx, rv, ifaceName, propId, NULL, 0);
 }
 
 JSBool
-xpc_qsGetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+xpc_qsGetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
 {
     return JS_ReportErrorFlagsAndNumber(cx,
                                         JSREPORT_WARNING | JSREPORT_STRICT |
                                         JSREPORT_STRICT_MODE_ERROR,
                                         js_GetErrorMessage, NULL,
                                         JSMSG_GETTER_ONLY);
 }
 
--- a/js/src/xpconnect/src/xpcquickstubs.h
+++ b/js/src/xpconnect/src/xpcquickstubs.h
@@ -46,17 +46,17 @@
 
 class XPCCallContext;
 
 #define XPC_QS_NULL_INDEX  ((size_t) -1)
 
 struct xpc_qsPropertySpec {
     const char *name;
     JSPropertyOp getter;
-    JSPropertyOp setter;
+    JSStrictPropertyOp setter;
 };
 
 struct xpc_qsFunctionSpec {
     const char *name;
     JSNative native;
     uintN arity;
 };
 
@@ -224,17 +224,17 @@ xpc_qsThrowBadArgWithDetails(JSContext *
  * See NOTE at xpc_qsThrowGetterSetterFailed.
  */
 void
 xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv, JSObject *obj,
                           jsid propId);
 
 
 JSBool
-xpc_qsGetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
+xpc_qsGetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
 
 /* Functions for converting values between COM and JS. */
 
 inline JSBool
 xpc_qsInt32ToJsval(JSContext *cx, PRInt32 i, jsval *rv)
 {
     *rv = INT_TO_JSVAL(i);
     return JS_TRUE;
--- a/js/src/xpconnect/src/xpcthreadcontext.cpp
+++ b/js/src/xpconnect/src/xpcthreadcontext.cpp
@@ -213,17 +213,17 @@ SafeFinalize(JSContext* cx, JSObject* ob
 
 static JSClass global_class = {
     "global_for_XPCJSContextStack_SafeJSContext",
 #ifndef XPCONNECT_STANDALONE
     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_GLOBAL_FLAGS,
 #else
     0,
 #endif
-    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, SafeGlobalResolve, JS_ConvertStub, SafeFinalize,
     JSCLASS_NO_OPTIONAL_MEMBERS
 };
 
 /* attribute JSContext safeJSContext; */
 NS_IMETHODIMP
 XPCJSContextStack::GetSafeJSContext(JSContext * *aSafeJSContext)
 {
--- a/js/src/xpconnect/src/xpcwrappedjsclass.cpp
+++ b/js/src/xpconnect/src/xpcwrappedjsclass.cpp
@@ -1479,17 +1479,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
 
     // Figure out what our callee is
     if(XPT_MD_IS_GETTER(info->flags) || XPT_MD_IS_SETTER(info->flags))
     {
         // Pull the getter or setter off of |obj|
         uintN attrs;
         JSBool found;
         JSPropertyOp getter;
-        JSPropertyOp setter;
+        JSStrictPropertyOp setter;
         if(!JS_GetPropertyAttrsGetterAndSetter(cx, obj, name,
                                                &attrs, &found,
                                                &getter, &setter))
         {
             // XXX Do we want to report this exception?
             JS_ClearPendingException(cx);
             goto pre_call_clean_up;
         }
--- a/js/src/xpconnect/src/xpcwrappednativejsops.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativejsops.cpp
@@ -488,22 +488,22 @@ DefinePropertyIfFound(XPCCallContext& cc
 
     // 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;
+    JSStrictPropertyOp setter;
     if(member->IsWritableAttribute())
     {
         propFlags |= JSPROP_SETTER;
         propFlags &= ~JSPROP_READONLY;
-        setter = getter;
+        setter = JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, funobj);
     }
     else
     {
         setter = js_GetterOnlyPropertyStub;
     }
 
     AutoResolveName arn(ccx, id);
     if(resolved)
@@ -512,36 +512,49 @@ DefinePropertyIfFound(XPCCallContext& cc
     return JS_DefinePropertyById(ccx, obj, id, JSVAL_VOID, getter, setter,
                                  propFlags);
 }
 
 /***************************************************************************/
 /***************************************************************************/
 
 static JSBool
-XPC_WN_OnlyIWrite_PropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+XPC_WN_OnlyIWrite_AddPropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     XPCCallContext ccx(JS_CALLER, cx, obj, nsnull, id);
     XPCWrappedNative* wrapper = ccx.GetWrapper();
     THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
 
-    // Allow only XPConnect to add the property
+    // Allow only XPConnect to add/set the property
     if(ccx.GetResolveName() == id)
         return JS_TRUE;
 
     return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
 }
 
 static JSBool
+XPC_WN_OnlyIWrite_SetPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
+{
+    return XPC_WN_OnlyIWrite_AddPropertyStub(cx, obj, id, vp);
+}
+
+static JSBool
 XPC_WN_CannotModifyPropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
 }
 
 static JSBool
+XPC_WN_CannotModifyStrictPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
+                                      jsval *vp)
+{
+    return XPC_WN_CannotModifyPropertyStub(cx, obj, id, vp);
+}
+
+static JSBool
 XPC_WN_Shared_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
 {
     if(type == JSTYPE_OBJECT)
     {
         *vp = OBJECT_TO_JSVAL(obj);
         return JS_TRUE;
     }
 
@@ -859,20 +872,20 @@ XPC_WN_OuterObject(JSContext *cx, JSObje
 
 js::Class XPC_WN_NoHelper_JSClass = {
     "XPCWrappedNative_NoHelper",    // name;
     WRAPPER_SLOTS |
     JSCLASS_PRIVATE_IS_NSISUPPORTS |
     JSCLASS_MARK_IS_TRACE, // flags;
 
     /* Mandatory non-null function pointer members. */
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_PropertyStub), // addProperty
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_CannotModifyPropertyStub),// delProperty
-    js::PropertyStub,                                            // getProperty
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_PropertyStub), // setProperty
+    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_AddPropertyStub),       // addProperty
+    JS_VALUEIFY(js::PropertyOp, XPC_WN_CannotModifyPropertyStub),         // delProperty
+    js::PropertyStub,                                                     // getProperty
+    JS_VALUEIFY(js::StrictPropertyOp, XPC_WN_OnlyIWrite_SetPropertyStub), // setProperty
    
     XPC_WN_Shared_Enumerate,                                     // enumerate
     XPC_WN_NoHelper_Resolve,                                     // resolve
     JS_VALUEIFY(js::ConvertOp, XPC_WN_Shared_Convert),           // convert
     XPC_WN_NoHelper_Finalize,                                    // finalize
    
     /* Optionally non-null members start here. */
     nsnull,                         // reserved0
@@ -921,16 +934,23 @@ XPC_WN_MaybeResolvingPropertyStub(JSCont
     XPCWrappedNative* wrapper = ccx.GetWrapper();
     THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);
 
     if(ccx.GetResolvingWrapper() == wrapper)
         return JS_TRUE;
     return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
 }
 
+static JSBool
+XPC_WN_MaybeResolvingStrictPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
+                                        jsval *vp)
+{
+    return XPC_WN_MaybeResolvingPropertyStub(cx, obj, id, vp);
+}
+
 // macro fun!
 #define PRE_HELPER_STUB_NO_SLIM                                              \
     XPCWrappedNative* wrapper =                                              \
         XPCWrappedNative::GetAndMorphWrappedNativeOfJSObject(cx, obj);       \
     THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);                            \
     PRBool retval = JS_TRUE;                                                 \
     nsresult rv = wrapper->GetScriptableCallback()->
 
@@ -976,17 +996,17 @@ static JSBool
 XPC_WN_Helper_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     PRE_HELPER_STUB
     GetProperty(wrapper, cx, obj, id, vp, &retval);
     POST_HELPER_STUB
 }
 
 static JSBool
-XPC_WN_Helper_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+XPC_WN_Helper_SetProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
 {
     PRE_HELPER_STUB
     SetProperty(wrapper, cx, obj, id, vp, &retval);
     POST_HELPER_STUB
 }
 
 static JSBool
 XPC_WN_Helper_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
@@ -1473,25 +1493,25 @@ XPCNativeScriptableShared::PopulateJSCla
         delProperty = XPC_WN_CannotModifyPropertyStub;
     mJSClass.base.delProperty = js::Valueify(delProperty);
 
     if(mFlags.WantGetProperty())
         mJSClass.base.getProperty = js::Valueify(XPC_WN_Helper_GetProperty);
     else
         mJSClass.base.getProperty = js::PropertyStub;
 
-    JSPropertyOp setProperty;
+    JSStrictPropertyOp setProperty;
     if(mFlags.WantSetProperty())
         setProperty = XPC_WN_Helper_SetProperty;
     else if(mFlags.UseJSStubForSetProperty())
-        setProperty = JS_PropertyStub;
+        setProperty = JS_StrictPropertyStub;
     else if(mFlags.AllowPropModsDuringResolve())
-        setProperty = XPC_WN_MaybeResolvingPropertyStub;
+        setProperty = XPC_WN_MaybeResolvingStrictPropertyStub;
     else
-        setProperty = XPC_WN_CannotModifyPropertyStub;
+        setProperty = XPC_WN_CannotModifyStrictPropertyStub;
     mJSClass.base.setProperty = js::Valueify(setProperty);
 
     // We figure out most of the enumerate strategy at call time.
 
     if(mFlags.WantNewEnumerate() || mFlags.WantEnumerate() ||
        mFlags.DontEnumStaticProps())
         mJSClass.base.enumerate = js::EnumerateStub;
     else
@@ -1747,17 +1767,17 @@ XPC_WN_ModsAllowed_Proto_Resolve(JSConte
 js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass = {
     "XPC_WN_ModsAllowed_WithCall_Proto_JSClass", // name;
     WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE, // flags;
 
     /* Mandatory non-null function pointer members. */
     js::PropertyStub,               // addProperty;
     js::PropertyStub,               // delProperty;
     js::PropertyStub,               // getProperty;
-    js::PropertyStub,               // setProperty;
+    js::StrictPropertyStub,         // setProperty;
     XPC_WN_Shared_Proto_Enumerate,  // enumerate;
     XPC_WN_ModsAllowed_Proto_Resolve, // resolve;
     JS_VALUEIFY(js::ConvertOp, XPC_WN_Shared_Proto_Convert), // convert;
     XPC_WN_Shared_Proto_Finalize,   // finalize;
 
     /* Optionally non-null members start here. */
     nsnull,                         // reserved0;
     nsnull,                         // checkAccess;
@@ -1774,17 +1794,17 @@ js::Class XPC_WN_ModsAllowed_WithCall_Pr
 js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass = {
     "XPC_WN_ModsAllowed_NoCall_Proto_JSClass", // name;
     WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE, // flags;
 
     /* Mandatory non-null function pointer members. */
     js::PropertyStub,               // addProperty;
     js::PropertyStub,               // delProperty;
     js::PropertyStub,               // getProperty;
-    js::PropertyStub,               // setProperty;
+    js::StrictPropertyStub,         // setProperty;
     XPC_WN_Shared_Proto_Enumerate,  // enumerate;
     XPC_WN_ModsAllowed_Proto_Resolve,// resolve;
     JS_VALUEIFY(js::ConvertOp, XPC_WN_Shared_Proto_Convert), // convert;
     XPC_WN_Shared_Proto_Finalize,    // finalize;
 
     /* Optionally non-null members start here. */
     nsnull,                         // reserved0;
     nsnull,                         // checkAccess;
@@ -1796,17 +1816,17 @@ js::Class XPC_WN_ModsAllowed_NoCall_Prot
 
     JS_NULL_CLASS_EXT,
     XPC_WN_NoCall_ObjectOps
 };
 
 /***************************************************************************/
 
 static JSBool
-XPC_WN_OnlyIWrite_Proto_PropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
 {
     NS_ASSERTION(obj->getClass() == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
                  obj->getClass() == &XPC_WN_NoMods_NoCall_Proto_JSClass,
                  "bad proto");
 
     XPCWrappedNativeProto* self =
         (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
     if(!self)
@@ -1819,16 +1839,23 @@ XPC_WN_OnlyIWrite_Proto_PropertyStub(JSC
     // Allow XPConnect to add the property only
     if(ccx.GetResolveName() == id)
         return JS_TRUE;
 
     return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
 }
 
 static JSBool
+XPC_WN_OnlyIWrite_Proto_SetPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict,
+                                        jsval *vp)
+{
+    return XPC_WN_OnlyIWrite_Proto_AddPropertyStub(cx, obj, id, vp);
+}
+
+static JSBool
 XPC_WN_NoMods_Proto_Resolve(JSContext *cx, JSObject *obj, jsid id)
 {
     NS_ASSERTION(obj->getClass() == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
                  obj->getClass() == &XPC_WN_NoMods_NoCall_Proto_JSClass,
                  "bad proto");
 
     XPCWrappedNativeProto* self =
         (XPCWrappedNativeProto*) xpc_GetJSPrivate(obj);
@@ -1852,24 +1879,24 @@ XPC_WN_NoMods_Proto_Resolve(JSContext *c
                                  enumFlag, nsnull);
 }
 
 js::Class XPC_WN_NoMods_WithCall_Proto_JSClass = {
     "XPC_WN_NoMods_WithCall_Proto_JSClass",      // name;
     WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE, // flags;
 
     /* Mandatory non-null function pointer members. */
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_Proto_PropertyStub), // addProperty;
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_CannotModifyPropertyStub),      // delProperty;
-    js::PropertyStub,                                                  // getProperty;
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_Proto_PropertyStub), // setProperty;
-    XPC_WN_Shared_Proto_Enumerate,                                     // enumerate;
-    XPC_WN_NoMods_Proto_Resolve,                                       // resolve;
-    JS_VALUEIFY(js::ConvertOp, XPC_WN_Shared_Proto_Convert),           // convert;
-    XPC_WN_Shared_Proto_Finalize,                                      // finalize;
+    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_Proto_AddPropertyStub),       // addProperty;
+    JS_VALUEIFY(js::PropertyOp, XPC_WN_CannotModifyPropertyStub),               // delProperty;
+    js::PropertyStub,                                                           // getProperty;
+    JS_VALUEIFY(js::StrictPropertyOp, XPC_WN_OnlyIWrite_Proto_SetPropertyStub), // setProperty;
+    XPC_WN_Shared_Proto_Enumerate,                                              // enumerate;
+    XPC_WN_NoMods_Proto_Resolve,                                                // resolve;
+    JS_VALUEIFY(js::ConvertOp, XPC_WN_Shared_Proto_Convert),                    // convert;
+    XPC_WN_Shared_Proto_Finalize,                                               // finalize;
 
     /* Optionally non-null members start here. */
     nsnull,                         // reserved0;
     nsnull,                         // checkAccess;
     nsnull,                         // call;
     nsnull,                         // construct;
     nsnull,                         // xdrObject;
     nsnull,                         // hasInstance;
@@ -1879,24 +1906,24 @@ js::Class XPC_WN_NoMods_WithCall_Proto_J
     XPC_WN_WithCall_ObjectOps
 };
 
 js::Class XPC_WN_NoMods_NoCall_Proto_JSClass = {
     "XPC_WN_NoMods_NoCall_Proto_JSClass",               // name;
     WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE,              // flags;
 
     /* Mandatory non-null function pointer members. */
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_Proto_PropertyStub), // addProperty;
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_CannotModifyPropertyStub),      // delProperty;
-    js::PropertyStub,                                                  // getProperty;
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_Proto_PropertyStub), // setProperty;
-    XPC_WN_Shared_Proto_Enumerate,                                     // enumerate;
-    XPC_WN_NoMods_Proto_Resolve,                                       // resolve;
-    JS_VALUEIFY(js::ConvertOp, XPC_WN_Shared_Proto_Convert),           // convert;
-    XPC_WN_Shared_Proto_Finalize,                                      // finalize;
+    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_Proto_AddPropertyStub),       // addProperty;
+    JS_VALUEIFY(js::PropertyOp, XPC_WN_CannotModifyPropertyStub),               // delProperty;
+    js::PropertyStub,                                                           // getProperty;
+    JS_VALUEIFY(js::StrictPropertyOp, XPC_WN_OnlyIWrite_Proto_SetPropertyStub), // setProperty;
+    XPC_WN_Shared_Proto_Enumerate,                                              // enumerate;
+    XPC_WN_NoMods_Proto_Resolve,                                                // resolve;
+    JS_VALUEIFY(js::ConvertOp, XPC_WN_Shared_Proto_Convert),                    // convert;
+    XPC_WN_Shared_Proto_Finalize,                                               // finalize;
 
     /* Optionally non-null members start here. */
     nsnull,                         // reserved0;
     nsnull,                         // checkAccess;
     nsnull,                         // call;
     nsnull,                         // construct;
     nsnull,                         // xdrObject;
     nsnull,                         // hasInstance;
@@ -1963,17 +1990,17 @@ XPC_WN_TearOff_Finalize(JSContext *cx, J
         return;
     p->JSObjectFinalized();
 }
 
 js::Class XPC_WN_Tearoff_JSClass = {
     "WrappedNative_TearOff",                        // name;
     WRAPPER_SLOTS | JSCLASS_MARK_IS_TRACE,          // flags;
 
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_PropertyStub),   // addProperty;
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_CannotModifyPropertyStub),  // delProperty;
-    js::PropertyStub,                                              // getProperty;
-    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_PropertyStub),   // setProperty;
-    XPC_WN_TearOff_Enumerate,                                      // enumerate;
-    XPC_WN_TearOff_Resolve,                                        // resolve;
-    JS_VALUEIFY(js::ConvertOp, XPC_WN_Shared_Convert),             // convert;
-    XPC_WN_TearOff_Finalize                                        // finalize;
+    JS_VALUEIFY(js::PropertyOp, XPC_WN_OnlyIWrite_AddPropertyStub),       // addProperty;
+    JS_VALUEIFY(js::PropertyOp, XPC_WN_CannotModifyPropertyStub),         // delProperty;
+    js::PropertyStub,                                                     // getProperty;
+    JS_VALUEIFY(js::StrictPropertyOp, XPC_WN_OnlyIWrite_SetPropertyStub), // setProperty;
+    XPC_WN_TearOff_Enumerate,                                             // enumerate;
+    XPC_WN_TearOff_Resolve,                                               // resolve;
+    JS_VALUEIFY(js::ConvertOp, XPC_WN_Shared_Convert),                    // convert;
+    XPC_WN_TearOff_Finalize                                               // finalize;
 };
--- a/js/src/xpconnect/src/xpcwrappednativescope.cpp
+++ b/js/src/xpconnect/src/xpcwrappednativescope.cpp
@@ -204,17 +204,17 @@ XPCWrappedNativeScope::SetComponents(nsX
 js::Class XPC_WN_NoHelper_Proto_JSClass = {
     "XPC_WN_NoHelper_Proto_JSClass",// name;
     WRAPPER_SLOTS,                  // flags;
 
     /* Mandatory non-null function pointer members. */
     js::PropertyStub,               // addProperty;
     js::PropertyStub,               // delProperty;
     js::PropertyStub,               // getProperty;
-    js::PropertyStub,               // setProperty;
+    js::StrictPropertyStub,         // setProperty;
     js::EnumerateStub,              // enumerate;
     JS_ResolveStub,                 // resolve;
     js::ConvertStub,                // convert;
     nsnull,                         // finalize;
 
     /* Optionally non-null members start here. */
     nsnull,                         // reserved0;
     nsnull,                         // checkAccess;
--- a/js/src/xpconnect/tests/TestXPC.cpp
+++ b/js/src/xpconnect/tests/TestXPC.cpp
@@ -133,17 +133,17 @@ Load(JSContext *cx, uintN argc, jsval *v
 static JSFunctionSpec glob_functions[] = {
     {"print",           Print,          0,0},
     {"load",            Load,           1,0},
     {nsnull,nsnull,0,0}
 };
 
 static JSClass global_class = {
     "global", 0,
-    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
+    JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   nsnull
 };
 
 static void
 my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
 {
     fputs(message, stdout);
 }
--- a/js/src/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/src/xpconnect/wrappers/XrayWrapper.cpp
@@ -94,17 +94,17 @@ IsResolving(JSObject *holder, jsid id)
 
     return false;
 }
 
 static JSBool
 holder_get(JSContext *cx, JSObject *holder, jsid id, jsval *vp);
 
 static JSBool
-holder_set(JSContext *cx, JSObject *holder, jsid id, jsval *vp);
+holder_set(JSContext *cx, JSObject *holder, jsid id, JSBool strict, jsval *vp);
 
 namespace XrayUtils {
 
 JSClass HolderClass = {
     "NativePropertyHolder",
     JSCLASS_HAS_RESERVED_SLOTS(3),
     JS_PropertyStub,        JS_PropertyStub, holder_get,      holder_set,
     JS_EnumerateStub,       JS_ResolveStub,  JS_ConvertStub,  NULL,
@@ -197,17 +197,17 @@ holder_get(JSContext *cx, JSObject *wrap
                 XPCThrower::Throw(rv, cx);
             return false;
         }
     }
     return true;
 }
 
 static JSBool
-holder_set(JSContext *cx, JSObject *wrapper, jsid id, jsval *vp)
+holder_set(JSContext *cx, JSObject *wrapper, jsid id, JSBool strict, jsval *vp)
 {
     NS_ASSERTION(wrapper->isProxy(), "bad this object in set");
     JSObject *holder = GetHolder(wrapper);
     if (IsResolving(holder, id)) {
         return true;
     }
 
     JSObject *wnObject = GetWrappedNativeObjectFromHolder(cx, holder);
@@ -291,26 +291,27 @@ ResolveNativeProperty(JSContext *cx, JSO
             JS_ReportError(cx, "Failed to clone function object for native function");
             return false;
         }
 
         // Without a wrapper the function would live on the prototype. Since we
         // don't have one, we have to avoid calling the scriptable helper's
         // GetProperty method for this property, so stub out the getter and
         // setter here explicitly.
-        desc->getter = desc->setter = JS_PropertyStub;
+        desc->getter = JS_PropertyStub;
+        desc->setter = JS_StrictPropertyStub;
     }
 
     if (!JS_WrapValue(cx, &desc->value) || !JS_WrapValue(cx, &fval))
         return false;
 
     if (desc->attrs & JSPROP_GETTER)
         desc->getter = CastAsJSPropertyOp(JSVAL_TO_OBJECT(fval));
     if (desc->attrs & JSPROP_SETTER)
-        desc->setter = desc->getter;
+        desc->setter = CastAsJSStrictPropertyOp(JSVAL_TO_OBJECT(fval));
 
     // Define the property.
     return JS_DefinePropertyById(cx, holder, id, desc->value,
                                  desc->getter, desc->setter, desc->attrs);
 }
 
 static JSBool
 wrappedJSObject_getter(JSContext *cx, JSObject *wrapper, jsid id, jsval *vp)
@@ -763,22 +764,22 @@ XrayWrapper<Base>::get(JSContext *cx, JS
     // NB: None of the functions we call are prepared for the receiver not
     // being the wrapper, so ignore the receiver here.
     return JSProxyHandler::get(cx, wrapper, wrapper, id, vp);
 }
 
 template <typename Base>
 bool
 XrayWrapper<Base>::set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id,
-                       js::Value *vp)
+                       bool strict, js::Value *vp)
 {
     // Skip our Base if it isn't already JSProxyHandler.
     // NB: None of the functions we call are prepared for the receiver not
     // being the wrapper, so ignore the receiver here.
-    return JSProxyHandler::set(cx, wrapper, wrapper, id, vp);
+    return JSProxyHandler::set(cx, wrapper, wrapper, id, strict, vp);
 }
 
 template <typename Base>
 bool
 XrayWrapper<Base>::has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp)
 {
     // Skip our Base if it isn't already JSProxyHandler.
     return JSProxyHandler::has(cx, wrapper, id, bp);
--- a/js/src/xpconnect/wrappers/XrayWrapper.h
+++ b/js/src/xpconnect/wrappers/XrayWrapper.h
@@ -79,17 +79,17 @@ class XrayWrapper : public Base {
     virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
     virtual bool enumerate(JSContext *cx, JSObject *wrapper, js::AutoIdVector &props);
     virtual bool fix(JSContext *cx, JSObject *proxy, js::Value *vp);
 
     /* Derived proxy traps. */
     virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id,
                      js::Value *vp);
     virtual bool set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id,
-                     js::Value *vp);
+                     bool strict, js::Value *vp);
     virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
     virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
     virtual bool keys(JSContext *cx, JSObject *wrapper, js::AutoIdVector &props);
     virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, js::Value *vp);
 
     virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, js::Value *vp);
     virtual bool construct(JSContext *cx, JSObject *wrapper,
                            uintN argc, js::Value *argv, js::Value *rval);
--- a/modules/plugin/base/src/nsJSNPRuntime.cpp
+++ b/modules/plugin/base/src/nsJSNPRuntime.cpp
@@ -146,17 +146,17 @@ NPClass nsJSObjWrapper::sJSObjWrapperNPC
 
 static JSBool
 NPObjWrapper_AddProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
 
 static JSBool
 NPObjWrapper_DelProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
 
 static JSBool
-NPObjWrapper_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
+NPObjWrapper_SetProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
 
 static JSBool
 NPObjWrapper_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
 
 static JSBool
 NPObjWrapper_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
                           jsval *statep, jsid *idp);
 
@@ -210,17 +210,17 @@ NPObjectMember_Call(JSContext *cx, uintN
 
 static uint32
 NPObjectMember_Mark(JSContext *cx, JSObject *obj, void *arg);
 
 static JSClass sNPObjectMemberClass =
   {
     "NPObject Ambiguous Member class", JSCLASS_HAS_PRIVATE,
     JS_PropertyStub, JS_PropertyStub,
-    JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
+    JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub,
     JS_ResolveStub, NPObjectMember_Convert,
     NPObjectMember_Finalize, nsnull, nsnull, NPObjectMember_Call,
     nsnull, nsnull, nsnull, NPObjectMember_Mark, nsnull
   };
 
 static void
 OnWrapperDestroyed();
 
@@ -1243,17 +1243,17 @@ NPObjWrapper_DelProperty(JSContext *cx, 
 
   if (!npobj->_class->removeProperty(npobj, identifier))
     *vp = JSVAL_FALSE;
 
   return ReportExceptionIfPending(cx);
 }
 
 static JSBool
-NPObjWrapper_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
+NPObjWrapper_SetProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
 {
   NPObject *npobj = GetNPObject(cx, obj);
 
   if (!npobj || !npobj->_class || !npobj->_class->hasProperty ||
       !npobj->_class->setProperty) {
     ThrowJSException(cx, "Bad NPObject as private data!");
 
     return JS_FALSE;