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