Bug 713944 - Assert that a data descriptor referenced in the property cache was writable only if the property cache entry was a hit. If it wasn't, the descriptor might have been made writable in the interim -- and if the cache entry was for finding the property along the prototype chain, the shape key used for the entry lookup would be invariant across the data descriptor's mutation. This also fixes bug 643847. r=jorendorff
authorJeff Walden <jwalden@mit.edu>
Thu, 29 Dec 2011 05:44:10 -0600
changeset 83601 a258a0b2d9e4093ae1844ba4733e1010054b5fa7
parent 83600 656af9b2d4817739d1eed19c6ef3e6f1d022f95c
child 83602 b91a01700813141d43744a0e509cc9cf60e0c88b
push id21773
push userphilringnalda@gmail.com
push dateSun, 01 Jan 2012 02:50:39 +0000
treeherdermozilla-central@da6c33eb4b16 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs713944, 643847
milestone12.0a1
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 713944 - Assert that a data descriptor referenced in the property cache was writable only if the property cache entry was a hit. If it wasn't, the descriptor might have been made writable in the interim -- and if the cache entry was for finding the property along the prototype chain, the shape key used for the entry lookup would be invariant across the data descriptor's mutation. This also fixes bug 643847. r=jorendorff
js/src/jsinterp.cpp
js/src/tests/ecma_5/Object/jstests.list
js/src/tests/ecma_5/Object/proto-property-change-writability-set.js
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -3156,21 +3156,23 @@ BEGIN_CASE(JSOP_SETMETHOD)
              * Property cache hit, only partially confirmed by testForSet. We
              * know that the entry applies to regs.pc and that obj's shape
              * matches.
              *
              * The entry predicts a set either an existing "own" property, or
              * on a prototype property that has a setter.
              */
             const Shape *shape = entry->prop;
-            JS_ASSERT_IF(shape->isDataDescriptor(), shape->writable());
-            JS_ASSERT_IF(shape->hasSlot(), entry->isOwnPropertyHit());
 
             if (entry->isOwnPropertyHit() ||
-                ((obj2 = obj->getProto()) && obj2->lastProperty() == entry->pshape)) {
+                ((obj2 = obj->getProto()) && obj2->lastProperty() == entry->pshape))
+            {
+                JS_ASSERT_IF(shape->isDataDescriptor(), shape->writable());
+                JS_ASSERT_IF(shape->hasSlot(), entry->isOwnPropertyHit());
+
 #ifdef DEBUG
                 if (entry->isOwnPropertyHit()) {
                     JS_ASSERT(obj->nativeContains(cx, *shape));
                 } else {
                     JS_ASSERT(obj2->nativeContains(cx, *shape));
                     JS_ASSERT(entry->isPrototypePropertyHit());
                     JS_ASSERT(entry->kshape != entry->pshape);
                     JS_ASSERT(!shape->hasSlot());
--- a/js/src/tests/ecma_5/Object/jstests.list
+++ b/js/src/tests/ecma_5/Object/jstests.list
@@ -33,16 +33,17 @@ skip-if(!xulRuntime.shell) script 15.2.3
 skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-4-of-8.js # uses shell load() function
 skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-5-of-8.js # uses shell load() function
 skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-6-of-8.js # uses shell load() function
 skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-7-of-8.js # uses shell load() function
 skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-8-of-8.js # uses shell load() function
 script 15.2.3.6-define-over-method.js
 script mutation-prevention-methods.js
 script object-toString-01.js
+script proto-property-change-writability-set.js
 script vacuous-accessor-unqualified-name.js
 script add-property-non-extensible.js
 skip-if(!xulRuntime.shell) script freeze-global-eval-const.js # uses evalcx
 script preventExtensions-idempotent.js
 script isPrototypeOf.js
 script propertyIsEnumerable.js
 script toLocaleString.js
 script gOPD-vs-prototype-accessor.js
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/Object/proto-property-change-writability-set.js
@@ -0,0 +1,44 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ * Contributors:
+ *   Gary Kwong
+ *   Jeff Walden
+ *   Jason Orendorff
+ */
+
+var accDesc = { set: function() {} };
+var dataDesc = { value: 3 };
+
+function f()
+{
+  constructor = {};
+}
+function g()
+{
+  constructor = {};
+}
+
+Object.defineProperty(Object.prototype, "constructor", accDesc);
+f();
+Object.defineProperty(Object.prototype, "constructor", dataDesc);
+assertEq(constructor, 3);
+f();
+assertEq(constructor, 3);
+g();
+assertEq(constructor, 3);
+
+
+
+var a = { p1: 1, p2: 2 };
+var b = Object.create(a);
+Object.defineProperty(a, "p1", {set: function () {}});
+for (var i = 0; i < 2; i++)
+{
+  b.p1 = {};
+  Object.defineProperty(a, "p1", {value: 3});
+}
+assertEq(b.p1, 3);
+assertEq(a.p1, 3);
+
+reportCompare(true, true);