<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    if i'm reading this right we should expect nightly breakage.<br>
    <br>
    -------- Original Message --------
    <table class="moz-email-headers-table" border="0" cellpadding="0"
      cellspacing="0">
      <tbody>
        <tr>
          <th align="RIGHT" nowrap="nowrap" valign="BASELINE">Subject: </th>
          <td>JSAPI interface break about to land: C++ setter functions
            for JS properties</td>
        </tr>
        <tr>
          <th align="RIGHT" nowrap="nowrap" valign="BASELINE">Date: </th>
          <td>Wed, 09 Feb 2011 11:26:22 -0800</td>
        </tr>
        <tr>
          <th align="RIGHT" nowrap="nowrap" valign="BASELINE">From: </th>
          <td>Jim Blandy <a class="moz-txt-link-rfc2396E" href="mailto:jimb@mozilla.com"><jimb@mozilla.com></a></td>
        </tr>
        <tr>
          <th align="RIGHT" nowrap="nowrap" valign="BASELINE">To: </th>
          <td><a class="moz-txt-link-abbreviated" href="mailto:dev-platform@lists.mozilla.org">dev-platform@lists.mozilla.org</a></td>
        </tr>
        <tr>
          <th align="RIGHT" nowrap="nowrap" valign="BASELINE">Newsgroups:
          </th>
          <td>mozilla.dev.platform,mozilla.dev.tech.js-engine</td>
        </tr>
      </tbody>
    </table>
    <br>
    <br>
    <pre>I'm about to land a change to one of JSAPI's widely used public types. 
My patch includes fixes for Firefox on all platforms, but no fixes 
outside the browser (Thunderbird, Seamonkey, etc). The compiler catches 
all code where changes are needed, and the fixes required are minor.

Details:

In order to implement ECMAScript 5's strict mode correctly, some object 
property setters need to know whether the assignment they're carrying 
out was written in strict mode code or old-style code. For example, the 
following must fail:

        var a=[1,2,3]
        Object.defineProperty(a,2,{configurable:false})
        a.length = 2

because the assignment to 'a.length' is unable to delete the last 
element of the array. The failure must be silent in 'lenient mode' code, 
but throw an exception in strict mode code. The setter for arrays' 
length properties needs to be sensitive to the strictness of the code in 
which the assignment is written.

As discussed in bug 537873:
<a class="moz-txt-link-freetext" href="https://bugzilla.mozilla.org/show_bug.cgi?id=537873">https://bugzilla.mozilla.org/show_bug.cgi?id=537873</a>

after some iterations and backouts, the best solution we found was to 
simply add a 'JSBool strict' argument to the setter callback functions 
for JS object properties. Thus, whereas getters and setters both used to 
be JSPropertyOp, setters are now JSStrictPropertyOp. (Getters are 
unchanged.)

Fortunately, since we're changing a type, you'll get compiler errors for 
all the code that needs to be changed. The fixes I've needed to make 
have fallen into three main categories:

1) Use JS_StrictPropertyStub for the default setter in class 
definitions, not JS_PropertyStub:

> @@ -144,7 +144,7 @@ nsXULPDGlobalObject_resolve(JSContext *c
>  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
>  };

2) Use JS_StrictPropertyStub for setters, not JS_PropertyStub, when 
defining properties explictly:

> @@ -6905,7 +6913,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
>        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;

3) Add a 'JSBool strict' argument to real setters. The setters can 
ignore this new argument.

@@ -138,7 +138,7 @@ nsXBLDocGlobalObject_getProperty(JSConte

 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);

If you'd like to see the details of how I resolved these in the browser 
and within SpiderMonkey itself, see these two patches:

<a class="moz-txt-link-freetext" href="https://bugzilla.mozilla.org/attachment.cgi?id=508274&action=diff">https://bugzilla.mozilla.org/attachment.cgi?id=508274&action=diff</a>
<a class="moz-txt-link-freetext" href="https://bugzilla.mozilla.org/attachment.cgi?id=509033&action=diff">https://bugzilla.mozilla.org/attachment.cgi?id=509033&action=diff</a>

This is annoying, but it's the best way to ES5 compliance, and it's 
actually pretty quick to go through these and fix them, and it doesn't 
require any deep understanding of the code in question.
_______________________________________________
dev-platform mailing list
<a class="moz-txt-link-abbreviated" href="mailto:dev-platform@lists.mozilla.org">dev-platform@lists.mozilla.org</a>
<a class="moz-txt-link-freetext" href="https://lists.mozilla.org/listinfo/dev-platform">https://lists.mozilla.org/listinfo/dev-platform</a>
</pre>
  </body>
</html>