blob: 00176b78b35edd7544cd218406735d13e55af751 [file] [log] [blame]
function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error("bad value: " + actual);
}
function makeDictionary(dict) {
for (let i = 0; i < 1000; ++i)
dict["k" + i] = i;
return dict;
}
function makePolyProtoObject() {
function foo() {
class C {
constructor() {
this._field = 42;
}
}
return new C();
}
for (let i = 0; i < 15; ++i)
foo();
return foo();
}
function test(proto, key1, key2) {
let nextValue = 10;
let value1;
Object.defineProperty(proto, key1, {
set(val) { value1 = val; },
configurable: true,
});
let value2;
Object.defineProperty(proto, key2, {
set(val) { value2 = val; },
configurable: true,
});
const child = Object.create(proto);
function setKey1(obj) {
obj[key1] = ++nextValue;
return value1 === nextValue;
}
function setKey2(obj) {
obj[key2] = ++nextValue;
return value2 === nextValue;
}
noInline(setKey1);
noInline(setKey2);
for (let i = 0; i < 1e4; ++i) {
shouldBe(setKey1(child), true);
shouldBe(setKey1(proto), true);
shouldBe(setKey2(child), true);
shouldBe(setKey2(proto), true);
}
Object.defineProperty(proto, key1, {set: undefined});
shouldBe(setKey1(child), false);
shouldBe(setKey1(proto), false);
Object.defineProperty(proto, key2, {set() {}});
shouldBe(setKey2(child), false);
shouldBe(setKey2(proto), false);
}
test({}, 0, "bar");
test(Object.create(null), "__proto__", 1);
test(makeDictionary({}), "foo", 2);
test(makeDictionary(Object.create(null)), 3, "__proto__");
test(makePolyProtoObject(), "foo", "bar");
test(makePolyProtoObject(), 4, 5);