ES6: Remove __proto__ setter poison pill
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-set-object.prototype.__proto__ The __proto__ setter should be reusable on other objects. BUG=v8:2804 LOG=y R=rossberg@chromium.org Review URL: https://codereview.chromium.org/103343005 Patch from Erik Arvidsson <arv@chromium.org>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19165 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
fca3f16b46
commit
01f5601129
@ -104,7 +104,6 @@ var kMessages = {
|
||||
observe_perform_non_string: ["Invalid non-string changeType"],
|
||||
observe_perform_non_function: ["Cannot perform non-function"],
|
||||
observe_notify_non_notifier: ["notify called on non-notifier object"],
|
||||
proto_poison_pill: ["Generic use of __proto__ accessor not allowed"],
|
||||
not_typed_array: ["this is not a typed array."],
|
||||
invalid_argument: ["invalid_argument"],
|
||||
data_view_not_array_buffer: ["First argument to DataView constructor must be an ArrayBuffer"],
|
||||
|
@ -397,8 +397,7 @@ function FromPropertyDescriptor(desc) {
|
||||
}
|
||||
// Must be an AccessorDescriptor then. We never return a generic descriptor.
|
||||
return { get: desc.getGet(),
|
||||
set: desc.getSet() === ObjectSetProto ? ObjectPoisonProto
|
||||
: desc.getSet(),
|
||||
set: desc.getSet(),
|
||||
enumerable: desc.isEnumerable(),
|
||||
configurable: desc.isConfigurable() };
|
||||
}
|
||||
@ -1397,12 +1396,6 @@ function ObjectSetProto(obj) {
|
||||
}
|
||||
|
||||
|
||||
// Harmony __proto__ poison pill.
|
||||
function ObjectPoisonProto(obj) {
|
||||
throw MakeTypeError("proto_poison_pill", []);
|
||||
}
|
||||
|
||||
|
||||
function ObjectConstructor(x) {
|
||||
if (%_IsConstructCall()) {
|
||||
if (x == null) return this;
|
||||
@ -1422,8 +1415,6 @@ function SetUpObject() {
|
||||
|
||||
%SetNativeFlag($Object);
|
||||
%SetCode($Object, ObjectConstructor);
|
||||
%FunctionSetName(ObjectPoisonProto, "__proto__");
|
||||
%FunctionRemovePrototype(ObjectPoisonProto);
|
||||
%SetExpectedNumberOfProperties($Object, 4);
|
||||
|
||||
%SetProperty($Object.prototype, "constructor", $Object, DONT_ENUM);
|
||||
|
@ -25,21 +25,57 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Check that the __proto__ accessor is properly poisoned when extracted
|
||||
// from Object.prototype using the property descriptor.
|
||||
var desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
|
||||
assertEquals("function", typeof desc.get);
|
||||
assertEquals("function", typeof desc.set);
|
||||
assertDoesNotThrow("desc.get.call({})");
|
||||
assertThrows("desc.set.call({})", TypeError);
|
||||
assertDoesNotThrow("desc.set.call({}, {})");
|
||||
|
||||
|
||||
var obj = {};
|
||||
var obj2 = {};
|
||||
desc.set.call(obj, obj2);
|
||||
assertEquals(obj.__proto__, obj2);
|
||||
assertEquals(desc.get.call(obj), obj2);
|
||||
|
||||
|
||||
// Check that any redefinition of the __proto__ accessor works.
|
||||
Object.defineProperty(Object.prototype, "__proto__", {
|
||||
get: function() {
|
||||
return 42;
|
||||
}
|
||||
});
|
||||
assertEquals({}.__proto__, 42);
|
||||
assertEquals(desc.get.call({}), Object.prototype);
|
||||
|
||||
|
||||
var desc2 = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
|
||||
assertEquals(desc2.get.call({}), 42);
|
||||
assertDoesNotThrow("desc2.set.call({})");
|
||||
|
||||
|
||||
// Check that any redefinition of the __proto__ accessor causes poising
|
||||
// to cease and the accessor to be extracted normally.
|
||||
Object.defineProperty(Object.prototype, "__proto__", { get:function(){} });
|
||||
desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
|
||||
assertDoesNotThrow("desc.get.call({})");
|
||||
assertThrows("desc.set.call({})", TypeError);
|
||||
Object.defineProperty(Object.prototype, "__proto__", { set:function(x){} });
|
||||
desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
|
||||
assertDoesNotThrow("desc.get.call({})");
|
||||
assertDoesNotThrow("desc.set.call({})");
|
||||
var desc3 = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
|
||||
assertDoesNotThrow("desc3.get.call({})");
|
||||
assertDoesNotThrow("desc3.set.call({})");
|
||||
|
||||
|
||||
Object.defineProperty(Object.prototype, "__proto__", { set: undefined });
|
||||
assertThrows(function() {
|
||||
"use strict";
|
||||
var o = {};
|
||||
var p = {};
|
||||
o.__proto__ = p;
|
||||
}, TypeError);
|
||||
|
||||
|
||||
assertTrue(delete Object.prototype.__proto__);
|
||||
var o = {};
|
||||
var p = {};
|
||||
o.__proto__ = p;
|
||||
assertEquals(Object.getPrototypeOf(o), Object.prototype);
|
||||
var desc4 = Object.getOwnPropertyDescriptor(o, "__proto__");
|
||||
assertTrue(desc4.configurable);
|
||||
assertTrue(desc4.enumerable);
|
||||
assertTrue(desc4.writable);
|
||||
assertEquals(desc4.value, p);
|
Loading…
Reference in New Issue
Block a user