Compliance issues
anba opened this issue · comments
isConstructor
should not execute the constructor function, but that can't be fixed without ES6 Proxies. 😞- HasProperty not HasOwnProperty, that means the
in
operator needs to be used. Test case:
Array.from({__proto__: {0: "abc", length: 1}})[0] === "abc";
- This line actually needs to use
Object.defineProperty()
to avoid executing setters. Test case:
Object.defineProperty(Array.prototype, "0", {
set: function(x) { throw "set:" + x }
});
Array.from({length: 1, 0: "abc"}); // should not throw
A.length = len
requires strict-mode semantics. Test case:
Array.from.call(function(){ return Object.freeze({}); }, {}); // should throw
Awesome bug reports, as usual! Thanks so much. I’ll fix these, except for the isConstructor
thing, as these polyfills are meant to be usable in ES3/ES5 environments (like you said).
except for the isConstructor thing, as these polyfills are meant to be usable in ES3/ES5 environments
Yeah, that's why I've added the sad smiley face. It's a shame that there is no built-in way to test for constructors in pre-ES6 environments.
Could you give an example of how to use Object.defineProperty(obj, x, { … })
to avoid executing the getter for x
?
// in Node / V8
Object.defineProperty(Array.prototype, '0', { 'set': function(x) { throw 'set:' + x; } });
var x = [];
Object.defineProperty(x, '0', { 'value': 42 }); // throws :(
Huh? The code you've given should never throw (*), well unless there is a bug in the JavaScript implementation. 😕
The spec text CreateDataPropertyOrThrow(A, Pk, mappedValue)
directly translates to:
Object.defineProperty(A, Pk, {
value: mappedValue, writable: true, enumerable: true, configurable: true
});
(*) There is actually one possibility for this to throw a TypeError exception. When there is either a "get" or "set" property on Object.prototype
, the property descriptor object {'value': 42}
will be considered both a value and a accessor property descriptor. Both that's somewhat unlikely here.
Thanks for taking a look. I’ve filed this as a V8 bug: https://code.google.com/p/v8/issues/detail?id=3068.
Closing as all ‘fixable’ bugs should now be fixed. Let me know if you spot anything sloppy in the patches. Thanks again!
Also see 105e3f0.
Re-opening pending @anba’s feedback.
The original bug report had no accompanying spec references, so I'm not actually sure if we even need the Object.freeze
check.
22.1.2.1 Array.from, step 17.f uses 7.3.4 CreateDataPropertyOrThrow which in turn calls 7.3.3 CreateDataProperty. And CreateDataProperty invokes [[DefineOwnProperty]] to create the property. That means no setters get called.
Interesting - %TypedArray%.from
uses [[Put]]
but all other mentions of that internal method have been removed. I'll restore the defineProperty checks here, and add them to the MDN polyfill and es6 shim later today, thanks.