Reviewers: rossberg,

Message:
Added new patch set. Landed.


http://codereview.chromium.org/8996008/diff/1/src/runtime.cc
File src/runtime.cc (right):

http://codereview.chromium.org/8996008/diff/1/src/runtime.cc#newcode4333
src/runtime.cc:4333: // in defineProperty. Firefox disagrees here, and
actually changes the value.
On 2011/12/19 16:47:44, rossberg wrote:
80 characters

Done.

http://codereview.chromium.org/8996008/diff/1/src/runtime.cc#newcode4346
src/runtime.cc:4346: kNonStrictMode);
On 2011/12/19 16:47:44, rossberg wrote:
This should be KStrictMode, I think.

Done. On this code path it doesn't actually matter. The mode is only
considered for JavaScript accessors, but not for API nor foreign
callbacks.

http://codereview.chromium.org/8996008/diff/1/test/mjsunit/regress/regress-1530.js
File test/mjsunit/regress/regress-1530.js (right):

http://codereview.chromium.org/8996008/diff/1/test/mjsunit/regress/regress-1530.js#newcode28
test/mjsunit/regress/regress-1530.js:28: // Test that redefining the
'prototype' property of a function object
On 2011/12/19 16:47:44, rossberg wrote:
Maybe test other magic properties of functions, too?

Done. All other properties of function objects for which we use foreign
callbacks are non-writable, but I added checks that
Object.defineProperty() throws on them as expected.

Description:
Fix handling of foreign callbacks in DefineOwnProperty.

We use foreign callbacks to make some properties shadow internal values
but still behave as data properties from within JavaScript. This means
when a value is passed to Object.defineProperty() on such a property,
it should update the internal value instead of redefinind the property
and destroying the shadowing.

[email protected]
BUG=v8:1530
TEST=mjsunit/regress/regress-1530,test262/S15.3.3.1_A4

Committed: http://code.google.com/p/v8/source/detail?r=10279

Please review this at http://codereview.chromium.org/8996008/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/runtime.cc
  A test/mjsunit/regress/regress-1530.js
  M test/test262/test262.status


Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index b0e1a057da4b4384cedff7372fd0a04775c14988..544b210c0b6f1520ecb2a161608fe81970cb8fd9 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -4326,12 +4326,26 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
   LookupResult result(isolate);
   js_object->LocalLookupRealNamedProperty(*name, &result);

-  // To be compatible with safari we do not change the value on API objects
- // in defineProperty. Firefox disagrees here, and actually changes the value.
-  if (result.IsProperty() &&
-      (result.type() == CALLBACKS) &&
-      result.GetCallbackObject()->IsAccessorInfo()) {
-    return isolate->heap()->undefined_value();
+  // Special case for callback properties.
+  if (result.IsProperty() && result.type() == CALLBACKS) {
+    Object* callback = result.GetCallbackObject();
+ // To be compatible with Safari we do not change the value on API objects + // in Object.defineProperty(). Firefox disagrees here, and actually changes
+    // the value.
+    if (callback->IsAccessorInfo()) {
+      return isolate->heap()->undefined_value();
+    }
+ // Avoid redefining foreign callback as data property, just use the stored
+    // setter to update the value instead.
+ // TODO(mstarzinger): So far this only works if property attributes don't
+    // change, this should be fixed once we cleanup the underlying code.
+    if (callback->IsForeign() && result.GetAttributes() == attr) {
+      return js_object->SetPropertyWithCallback(callback,
+                                                *name,
+                                                *obj_value,
+                                                result.holder(),
+                                                kStrictMode);
+    }
   }

   // Take special care when attributes are different and there is already
Index: test/mjsunit/regress/regress-1530.js
diff --git a/test/mjsunit/regress/regress-1530.js b/test/mjsunit/regress/regress-1530.js
new file mode 100644
index 0000000000000000000000000000000000000000..db2114450e4133371bc9045e0c409f5154333d01
--- /dev/null
+++ b/test/mjsunit/regress/regress-1530.js
@@ -0,0 +1,69 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test that redefining the 'prototype' property of a function object
+// does actually set the internal value and does not screw up any
+// shadowing between said property and the internal value.
+
+var f = function() {};
+
+// Verify that normal assignment of 'prototype' property works properly
+// and updates the internal value.
+var x = { foo: 'bar' };
+f.prototype = x;
+assertSame(f.prototype, x);
+assertSame(f.prototype.foo, 'bar');
+assertSame(new f().foo, 'bar');
+assertSame(Object.getPrototypeOf(new f()), x);
+assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, x);
+
+// Verify that 'prototype' behaves like a data property when it comes to
+// redefining with Object.defineProperty() and the internal value gets
+// updated.
+var y = { foo: 'baz' };
+Object.defineProperty(f, 'prototype', { value: y, writable: true });
+assertSame(f.prototype, y);
+assertSame(f.prototype.foo, 'baz');
+assertSame(new f().foo, 'baz');
+assertSame(Object.getPrototypeOf(new f()), y);
+assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, y);
+
+// Verify that the previous redefinition didn't screw up callbacks and
+// the internal value still gets updated.
+var z = { foo: 'other' };
+f.prototype = z;
+assertSame(f.prototype, z);
+assertSame(f.prototype.foo, 'other');
+assertSame(new f().foo, 'other');
+assertSame(Object.getPrototypeOf(new f()), z);
+assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, z);
+
+// Verify that non-writability of other properties is respected.
+assertThrows("Object.defineProperty(f, 'name', { value: {} })");
+assertThrows("Object.defineProperty(f, 'length', { value: {} })");
+assertThrows("Object.defineProperty(f, 'caller', { value: {} })");
+assertThrows("Object.defineProperty(f, 'arguments', { value: {} })");
Index: test/test262/test262.status
diff --git a/test/test262/test262.status b/test/test262/test262.status
index 5fa0ba8518af10a175afa461870b4f4d7c0aae07..1da988efc196a7c79cb9d2865297d67a9640fbec 100644
--- a/test/test262/test262.status
+++ b/test/test262/test262.status
@@ -39,9 +39,6 @@ S8.7_A5_T2: FAIL
 # V8 Bug: http://code.google.com/p/v8/issues/detail?id=1624
 S10.4.2.1_A1: FAIL

-# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1530
-S15.3.3.1_A4: FAIL
-
 # V8 Bug: http://code.google.com/p/v8/issues/detail?id=1475
 15.2.3.6-4-405: FAIL
 15.2.3.6-4-410: FAIL


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to