mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-28 06:53:42 +08:00
314 lines
11 KiB
JavaScript
314 lines
11 KiB
JavaScript
// Copyright (C) 2015 André Bargull. All rights reserved.
|
|
// This adaptation of Test262's testTypedArray.js is governed by the BSD license in vendor/LICENSE.
|
|
// It keeps the upstream constructor lists and argument factories. The host
|
|
// assert.js is replaced by harness.ts, so isPrimitive is defined here, and
|
|
// Test262Error is a class that needs `new`. Factories bind through a
|
|
// closure, and feature checks use typeof (and tolerate an ArrayBuffer
|
|
// without a reachable prototype, which then has no resizable or immutable
|
|
// factories). %TypedArray% (`TypedArray`) is left out: tests that name it
|
|
// are excluded.
|
|
|
|
function isPrimitive(value) {
|
|
return !value || (typeof value !== "object" && typeof value !== "function");
|
|
}
|
|
|
|
var floatArrayConstructors = [
|
|
Float64Array,
|
|
Float32Array
|
|
];
|
|
|
|
var nonClampedIntArrayConstructors = [
|
|
Int32Array,
|
|
Int16Array,
|
|
Int8Array,
|
|
Uint32Array,
|
|
Uint16Array,
|
|
Uint8Array
|
|
];
|
|
|
|
var intArrayConstructors = nonClampedIntArrayConstructors.concat([Uint8ClampedArray]);
|
|
|
|
// Float16Array is a newer feature
|
|
// adding it to this list unconditionally would cause implementations lacking it to fail every test which uses it
|
|
if (typeof Float16Array !== "undefined") {
|
|
floatArrayConstructors.push(Float16Array);
|
|
}
|
|
|
|
var bigIntArrayConstructors = [];
|
|
if (typeof BigInt64Array !== "undefined") {
|
|
bigIntArrayConstructors.push(BigInt64Array);
|
|
}
|
|
if (typeof BigUint64Array !== "undefined") {
|
|
bigIntArrayConstructors.push(BigUint64Array);
|
|
}
|
|
|
|
var typedArrayConstructors = floatArrayConstructors.concat(intArrayConstructors);
|
|
|
|
var allTypedArrayConstructors = typedArrayConstructors.concat(bigIntArrayConstructors);
|
|
|
|
function makePassthrough(TA, primitiveOrIterable) {
|
|
return primitiveOrIterable;
|
|
}
|
|
|
|
function makeArray(TA, primitiveOrIterable) {
|
|
if (isPrimitive(primitiveOrIterable)) {
|
|
var n = Number(primitiveOrIterable);
|
|
// Only values between 0 and 2**53 - 1 inclusive can get mapped into TA contents.
|
|
if (!(n >= 0 && n < 9007199254740992)) return primitiveOrIterable;
|
|
return Array.from({ length: n }, function() { return "0"; });
|
|
}
|
|
return Array.from(primitiveOrIterable);
|
|
}
|
|
|
|
function makeArrayLike(TA, primitiveOrIterable) {
|
|
var arr = makeArray(TA, primitiveOrIterable);
|
|
if (isPrimitive(arr)) return arr;
|
|
var obj = { length: arr.length };
|
|
for (var i = 0; i < obj.length; i++) obj[i] = arr[i];
|
|
return obj;
|
|
}
|
|
|
|
var makeIterable;
|
|
if (typeof Symbol !== "undefined") {
|
|
makeIterable = function makeIterable(TA, primitiveOrIterable) {
|
|
var src = makeArray(TA, primitiveOrIterable);
|
|
if (isPrimitive(src)) return src;
|
|
var obj = {};
|
|
obj[Symbol.iterator] = function() { return src[Symbol.iterator](); };
|
|
return obj;
|
|
};
|
|
}
|
|
|
|
function makeArrayBuffer(TA, primitiveOrIterable) {
|
|
var arr = makeArray(TA, primitiveOrIterable);
|
|
if (isPrimitive(arr)) return arr;
|
|
return new TA(arr).buffer;
|
|
}
|
|
|
|
var makeResizableArrayBuffer, makeGrownArrayBuffer, makeShrunkArrayBuffer, makeImmutableArrayBuffer;
|
|
if (typeof ArrayBuffer.prototype === "object" && typeof ArrayBuffer.prototype.resize === "function") {
|
|
var copyIntoArrayBuffer = function(destBuffer, srcBuffer) {
|
|
var destView = new Uint8Array(destBuffer);
|
|
var srcView = new Uint8Array(srcBuffer);
|
|
for (var i = 0; i < srcView.length; i++) destView[i] = srcView[i];
|
|
return destBuffer;
|
|
};
|
|
|
|
makeResizableArrayBuffer = function makeResizableArrayBuffer(TA, primitiveOrIterable) {
|
|
if (isPrimitive(primitiveOrIterable)) {
|
|
var n = Number(primitiveOrIterable) * TA.BYTES_PER_ELEMENT;
|
|
if (!(n >= 0 && n < 9007199254740992)) return primitiveOrIterable;
|
|
return new ArrayBuffer(n, { maxByteLength: n * 2 });
|
|
}
|
|
var fixed = makeArrayBuffer(TA, primitiveOrIterable);
|
|
var byteLength = fixed.byteLength;
|
|
var resizable = new ArrayBuffer(byteLength, { maxByteLength: byteLength * 2 });
|
|
return copyIntoArrayBuffer(resizable, fixed);
|
|
};
|
|
|
|
makeGrownArrayBuffer = function makeGrownArrayBuffer(TA, primitiveOrIterable) {
|
|
if (isPrimitive(primitiveOrIterable)) {
|
|
var n = Number(primitiveOrIterable) * TA.BYTES_PER_ELEMENT;
|
|
if (!(n >= 0 && n < 9007199254740992)) return primitiveOrIterable;
|
|
var grown = new ArrayBuffer(Math.floor(n / 2), { maxByteLength: n });
|
|
grown.resize(n);
|
|
}
|
|
var fixed = makeArrayBuffer(TA, primitiveOrIterable);
|
|
var byteLength = fixed.byteLength;
|
|
var grown = new ArrayBuffer(Math.floor(byteLength / 2), { maxByteLength: byteLength });
|
|
grown.resize(byteLength);
|
|
return copyIntoArrayBuffer(grown, fixed);
|
|
};
|
|
|
|
makeShrunkArrayBuffer = function makeShrunkArrayBuffer(TA, primitiveOrIterable) {
|
|
if (isPrimitive(primitiveOrIterable)) {
|
|
var n = Number(primitiveOrIterable) * TA.BYTES_PER_ELEMENT;
|
|
if (!(n >= 0 && n < 9007199254740992)) return primitiveOrIterable;
|
|
var shrunk = new ArrayBuffer(n * 2, { maxByteLength: n * 2 });
|
|
shrunk.resize(n);
|
|
}
|
|
var fixed = makeArrayBuffer(TA, primitiveOrIterable);
|
|
var byteLength = fixed.byteLength;
|
|
var shrunk = new ArrayBuffer(byteLength * 2, { maxByteLength: byteLength * 2 });
|
|
copyIntoArrayBuffer(shrunk, fixed);
|
|
shrunk.resize(byteLength);
|
|
return shrunk;
|
|
};
|
|
}
|
|
if (typeof ArrayBuffer.prototype === "object" && typeof ArrayBuffer.prototype.transferToImmutable === "function") {
|
|
makeImmutableArrayBuffer = function makeImmutableArrayBuffer(TA, primitiveOrIterable) {
|
|
if (isPrimitive(primitiveOrIterable)) {
|
|
var n = Number(primitiveOrIterable) * TA.BYTES_PER_ELEMENT;
|
|
if (!(n >= 0 && n < 9007199254740992)) return primitiveOrIterable;
|
|
return (new ArrayBuffer(n)).transferToImmutable();
|
|
}
|
|
var mutable = makeArrayBuffer(TA, primitiveOrIterable);
|
|
return mutable.transferToImmutable();
|
|
};
|
|
}
|
|
|
|
var typedArrayCtorArgFactories = [makePassthrough, makeArray, makeArrayLike];
|
|
if (makeIterable) typedArrayCtorArgFactories.push(makeIterable);
|
|
typedArrayCtorArgFactories.push(makeArrayBuffer);
|
|
if (makeResizableArrayBuffer) typedArrayCtorArgFactories.push(makeResizableArrayBuffer);
|
|
if (makeGrownArrayBuffer) typedArrayCtorArgFactories.push(makeGrownArrayBuffer);
|
|
if (makeShrunkArrayBuffer) typedArrayCtorArgFactories.push(makeShrunkArrayBuffer);
|
|
if (makeImmutableArrayBuffer) typedArrayCtorArgFactories.push(makeImmutableArrayBuffer);
|
|
|
|
|
|
function ctorArgFactoryMatchesSome(argFactory, features) {
|
|
for (var i = 0; i < features.length; ++i) {
|
|
switch (features[i]) {
|
|
case "passthrough":
|
|
if (argFactory === makePassthrough) return true;
|
|
break;
|
|
case "arraylike":
|
|
if (argFactory === makeArray || argFactory === makeArrayLike) return true;
|
|
break;
|
|
case "iterable":
|
|
if (argFactory === makeIterable) return true;
|
|
break;
|
|
case "arraybuffer":
|
|
if (
|
|
argFactory === makeArrayBuffer ||
|
|
argFactory === makeResizableArrayBuffer ||
|
|
argFactory === makeGrownArrayBuffer ||
|
|
argFactory === makeShrunkArrayBuffer ||
|
|
argFactory === makeImmutableArrayBuffer
|
|
) {
|
|
return true;
|
|
}
|
|
break;
|
|
case "resizable":
|
|
if (
|
|
argFactory === makeResizableArrayBuffer ||
|
|
argFactory === makeGrownArrayBuffer ||
|
|
argFactory === makeShrunkArrayBuffer
|
|
) {
|
|
return true;
|
|
}
|
|
break;
|
|
case "immutable":
|
|
if (argFactory === makeImmutableArrayBuffer) return true;
|
|
break;
|
|
default:
|
|
throw new Test262Error("unknown feature: " + features[i]);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
function bindArgFactory(argFactory, constructor) {
|
|
return function(primitiveOrIterable) {
|
|
return argFactory(constructor, primitiveOrIterable);
|
|
};
|
|
}
|
|
|
|
function testWithAllTypedArrayConstructors(f, constructors, includeArgFactories, excludeArgFactories) {
|
|
var ctors = constructors || allTypedArrayConstructors;
|
|
var ctorArgFactories = typedArrayCtorArgFactories;
|
|
if (includeArgFactories) {
|
|
ctorArgFactories = [];
|
|
for (var i = 0; i < typedArrayCtorArgFactories.length; ++i) {
|
|
if (ctorArgFactoryMatchesSome(typedArrayCtorArgFactories[i], includeArgFactories)) {
|
|
ctorArgFactories.push(typedArrayCtorArgFactories[i]);
|
|
}
|
|
}
|
|
}
|
|
if (excludeArgFactories) {
|
|
ctorArgFactories = ctorArgFactories.slice();
|
|
for (var i = ctorArgFactories.length - 1; i >= 0; --i) {
|
|
if (ctorArgFactoryMatchesSome(ctorArgFactories[i], excludeArgFactories)) {
|
|
ctorArgFactories.splice(i, 1);
|
|
}
|
|
}
|
|
}
|
|
if (ctorArgFactories.length === 0) {
|
|
throw new Test262Error("no arg factories match include " + includeArgFactories + " and exclude " + excludeArgFactories);
|
|
}
|
|
for (var k = 0; k < ctorArgFactories.length; ++k) {
|
|
var argFactory = ctorArgFactories[k];
|
|
for (var i = 0; i < ctors.length; ++i) {
|
|
var constructor = ctors[i];
|
|
var boundArgFactory = bindArgFactory(argFactory, constructor);
|
|
try {
|
|
f(constructor, boundArgFactory);
|
|
} catch (e) {
|
|
e.message += " (Testing with " + constructor.name + " and " + argFactory.name + ".)";
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function testWithTypedArrayConstructors(f, constructors, includeArgFactories, excludeArgFactories) {
|
|
var ctors = constructors || typedArrayConstructors;
|
|
testWithAllTypedArrayConstructors(f, ctors, includeArgFactories, excludeArgFactories);
|
|
}
|
|
|
|
function testWithBigIntTypedArrayConstructors(f, constructors, includeArgFactories, excludeArgFactories) {
|
|
var ctors = constructors || [BigInt64Array, BigUint64Array];
|
|
testWithAllTypedArrayConstructors(f, ctors, includeArgFactories, excludeArgFactories);
|
|
}
|
|
|
|
var nonAtomicsFriendlyTypedArrayConstructors = floatArrayConstructors.concat([Uint8ClampedArray]);
|
|
function testWithNonAtomicsFriendlyTypedArrayConstructors(f, includeArgFactories, excludeArgFactories) {
|
|
testWithAllTypedArrayConstructors(
|
|
f,
|
|
nonAtomicsFriendlyTypedArrayConstructors,
|
|
includeArgFactories,
|
|
excludeArgFactories
|
|
);
|
|
}
|
|
|
|
function testWithAtomicsFriendlyTypedArrayConstructors(f, includeArgFactories, excludeArgFactories) {
|
|
testWithAllTypedArrayConstructors(
|
|
f,
|
|
[
|
|
Int32Array,
|
|
Int16Array,
|
|
Int8Array,
|
|
Uint32Array,
|
|
Uint16Array,
|
|
Uint8Array,
|
|
],
|
|
includeArgFactories,
|
|
excludeArgFactories
|
|
);
|
|
}
|
|
|
|
function testTypedArrayConversions(byteConversionValues, fn) {
|
|
var values = byteConversionValues.values;
|
|
var expected = byteConversionValues.expected;
|
|
|
|
testWithTypedArrayConstructors(function(TA) {
|
|
var name = TA.name.slice(0, -5);
|
|
|
|
return values.forEach(function(value, index) {
|
|
var exp = expected[name][index];
|
|
var initial = 0;
|
|
if (exp === 0) {
|
|
initial = 1;
|
|
}
|
|
fn(TA, value, exp, initial);
|
|
});
|
|
}, null, ["passthrough"]);
|
|
}
|
|
|
|
function isFloatTypedArrayConstructor(arg) {
|
|
return floatArrayConstructors.indexOf(arg) !== -1;
|
|
}
|
|
|
|
function floatTypedArrayConstructorPrecision(FA) {
|
|
if (typeof Float16Array !== "undefined" && FA === Float16Array) {
|
|
return "half";
|
|
} else if (FA === Float32Array) {
|
|
return "single";
|
|
} else if (FA === Float64Array) {
|
|
return "double";
|
|
} else {
|
|
throw new Error("Malformed test - floatTypedArrayConstructorPrecision called with non-float TypedArray");
|
|
}
|
|
}
|