Reviewers: Sven Panne,

Description:
Fix behavior of oneshot accessors of error objects.


[email protected]
BUG=


Please review this at https://chromiumcodereview.appspot.com/11368136/

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

Affected files:
  M src/messages.js
  A + test/mjsunit/error-accessors.js


Index: src/messages.js
diff --git a/src/messages.js b/src/messages.js
index 7d0c6bda42f1931e01c787959395caf64cae3b50..81619b32c9019150a7472c4e14c8b30956dc3660 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -768,23 +768,18 @@ function GetStackTraceLine(recv, fun, pos, isGlobal) {

 // Defines accessors for a property that is calculated the first time
 // the property is read.
-function DefineOneShotAccessor(obj, name, fun) {
-  // Note that the accessors consistently operate on 'obj', not 'this'.
-  // Since the object may occur in someone else's prototype chain we
-  // can't rely on 'this' being the same as 'obj'.
-  var value;
-  var value_factory = fun;
+function DefineOneShotAccessor(obj, name, value_factory) {
+  // Note that 'obj' may be different than 'this' since obj may be on the
+  // prototype chain of 'this'.
   var getter = function() {
-    if (value_factory == null) {
-      return value;
-    }
-    value = value_factory(obj);
-    value_factory = null;
+    var value = value_factory(obj);
+    delete obj[name];
+    obj[name] = value;
     return value;
   };
   var setter = function(v) {
-    value_factory = null;
-    value = v;
+    // Set the property for 'this', ignoring this setter.
+    %DefineOrRedefineDataProperty(this, name, v, NONE);
   };
   %DefineOrRedefineAccessorProperty(obj, name, getter, setter, DONT_ENUM);
 }
Index: test/mjsunit/error-accessors.js
diff --git a/test/mjsunit/regress/regress-cntl-descriptors-enum.js b/test/mjsunit/error-accessors.js
similarity index 60%
copy from test/mjsunit/regress/regress-cntl-descriptors-enum.js
copy to test/mjsunit/error-accessors.js
index ee72fafc8a7c67f2b1ab6cc22a734ef8033a5697..9dbdbf3ae641041966392dc4c78ba1266140f2d5 100644
--- a/test/mjsunit/regress/regress-cntl-descriptors-enum.js
+++ b/test/mjsunit/error-accessors.js
@@ -25,22 +25,38 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-// Flags: --allow-natives-syntax --expose-gc
+// Test that the oneshot accessors of error objects behave just like
+// data properties wrt objects that have the error object in the
+// prototype chain.

-DontEnum = 2;
+var o;

-var o = {};
-%SetProperty(o, "a", 0, DontEnum);
+// message is constructed as data property.
+var data_error = new Error("custom message");
+o = {};
+o.__proto__ = data_error;

-var o2 = {};
-%SetProperty(o2, "a", 0, DontEnum);
+assertEquals("custom message", o.message);
+o.message = "another message";
+assertEquals("another message", o.message);
+assertEquals("custom message", data_error.message);

-assertTrue(%HaveSameMap(o, o2));
+// message is constructed as getter.
+var getter_error_1;
+try { x.x } catch (e) { getter_error_1 = e; }
+o = {};
+o.__proto__ = getter_error_1;

-o.y = 2;
+assertEquals("x is not defined", o.message);  // Getter fires.
+o.message = "another message";
+assertEquals("another message", o.message);
+assertEquals("x is not defined", getter_error_1.message);

-for (var v in o) { print(v); }
+var getter_error_2;
+try { x.x } catch (e) { getter_error_2 = e; }
 o = {};
-gc();
+o.__proto__ = getter_error_2;

-for (var v in o2) { print(v); }
+o.message = "another message";  // Setter fires.
+assertEquals("another message", o.message);
+assertEquals("x is not defined", getter_error_1.message);


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

Reply via email to