Source code

Revision control

Copy as Markdown

Other Tools

// Out of bounds writes on typed arrays are uneffectful for all integers.
var x = new Int32Array(10);
// 7.1.16 CanonicalNumericIndexString ( argument )
function CanonicalNumericIndexString(argument) {
// Step 1.
assertEq(typeof argument, "string");
// Step 2.
if (argument === "-0") {
return -0;
}
// Step 3.
var n = Number(argument);
// Step 4.
if (String(n) !== argument) {
return undefined;
}
// Step 5.
return n;
}
function CanonicalIndexInRange(argument) {
return Number.isInteger(argument) && !Object.is(argument, -0) &&
argument >= 0 && argument < x.length;
}
function assertCanonicalNumericIndexString(i) {
var canonical = CanonicalNumericIndexString(i);
assertEq(canonical !== undefined, true,
`Argument ${i} is not a canonical numeric index string`);
x[i] = 0; // Clear any previous value.
x[i] = 1;
var expected = CanonicalIndexInRange(canonical) ? 1 : undefined;
assertEq(x[i], expected, `${i} is a canonical index string`);
// Also test when accessing with a number instead of a string.
x[canonical] = 0; // Clear any previous value.
x[canonical] = 2;
// Add +0 to convert -0 to +0.
var expected = CanonicalIndexInRange(canonical + 0) ? 2 : undefined;
assertEq(x[canonical], expected, `${i} is a canonical index string`);
}
function assertNotCanonicalNumericIndexString(i) {
assertEq(CanonicalNumericIndexString(i) === undefined, true,
`Argument ${i} is a canonical numeric index string`);
x[i] = ""; // Clear any previous value.
x[i] = "test";
assertEq(x[i], "test", `${i} isn't a canonical index string`);
}
function f() {
for (var i = -100; i < 100; i++) {
assertCanonicalNumericIndexString(String(i));
}
}
f();
// INT32_MAX and UINT32_MAX are canonical numeric indices.
assertCanonicalNumericIndexString("2147483647");
assertCanonicalNumericIndexString("4294967295");
// Neither INT64_MAX nor UINT64_MAX are canonical numeric indices.
assertNotCanonicalNumericIndexString("9223372036854775807");
assertNotCanonicalNumericIndexString("18446744073709551615");
// "18446744073709552000" and "18446744073709556000" are canonical numeric indices.
assertEq(String(18446744073709551615), "18446744073709552000");
assertCanonicalNumericIndexString("18446744073709552000");
assertCanonicalNumericIndexString("18446744073709556000");
// Number.MAX_SAFE_INTEGER and Number.MAX_SAFE_INTEGER + 1 are canonical numeric
// indices, but Number.MAX_SAFE_INTEGER + 2 is not.
assertEq(String(Number.MAX_SAFE_INTEGER), "9007199254740991");
assertCanonicalNumericIndexString("9007199254740991");
assertCanonicalNumericIndexString("9007199254740992");
assertNotCanonicalNumericIndexString("9007199254740993");
// Number.MIN_SAFE_INTEGER and Number.MIN_SAFE_INTEGER - 1 are canonical numeric
// indices, but Number.MIN_SAFE_INTEGER - 2 is not.
assertEq(String(Number.MIN_SAFE_INTEGER), "-9007199254740991");
assertCanonicalNumericIndexString("-9007199254740991");
assertCanonicalNumericIndexString("-9007199254740992");
assertNotCanonicalNumericIndexString("-9007199254740993");
// -0 is a canonical numeric index.
assertCanonicalNumericIndexString("-0");
// 0.1 and -0.1 are canonical numeric indices.
assertCanonicalNumericIndexString("0.1");
assertCanonicalNumericIndexString("-0.1");
// 0.10 and -0.10 aren't canonical numeric indices.
assertNotCanonicalNumericIndexString("0.10");
assertNotCanonicalNumericIndexString("-0.10");
// Number.MIN_VALUE and -Number.MIN_VALUE are canonical numeric indices.
assertEq(String(Number.MIN_VALUE), "5e-324");
assertEq(String(-Number.MIN_VALUE), "-5e-324");
assertCanonicalNumericIndexString("5e-324");
assertCanonicalNumericIndexString("-5e-324");
assertNotCanonicalNumericIndexString("5E-324");
assertNotCanonicalNumericIndexString("-5E-324");
// 1e2, -1e2, 1e-2, and -1e-2 aren't canonical numeric indices.
assertNotCanonicalNumericIndexString("1e2");
assertNotCanonicalNumericIndexString("-1e2");
assertNotCanonicalNumericIndexString("1e+2");
assertNotCanonicalNumericIndexString("-1e+2");
assertNotCanonicalNumericIndexString("1e-2");
assertNotCanonicalNumericIndexString("-1e-2");
assertNotCanonicalNumericIndexString("1E2");
assertNotCanonicalNumericIndexString("-1E2");
assertNotCanonicalNumericIndexString("1E+2");
assertNotCanonicalNumericIndexString("-1E+2");
assertNotCanonicalNumericIndexString("1E-2");
assertNotCanonicalNumericIndexString("-1E-2");
// Number.MAX_VALUE and -Number.MAX_VALUE are canonical numeric indices.
assertEq(String(Number.MAX_VALUE), "1.7976931348623157e+308");
assertEq(String(-Number.MAX_VALUE), "-1.7976931348623157e+308");
assertCanonicalNumericIndexString("1.7976931348623157e+308");
assertCanonicalNumericIndexString("-1.7976931348623157e+308");
assertNotCanonicalNumericIndexString("1.7976931348623157E+308");
assertNotCanonicalNumericIndexString("-1.7976931348623157E+308");
// Infinity, -Infinity, and NaN are canonical numeric indices and are handled
// the same way as other out-of-bounds accesses.
assertCanonicalNumericIndexString("Infinity");
assertCanonicalNumericIndexString("-Infinity");
assertCanonicalNumericIndexString("NaN");
// +Infinity, +NaN, or -NaN are not canonical numeric indices.
assertNotCanonicalNumericIndexString("+Infinity");
assertNotCanonicalNumericIndexString("+NaN");
assertNotCanonicalNumericIndexString("-NaN");