Bug 599159: Revert changes making Array length handling strict-sensitive, to be redone differently. r=brendan
authorJim Blandy <jimb@mozilla.com>
Thu, 09 Dec 2010 11:43:31 -0800
changeset 59216 d416528b57827abb0be99fdf220229eefb51af30
parent 59009 52d20032116aa1ecd79113d0413d2f83ae9400d5
child 59217 9a9e6e0179295f5f47398e1607d2ea408c9ce976
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersbrendan
bugs599159
milestone2.0b8pre
Bug 599159: Revert changes making Array length handling strict-sensitive, to be redone differently. r=brendan
js/src/jsarray.cpp
js/src/tests/ecma_5/Array/jstests.list
js/src/tests/ecma_5/Array/regress-599159.js
js/src/tests/ecma_5/strict/jstests.list
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -576,28 +576,21 @@ array_length_getter(JSContext *cx, JSObj
             vp->setNumber(obj->getArrayLength());
             return JS_TRUE;
         }
     } while ((obj = obj->getProto()) != NULL);
     return JS_TRUE;
 }
 
 static JSBool
-array_length_setter(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
+array_length_setter(JSContext *cx, JSObject *obj, jsid id, Value *vp)
 {
     jsuint newlen, oldlen, gap, index;
     Value junk;
 
-    /* Check for a sealed object first. */
-    if (!obj->isExtensible()) {
-        return js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_READ_ONLY,
-                                        JSDVG_IGNORE_STACK, IdToValue(id), NULL,
-                                        NULL, NULL);
-    }
-
     if (!obj->isArray()) {
         jsid lengthId = ATOM_TO_JSID(cx->runtime->atomState.lengthAtom);
 
         return obj->defineProperty(cx, lengthId, *vp, NULL, NULL, JSPROP_ENUMERATE);
     }
 
     newlen = ValueIsLength(cx, vp);
     if (vp->isNull())
@@ -628,18 +621,16 @@ array_length_setter(JSContext *cx, JSObj
         do {
             --oldlen;
             if (!JS_CHECK_OPERATION_LIMIT(cx)) {
                 obj->setArrayLength(oldlen + 1);
                 return false;
             }
             if (!DeleteArrayElement(cx, obj, oldlen, true)) {
                 obj->setArrayLength(oldlen + 1);
-                if (strict)
-                    return false;
                 JS_ClearPendingException(cx);
                 return true;
             }
         } while (oldlen != newlen);
         obj->setArrayLength(newlen);
     } else {
         /*
          * We are going to remove a lot of indexes in a presumably sparse
@@ -793,17 +784,17 @@ array_typeOf(JSContext *cx, JSObject *ob
 }
 
 static JSBool
 array_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
 {
     uint32 i;
 
     if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
-        return array_length_setter(cx, obj, id, vp, strict);
+        return array_length_setter(cx, obj, id, vp);
 
     if (!obj->isDenseArray())
         return js_SetProperty(cx, obj, id, vp, strict);
 
     do {
         if (!js_IdIsIndex(id, &i))
             break;
         if (js_PrototypeHasIndexedProperties(cx, obj))
@@ -823,27 +814,16 @@ array_setProperty(JSContext *cx, JSObjec
         return true;
     } while (false);
 
     if (!obj->makeDenseArraySlow(cx))
         return false;
     return js_SetProperty(cx, obj, id, vp, strict);
 }
 
-static JSBool
-slowarray_setProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict)
-{
-    JS_ASSERT(obj->isSlowArray());
-
-    if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom))
-        return array_length_setter(cx, obj, id, vp, strict);
-
-    return js_SetProperty(cx, obj, id, vp, strict);
-}
-
 JSBool
 js_PrototypeHasIndexedProperties(JSContext *cx, JSObject *obj)
 {
     /*
      * Walk up the prototype chain and see if this indexed element already
      * exists. If we hit the end of the prototype chain, it's safe to set the
      * element on the original object.
      */
@@ -991,44 +971,17 @@ Class js_SlowArrayClass = {
     JSCLASS_HAS_PRIVATE |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
     slowarray_addProperty,
     PropertyStub,   /* delProperty */
     PropertyStub,   /* getProperty */
     PropertyStub,   /* setProperty */
     EnumerateStub,
     ResolveStub,
-    js_TryValueOf,
-    NULL,           /* finalize    */
-    NULL,           /* reserved0   */
-    NULL,           /* checkAccess */
-    NULL,           /* call        */
-    NULL,           /* construct   */
-    NULL,           /* xdrObject   */
-    NULL,           /* hasInstance */
-    NULL,           /* mark        */
-    JS_NULL_CLASS_EXT,
-    {
-        NULL,       /* lookupProperty   */
-        NULL,       /* defineProperty   */
-        NULL,       /* getProperty      */
-        /*
-         * For assignments to 'length', we need to know the setter's strictness. A property's
-         * setter isn't passed that, but the ObjectOps member is, so use that.
-         */
-        slowarray_setProperty,
-        NULL,       /* getAttributes    */
-        NULL,       /* setAttributes    */
-        NULL,       /* deleteProperty   */
-        NULL,       /* enumerate        */
-        NULL,       /* typeOf           */
-        NULL,       /* trace            */
-        NULL,       /* thisObject       */
-        NULL,       /* clear            */
-    }
+    js_TryValueOf
 };
 
 /*
  * Convert an array object from fast-and-dense to slow-and-flexible.
  */
 JSBool
 JSObject::makeDenseArraySlow(JSContext *cx)
 {
@@ -1048,17 +1001,17 @@ JSObject::makeDenseArraySlow(JSContext *
 
     uint32 capacity = getDenseArrayCapacity();
 
     /*
      * Begin with the length property to share more of the property tree.
      * The getter/setter here will directly access the object's private value.
      */
     if (!addProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.lengthAtom),
-                     array_length_getter, NULL,
+                     array_length_getter, array_length_setter,
                      SHAPE_INVALID_SLOT, JSPROP_PERMANENT | JSPROP_SHARED, 0, 0)) {
         setMap(oldMap);
         return false;
     }
 
     /*
      * Create new properties pointing to existing elements. Pack the array to
      * remove holes, so that shapes use successive slots (as for other objects).
--- a/js/src/tests/ecma_5/Array/jstests.list
+++ b/js/src/tests/ecma_5/Array/jstests.list
@@ -1,5 +1,6 @@
 url-prefix ../../jsreftest.html?test=ecma_5/Array/
 script sort-01.js
 script toString-01.js
 script toLocaleString-01.js
+script regress-599159.js
 script unshift-01.js
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/Array/regress-599159.js
@@ -0,0 +1,10 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+var b = Object.create(Array.prototype);
+b.length = 12;
+assertEq(b.length, 12);
+
+reportCompare(true,true);
--- a/js/src/tests/ecma_5/strict/jstests.list
+++ b/js/src/tests/ecma_5/strict/jstests.list
@@ -20,17 +20,17 @@ script 13.1.js
 script 15.3.4.5.js
 script 15.3.5.1.js
 script 15.3.5.2.js
 script 15.4.4.6.js
 script 15.4.4.8.js
 script 15.4.4.9.js
 script 15.4.4.12.js
 script 15.4.4.13.js
-script 15.4.5.1.js
+skip script 15.4.5.1.js  # Waiting for bug 537873 to be fully resolved.
 script 15.5.5.1.js
 script 15.5.5.2.js
 script 15.10.7.js
 script B.1.1.js
 script B.1.2.js
 script function-name-arity.js
 script primitive-this-no-writeback.js
 script regress-532254.js