blob: 1a10ca1588cf13f26239a4e55092cacaa87a5f74 [file] [log] [blame]
function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error("Failed assertion: actual " + actual + " should be " + expected);
}
function shouldNotBe(actual, expected) {
if (actual === expected)
throw new Error("Failed assertion: actual " + actual + " should not be " + expected);
}
function readX(f) {
return f.x;
}
noInline(readX);
function readY(f) {
return f.y;
}
noInline(readY);
var lazyPropNames = [ "name", "length" ];
function test(propName, foo) {
foo.x = 20;
for (var i = 0; i < 1000; i++)
shouldBe(readX(foo), 20);
// Reify the lazy property.
var propValue = foo[propName];
// Verify that we can still access the property after the reification of foo.name.
for (var i = 0; i < 1000; i++)
shouldBe(readX(foo), 20);
foo.y = 25;
for (var i = 0; i < 1000; i++)
shouldBe(readY(foo), 25);
// Verify that the property has the configurable attribute.
var desc = Object.getOwnPropertyDescriptor(foo, propName);
shouldBe(desc.configurable, true);
shouldBe(desc.writable, false);
shouldBe(desc.enumerable, false);
shouldBe(desc.value, propValue);
shouldBe(eval("foo[propName] = 5, foo[propName]"), propValue);
shouldBe(eval("foo." + propName + " = 5, foo." + propName), propValue);
for (var prop in foo)
shouldNotBe(prop, propName);
Object.defineProperty(foo, propName, {
value: propValue,
writable: true,
enumerable: true,
configurable: true
});
shouldBe(eval("foo[propName] = 5, foo[propName]"), 5);
shouldBe(eval("foo." + propName + " = 25, foo." + propName), 25);
var found = false;
for (var prop in foo) {
if (prop === propName) {
found = true;
break;
}
}
shouldBe(found, true);
shouldBe(eval("delete foo." + propName), true);
delete foo.y;
shouldBe(foo.y, undefined);
}
function runTest() {
for (var i = 0; i < lazyPropNames.length; i++)
test(lazyPropNames[i], new Function(""));
}
runTest();