96 lines
2.2 KiB
JavaScript
96 lines
2.2 KiB
JavaScript
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) {
|
|
proto[key1] = 1;
|
|
proto[key2] = 2;
|
|
Object.defineProperty(proto, key2, {writable: false});
|
|
|
|
const child = Object.create(proto);
|
|
let nextValue = 10;
|
|
|
|
function isKey1WritableStrict(obj) {
|
|
"use strict";
|
|
try {
|
|
obj[key1] = ++nextValue;
|
|
} catch {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function isKey1Writable(obj) {
|
|
obj[key1] = ++nextValue;
|
|
return obj[key1] === nextValue;
|
|
}
|
|
|
|
function isKey2WritableStrict(obj) {
|
|
"use strict";
|
|
try {
|
|
obj[key2] = ++nextValue;
|
|
} catch {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function isKey2Writable(obj) {
|
|
obj[key2] = ++nextValue;
|
|
return obj[key2] === nextValue;
|
|
}
|
|
|
|
noInline(isKey1WritableStrict);
|
|
noInline(isKey1Writable);
|
|
noInline(isKey2WritableStrict);
|
|
noInline(isKey2Writable);
|
|
|
|
for (let i = 0; i < 1e4; ++i) {
|
|
shouldBe(isKey1WritableStrict(child), true);
|
|
shouldBe(isKey1Writable(proto), true);
|
|
shouldBe(isKey2WritableStrict(child), false);
|
|
shouldBe(isKey2Writable(proto), false);
|
|
|
|
delete child[key1];
|
|
delete child[key2];
|
|
}
|
|
|
|
Object.defineProperty(proto, key1, {writable: false});
|
|
shouldBe(isKey1WritableStrict(child), false);
|
|
shouldBe(isKey1Writable(proto), false);
|
|
|
|
Object.defineProperty(proto, key2, {writable: true});
|
|
shouldBe(isKey2WritableStrict(child), true);
|
|
shouldBe(isKey2Writable(proto), true);
|
|
}
|
|
|
|
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);
|