[].push wrt properties along the [[Prototype]] chain
Mark S. Miller
erights at google.com
Sat Feb 16 10:57:15 PST 2013
Allen, by "put:", did you mean "set:"?
On Sat, Feb 16, 2013 at 10:51 AM, Allen Wirfs-Brock
<allen at wirfs-brock.com>wrote:
>
> On Feb 15, 2013, at 6:30 PM, Jeff Walden wrote:
>
> Consider:
>
> Object.defineProperty(Object.prototype, "0", { value: 17, writable:
> false, configurable: false });
> [].push(42);
>
> Per ES5, I think this is supposed to throw a TypeError. The push should
> be setting property "0" with Throw = true, which means that when [[CanPut]]
> fails, a TypeError gets thrown. No engine I can test does this, I suspect
> because everyone's mis-implemented an optimization.
>
>
> Right, ES5 carefully put in all those Throw = true's, to account for
> exactly those situations. Did you also test for non-writable and accessor
> properties on an actual Array instance.
>
> Did you try this on IE9/10 (I don't have copies available with me right
> now). All the other browsers had implementations of push and other Array
> methods that predate ES5, so it is conceivable that those implementations
> have not been updated to match the spec. IE9, on the other-hand, was a new
> implementation that post dates ES5 and was supposed to be following the
> spec.
>
> I'm shocked if Test262 doesn't include any tests for these situations.
> I'm remember including them in a list of things that needed to be tested
> for all of the Array methods that was handed off to the team that wrote the
> Test262 tests.
>
>
> On IRC it was pointed out that
> http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistakeis supposed to fix this: you should be able to shadow a non-writable
> property on a prototype. Or something. But there's contention there about
> this not actually being a mistake. (I think that contention's probably
> right, for what it's worth, but I digress.)
>
> But suppose it isn't, for the moment. What then of this:
>
> Object.defineProperty(Object.prototype, 0, { set: function() { throw
> "FAIL"; } });
> [].push(42)
>
> I think this should throw, again because it's *setting* property "0". But
> again, no engine I can test actually throws for this.
>
> My gut says this is a case where every engine attempted to optimize, and
> optimized wrongly such that incorrect semantics resulted. The question is,
> since no engine's following the spec, whether the spec should change, the
> engines should change, or what. Given that indexed properties on
> Array.prototype and Object.prototype are not something anyone sane does, I
> tend to think changing it to [[DefineOwnProperty]] would be good. But
> maybe the spec really should win, and everyone should change. I dunno.
> Please sort this out! :-)
>
>
> Prior to ES5, implementations were doing various random things for the
> edge cases of accessor properties in arrays. ES5 now tells them what they
> are supposed to do.
>
> Note that implementation bugs aren't just in the Array methods and don't
> require access to inherited properties. I just tried the following in a
> FF18 scratch pad:
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
>
> Note that no exception was reported on the [[Put]] to the accessor.
>
> Allen
>
> var a = []
> Object.defineProperty(a, "1", {
> get: function() {throw "get"; return "got 1"},
> put: function(v) {throw "put"+v},
> configurable: true});
>
> a[1]
> /*
> Exception: get
> */
>
> a[1]=0
> /*
> 0
> */
>
>
>
>
> Jeff
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
--
Cheers,
--MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130216/0a686658/attachment.html>
More information about the es-discuss
mailing list